summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:11:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:11:38 +0000
commitbc7e963c37d9c8d1c854ac960df241cfa34e3dc5 (patch)
treeaa35d7414ce9f1326abf6f723f6dfa5b0aa08b1d /include
parentInitial commit. (diff)
downloadapr-upstream.tar.xz
apr-upstream.zip
Adding upstream version 1.7.2.upstream/1.7.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include')
-rw-r--r--include/apr.h.in656
-rw-r--r--include/apr.hnw445
-rw-r--r--include/apr.hw667
-rw-r--r--include/apr.hwc664
-rw-r--r--include/apr_allocator.h179
-rw-r--r--include/apr_atomic.h207
-rw-r--r--include/apr_cstr.h292
-rw-r--r--include/apr_dso.h94
-rw-r--r--include/apr_encode.h650
-rw-r--r--include/apr_env.h67
-rw-r--r--include/apr_errno.h1342
-rw-r--r--include/apr_escape.h431
-rw-r--r--include/apr_file_info.h428
-rw-r--r--include/apr_file_io.h1005
-rw-r--r--include/apr_fnmatch.h153
-rw-r--r--include/apr_general.h244
-rw-r--r--include/apr_getopt.h160
-rw-r--r--include/apr_global_mutex.h195
-rw-r--r--include/apr_hash.h283
-rw-r--r--include/apr_inherit.h51
-rw-r--r--include/apr_lib.h241
-rw-r--r--include/apr_mmap.h171
-rw-r--r--include/apr_network_io.h953
-rw-r--r--include/apr_perms_set.h65
-rw-r--r--include/apr_poll.h446
-rw-r--r--include/apr_pools.h815
-rw-r--r--include/apr_portable.h549
-rw-r--r--include/apr_proc_mutex.h192
-rw-r--r--include/apr_random.h153
-rw-r--r--include/apr_ring.h517
-rw-r--r--include/apr_shm.h229
-rw-r--r--include/apr_signal.h109
-rw-r--r--include/apr_skiplist.h381
-rw-r--r--include/apr_strings.h380
-rw-r--r--include/apr_support.h57
-rw-r--r--include/apr_tables.h507
-rw-r--r--include/apr_thread_cond.h139
-rw-r--r--include/apr_thread_mutex.h123
-rw-r--r--include/apr_thread_proc.h846
-rw-r--r--include/apr_thread_rwlock.h129
-rw-r--r--include/apr_time.h237
-rw-r--r--include/apr_user.h158
-rw-r--r--include/apr_version.h164
-rw-r--r--include/apr_want.h124
-rw-r--r--include/arch/aix/apr_arch_dso.h41
-rw-r--r--include/arch/apr_private_common.h41
-rw-r--r--include/arch/beos/apr_arch_dso.h41
-rw-r--r--include/arch/beos/apr_arch_proc_mutex.h36
-rw-r--r--include/arch/beos/apr_arch_thread_cond.h46
-rw-r--r--include/arch/beos/apr_arch_thread_mutex.h42
-rw-r--r--include/arch/beos/apr_arch_thread_rwlock.h45
-rw-r--r--include/arch/beos/apr_arch_threadproc.h95
-rw-r--r--include/arch/netware/apr_arch_dso.h43
-rw-r--r--include/arch/netware/apr_arch_file_io.h176
-rw-r--r--include/arch/netware/apr_arch_global_mutex.h29
-rw-r--r--include/arch/netware/apr_arch_internal_time.h26
-rw-r--r--include/arch/netware/apr_arch_networkio.h31
-rw-r--r--include/arch/netware/apr_arch_pre_nw.h57
-rw-r--r--include/arch/netware/apr_arch_proc_mutex.h29
-rw-r--r--include/arch/netware/apr_arch_thread_cond.h29
-rw-r--r--include/arch/netware/apr_arch_thread_mutex.h32
-rw-r--r--include/arch/netware/apr_arch_thread_rwlock.h29
-rw-r--r--include/arch/netware/apr_arch_threadproc.h80
-rw-r--r--include/arch/netware/apr_private.h205
-rw-r--r--include/arch/os2/apr_arch_dso.h37
-rw-r--r--include/arch/os2/apr_arch_file_io.h86
-rw-r--r--include/arch/os2/apr_arch_inherit.h50
-rw-r--r--include/arch/os2/apr_arch_networkio.h76
-rw-r--r--include/arch/os2/apr_arch_os2calls.h59
-rw-r--r--include/arch/os2/apr_arch_proc_mutex.h31
-rw-r--r--include/arch/os2/apr_arch_thread_cond.h33
-rw-r--r--include/arch/os2/apr_arch_thread_mutex.h29
-rw-r--r--include/arch/os2/apr_arch_thread_rwlock.h31
-rw-r--r--include/arch/os2/apr_arch_threadproc.h67
-rw-r--r--include/arch/os390/apr_arch_dso.h39
-rw-r--r--include/arch/unix/apr_arch_atomic.h60
-rw-r--r--include/arch/unix/apr_arch_dso.h63
-rw-r--r--include/arch/unix/apr_arch_file_io.h174
-rw-r--r--include/arch/unix/apr_arch_global_mutex.h37
-rw-r--r--include/arch/unix/apr_arch_inherit.h64
-rw-r--r--include/arch/unix/apr_arch_internal_time.h24
-rw-r--r--include/arch/unix/apr_arch_misc.h67
-rw-r--r--include/arch/unix/apr_arch_networkio.h145
-rw-r--r--include/arch/unix/apr_arch_poll_private.h187
-rw-r--r--include/arch/unix/apr_arch_proc_mutex.h121
-rw-r--r--include/arch/unix/apr_arch_shm.h74
-rw-r--r--include/arch/unix/apr_arch_thread_cond.h42
-rw-r--r--include/arch/unix/apr_arch_thread_mutex.h44
-rw-r--r--include/arch/unix/apr_arch_thread_rwlock.h49
-rw-r--r--include/arch/unix/apr_arch_threadproc.h119
-rw-r--r--include/arch/unix/apr_private.h.in1142
-rw-r--r--include/arch/win32/apr_arch_atime.h63
-rw-r--r--include/arch/win32/apr_arch_dso.h36
-rw-r--r--include/arch/win32/apr_arch_file_io.h266
-rw-r--r--include/arch/win32/apr_arch_inherit.h123
-rw-r--r--include/arch/win32/apr_arch_misc.h517
-rw-r--r--include/arch/win32/apr_arch_networkio.h90
-rw-r--r--include/arch/win32/apr_arch_proc_mutex.h29
-rw-r--r--include/arch/win32/apr_arch_thread_cond.h32
-rw-r--r--include/arch/win32/apr_arch_thread_mutex.h40
-rw-r--r--include/arch/win32/apr_arch_thread_rwlock.h30
-rw-r--r--include/arch/win32/apr_arch_threadproc.h74
-rw-r--r--include/arch/win32/apr_arch_utf8.h56
-rw-r--r--include/arch/win32/apr_dbg_win32_handles.h217
-rw-r--r--include/arch/win32/apr_private.h175
-rw-r--r--include/private/apr_encode_private.h89
106 files changed, 21838 insertions, 0 deletions
diff --git a/include/apr.h.in b/include/apr.h.in
new file mode 100644
index 0000000..ee99def
--- /dev/null
+++ b/include/apr.h.in
@@ -0,0 +1,656 @@
+/* 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 APR_H
+#define APR_H
+
+/* GENERATED FILE WARNING! DO NOT EDIT apr.h
+ *
+ * You must modify apr.h.in instead.
+ *
+ * And please, make an effort to stub apr.hw and apr.hnw in the process.
+ */
+
+/**
+ * @file apr.h
+ * @brief APR Platform Definitions
+ * @remark This is a generated header generated from include/apr.h.in by
+ * ./configure, or copied from include/apr.hw or include/apr.hnw
+ * for Win32 or Netware by those build environments, respectively.
+ */
+
+/**
+ * @defgroup APR Apache Portability Runtime library
+ * @{
+ */
+/**
+ * @defgroup apr_platform Platform Definitions
+ * @{
+ * @warning
+ * <strong><em>The actual values of macros and typedefs on this page<br>
+ * are platform specific and should NOT be relied upon!</em></strong>
+ */
+
+/* So that we can use inline on some critical functions, and use
+ * GNUC attributes (such as to get -Wall warnings for printf-like
+ * functions). Only do this in gcc 2.7 or later ... it may work
+ * on earlier stuff, but why chance it.
+ *
+ * We've since discovered that the gcc shipped with NeXT systems
+ * as "cc" is completely broken. It claims to be __GNUC__ and so
+ * on, but it doesn't implement half of the things that __GNUC__
+ * means. In particular it's missing inline and the __attribute__
+ * stuff. So we hack around it. PR#1613. -djg
+ */
+#if !defined(__GNUC__) || __GNUC__ < 2 || \
+ (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ||\
+ defined(NEXT)
+#ifndef __attribute__
+#define __attribute__(__x)
+#endif
+#define APR_INLINE
+#define APR_HAS_INLINE 0
+#else
+#define APR_INLINE __inline__
+#define APR_HAS_INLINE 1
+#endif
+
+#define APR_HAVE_ARPA_INET_H @arpa_ineth@
+#define APR_HAVE_CONIO_H @conioh@
+#define APR_HAVE_CRYPT_H @crypth@
+#define APR_HAVE_CTYPE_H @ctypeh@
+#define APR_HAVE_DIRENT_H @direnth@
+#define APR_HAVE_ERRNO_H @errnoh@
+#define APR_HAVE_FCNTL_H @fcntlh@
+#define APR_HAVE_IO_H @ioh@
+#define APR_HAVE_LIMITS_H @limitsh@
+#define APR_HAVE_NETDB_H @netdbh@
+#define APR_HAVE_NETINET_IN_H @netinet_inh@
+#define APR_HAVE_NETINET_SCTP_H @netinet_sctph@
+#define APR_HAVE_NETINET_SCTP_UIO_H @netinet_sctp_uioh@
+#define APR_HAVE_NETINET_TCP_H @netinet_tcph@
+#define APR_HAVE_PROCESS_H @processh@
+#define APR_HAVE_PTHREAD_H @pthreadh@
+#define APR_HAVE_SEMAPHORE_H @semaphoreh@
+#define APR_HAVE_SIGNAL_H @signalh@
+#define APR_HAVE_STDARG_H @stdargh@
+#define APR_HAVE_STDINT_H @stdint@
+#define APR_HAVE_STDIO_H @stdioh@
+#define APR_HAVE_STDLIB_H @stdlibh@
+#define APR_HAVE_STRING_H @stringh@
+#define APR_HAVE_STRINGS_H @stringsh@
+#define APR_HAVE_INTTYPES_H @inttypesh@
+#define APR_HAVE_SYS_IOCTL_H @sys_ioctlh@
+#define APR_HAVE_SYS_SENDFILE_H @sys_sendfileh@
+#define APR_HAVE_SYS_SIGNAL_H @sys_signalh@
+#define APR_HAVE_SYS_SOCKET_H @sys_socketh@
+#define APR_HAVE_SYS_SOCKIO_H @sys_sockioh@
+#define APR_HAVE_SYS_SYSLIMITS_H @sys_syslimitsh@
+#define APR_HAVE_SYS_TIME_H @sys_timeh@
+#define APR_HAVE_SYS_TYPES_H @sys_typesh@
+#define APR_HAVE_SYS_UIO_H @sys_uioh@
+#define APR_HAVE_SYS_UN_H @sys_unh@
+#define APR_HAVE_SYS_WAIT_H @sys_waith@
+#define APR_HAVE_TIME_H @timeh@
+#define APR_HAVE_UNISTD_H @unistdh@
+#define APR_HAVE_WINDOWS_H @windowsh@
+#define APR_HAVE_WINSOCK2_H @winsock2h@
+
+/** @} */
+/** @} */
+
+/* We don't include our conditional headers within the doxyblocks
+ * or the extern "C" namespace
+ */
+
+#if APR_HAVE_WINDOWS_H && defined(WIN32)
+/* If windows.h was already included, our preferences don't matter.
+ * If not, include a restricted set of windows headers to our tastes.
+ */
+#ifndef _WINDOWS_
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#ifndef _WIN32_WINNT
+/* Restrict the server to a subset of Windows XP header files by default
+ */
+#define _WIN32_WINNT 0x0501
+#endif
+
+#ifndef NOUSER
+#define NOUSER
+#endif
+#ifndef NOMCX
+#define NOMCX
+#endif
+#ifndef NOIME
+#define NOIME
+#endif
+
+#include <windows.h>
+/*
+ * Add a _very_few_ declarations missing from the restricted set of headers
+ * (If this list becomes extensive, re-enable the required headers above!)
+ * winsock headers were excluded by WIN32_LEAN_AND_MEAN, so include them now
+ */
+#define SW_HIDE 0
+#ifndef _WIN32_WCE
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <mswsock.h>
+#else
+#include <winsock.h>
+#endif
+
+#endif /* ndef _WINDOWS_ */
+#endif /* APR_HAVE_WINDOWS_H */
+
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if APR_HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#if APR_HAVE_STDINT_H
+#ifdef __cplusplus
+/* C99 7.18.4 requires that stdint.h only exposes INT64_C
+ * and UINT64_C for C++ implementations if this is defined: */
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+/* C++ needs this too for PRI*NN formats: */
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+#endif /* __cplusplus */
+#include <stdint.h>
+#endif
+
+#if APR_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if APR_HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef OS2
+#define INCL_DOS
+#define INCL_DOSERRORS
+#include <os2.h>
+#endif
+
+/* header files for PATH_MAX, _POSIX_PATH_MAX */
+#if APR_HAVE_LIMITS_H
+#include <limits.h>
+#else
+#if APR_HAVE_SYS_SYSLIMITS_H
+#include <sys/syslimits.h>
+#endif
+#endif
+
+/* __APPLE__ is now the official pre-defined macro for macOS */
+#ifdef __APPLE__
+#undef DARWIN
+#undef DARWIN_10
+#define DARWIN
+#define DARWIN_10
+#endif /* __APPLE__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup apr_platform
+ * @ingroup APR
+ * @{
+ */
+
+#define APR_HAVE_SHMEM_MMAP_TMP @havemmaptmp@
+#define APR_HAVE_SHMEM_MMAP_SHM @havemmapshm@
+#define APR_HAVE_SHMEM_MMAP_ZERO @havemmapzero@
+#define APR_HAVE_SHMEM_SHMGET_ANON @haveshmgetanon@
+#define APR_HAVE_SHMEM_SHMGET @haveshmget@
+#define APR_HAVE_SHMEM_MMAP_ANON @havemmapanon@
+#define APR_HAVE_SHMEM_BEOS @havebeosarea@
+
+#define APR_USE_SHMEM_MMAP_TMP @usemmaptmp@
+#define APR_USE_SHMEM_MMAP_SHM @usemmapshm@
+#define APR_USE_SHMEM_MMAP_ZERO @usemmapzero@
+#define APR_USE_SHMEM_SHMGET_ANON @useshmgetanon@
+#define APR_USE_SHMEM_SHMGET @useshmget@
+#define APR_USE_SHMEM_MMAP_ANON @usemmapanon@
+#define APR_USE_SHMEM_BEOS @usebeosarea@
+
+#define APR_USE_FLOCK_SERIALIZE @flockser@
+#define APR_USE_SYSVSEM_SERIALIZE @sysvser@
+#define APR_USE_POSIXSEM_SERIALIZE @posixser@
+#define APR_USE_FCNTL_SERIALIZE @fcntlser@
+#define APR_USE_PROC_PTHREAD_SERIALIZE @procpthreadser@
+#define APR_USE_PTHREAD_SERIALIZE @pthreadser@
+
+#define APR_HAS_FLOCK_SERIALIZE @hasflockser@
+#define APR_HAS_SYSVSEM_SERIALIZE @hassysvser@
+#define APR_HAS_POSIXSEM_SERIALIZE @hasposixser@
+#define APR_HAS_FCNTL_SERIALIZE @hasfcntlser@
+#define APR_HAS_PROC_PTHREAD_SERIALIZE @hasprocpthreadser@
+
+#define APR_PROCESS_LOCK_IS_GLOBAL @proclockglobal@
+
+#define APR_HAVE_CORKABLE_TCP @have_corkable_tcp@
+#define APR_HAVE_GETRLIMIT @have_getrlimit@
+#define APR_HAVE_IN_ADDR @have_in_addr@
+#define APR_HAVE_INET_ADDR @have_inet_addr@
+#define APR_HAVE_INET_NETWORK @have_inet_network@
+#define APR_HAVE_IPV6 @have_ipv6@
+#define APR_HAVE_SOCKADDR_UN @have_sockaddr_un@
+#define APR_HAVE_MEMMOVE @have_memmove@
+#define APR_HAVE_SETRLIMIT @have_setrlimit@
+#define APR_HAVE_SIGACTION @have_sigaction@
+#define APR_HAVE_SIGSUSPEND @have_sigsuspend@
+#define APR_HAVE_SIGWAIT @have_sigwait@
+#define APR_HAVE_SA_STORAGE @have_sa_storage@
+#define APR_HAVE_STRCASECMP @have_strcasecmp@
+#define APR_HAVE_STRDUP @have_strdup@
+#define APR_HAVE_STRICMP @have_stricmp@
+#define APR_HAVE_STRNCASECMP @have_strncasecmp@
+#define APR_HAVE_STRNICMP @have_strnicmp@
+#define APR_HAVE_STRSTR @have_strstr@
+#define APR_HAVE_MEMCHR @have_memchr@
+#define APR_HAVE_STRUCT_RLIMIT @struct_rlimit@
+#define APR_HAVE_UNION_SEMUN @have_union_semun@
+#define APR_HAVE_SCTP @have_sctp@
+#define APR_HAVE_IOVEC @have_iovec@
+
+/* APR Feature Macros */
+#define APR_HAS_SHARED_MEMORY @sharedmem@
+#define APR_HAS_THREADS @threads@
+#define APR_HAS_SENDFILE @sendfile@
+#define APR_HAS_MMAP @mmap@
+#define APR_HAS_FORK @fork@
+#define APR_HAS_RANDOM @rand@
+#define APR_HAS_OTHER_CHILD @oc@
+#define APR_HAS_DSO @aprdso@
+#define APR_HAS_SO_ACCEPTFILTER @acceptfilter@
+#define APR_HAS_UNICODE_FS @have_unicode_fs@
+#define APR_HAS_PROC_INVOKED @have_proc_invoked@
+#define APR_HAS_USER @apr_has_user@
+#define APR_HAS_LARGE_FILES @aprlfs@
+#define APR_HAS_XTHREAD_FILES @apr_has_xthread_files@
+#define APR_HAS_OS_UUID @osuuid@
+#define APR_HAS_TIMEDLOCKS @apr_has_timedlocks@
+
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD @apr_procattr_user_set_requires_password@
+
+/* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
+ * to poll on files/pipes.
+ */
+#define APR_FILES_AS_SOCKETS @file_as_socket@
+
+/* This macro indicates whether or not EBCDIC is the native character set.
+ */
+#define APR_CHARSET_EBCDIC @apr_charset_ebcdic@
+
+/* If we have a TCP implementation that can be "corked", what flag
+ * do we use?
+ */
+#define APR_TCP_NOPUSH_FLAG @apr_tcp_nopush_flag@
+
+/* Is the TCP_NODELAY socket option inherited from listening sockets?
+*/
+#define APR_TCP_NODELAY_INHERITED @tcp_nodelay_inherited@
+
+/* Is the O_NONBLOCK flag inherited from listening sockets?
+*/
+#define APR_O_NONBLOCK_INHERITED @o_nonblock_inherited@
+
+/* Typedefs that APR needs. */
+
+typedef unsigned char apr_byte_t;
+
+typedef @short_value@ apr_int16_t;
+typedef unsigned @short_value@ apr_uint16_t;
+
+typedef @int_value@ apr_int32_t;
+typedef unsigned @int_value@ apr_uint32_t;
+
+#define APR_SIZEOF_VOIDP @voidp_size@
+
+/*
+ * Darwin 10's default compiler (gcc42) builds for both 64 and
+ * 32 bit architectures unless specifically told not to.
+ * In those cases, we need to override types depending on how
+ * we're being built at compile time.
+ * NOTE: This is an ugly work-around for Darwin's
+ * concept of universal binaries, a single package
+ * (executable, lib, etc...) which contains both 32
+ * and 64 bit versions. The issue is that if APR is
+ * built universally, if something else is compiled
+ * against it, some bit sizes will depend on whether
+ * it is 32 or 64 bit. This is determined by the __LP64__
+ * flag. Since we need to support both, we have to
+ * handle OS X unqiuely.
+ */
+#ifdef DARWIN_10
+#undef APR_SIZEOF_VOIDP
+#undef APR_INT64_C
+#undef APR_UINT64_C
+#ifdef __LP64__
+ typedef long apr_int64_t;
+ typedef unsigned long apr_uint64_t;
+ #define APR_SIZEOF_VOIDP 8
+ #define APR_INT64_C(v) (v ## L)
+ #define APR_UINT64_C(v) (v ## UL)
+#else
+ typedef long long apr_int64_t;
+ typedef unsigned long long apr_uint64_t;
+ #define APR_SIZEOF_VOIDP 4
+ #define APR_INT64_C(v) (v ## LL)
+ #define APR_UINT64_C(v) (v ## ULL)
+#endif
+#else
+ typedef @int64_value@ apr_int64_t;
+ typedef @uint64_value@ apr_uint64_t;
+
+ /* Mechanisms to properly type numeric literals */
+ @int64_literal@
+ @uint64_literal@
+#endif
+
+typedef @size_t_value@ apr_size_t;
+typedef @ssize_t_value@ apr_ssize_t;
+typedef @off_t_value@ apr_off_t;
+typedef @socklen_t_value@ apr_socklen_t;
+typedef @ino_t_value@ apr_ino_t;
+
+#if APR_SIZEOF_VOIDP == 8
+typedef apr_uint64_t apr_uintptr_t;
+#else
+typedef apr_uint32_t apr_uintptr_t;
+#endif
+
+/* Are we big endian? */
+#define APR_IS_BIGENDIAN @bigendian@
+
+#ifdef INT16_MIN
+#define APR_INT16_MIN INT16_MIN
+#else
+#define APR_INT16_MIN (-0x7fff - 1)
+#endif
+
+#ifdef INT16_MAX
+#define APR_INT16_MAX INT16_MAX
+#else
+#define APR_INT16_MAX (0x7fff)
+#endif
+
+#ifdef UINT16_MAX
+#define APR_UINT16_MAX UINT16_MAX
+#else
+#define APR_UINT16_MAX (0xffff)
+#endif
+
+#ifdef INT32_MIN
+#define APR_INT32_MIN INT32_MIN
+#else
+#define APR_INT32_MIN (-0x7fffffff - 1)
+#endif
+
+#ifdef INT32_MAX
+#define APR_INT32_MAX INT32_MAX
+#else
+#define APR_INT32_MAX 0x7fffffff
+#endif
+
+#ifdef UINT32_MAX
+#define APR_UINT32_MAX UINT32_MAX
+#else
+#define APR_UINT32_MAX (0xffffffffU)
+#endif
+
+#ifdef INT64_MIN
+#define APR_INT64_MIN INT64_MIN
+#else
+#define APR_INT64_MIN (APR_INT64_C(-0x7fffffffffffffff) - 1)
+#endif
+
+#ifdef INT64_MAX
+#define APR_INT64_MAX INT64_MAX
+#else
+#define APR_INT64_MAX APR_INT64_C(0x7fffffffffffffff)
+#endif
+
+#ifdef UINT64_MAX
+#define APR_UINT64_MAX UINT64_MAX
+#else
+#define APR_UINT64_MAX APR_UINT64_C(0xffffffffffffffff)
+#endif
+
+#define APR_SIZE_MAX (~((apr_size_t)0))
+
+
+/* Definitions that APR programs need to work properly. */
+
+/**
+ * APR public API wrap for C++ compilers.
+ */
+#ifdef __cplusplus
+#define APR_BEGIN_DECLS extern "C" {
+#define APR_END_DECLS }
+#else
+#define APR_BEGIN_DECLS
+#define APR_END_DECLS
+#endif
+
+/**
+ * Thread callbacks from APR functions must be declared with APR_THREAD_FUNC,
+ * so that they follow the platform's calling convention.
+ * <PRE>
+ *
+ * void* APR_THREAD_FUNC my_thread_entry_fn(apr_thread_t *thd, void *data);
+ *
+ * </PRE>
+ */
+#define APR_THREAD_FUNC @apr_thread_func@
+
+#if defined(DOXYGEN) || !defined(WIN32)
+
+/**
+ * The public APR functions are declared with APR_DECLARE(), so they may
+ * use the most appropriate calling convention. Public APR functions with
+ * variable arguments must use APR_DECLARE_NONSTD().
+ *
+ * @remark Both the declaration and implementations must use the same macro.
+ *
+ * <PRE>
+ * APR_DECLARE(rettype) apr_func(args)
+ * </PRE>
+ * @see APR_DECLARE_NONSTD @see APR_DECLARE_DATA
+ * @remark Note that when APR compiles the library itself, it passes the
+ * symbol -DAPR_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32)
+ * to export public symbols from the dynamic library build.\n
+ * The user must define the APR_DECLARE_STATIC when compiling to target
+ * the static APR library on some platforms (e.g. Win32.) The public symbols
+ * are neither exported nor imported when APR_DECLARE_STATIC is defined.\n
+ * By default, compiling an application and including the APR public
+ * headers, without defining APR_DECLARE_STATIC, will prepare the code to be
+ * linked to the dynamic library.
+ */
+#define APR_DECLARE(type) type
+
+/**
+ * The public APR functions using variable arguments are declared with
+ * APR_DECLARE_NONSTD(), as they must follow the C language calling convention.
+ * @see APR_DECLARE @see APR_DECLARE_DATA
+ * @remark Both the declaration and implementations must use the same macro.
+ * <PRE>
+ *
+ * APR_DECLARE_NONSTD(rettype) apr_func(args, ...);
+ *
+ * </PRE>
+ */
+#define APR_DECLARE_NONSTD(type) type
+
+/**
+ * The public APR variables are declared with AP_MODULE_DECLARE_DATA.
+ * This assures the appropriate indirection is invoked at compile time.
+ * @see APR_DECLARE @see APR_DECLARE_NONSTD
+ * @remark Note that the declaration and implementations use different forms,
+ * but both must include the macro.
+ *
+ * <PRE>
+ *
+ * extern APR_DECLARE_DATA type apr_variable;\n
+ * APR_DECLARE_DATA type apr_variable = value;
+ *
+ * </PRE>
+ */
+#define APR_DECLARE_DATA
+
+#elif defined(APR_DECLARE_STATIC)
+#define APR_DECLARE(type) type __stdcall
+#define APR_DECLARE_NONSTD(type) type __cdecl
+#define APR_DECLARE_DATA
+#elif defined(APR_DECLARE_EXPORT)
+#define APR_DECLARE(type) __declspec(dllexport) type __stdcall
+#define APR_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
+#define APR_DECLARE_DATA __declspec(dllexport)
+#else
+#define APR_DECLARE(type) __declspec(dllimport) type __stdcall
+#define APR_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
+#define APR_DECLARE_DATA __declspec(dllimport)
+#endif
+
+/* Define APR_SSIZE_T_FMT.
+ * If ssize_t is an integer we define it to be "d",
+ * if ssize_t is a long int we define it to be "ld",
+ * if ssize_t is neither we declare an error here.
+ * I looked for a better way to define this here, but couldn't find one, so
+ * to find the logic for this definition search for "ssize_t_fmt" in
+ * configure.in.
+ */
+
+@ssize_t_fmt@
+
+/* And APR_SIZE_T_FMT */
+@size_t_fmt@
+
+/* And APR_OFF_T_FMT */
+@off_t_fmt@
+
+/* And APR_PID_T_FMT */
+@pid_t_fmt@
+
+/* And APR_INT64_T_FMT */
+@int64_t_fmt@
+
+/* And APR_UINT64_T_FMT */
+@uint64_t_fmt@
+
+/* And APR_UINT64_T_HEX_FMT */
+@uint64_t_hex_fmt@
+
+/*
+ * Ensure we work with universal binaries on Darwin
+ */
+#ifdef DARWIN_10
+
+#undef APR_HAS_LARGE_FILES
+#undef APR_SIZEOF_VOIDP
+#undef APR_INT64_T_FMT
+#undef APR_UINT64_T_FMT
+#undef APR_UINT64_T_HEX_FMT
+
+#ifdef __LP64__
+ #define APR_HAS_LARGE_FILES 0
+ #define APR_SIZEOF_VOIDP 8
+ #define APR_INT64_T_FMT "ld"
+ #define APR_UINT64_T_FMT "lu"
+ #define APR_UINT64_T_HEX_FMT "lx"
+#else
+ #define APR_HAS_LARGE_FILES 1
+ #define APR_SIZEOF_VOIDP 4
+ #define APR_INT64_T_FMT "lld"
+ #define APR_UINT64_T_FMT "llu"
+ #define APR_UINT64_T_HEX_FMT "llx"
+#endif
+
+#undef APR_IS_BIGENDIAN
+#ifdef __BIG_ENDIAN__
+ #define APR_IS_BIGENDIAN 1
+#else
+ #define APR_IS_BIGENDIAN 0
+#endif
+
+#undef APR_OFF_T_FMT
+#define APR_OFF_T_FMT "lld"
+
+#endif /* DARWIN_10 */
+
+/* Does the proc mutex lock threads too */
+#define APR_PROC_MUTEX_IS_GLOBAL @proc_mutex_is_global@
+
+/* Local machine definition for console and log output. */
+#define APR_EOL_STR "@eolstr@"
+
+#if APR_HAVE_SYS_WAIT_H
+#ifdef WEXITSTATUS
+#define apr_wait_t int
+#else
+#define apr_wait_t union wait
+#define WEXITSTATUS(status) (int)((status).w_retcode)
+#define WTERMSIG(status) (int)((status).w_termsig)
+#endif /* !WEXITSTATUS */
+#elif defined(__MINGW32__)
+typedef int apr_wait_t;
+#endif /* HAVE_SYS_WAIT_H */
+
+#if defined(PATH_MAX)
+#define APR_PATH_MAX PATH_MAX
+#elif defined(_POSIX_PATH_MAX)
+#define APR_PATH_MAX _POSIX_PATH_MAX
+#else
+#error no decision has been made on APR_PATH_MAX for your platform
+#endif
+
+#define APR_DSOPATH "@shlibpath_var@"
+
+/** @} */
+
+/* Definitions that only Win32 programs need to compile properly. */
+
+/* XXX These simply don't belong here, perhaps in apr_portable.h
+ * based on some APR_HAVE_PID/GID/UID?
+ */
+#ifdef __MINGW32__
+#ifndef __GNUC__
+typedef int pid_t;
+#endif
+typedef int uid_t;
+typedef int gid_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APR_H */
diff --git a/include/apr.hnw b/include/apr.hnw
new file mode 100644
index 0000000..5df7d9d
--- /dev/null
+++ b/include/apr.hnw
@@ -0,0 +1,445 @@
+/* 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 APR_H
+#define APR_H
+
+/* GENERATED FILE WARNING! DO NOT EDIT apr.h
+ *
+ * You must modify apr.hnw instead.
+ *
+ * And please, make an effort to stub apr.hw and apr.h.in in the process.
+ *
+ * This is the NetWare specific version of apr.h. It is copied from
+ * apr.hnw at the start of a NetWare build by the ./build/NWGNmakefile.
+ */
+
+/**
+ * @file apr.h
+ * @brief APR Platform Definitions
+ * @remark This is a generated header generated from include/apr.h.in by
+ * ./configure, or copied from include/apr.hw or include/apr.hnw
+ * for Win32 or Netware by those build environments, respectively.
+ */
+
+#if defined(NETWARE) || defined(DOXYGEN)
+
+#undef FD_SETSIZE
+#define FD_SETSIZE 1024
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <netware.h>
+#include <nks/thread.h>
+#include <nks/synch.h>
+#include <nks/time.h>
+#include <signal.h>
+#ifdef USE_WINSOCK
+#include <novsock2.h>
+#ifdef NW_BUILD_IPV6
+#include <novtcpip.h>
+#endif
+#else
+#include <sys/socket.h>
+#include <sys/select.h>
+#endif
+#include <sys/types.h>
+
+#define _POSIX_THREAD_SAFE_FUNCTIONS 1
+#define READDIR_IS_THREAD_SAFE 1
+
+/* Keep #include'd headers from within the __cplusplus or doxyblocks */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup apr_platform Platform Definitions
+ * @ingroup APR
+ * @{
+ */
+
+#define APR_INLINE
+#define APR_HAS_INLINE 0
+#ifndef __attribute__
+#define __attribute__(__x)
+#endif
+#define ENUM_BITFIELD(e,n,w) signed int n : w
+
+#define APR_HAVE_CONIO_H 0
+#define APR_HAVE_CRYPT_H 0
+#define APR_HAVE_CTYPE_H 1
+#define APR_HAVE_DIRENT_H 1
+#define APR_HAVE_ERRNO_H 1
+#define APR_HAVE_FCNTL_H 1
+#define APR_HAVE_IO_H 0
+#define APR_HAVE_LIMITS_H 1
+#ifdef USE_WINSOCK
+#define APR_HAVE_ARPA_INET_H 0
+#define APR_HAVE_NETDB_H 0
+#define APR_HAVE_NETINET_IN_H 0
+#else
+#define APR_HAVE_ARPA_INET_H 1
+#define APR_HAVE_NETDB_H 1
+#define APR_HAVE_NETINET_IN_H 1
+#endif
+#define APR_HAVE_NETINET_SCTP_H 0
+#define APR_HAVE_NETINET_SCTP_UIO_H 0
+#define APR_HAVE_NETINET_TCP_H 0
+#define APR_HAVE_PTHREAD_H 0
+#define APR_HAVE_SIGNAL_H 1
+#define APR_HAVE_STDARG_H 1
+#define APR_HAVE_STDINT_H 0
+#define APR_HAVE_STDIO_H 1
+#define APR_HAVE_STDLIB_H 1
+#define APR_HAVE_STRING_H 1
+#define APR_HAVE_STRINGS_H 0
+#define APR_HAVE_STRTOLL 1
+#define APR_HAVE_SYS_SENDFILE_H 0
+#define APR_HAVE_SYS_SYSLIMITS_H 0
+#ifdef USE_WINSOCK
+#define APR_HAVE_SYS_SOCKET_H 0
+#define APR_HAVE_SYS_SOCKIO_H 0
+#define APR_HAVE_SYS_UN_H 0
+#else
+#define APR_HAVE_SYS_SOCKET_H 1
+#define APR_HAVE_SYS_SOCKIO_H 1
+#define APR_HAVE_SYS_UN_H 1
+#endif
+#define APR_HAVE_SYS_SIGNAL_H 1
+#define APR_HAVE_SYS_TIME_H 1
+#define APR_HAVE_SYS_TYPES_H 1
+#define APR_HAVE_SYS_UIO_H 1
+#define APR_HAVE_SYS_WAIT_H 1
+#define APR_HAVE_TIME_H 1
+#define APR_HAVE_UNISTD_H 1
+
+#define APR_HAVE_SHMEM_MMAP_TMP 0
+#define APR_HAVE_SHMEM_MMAP_SHM 0
+#define APR_HAVE_SHMEM_MMAP_ZERO 0
+#define APR_HAVE_SHMEM_SHMGET_ANON 0
+#define APR_HAVE_SHMEM_SHMGET 0
+#define APR_HAVE_SHMEM_MMAP_ANON 0
+#define APR_HAVE_SHMEM_BEOS 0
+
+#define APR_USE_SHMEM_MMAP_TMP 0
+#define APR_USE_SHMEM_MMAP_SHM 0
+#define APR_USE_SHMEM_MMAP_ZERO 0
+#define APR_USE_SHMEM_SHMGET_ANON 0
+#define APR_USE_SHMEM_SHMGET 0
+#define APR_USE_SHMEM_MMAP_ANON 0
+#define APR_USE_SHMEM_BEOS 0
+
+#define APR_USE_FLOCK_SERIALIZE 0
+#define APR_USE_SYSVSEM_SERIALIZE 0
+#define APR_USE_FCNTL_SERIALIZE 0
+#define APR_USE_PROC_PTHREAD_SERIALIZE 0
+#define APR_USE_PTHREAD_SERIALIZE 0
+
+#define APR_HAS_FLOCK_SERIALIZE 0
+#define APR_HAS_SYSVSEM_SERIALIZE 0
+#define APR_HAS_FCNTL_SERIALIZE 0
+#define APR_HAS_PROC_PTHREAD_SERIALIZE 0
+#define APR_HAS_RWLOCK_SERIALIZE 0
+
+#define APR_HAS_LOCK_CREATE_NP 0
+
+#define APR_PROCESS_LOCK_IS_GLOBAL 1
+
+#define APR_FILE_BASED_SHM 0
+
+#define APR_HAVE_CORKABLE_TCP 0
+#define APR_HAVE_GETRLIMIT 0
+#define APR_HAVE_ICONV 0
+#define APR_HAVE_IN_ADDR 1
+#define APR_HAVE_INET_ADDR 1
+#define APR_HAVE_INET_NETWORK 0
+#ifdef NW_BUILD_IPV6
+#define APR_HAVE_IPV6 1
+#else
+#define APR_HAVE_IPV6 0
+#endif
+#define APR_HAVE_SOCKADDR_UN 0
+#define APR_HAVE_MEMCHR 1
+#define APR_HAVE_MEMMOVE 1
+#define APR_HAVE_SETRLIMIT 0
+#define APR_HAVE_SIGACTION 0
+#define APR_HAVE_SIGSUSPEND 0
+#define APR_HAVE_SIGWAIT 0
+#define APR_HAVE_STRCASECMP 1
+#define APR_HAVE_STRDUP 1
+#define APR_HAVE_STRICMP 1
+#define APR_HAVE_STRNCASECMP 1
+#define APR_HAVE_STRNICMP 1
+#define APR_HAVE_STRSTR 1
+#define APR_HAVE_STRUCT_RLIMIT 0
+#define APR_HAVE_UNION_SEMUN 0
+#define APR_HAVE_SCTP 0
+#define APR_HAVE_IOVEC 1
+
+/* APR Feature Macros */
+#define APR_HAS_SHARED_MEMORY 0
+#define APR_HAS_THREADS 1
+#define APR_HAS_SENDFILE 0
+#define APR_HAS_MMAP 0
+#define APR_HAS_FORK 0
+#define APR_HAS_RANDOM 1
+#define APR_HAS_OTHER_CHILD 0
+#define APR_HAS_DSO 1
+#define APR_HAS_SO_ACCEPTFILTER 0
+#define APR_HAS_UNICODE_FS 0
+#define APR_HAS_PROC_INVOKED 0
+#define APR_HAS_USER 1
+#define APR_HAS_LARGE_FILES 1
+#define APR_HAS_XTHREAD_FILES 0
+#define APR_HAS_OS_UUID 0
+#define APR_HAS_TIMEDLOCKS 1
+
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
+
+/* Netware can poll on files/pipes.
+ */
+#define APR_FILES_AS_SOCKETS 1
+
+/* This macro indicates whether or not EBCDIC is the native character set.
+ */
+#define APR_CHARSET_EBCDIC 0
+
+/* Is the TCP_NODELAY socket option inherited from listening sockets?
+*/
+#define APR_TCP_NODELAY_INHERITED 1
+
+/* Is the O_NONBLOCK flag inherited from listening sockets?
+*/
+#define APR_O_NONBLOCK_INHERITED 1
+
+/* Typedefs that APR needs. */
+
+typedef unsigned char apr_byte_t;
+
+typedef short apr_int16_t;
+typedef unsigned short apr_uint16_t;
+
+typedef int apr_int32_t;
+typedef unsigned int apr_uint32_t;
+
+typedef long long apr_int64_t;
+typedef unsigned long long apr_uint64_t;
+
+typedef size_t apr_size_t;
+typedef ssize_t apr_ssize_t;
+#if APR_HAS_LARGE_FILES
+typedef off64_t apr_off_t;
+#else
+typedef off_t apr_off_t;
+#endif
+#ifdef USE_WINSOCK
+typedef int apr_socklen_t;
+#else
+typedef size_t apr_socklen_t;
+#endif
+typedef apr_uint64_t apr_ino_t;
+
+/* Are we big endian? */
+/* XXX: Fatal assumption on Alpha platforms */
+#define APR_IS_BIGENDIAN 0
+
+#ifdef UNKNOWN_NETWARE_64BIT_FLAG_NEEDED
+#define APR_SIZEOF_VOIDP 8
+#else
+#define APR_SIZEOF_VOIDP 4
+#endif
+
+#if APR_SIZEOF_VOIDP == 8
+typedef apr_uint64_t apr_uintptr_t;
+#else
+typedef apr_uint32_t apr_uintptr_t;
+#endif
+
+/* Mechanisms to properly type numeric literals */
+#define APR_INT64_C(val) (val##LL)
+#define APR_UINT64_C(val) (val##ULL)
+
+#ifdef INT16_MIN
+#define APR_INT16_MIN INT16_MIN
+#else
+#define APR_INT16_MIN (-0x7fff - 1)
+#endif
+
+#ifdef INT16_MAX
+#define APR_INT16_MAX INT16_MAX
+#else
+#define APR_INT16_MAX (0x7fff)
+#endif
+
+#ifdef UINT16_MAX
+#define APR_UINT16_MAX UINT16_MAX
+#else
+#define APR_UINT16_MAX (0xffff)
+#endif
+
+#ifdef INT32_MIN
+#define APR_INT32_MIN INT32_MIN
+#else
+#define APR_INT32_MIN (-0x7fffffff - 1)
+#endif
+
+#ifdef INT32_MAX
+#define APR_INT32_MAX INT32_MAX
+#else
+#define APR_INT32_MAX 0x7fffffff
+#endif
+
+#ifdef UINT32_MAX
+#define APR_UINT32_MAX UINT32_MAX
+#else
+#define APR_UINT32_MAX (0xffffffffU)
+#endif
+
+#ifdef INT64_MIN
+#define APR_INT64_MIN INT64_MIN
+#else
+#define APR_INT64_MIN (APR_INT64_C(-0x7fffffffffffffff) - 1)
+#endif
+
+#ifdef INT64_MAX
+#define APR_INT64_MAX INT64_MAX
+#else
+#define APR_INT64_MAX APR_INT64_C(0x7fffffffffffffff)
+#endif
+
+#ifdef UINT64_MAX
+#define APR_UINT64_MAX UINT64_MAX
+#else
+#define APR_UINT64_MAX APR_UINT64_C(0xffffffffffffffff)
+#endif
+
+#define APR_SIZE_MAX (~((apr_size_t)0))
+
+/* PROC mutex is a GLOBAL mutex on Netware */
+#define APR_PROC_MUTEX_IS_GLOBAL 1
+
+/* Definitions that APR programs need to work properly. */
+
+/**
+ * APR public API wrap for C++ compilers.
+ */
+#ifdef __cplusplus
+#define APR_BEGIN_DECLS extern "C" {
+#define APR_END_DECLS }
+#else
+#define APR_BEGIN_DECLS
+#define APR_END_DECLS
+#endif
+
+/**
+ * Thread callbacks from APR functions must be declared with APR_THREAD_FUNC,
+ * so that they follow the platform's calling convention.
+ * @example
+ */
+/** void* APR_THREAD_FUNC my_thread_entry_fn(apr_thread_t *thd, void *data);
+ */
+#define APR_THREAD_FUNC
+
+/**
+ * The public APR functions are declared with APR_DECLARE(), so they may
+ * use the most appropriate calling convention. Public APR functions with
+ * variable arguments must use APR_DECLARE_NONSTD().
+ *
+ * @remark Both the declaration and implementations must use the same macro.
+ * @example
+ */
+/** APR_DECLARE(rettype) apr_func(args)
+ * @see APR_DECLARE_NONSTD @see APR_DECLARE_DATA
+ * @remark Note that when APR compiles the library itself, it passes the
+ * symbol -DAPR_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32)
+ * to export public symbols from the dynamic library build.\n
+ * The user must define the APR_DECLARE_STATIC when compiling to target
+ * the static APR library on some platforms (e.g. Win32.) The public symbols
+ * are neither exported nor imported when APR_DECLARE_STATIC is defined.\n
+ * By default, compiling an application and including the APR public
+ * headers, without defining APR_DECLARE_STATIC, will prepare the code to be
+ * linked to the dynamic library.
+ */
+#define APR_DECLARE(type) type
+
+/**
+ * The public APR functions using variable arguments are declared with
+ * APR_DECLARE_NONSTD(), as they must follow the C language calling convention.
+ * @see APR_DECLARE @see APR_DECLARE_DATA
+ * @remark Both the declaration and implementations must use the same macro.
+ * @example
+ */
+/** APR_DECLARE_NONSTD(rettype) apr_func(args, ...);
+ */
+#define APR_DECLARE_NONSTD(type) type
+
+/**
+ * The public APR variables are declared with APR_DECLARE_DATA.
+ * This assures the appropriate indirection is invoked at compile time.
+ * @see APR_DECLARE @see APR_DECLARE_NONSTD
+ * @remark Note that the declaration and implementations use different forms,
+ * but both must include the macro.
+ * @example
+ */
+/** extern APR_DECLARE_DATA type apr_variable;\n
+ * APR_DECLARE_DATA type apr_variable = value;
+ */
+#define APR_DECLARE_DATA
+
+#define APR_SSIZE_T_FMT "d"
+
+#define APR_SIZE_T_FMT "d"
+
+#if APR_HAS_LARGE_FILES
+#define APR_OFF_T_FMT "lld"
+#else
+#define APR_OFF_T_FMT "ld"
+#endif
+
+#define APR_PID_T_FMT "d"
+
+/* Local machine definition for console and log output. */
+#define APR_EOL_STR "\r\n"
+
+typedef int apr_wait_t;
+
+#define APR_PATH_MAX PATH_MAX
+
+#define APR_DSOPATH "PATH"
+
+#define APR_INT64_T_FMT "lld"
+#define APR_UINT64_T_FMT "llu"
+#define APR_UINT64_T_HEX_FMT "llx"
+#define APR_TIME_T_FMT APR_INT64_T_FMT
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETWARE */
+
+#endif /* APR_H */
diff --git a/include/apr.hw b/include/apr.hw
new file mode 100644
index 0000000..4247d61
--- /dev/null
+++ b/include/apr.hw
@@ -0,0 +1,667 @@
+/* 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 APR_H
+#define APR_H
+
+/* GENERATED FILE WARNING! DO NOT EDIT apr.h
+ *
+ * You must modify apr.hw instead.
+ *
+ * And please, make an effort to stub apr.hnw and apr.h.in in the process.
+ *
+ * This is the Win32 specific version of apr.h. It is copied from
+ * apr.hw by the apr.dsp and libapr.dsp projects.
+ */
+
+/**
+ * @file apr.h
+ * @brief APR Platform Definitions
+ * @remark This is a generated header generated from include/apr.h.in by
+ * ./configure, or copied from include/apr.hw or include/apr.hnw
+ * for Win32 or Netware by those build environments, respectively.
+ */
+
+/* Make sure we have our platform identifier macro defined we ask for later.
+ */
+#if defined(_WIN32) && !defined(WIN32)
+#define WIN32 1
+#endif
+
+#if defined(WIN32) || defined(DOXYGEN)
+
+/* Ignore most warnings (back down to /W3) for poorly constructed headers
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+#pragma warning(push, 3)
+#endif
+
+/* disable or reduce the frequency of...
+ * C4057: indirection to slightly different base types
+ * C4075: slight indirection changes (unsigned short* vs short[])
+ * C4100: unreferenced formal parameter
+ * C4127: conditional expression is constant
+ * C4163: '_rotl64' : not available as an intrinsic function
+ * C4201: nonstandard extension nameless struct/unions
+ * C4244: int to char/short - precision loss
+ * C4514: unreferenced inline function removed
+ */
+#if defined(_MSC_VER)
+#pragma warning(disable: 4100 4127 4163 4201 4514; once: 4057 4075 4244)
+#endif
+
+/* Ignore Microsoft's interpretation of secure development
+ * and the POSIX string handling API
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#pragma warning(disable: 4996)
+#endif
+
+/* Has windows.h already been included? If so, our preferences don't matter,
+ * but we will still need the winsock things no matter what was included.
+ * If not, include a restricted set of windows headers to our tastes.
+ */
+#ifndef _WINDOWS_
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#ifndef _WIN32_WINNT
+
+/* Restrict the server to a subset of Windows XP header files by default
+ */
+#define _WIN32_WINNT 0x0501
+#endif
+#ifndef NOUSER
+#define NOUSER
+#endif
+#ifndef NOMCX
+#define NOMCX
+#endif
+#ifndef NOIME
+#define NOIME
+#endif
+#include <windows.h>
+/*
+ * Add a _very_few_ declarations missing from the restricted set of headers
+ * (If this list becomes extensive, re-enable the required headers above!)
+ * winsock headers were excluded by WIN32_LEAN_AND_MEAN, so include them now
+ */
+#define SW_HIDE 0
+#ifndef _WIN32_WCE
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <mswsock.h>
+#else
+#include <winsock.h>
+#endif
+#endif /* !_WINDOWS_ */
+
+/**
+ * @defgroup APR Apache Portability Runtime library
+ * @{
+ */
+/**
+ * @defgroup apr_platform Platform Definitions
+ * @{
+ * @warning
+ * <strong><em>The actual values of macros and typedefs on this page<br>
+ * are platform specific and should NOT be relied upon!</em></strong>
+ */
+
+#define APR_INLINE __inline
+#define APR_HAS_INLINE 1
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(__x)
+#endif
+
+#ifndef _WIN32_WCE
+#define APR_HAVE_ARPA_INET_H 0
+#define APR_HAVE_CONIO_H 1
+#define APR_HAVE_CRYPT_H 0
+#define APR_HAVE_CTYPE_H 1
+#define APR_HAVE_DIRENT_H 0
+#define APR_HAVE_ERRNO_H 1
+#define APR_HAVE_FCNTL_H 1
+#define APR_HAVE_IO_H 1
+#define APR_HAVE_LIMITS_H 1
+#define APR_HAVE_NETDB_H 0
+#define APR_HAVE_NETINET_IN_H 0
+#define APR_HAVE_NETINET_SCTP_H 0
+#define APR_HAVE_NETINET_SCTP_UIO_H 0
+#define APR_HAVE_NETINET_TCP_H 0
+#define APR_HAVE_PTHREAD_H 0
+#define APR_HAVE_SEMAPHORE_H 0
+#define APR_HAVE_SIGNAL_H 1
+#define APR_HAVE_STDARG_H 1
+#define APR_HAVE_STDINT_H 0
+#define APR_HAVE_STDIO_H 1
+#define APR_HAVE_STDLIB_H 1
+#define APR_HAVE_STRING_H 1
+#define APR_HAVE_STRINGS_H 0
+#define APR_HAVE_SYS_IOCTL_H 0
+#define APR_HAVE_SYS_SENDFILE_H 0
+#define APR_HAVE_SYS_SIGNAL_H 0
+#define APR_HAVE_SYS_SOCKET_H 0
+#define APR_HAVE_SYS_SOCKIO_H 0
+#define APR_HAVE_SYS_SYSLIMITS_H 0
+#define APR_HAVE_SYS_TIME_H 0
+#define APR_HAVE_SYS_TYPES_H 1
+#define APR_HAVE_SYS_UIO_H 0
+#define APR_HAVE_SYS_UN_H 0
+#define APR_HAVE_SYS_WAIT_H 0
+#define APR_HAVE_TIME_H 1
+#define APR_HAVE_UNISTD_H 0
+#define APR_HAVE_STDDEF_H 1
+#define APR_HAVE_PROCESS_H 1
+#else
+#define APR_HAVE_ARPA_INET_H 0
+#define APR_HAVE_CONIO_H 0
+#define APR_HAVE_CRYPT_H 0
+#define APR_HAVE_CTYPE_H 0
+#define APR_HAVE_DIRENT_H 0
+#define APR_HAVE_ERRNO_H 0
+#define APR_HAVE_FCNTL_H 0
+#define APR_HAVE_IO_H 0
+#define APR_HAVE_LIMITS_H 0
+#define APR_HAVE_NETDB_H 0
+#define APR_HAVE_NETINET_IN_H 0
+#define APR_HAVE_NETINET_SCTP_H 0
+#define APR_HAVE_NETINET_SCTP_UIO_H 0
+#define APR_HAVE_NETINET_TCP_H 0
+#define APR_HAVE_PTHREAD_H 0
+#define APR_HAVE_SEMAPHORE_H 0
+#define APR_HAVE_SIGNAL_H 0
+#define APR_HAVE_STDARG_H 0
+#define APR_HAVE_STDINT_H 0
+#define APR_HAVE_STDIO_H 1
+#define APR_HAVE_STDLIB_H 1
+#define APR_HAVE_STRING_H 1
+#define APR_HAVE_STRINGS_H 0
+#define APR_HAVE_SYS_IOCTL_H 0
+#define APR_HAVE_SYS_SENDFILE_H 0
+#define APR_HAVE_SYS_SIGNAL_H 0
+#define APR_HAVE_SYS_SOCKET_H 0
+#define APR_HAVE_SYS_SOCKIO_H 0
+#define APR_HAVE_SYS_SYSLIMITS_H 0
+#define APR_HAVE_SYS_TIME_H 0
+#define APR_HAVE_SYS_TYPES_H 0
+#define APR_HAVE_SYS_UIO_H 0
+#define APR_HAVE_SYS_UN_H 0
+#define APR_HAVE_SYS_WAIT_H 0
+#define APR_HAVE_TIME_H 0
+#define APR_HAVE_UNISTD_H 0
+#define APR_HAVE_STDDEF_H 0
+#define APR_HAVE_PROCESS_H 0
+#endif
+
+/** @} */
+/** @} */
+
+/* We don't include our conditional headers within the doxyblocks
+ * or the extern "C" namespace
+ */
+
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if APR_HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#if APR_HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#if APR_HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if APR_HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if APR_HAVE_TIME_H
+#include <time.h>
+#endif
+
+#if APR_HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup apr_platform
+ * @ingroup APR
+ * @{
+ */
+
+#define APR_HAVE_SHMEM_MMAP_TMP 0
+#define APR_HAVE_SHMEM_MMAP_SHM 0
+#define APR_HAVE_SHMEM_MMAP_ZERO 0
+#define APR_HAVE_SHMEM_SHMGET_ANON 0
+#define APR_HAVE_SHMEM_SHMGET 0
+#define APR_HAVE_SHMEM_MMAP_ANON 0
+#define APR_HAVE_SHMEM_BEOS 0
+
+#define APR_USE_SHMEM_MMAP_TMP 0
+#define APR_USE_SHMEM_MMAP_SHM 0
+#define APR_USE_SHMEM_MMAP_ZERO 0
+#define APR_USE_SHMEM_SHMGET_ANON 0
+#define APR_USE_SHMEM_SHMGET 0
+#define APR_USE_SHMEM_MMAP_ANON 0
+#define APR_USE_SHMEM_BEOS 0
+
+#define APR_USE_FLOCK_SERIALIZE 0
+#define APR_USE_POSIXSEM_SERIALIZE 0
+#define APR_USE_SYSVSEM_SERIALIZE 0
+#define APR_USE_FCNTL_SERIALIZE 0
+#define APR_USE_PROC_PTHREAD_SERIALIZE 0
+#define APR_USE_PTHREAD_SERIALIZE 0
+
+#define APR_HAS_FLOCK_SERIALIZE 0
+#define APR_HAS_SYSVSEM_SERIALIZE 0
+#define APR_HAS_POSIXSEM_SERIALIZE 0
+#define APR_HAS_FCNTL_SERIALIZE 0
+#define APR_HAS_PROC_PTHREAD_SERIALIZE 0
+
+#define APR_PROCESS_LOCK_IS_GLOBAL 0
+
+#define APR_HAVE_CORKABLE_TCP 0
+#define APR_HAVE_GETRLIMIT 0
+#define APR_HAVE_ICONV 0
+#define APR_HAVE_IN_ADDR 1
+#define APR_HAVE_INET_ADDR 1
+#define APR_HAVE_INET_NETWORK 0
+#define APR_HAVE_IPV6 1
+#define APR_HAVE_SOCKADDR_UN 0
+#define APR_HAVE_MEMMOVE 1
+#define APR_HAVE_SETRLIMIT 0
+#define APR_HAVE_SIGACTION 0
+#define APR_HAVE_SIGSUSPEND 0
+#define APR_HAVE_SIGWAIT 0
+#define APR_HAVE_SA_STORAGE 0
+#define APR_HAVE_STRCASECMP 0
+#define APR_HAVE_STRDUP 1
+#define APR_HAVE_STRNCASECMP 0
+#define APR_HAVE_STRSTR 1
+#define APR_HAVE_MEMCHR 1
+#define APR_HAVE_STRUCT_RLIMIT 0
+#define APR_HAVE_UNION_SEMUN 0
+#define APR_HAVE_SCTP 0
+#define APR_HAVE_IOVEC 0
+
+#ifndef _WIN32_WCE
+#define APR_HAVE_STRICMP 1
+#define APR_HAVE_STRNICMP 1
+#else
+#define APR_HAVE_STRICMP 0
+#define APR_HAVE_STRNICMP 0
+#endif
+
+/* APR Feature Macros */
+#define APR_HAS_SHARED_MEMORY 1
+#define APR_HAS_THREADS 1
+#define APR_HAS_MMAP 1
+#define APR_HAS_FORK 0
+#define APR_HAS_RANDOM 1
+#define APR_HAS_OTHER_CHILD 1
+#define APR_HAS_DSO 1
+#define APR_HAS_SO_ACCEPTFILTER 0
+#define APR_HAS_UNICODE_FS 1
+#define APR_HAS_PROC_INVOKED 1
+#define APR_HAS_OS_UUID 1
+#define APR_HAS_TIMEDLOCKS 1
+
+#ifndef _WIN32_WCE
+#define APR_HAS_SENDFILE 1
+#define APR_HAS_USER 1
+#define APR_HAS_LARGE_FILES 1
+#define APR_HAS_XTHREAD_FILES 1
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 1
+#else
+#define APR_HAS_SENDFILE 0
+#define APR_HAS_USER 0
+#define APR_HAS_LARGE_FILES 0
+#define APR_HAS_XTHREAD_FILES 0
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
+#endif
+
+/* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
+ * to poll on files/pipes.
+ */
+#define APR_FILES_AS_SOCKETS 0
+
+/* This macro indicates whether or not EBCDIC is the native character set.
+ */
+#define APR_CHARSET_EBCDIC 0
+
+/* If we have a TCP implementation that can be "corked", what flag
+ * do we use?
+ */
+#define APR_TCP_NOPUSH_FLAG 0
+
+/* Is the TCP_NODELAY socket option inherited from listening sockets?
+ */
+#define APR_TCP_NODELAY_INHERITED 1
+
+/* Is the O_NONBLOCK flag inherited from listening sockets?
+ */
+#define APR_O_NONBLOCK_INHERITED 1
+
+/* Typedefs that APR needs. */
+
+typedef unsigned char apr_byte_t;
+
+typedef short apr_int16_t;
+typedef unsigned short apr_uint16_t;
+
+typedef int apr_int32_t;
+typedef unsigned int apr_uint32_t;
+
+typedef __int64 apr_int64_t;
+typedef unsigned __int64 apr_uint64_t;
+
+typedef size_t apr_size_t;
+#if APR_HAVE_STDDEF_H
+typedef ptrdiff_t apr_ssize_t;
+#else
+typedef int apr_ssize_t;
+#endif
+#if APR_HAS_LARGE_FILES
+typedef __int64 apr_off_t;
+#else
+typedef int apr_off_t;
+#endif
+typedef int apr_socklen_t;
+typedef apr_uint64_t apr_ino_t;
+
+#ifdef _WIN64
+#define APR_SIZEOF_VOIDP 8
+#else
+#define APR_SIZEOF_VOIDP 4
+#endif
+
+#if APR_SIZEOF_VOIDP == 8
+typedef apr_uint64_t apr_uintptr_t;
+#else
+typedef apr_uint32_t apr_uintptr_t;
+#endif
+
+/* Are we big endian? */
+/* XXX: Fatal assumption on Alpha platforms */
+#define APR_IS_BIGENDIAN 0
+
+/* Mechanisms to properly type numeric literals */
+
+#ifndef __GNUC__
+#define APR_INT64_C(val) (val##i64)
+#define APR_UINT64_C(val) (val##Ui64)
+#else
+#define APR_INT64_C(val) (val##LL)
+#define APR_UINT64_C(val) (val##ULL)
+#endif
+
+#ifdef INT16_MIN
+#define APR_INT16_MIN INT16_MIN
+#else
+#define APR_INT16_MIN (-0x7fff - 1)
+#endif
+
+#ifdef INT16_MAX
+#define APR_INT16_MAX INT16_MAX
+#else
+#define APR_INT16_MAX (0x7fff)
+#endif
+
+#ifdef UINT16_MAX
+#define APR_UINT16_MAX UINT16_MAX
+#else
+#define APR_UINT16_MAX (0xffff)
+#endif
+
+#ifdef INT32_MIN
+#define APR_INT32_MIN INT32_MIN
+#else
+#define APR_INT32_MIN (-0x7fffffff - 1)
+#endif
+
+#ifdef INT32_MAX
+#define APR_INT32_MAX INT32_MAX
+#else
+#define APR_INT32_MAX 0x7fffffff
+#endif
+
+#ifdef UINT32_MAX
+#define APR_UINT32_MAX UINT32_MAX
+#else
+#define APR_UINT32_MAX (0xffffffffU)
+#endif
+
+#ifdef INT64_MIN
+#define APR_INT64_MIN INT64_MIN
+#else
+#define APR_INT64_MIN (APR_INT64_C(-0x7fffffffffffffff) - 1)
+#endif
+
+#ifdef INT64_MAX
+#define APR_INT64_MAX INT64_MAX
+#else
+#define APR_INT64_MAX APR_INT64_C(0x7fffffffffffffff)
+#endif
+
+#ifdef UINT64_MAX
+#define APR_UINT64_MAX UINT64_MAX
+#else
+#define APR_UINT64_MAX APR_UINT64_C(0xffffffffffffffff)
+#endif
+
+#define APR_SIZE_MAX (~((apr_size_t)0))
+
+/* Definitions that APR programs need to work properly. */
+
+/**
+ * APR public API wrap for C++ compilers.
+ */
+#ifdef __cplusplus
+#define APR_BEGIN_DECLS extern "C" {
+#define APR_END_DECLS }
+#else
+#define APR_BEGIN_DECLS
+#define APR_END_DECLS
+#endif
+
+/**
+ * Thread callbacks from APR functions must be declared with APR_THREAD_FUNC,
+ * so that they follow the platform's calling convention.
+ * <PRE>
+ *
+ * void* APR_THREAD_FUNC my_thread_entry_fn(apr_thread_t *thd, void *data);
+ *
+ * </PRE>
+ */
+#define APR_THREAD_FUNC __stdcall
+
+
+#if defined(DOXYGEN) || !defined(WIN32)
+
+/**
+ * The public APR functions are declared with APR_DECLARE(), so they may
+ * use the most appropriate calling convention. Public APR functions with
+ * variable arguments must use APR_DECLARE_NONSTD().
+ *
+ * @remark Both the declaration and implementations must use the same macro.
+ *
+ * <PRE>
+ * APR_DECLARE(rettype) apr_func(args)
+ * </PRE>
+ * @see APR_DECLARE_NONSTD @see APR_DECLARE_DATA
+ * @remark Note that when APR compiles the library itself, it passes the
+ * symbol -DAPR_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32)
+ * to export public symbols from the dynamic library build.\n
+ * The user must define the APR_DECLARE_STATIC when compiling to target
+ * the static APR library on some platforms (e.g. Win32.) The public symbols
+ * are neither exported nor imported when APR_DECLARE_STATIC is defined.\n
+ * By default, compiling an application and including the APR public
+ * headers, without defining APR_DECLARE_STATIC, will prepare the code to be
+ * linked to the dynamic library.
+ */
+#define APR_DECLARE(type) type
+
+/**
+ * The public APR functions using variable arguments are declared with
+ * APR_DECLARE_NONSTD(), as they must follow the C language calling convention.
+ * @see APR_DECLARE @see APR_DECLARE_DATA
+ * @remark Both the declaration and implementations must use the same macro.
+ * <PRE>
+ *
+ * APR_DECLARE_NONSTD(rettype) apr_func(args, ...);
+ *
+ * </PRE>
+ */
+#define APR_DECLARE_NONSTD(type) type
+
+/**
+ * The public APR variables are declared with AP_MODULE_DECLARE_DATA.
+ * This assures the appropriate indirection is invoked at compile time.
+ * @see APR_DECLARE @see APR_DECLARE_NONSTD
+ * @remark Note that the declaration and implementations use different forms,
+ * but both must include the macro.
+ *
+ * <PRE>
+ *
+ * extern APR_DECLARE_DATA type apr_variable;\n
+ * APR_DECLARE_DATA type apr_variable = value;
+ *
+ * </PRE>
+ */
+#define APR_DECLARE_DATA
+
+#elif defined(APR_DECLARE_STATIC)
+#define APR_DECLARE(type) type __stdcall
+#define APR_DECLARE_NONSTD(type) type __cdecl
+#define APR_DECLARE_DATA
+#elif defined(APR_DECLARE_EXPORT)
+#define APR_DECLARE(type) __declspec(dllexport) type __stdcall
+#define APR_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
+#define APR_DECLARE_DATA __declspec(dllexport)
+#else
+#define APR_DECLARE(type) __declspec(dllimport) type __stdcall
+#define APR_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
+#define APR_DECLARE_DATA __declspec(dllimport)
+#endif
+
+#ifdef _WIN64
+#define APR_SSIZE_T_FMT "I64d"
+#define APR_SIZE_T_FMT "I64u"
+#else
+#define APR_SSIZE_T_FMT "d"
+#define APR_SIZE_T_FMT "u"
+#endif
+
+#if APR_HAS_LARGE_FILES
+#define APR_OFF_T_FMT "I64d"
+#else
+#define APR_OFF_T_FMT "d"
+#endif
+
+#define APR_PID_T_FMT "d"
+
+#define APR_INT64_T_FMT "I64d"
+#define APR_UINT64_T_FMT "I64u"
+#define APR_UINT64_T_HEX_FMT "I64x"
+
+/* No difference between PROC and GLOBAL mutex */
+#define APR_PROC_MUTEX_IS_GLOBAL 1
+
+/* Local machine definition for console and log output. */
+#define APR_EOL_STR "\r\n"
+
+typedef int apr_wait_t;
+
+#if APR_HAS_UNICODE_FS
+/* An arbitrary size that is digestable. True max is a bit less than 32000 */
+#define APR_PATH_MAX 8192
+#else /* !APR_HAS_UNICODE_FS */
+#define APR_PATH_MAX MAX_PATH
+#endif
+
+#define APR_DSOPATH "PATH"
+
+/** @} */
+
+/* Definitions that only Win32 programs need to compile properly. */
+
+/* XXX These simply don't belong here, perhaps in apr_portable.h
+ * based on some APR_HAVE_PID/GID/UID?
+ */
+#ifndef __GNUC__
+typedef int pid_t;
+#endif
+typedef int uid_t;
+typedef int gid_t;
+
+/* Win32 .h ommissions we really need */
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#if APR_HAVE_IPV6
+
+/* Appears in later flavors, not the originals. */
+#ifndef in_addr6
+#define in6_addr in_addr6
+#endif
+
+#ifndef WS2TCPIP_INLINE
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ ( (*(const apr_uint64_t *)(const void *)(&(a)->s6_addr[0]) == 0) \
+ && (*(const apr_uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
+#endif
+
+#endif /* APR_HAVE_IPV6 */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Done with badly written headers, leave 'deprecated CRT' undeprecated
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+#pragma warning(pop)
+#if _MSC_VER >= 1400
+#pragma warning(disable: 4996)
+#endif
+#endif
+
+#endif /* WIN32 */
+
+#endif /* APR_H */
diff --git a/include/apr.hwc b/include/apr.hwc
new file mode 100644
index 0000000..ef00a45
--- /dev/null
+++ b/include/apr.hwc
@@ -0,0 +1,664 @@
+/* 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 APR_H
+#define APR_H
+
+/* GENERATED FILE WARNING! DO NOT EDIT apr.h
+ *
+ * You must modify apr.hwc instead.
+ *
+ * And please, make an effort to stub apr.hnw and apr.h.in in the process.
+ *
+ * This is the Win32 specific version of apr.h. It is copied from
+ * apr.hw by the apr.dsp and libapr.dsp projects.
+ */
+
+/**
+ * @file apr.h
+ * @brief APR Platform Definitions
+ * @remark This is a generated header generated from include/apr.h.in by
+ * ./configure, or copied from include/apr.hw or include/apr.hnw
+ * for Win32 or Netware by those build environments, respectively.
+ */
+
+/* Make sure we have our platform identifier macro defined we ask for later.
+ */
+#if defined(_WIN32) && !defined(WIN32)
+#define WIN32 1
+#endif
+
+#if defined(WIN32) || defined(DOXYGEN)
+
+/* Ignore most warnings (back down to /W3) for poorly constructed headers
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+#pragma warning(push, 3)
+#endif
+
+/* disable or reduce the frequency of...
+ * C4057: indirection to slightly different base types
+ * C4075: slight indirection changes (unsigned short* vs short[])
+ * C4100: unreferenced formal parameter
+ * C4127: conditional expression is constant
+ * C4163: '_rotl64' : not available as an intrinsic function
+ * C4201: nonstandard extension nameless struct/unions
+ * C4244: int to char/short - precision loss
+ * C4514: unreferenced inline function removed
+ */
+#if defined(_MSC_VER)
+#pragma warning(disable: 4100 4127 4163 4201 4514; once: 4057 4075 4244)
+#endif
+
+/* Ignore Microsoft's interpretation of secure development
+ * and the POSIX string handling API
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#pragma warning(disable: 4996)
+#endif
+
+/* Has windows.h already been included? If so, our preferences don't matter,
+ * but we will still need the winsock things no matter what was included.
+ * If not, include a restricted set of windows headers to our tastes.
+ */
+#ifndef _WINDOWS_
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT @win32_winnt_str@
+#endif
+#ifndef NOUSER
+#define NOUSER
+#endif
+#ifndef NOMCX
+#define NOMCX
+#endif
+#ifndef NOIME
+#define NOIME
+#endif
+#include <windows.h>
+/*
+ * Add a _very_few_ declarations missing from the restricted set of headers
+ * (If this list becomes extensive, re-enable the required headers above!)
+ * winsock headers were excluded by WIN32_LEAN_AND_MEAN, so include them now
+ */
+#define SW_HIDE 0
+#ifndef _WIN32_WCE
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <mswsock.h>
+#else
+#include <winsock.h>
+#endif
+#endif /* !_WINDOWS_ */
+
+/**
+ * @defgroup APR Apache Portability Runtime library
+ * @{
+ */
+/**
+ * @defgroup apr_platform Platform Definitions
+ * @{
+ * @warning
+ * <strong><em>The actual values of macros and typedefs on this page<br>
+ * are platform specific and should NOT be relied upon!</em></strong>
+ */
+
+#define APR_INLINE __inline
+#define APR_HAS_INLINE 1
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(__x)
+#endif
+
+#ifndef _WIN32_WCE
+#define APR_HAVE_ARPA_INET_H 0
+#define APR_HAVE_CONIO_H 1
+#define APR_HAVE_CRYPT_H 0
+#define APR_HAVE_CTYPE_H 1
+#define APR_HAVE_DIRENT_H 0
+#define APR_HAVE_ERRNO_H 1
+#define APR_HAVE_FCNTL_H 1
+#define APR_HAVE_IO_H 1
+#define APR_HAVE_LIMITS_H 1
+#define APR_HAVE_NETDB_H 0
+#define APR_HAVE_NETINET_IN_H 0
+#define APR_HAVE_NETINET_SCTP_H 0
+#define APR_HAVE_NETINET_SCTP_UIO_H 0
+#define APR_HAVE_NETINET_TCP_H 0
+#define APR_HAVE_PTHREAD_H 0
+#define APR_HAVE_SEMAPHORE_H 0
+#define APR_HAVE_SIGNAL_H 1
+#define APR_HAVE_STDARG_H 1
+#define APR_HAVE_STDINT_H 0
+#define APR_HAVE_STDIO_H 1
+#define APR_HAVE_STDLIB_H 1
+#define APR_HAVE_STRING_H 1
+#define APR_HAVE_STRINGS_H 0
+#define APR_HAVE_SYS_IOCTL_H 0
+#define APR_HAVE_SYS_SENDFILE_H 0
+#define APR_HAVE_SYS_SIGNAL_H 0
+#define APR_HAVE_SYS_SOCKET_H 0
+#define APR_HAVE_SYS_SOCKIO_H 0
+#define APR_HAVE_SYS_SYSLIMITS_H 0
+#define APR_HAVE_SYS_TIME_H 0
+#define APR_HAVE_SYS_TYPES_H 1
+#define APR_HAVE_SYS_UIO_H 0
+#define APR_HAVE_SYS_UN_H 0
+#define APR_HAVE_SYS_WAIT_H 0
+#define APR_HAVE_TIME_H 1
+#define APR_HAVE_UNISTD_H 0
+#define APR_HAVE_STDDEF_H 1
+#define APR_HAVE_PROCESS_H 1
+#else
+#define APR_HAVE_ARPA_INET_H 0
+#define APR_HAVE_CONIO_H 0
+#define APR_HAVE_CRYPT_H 0
+#define APR_HAVE_CTYPE_H 0
+#define APR_HAVE_DIRENT_H 0
+#define APR_HAVE_ERRNO_H 0
+#define APR_HAVE_FCNTL_H 0
+#define APR_HAVE_IO_H 0
+#define APR_HAVE_LIMITS_H 0
+#define APR_HAVE_NETDB_H 0
+#define APR_HAVE_NETINET_IN_H 0
+#define APR_HAVE_NETINET_SCTP_H 0
+#define APR_HAVE_NETINET_SCTP_UIO_H 0
+#define APR_HAVE_NETINET_TCP_H 0
+#define APR_HAVE_PTHREAD_H 0
+#define APR_HAVE_SEMAPHORE_H 0
+#define APR_HAVE_SIGNAL_H 0
+#define APR_HAVE_STDARG_H 0
+#define APR_HAVE_STDINT_H 0
+#define APR_HAVE_STDIO_H 1
+#define APR_HAVE_STDLIB_H 1
+#define APR_HAVE_STRING_H 1
+#define APR_HAVE_STRINGS_H 0
+#define APR_HAVE_SYS_IOCTL_H 0
+#define APR_HAVE_SYS_SENDFILE_H 0
+#define APR_HAVE_SYS_SIGNAL_H 0
+#define APR_HAVE_SYS_SOCKET_H 0
+#define APR_HAVE_SYS_SOCKIO_H 0
+#define APR_HAVE_SYS_SYSLIMITS_H 0
+#define APR_HAVE_SYS_TIME_H 0
+#define APR_HAVE_SYS_TYPES_H 0
+#define APR_HAVE_SYS_UIO_H 0
+#define APR_HAVE_SYS_UN_H 0
+#define APR_HAVE_SYS_WAIT_H 0
+#define APR_HAVE_TIME_H 0
+#define APR_HAVE_UNISTD_H 0
+#define APR_HAVE_STDDEF_H 0
+#define APR_HAVE_PROCESS_H 0
+#endif
+
+/** @} */
+/** @} */
+
+/* We don't include our conditional headers within the doxyblocks
+ * or the extern "C" namespace
+ */
+
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if APR_HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#if APR_HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#if APR_HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if APR_HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if APR_HAVE_TIME_H
+#include <time.h>
+#endif
+
+#if APR_HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup apr_platform
+ * @ingroup APR
+ * @{
+ */
+
+#define APR_HAVE_SHMEM_MMAP_TMP 0
+#define APR_HAVE_SHMEM_MMAP_SHM 0
+#define APR_HAVE_SHMEM_MMAP_ZERO 0
+#define APR_HAVE_SHMEM_SHMGET_ANON 0
+#define APR_HAVE_SHMEM_SHMGET 0
+#define APR_HAVE_SHMEM_MMAP_ANON 0
+#define APR_HAVE_SHMEM_BEOS 0
+
+#define APR_USE_SHMEM_MMAP_TMP 0
+#define APR_USE_SHMEM_MMAP_SHM 0
+#define APR_USE_SHMEM_MMAP_ZERO 0
+#define APR_USE_SHMEM_SHMGET_ANON 0
+#define APR_USE_SHMEM_SHMGET 0
+#define APR_USE_SHMEM_MMAP_ANON 0
+#define APR_USE_SHMEM_BEOS 0
+
+#define APR_USE_FLOCK_SERIALIZE 0
+#define APR_USE_POSIXSEM_SERIALIZE 0
+#define APR_USE_SYSVSEM_SERIALIZE 0
+#define APR_USE_FCNTL_SERIALIZE 0
+#define APR_USE_PROC_PTHREAD_SERIALIZE 0
+#define APR_USE_PTHREAD_SERIALIZE 0
+
+#define APR_HAS_FLOCK_SERIALIZE 0
+#define APR_HAS_SYSVSEM_SERIALIZE 0
+#define APR_HAS_POSIXSEM_SERIALIZE 0
+#define APR_HAS_FCNTL_SERIALIZE 0
+#define APR_HAS_PROC_PTHREAD_SERIALIZE 0
+
+#define APR_PROCESS_LOCK_IS_GLOBAL 0
+
+#define APR_HAVE_CORKABLE_TCP 0
+#define APR_HAVE_GETRLIMIT 0
+#define APR_HAVE_ICONV 0
+#define APR_HAVE_IN_ADDR 1
+#define APR_HAVE_INET_ADDR 1
+#define APR_HAVE_INET_NETWORK 0
+#define APR_HAVE_IPV6 @apr_have_ipv6_10@
+#define APR_HAVE_SOCKADDR_UN 0
+#define APR_HAVE_MEMMOVE 1
+#define APR_HAVE_SETRLIMIT 0
+#define APR_HAVE_SIGACTION 0
+#define APR_HAVE_SIGSUSPEND 0
+#define APR_HAVE_SIGWAIT 0
+#define APR_HAVE_SA_STORAGE 0
+#define APR_HAVE_STRCASECMP 0
+#define APR_HAVE_STRDUP 1
+#define APR_HAVE_STRNCASECMP 0
+#define APR_HAVE_STRSTR 1
+#define APR_HAVE_MEMCHR 1
+#define APR_HAVE_STRUCT_RLIMIT 0
+#define APR_HAVE_UNION_SEMUN 0
+#define APR_HAVE_SCTP 0
+#define APR_HAVE_IOVEC 0
+
+#ifndef _WIN32_WCE
+#define APR_HAVE_STRICMP 1
+#define APR_HAVE_STRNICMP 1
+#else
+#define APR_HAVE_STRICMP 0
+#define APR_HAVE_STRNICMP 0
+#endif
+
+/* APR Feature Macros */
+#define APR_HAS_SHARED_MEMORY 1
+#define APR_HAS_THREADS 1
+#define APR_HAS_MMAP 1
+#define APR_HAS_FORK 0
+#define APR_HAS_RANDOM 1
+#define APR_HAS_OTHER_CHILD 1
+#define APR_HAS_DSO 1
+#define APR_HAS_SO_ACCEPTFILTER 0
+#define APR_HAS_UNICODE_FS 1
+#define APR_HAS_PROC_INVOKED 1
+#define APR_HAS_OS_UUID 1
+#define APR_HAS_TIMEDLOCKS 1
+
+#ifndef _WIN32_WCE
+#define APR_HAS_SENDFILE 1
+#define APR_HAS_USER 1
+#define APR_HAS_LARGE_FILES 1
+#define APR_HAS_XTHREAD_FILES 1
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 1
+#else
+#define APR_HAS_SENDFILE 0
+#define APR_HAS_USER 0
+#define APR_HAS_LARGE_FILES 0
+#define APR_HAS_XTHREAD_FILES 0
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
+#endif
+
+/* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
+ * to poll on files/pipes.
+ */
+#define APR_FILES_AS_SOCKETS 0
+
+/* This macro indicates whether or not EBCDIC is the native character set.
+ */
+#define APR_CHARSET_EBCDIC 0
+
+/* If we have a TCP implementation that can be "corked", what flag
+ * do we use?
+ */
+#define APR_TCP_NOPUSH_FLAG 0
+
+/* Is the TCP_NODELAY socket option inherited from listening sockets?
+ */
+#define APR_TCP_NODELAY_INHERITED 1
+
+/* Is the O_NONBLOCK flag inherited from listening sockets?
+ */
+#define APR_O_NONBLOCK_INHERITED 1
+
+/* Typedefs that APR needs. */
+
+typedef unsigned char apr_byte_t;
+
+typedef short apr_int16_t;
+typedef unsigned short apr_uint16_t;
+
+typedef int apr_int32_t;
+typedef unsigned int apr_uint32_t;
+
+typedef __int64 apr_int64_t;
+typedef unsigned __int64 apr_uint64_t;
+
+typedef size_t apr_size_t;
+#if APR_HAVE_STDDEF_H
+typedef ptrdiff_t apr_ssize_t;
+#else
+typedef int apr_ssize_t;
+#endif
+#if APR_HAS_LARGE_FILES
+typedef __int64 apr_off_t;
+#else
+typedef int apr_off_t;
+#endif
+typedef int apr_socklen_t;
+typedef apr_uint64_t apr_ino_t;
+
+#ifdef _WIN64
+#define APR_SIZEOF_VOIDP 8
+#else
+#define APR_SIZEOF_VOIDP 4
+#endif
+
+#if APR_SIZEOF_VOIDP == 8
+typedef apr_uint64_t apr_uintptr_t;
+#else
+typedef apr_uint32_t apr_uintptr_t;
+#endif
+
+/* Are we big endian? */
+/* XXX: Fatal assumption on Alpha platforms */
+#define APR_IS_BIGENDIAN 0
+
+/* Mechanisms to properly type numeric literals */
+
+#ifndef __GNUC__
+#define APR_INT64_C(val) (val##i64)
+#define APR_UINT64_C(val) (val##Ui64)
+#else
+#define APR_INT64_C(val) (val##LL)
+#define APR_UINT64_C(val) (val##ULL)
+#endif
+
+#ifdef INT16_MIN
+#define APR_INT16_MIN INT16_MIN
+#else
+#define APR_INT16_MIN (-0x7fff - 1)
+#endif
+
+#ifdef INT16_MAX
+#define APR_INT16_MAX INT16_MAX
+#else
+#define APR_INT16_MAX (0x7fff)
+#endif
+
+#ifdef UINT16_MAX
+#define APR_UINT16_MAX UINT16_MAX
+#else
+#define APR_UINT16_MAX (0xffff)
+#endif
+
+#ifdef INT32_MIN
+#define APR_INT32_MIN INT32_MIN
+#else
+#define APR_INT32_MIN (-0x7fffffff - 1)
+#endif
+
+#ifdef INT32_MAX
+#define APR_INT32_MAX INT32_MAX
+#else
+#define APR_INT32_MAX 0x7fffffff
+#endif
+
+#ifdef UINT32_MAX
+#define APR_UINT32_MAX UINT32_MAX
+#else
+#define APR_UINT32_MAX (0xffffffffU)
+#endif
+
+#ifdef INT64_MIN
+#define APR_INT64_MIN INT64_MIN
+#else
+#define APR_INT64_MIN (APR_INT64_C(-0x7fffffffffffffff) - 1)
+#endif
+
+#ifdef INT64_MAX
+#define APR_INT64_MAX INT64_MAX
+#else
+#define APR_INT64_MAX APR_INT64_C(0x7fffffffffffffff)
+#endif
+
+#ifdef UINT64_MAX
+#define APR_UINT64_MAX UINT64_MAX
+#else
+#define APR_UINT64_MAX APR_UINT64_C(0xffffffffffffffff)
+#endif
+
+#define APR_SIZE_MAX (~((apr_size_t)0))
+
+/* Definitions that APR programs need to work properly. */
+
+/**
+ * APR public API wrap for C++ compilers.
+ */
+#ifdef __cplusplus
+#define APR_BEGIN_DECLS extern "C" {
+#define APR_END_DECLS }
+#else
+#define APR_BEGIN_DECLS
+#define APR_END_DECLS
+#endif
+
+/**
+ * Thread callbacks from APR functions must be declared with APR_THREAD_FUNC,
+ * so that they follow the platform's calling convention.
+ * <PRE>
+ *
+ * void* APR_THREAD_FUNC my_thread_entry_fn(apr_thread_t *thd, void *data);
+ *
+ * </PRE>
+ */
+#define APR_THREAD_FUNC __stdcall
+
+
+#if defined(DOXYGEN) || !defined(WIN32)
+
+/**
+ * The public APR functions are declared with APR_DECLARE(), so they may
+ * use the most appropriate calling convention. Public APR functions with
+ * variable arguments must use APR_DECLARE_NONSTD().
+ *
+ * @remark Both the declaration and implementations must use the same macro.
+ *
+ * <PRE>
+ * APR_DECLARE(rettype) apr_func(args)
+ * </PRE>
+ * @see APR_DECLARE_NONSTD @see APR_DECLARE_DATA
+ * @remark Note that when APR compiles the library itself, it passes the
+ * symbol -DAPR_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32)
+ * to export public symbols from the dynamic library build.\n
+ * The user must define the APR_DECLARE_STATIC when compiling to target
+ * the static APR library on some platforms (e.g. Win32.) The public symbols
+ * are neither exported nor imported when APR_DECLARE_STATIC is defined.\n
+ * By default, compiling an application and including the APR public
+ * headers, without defining APR_DECLARE_STATIC, will prepare the code to be
+ * linked to the dynamic library.
+ */
+#define APR_DECLARE(type) type
+
+/**
+ * The public APR functions using variable arguments are declared with
+ * APR_DECLARE_NONSTD(), as they must follow the C language calling convention.
+ * @see APR_DECLARE @see APR_DECLARE_DATA
+ * @remark Both the declaration and implementations must use the same macro.
+ * <PRE>
+ *
+ * APR_DECLARE_NONSTD(rettype) apr_func(args, ...);
+ *
+ * </PRE>
+ */
+#define APR_DECLARE_NONSTD(type) type
+
+/**
+ * The public APR variables are declared with AP_MODULE_DECLARE_DATA.
+ * This assures the appropriate indirection is invoked at compile time.
+ * @see APR_DECLARE @see APR_DECLARE_NONSTD
+ * @remark Note that the declaration and implementations use different forms,
+ * but both must include the macro.
+ *
+ * <PRE>
+ *
+ * extern APR_DECLARE_DATA type apr_variable;\n
+ * APR_DECLARE_DATA type apr_variable = value;
+ *
+ * </PRE>
+ */
+#define APR_DECLARE_DATA
+
+#elif defined(APR_DECLARE_STATIC)
+#define APR_DECLARE(type) type __stdcall
+#define APR_DECLARE_NONSTD(type) type __cdecl
+#define APR_DECLARE_DATA
+#elif defined(APR_DECLARE_EXPORT)
+#define APR_DECLARE(type) __declspec(dllexport) type __stdcall
+#define APR_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
+#define APR_DECLARE_DATA __declspec(dllexport)
+#else
+#define APR_DECLARE(type) __declspec(dllimport) type __stdcall
+#define APR_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
+#define APR_DECLARE_DATA __declspec(dllimport)
+#endif
+
+#ifdef _WIN64
+#define APR_SSIZE_T_FMT "I64d"
+#define APR_SIZE_T_FMT "I64u"
+#else
+#define APR_SSIZE_T_FMT "d"
+#define APR_SIZE_T_FMT "u"
+#endif
+
+#if APR_HAS_LARGE_FILES
+#define APR_OFF_T_FMT "I64d"
+#else
+#define APR_OFF_T_FMT "d"
+#endif
+
+#define APR_PID_T_FMT "d"
+
+#define APR_INT64_T_FMT "I64d"
+#define APR_UINT64_T_FMT "I64u"
+#define APR_UINT64_T_HEX_FMT "I64x"
+
+/* No difference between PROC and GLOBAL mutex */
+#define APR_PROC_MUTEX_IS_GLOBAL 1
+
+/* Local machine definition for console and log output. */
+#define APR_EOL_STR "\r\n"
+
+typedef int apr_wait_t;
+
+#if APR_HAS_UNICODE_FS
+/* An arbitrary size that is digestable. True max is a bit less than 32000 */
+#define APR_PATH_MAX 8192
+#else /* !APR_HAS_UNICODE_FS */
+#define APR_PATH_MAX MAX_PATH
+#endif
+
+#define APR_DSOPATH "PATH"
+
+/** @} */
+
+/* Definitions that only Win32 programs need to compile properly. */
+
+/* XXX These simply don't belong here, perhaps in apr_portable.h
+ * based on some APR_HAVE_PID/GID/UID?
+ */
+#ifndef __GNUC__
+typedef int pid_t;
+#endif
+typedef int uid_t;
+typedef int gid_t;
+
+/* Win32 .h ommissions we really need */
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#if APR_HAVE_IPV6
+
+/* Appears in later flavors, not the originals. */
+#ifndef in_addr6
+#define in6_addr in_addr6
+#endif
+
+#ifndef WS2TCPIP_INLINE
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ ( (*(const apr_uint64_t *)(const void *)(&(a)->s6_addr[0]) == 0) \
+ && (*(const apr_uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
+#endif
+
+#endif /* APR_HAVE_IPV6 */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Done with badly written headers, leave 'deprecated CRT' undeprecated
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+#pragma warning(pop)
+#if _MSC_VER >= 1400
+#pragma warning(disable: 4996)
+#endif
+#endif
+
+#endif /* WIN32 */
+
+#endif /* APR_H */
diff --git a/include/apr_allocator.h b/include/apr_allocator.h
new file mode 100644
index 0000000..be05d0e
--- /dev/null
+++ b/include/apr_allocator.h
@@ -0,0 +1,179 @@
+/* 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 APR_ALLOCATOR_H
+#define APR_ALLOCATOR_H
+
+/**
+ * @file apr_allocator.h
+ * @brief APR Internal Memory Allocation
+ */
+
+#include "apr.h"
+#include "apr_errno.h"
+#define APR_WANT_MEMFUNC /**< For no good reason? */
+#include "apr_want.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup apr_allocator Internal Memory Allocation
+ * @ingroup APR
+ * @{
+ */
+
+/** the allocator structure */
+typedef struct apr_allocator_t apr_allocator_t;
+/** the structure which holds information about the allocation */
+typedef struct apr_memnode_t apr_memnode_t;
+
+/** basic memory node structure
+ * @note The next, ref and first_avail fields are available for use by the
+ * caller of apr_allocator_alloc(), the remaining fields are read-only.
+ * The next field has to be used with caution and sensibly set when the
+ * memnode is passed back to apr_allocator_free(). See apr_allocator_free()
+ * for details.
+ * The ref and first_avail fields will be properly restored by
+ * apr_allocator_free().
+ */
+struct apr_memnode_t {
+ apr_memnode_t *next; /**< next memnode */
+ apr_memnode_t **ref; /**< reference to self */
+ apr_uint32_t index; /**< size */
+ apr_uint32_t free_index; /**< how much free */
+ char *first_avail; /**< pointer to first free memory */
+ char *endp; /**< pointer to end of free memory */
+};
+
+/** The base size of a memory node - aligned. */
+#define APR_MEMNODE_T_SIZE APR_ALIGN_DEFAULT(sizeof(apr_memnode_t))
+
+/** Symbolic constants */
+#define APR_ALLOCATOR_MAX_FREE_UNLIMITED 0
+
+/**
+ * Create a new allocator
+ * @param allocator The allocator we have just created.
+ *
+ */
+APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator)
+ __attribute__((nonnull(1)));
+
+/**
+ * Destroy an allocator
+ * @param allocator The allocator to be destroyed
+ * @remark Any memnodes not given back to the allocator prior to destroying
+ * will _not_ be free()d.
+ */
+APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator)
+ __attribute__((nonnull(1)));
+
+/**
+ * Allocate a block of mem from the allocator
+ * @param allocator The allocator to allocate from
+ * @param size The size of the mem to allocate (excluding the
+ * memnode structure)
+ */
+APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator,
+ apr_size_t size)
+ __attribute__((nonnull(1)));
+
+/**
+ * Free a list of blocks of mem, giving them back to the allocator.
+ * The list is typically terminated by a memnode with its next field
+ * set to NULL.
+ * @param allocator The allocator to give the mem back to
+ * @param memnode The memory node to return
+ */
+APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator,
+ apr_memnode_t *memnode)
+ __attribute__((nonnull(1,2)));
+
+/**
+ * Get the true size that would be allocated for the given size (including
+ * the header and alignment).
+ * @param allocator The allocator from which to the memory would be allocated
+ * @param size The size to align
+ * @return The aligned size (or zero on apr_size_t overflow)
+ */
+APR_DECLARE(apr_size_t) apr_allocator_align(apr_allocator_t *allocator,
+ apr_size_t size);
+
+#include "apr_pools.h"
+
+/**
+ * Set the owner of the allocator
+ * @param allocator The allocator to set the owner for
+ * @param pool The pool that is to own the allocator
+ * @remark Typically pool is the highest level pool using the allocator
+ */
+/*
+ * XXX: see if we can come up with something a bit better. Currently
+ * you can make a pool an owner, but if the pool doesn't use the allocator
+ * the allocator will never be destroyed.
+ */
+APR_DECLARE(void) apr_allocator_owner_set(apr_allocator_t *allocator,
+ apr_pool_t *pool)
+ __attribute__((nonnull(1)));
+
+/**
+ * Get the current owner of the allocator
+ * @param allocator The allocator to get the owner from
+ */
+APR_DECLARE(apr_pool_t *) apr_allocator_owner_get(apr_allocator_t *allocator)
+ __attribute__((nonnull(1)));
+
+/**
+ * Set the current threshold at which the allocator should start
+ * giving blocks back to the system.
+ * @param allocator The allocator to set the threshold on
+ * @param size The threshold. 0 == unlimited.
+ */
+APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator,
+ apr_size_t size)
+ __attribute__((nonnull(1)));
+
+#include "apr_thread_mutex.h"
+
+#if APR_HAS_THREADS
+/**
+ * Set a mutex for the allocator to use
+ * @param allocator The allocator to set the mutex for
+ * @param mutex The mutex
+ */
+APR_DECLARE(void) apr_allocator_mutex_set(apr_allocator_t *allocator,
+ apr_thread_mutex_t *mutex)
+ __attribute__((nonnull(1)));
+
+/**
+ * Get the mutex currently set for the allocator
+ * @param allocator The allocator
+ */
+APR_DECLARE(apr_thread_mutex_t *) apr_allocator_mutex_get(
+ apr_allocator_t *allocator)
+ __attribute__((nonnull(1)));
+
+#endif /* APR_HAS_THREADS */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_ALLOCATOR_H */
diff --git a/include/apr_atomic.h b/include/apr_atomic.h
new file mode 100644
index 0000000..3d203ed
--- /dev/null
+++ b/include/apr_atomic.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 APR_ATOMIC_H
+#define APR_ATOMIC_H
+
+/**
+ * @file apr_atomic.h
+ * @brief APR Atomic Operations
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup apr_atomic Atomic Operations
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * this function is required on some platforms to initialize the
+ * atomic operation's internal structures
+ * @param p pool
+ * @return APR_SUCCESS on successful completion
+ * @remark Programs do NOT need to call this directly. APR will call this
+ * automatically from apr_initialize().
+ * @internal
+ */
+APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p);
+
+/*
+ * Atomic operations on 32-bit values
+ * Note: Each of these functions internally implements a memory barrier
+ * on platforms that require it
+ */
+
+/**
+ * atomically read an apr_uint32_t from memory
+ * @param mem the pointer
+ */
+APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem);
+
+/**
+ * atomically set an apr_uint32_t in memory
+ * @param mem pointer to the object
+ * @param val value that the object will assume
+ */
+APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val);
+
+/**
+ * atomically add 'val' to an apr_uint32_t
+ * @param mem pointer to the object
+ * @param val amount to add
+ * @return old value pointed to by mem
+ */
+APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val);
+
+/**
+ * atomically subtract 'val' from an apr_uint32_t
+ * @param mem pointer to the object
+ * @param val amount to subtract
+ */
+APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val);
+
+/**
+ * atomically increment an apr_uint32_t by 1
+ * @param mem pointer to the object
+ * @return old value pointed to by mem
+ */
+APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem);
+
+/**
+ * atomically decrement an apr_uint32_t by 1
+ * @param mem pointer to the atomic value
+ * @return zero if the value becomes zero on decrement, otherwise non-zero
+ */
+APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem);
+
+/**
+ * compare an apr_uint32_t's value with 'cmp'.
+ * If they are the same swap the value with 'with'
+ * @param mem pointer to the value
+ * @param with what to swap it with
+ * @param cmp the value to compare it to
+ * @return the old value of *mem
+ */
+APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,
+ apr_uint32_t cmp);
+
+/**
+ * exchange an apr_uint32_t's value with 'val'.
+ * @param mem pointer to the value
+ * @param val what to swap it with
+ * @return the old value of *mem
+ */
+APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val);
+
+/*
+ * Atomic operations on 64-bit values
+ * Note: Each of these functions internally implements a memory barrier
+ * on platforms that require it
+ */
+
+/**
+ * atomically read an apr_uint64_t from memory
+ * @param mem the pointer
+ */
+APR_DECLARE(apr_uint64_t) apr_atomic_read64(volatile apr_uint64_t *mem);
+
+/**
+ * atomically set an apr_uint64_t in memory
+ * @param mem pointer to the object
+ * @param val value that the object will assume
+ */
+APR_DECLARE(void) apr_atomic_set64(volatile apr_uint64_t *mem, apr_uint64_t val);
+
+/**
+ * atomically add 'val' to an apr_uint64_t
+ * @param mem pointer to the object
+ * @param val amount to add
+ * @return old value pointed to by mem
+ */
+APR_DECLARE(apr_uint64_t) apr_atomic_add64(volatile apr_uint64_t *mem, apr_uint64_t val);
+
+/**
+ * atomically subtract 'val' from an apr_uint64_t
+ * @param mem pointer to the object
+ * @param val amount to subtract
+ */
+APR_DECLARE(void) apr_atomic_sub64(volatile apr_uint64_t *mem, apr_uint64_t val);
+
+/**
+ * atomically increment an apr_uint64_t by 1
+ * @param mem pointer to the object
+ * @return old value pointed to by mem
+ */
+APR_DECLARE(apr_uint64_t) apr_atomic_inc64(volatile apr_uint64_t *mem);
+
+/**
+ * atomically decrement an apr_uint64_t by 1
+ * @param mem pointer to the atomic value
+ * @return zero if the value becomes zero on decrement, otherwise non-zero
+ */
+APR_DECLARE(int) apr_atomic_dec64(volatile apr_uint64_t *mem);
+
+/**
+ * compare an apr_uint64_t's value with 'cmp'.
+ * If they are the same swap the value with 'with'
+ * @param mem pointer to the value
+ * @param with what to swap it with
+ * @param cmp the value to compare it to
+ * @return the old value of *mem
+ */
+APR_DECLARE(apr_uint64_t) apr_atomic_cas64(volatile apr_uint64_t *mem, apr_uint64_t with,
+ apr_uint64_t cmp);
+
+/**
+ * exchange an apr_uint64_t's value with 'val'.
+ * @param mem pointer to the value
+ * @param val what to swap it with
+ * @return the old value of *mem
+ */
+APR_DECLARE(apr_uint64_t) apr_atomic_xchg64(volatile apr_uint64_t *mem, apr_uint64_t val);
+
+/**
+ * compare the pointer's value with cmp.
+ * If they are the same swap the value with 'with'
+ * @param mem pointer to the pointer
+ * @param with what to swap it with
+ * @param cmp the value to compare it to
+ * @return the old value of the pointer
+ */
+APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
+
+/**
+ * exchange a pair of pointer values
+ * @param mem pointer to the pointer
+ * @param with what to swap it with
+ * @return the old value of the pointer
+ */
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_ATOMIC_H */
diff --git a/include/apr_cstr.h b/include/apr_cstr.h
new file mode 100644
index 0000000..3f1b1a0
--- /dev/null
+++ b/include/apr_cstr.h
@@ -0,0 +1,292 @@
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ */
+
+/**
+ * @file apr_cstr.h
+ * @brief C string goodies.
+ */
+
+#ifndef APR_CSTR_H
+#define APR_CSTR_H
+
+#include <apr.h> /* for apr_size_t */
+#include <apr_pools.h> /* for apr_pool_t */
+#include <apr_tables.h> /* for apr_array_header_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_cstr C (POSIX) locale string functions
+ * @ingroup apr_strings
+ *
+ * The apr_cstr_* functions provide traditional C char * string text handling,
+ * and notabilty they treat all text in the C (a.k.a. POSIX) locale using the
+ * minimal POSIX character set, represented in either ASCII or a corresponding
+ * EBCDIC subset.
+ *
+ * Character values outside of that set are treated as opaque bytes, and all
+ * multi-byte character sequences are handled as individual distinct octets.
+ *
+ * Multi-byte characters sequences whose octets fall in the ASCII range cause
+ * unexpected results, such as in the ISO-2022-JP code page where ASCII octets
+ * occur within both shift-state and multibyte sequences.
+ *
+ * In the case of the UTF-8 encoding, all multibyte characters all fall outside
+ * of the C/POSIX range of characters, so these functions are generally safe
+ * to use on UTF-8 strings. The programmer must be aware that each octet may
+ * not represent a distinct printable character in such encodings.
+ *
+ * The standard C99/POSIX string functions, rather than apr_cstr, should be
+ * used in all cases where the current locale and encoding of the text is
+ * significant.
+ * @{
+ */
+
+
+/** Divide @a input into substrings, interpreting any char from @a sep
+ * as a token separator.
+ *
+ * Return an array of copies of those substrings (plain const char*),
+ * allocating both the array and the copies in @a pool.
+ *
+ * None of the elements added to the array contain any of the
+ * characters in @a sep_chars, and none of the new elements are empty
+ * (thus, it is possible that the returned array will have length
+ * zero).
+ *
+ * If @a chop_whitespace is TRUE, then remove leading and trailing
+ * whitespace from the returned strings.
+ *
+ * @since New in 1.6
+ */
+APR_DECLARE(apr_array_header_t *) apr_cstr_split(const char *input,
+ const char *sep_chars,
+ int chop_whitespace,
+ apr_pool_t *pool);
+
+/** Like apr_cstr_split(), but append to existing @a array instead of
+ * creating a new one. Allocate the copied substrings in @a pool
+ * (i.e., caller decides whether or not to pass @a array->pool as @a pool).
+ *
+ * @since New in 1.6
+ */
+APR_DECLARE(void) apr_cstr_split_append(apr_array_header_t *array,
+ const char *input,
+ const char *sep_chars,
+ int chop_whitespace,
+ apr_pool_t *pool);
+
+
+/** Return @c TRUE iff @a str matches any of the elements of @a list, a list
+ * of zero or more glob patterns.
+ *
+ * @since New in 1.6
+ */
+APR_DECLARE(int) apr_cstr_match_glob_list(const char *str,
+ const apr_array_header_t *list);
+
+/** Return @c TRUE iff @a str exactly matches any of the elements of @a list.
+ *
+ * @since New in 1.6
+ */
+APR_DECLARE(int) apr_cstr_match_list(const char *str,
+ const apr_array_header_t *list);
+
+/**
+ * Get the next token from @a *str interpreting any char from @a sep as a
+ * token separator. Separators at the beginning of @a str will be skipped.
+ * Returns a pointer to the beginning of the first token in @a *str or NULL
+ * if no token is left. Modifies @a str such that the next call will return
+ * the next token.
+ *
+ * @note The content of @a *str may be modified by this function.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(char *) apr_cstr_tokenize(const char *sep, char **str);
+
+/**
+ * Return the number of line breaks in @a msg, allowing any kind of newline
+ * termination (CR, LF, CRLF, or LFCR), even inconsistent.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(int) apr_cstr_count_newlines(const char *msg);
+
+#if 0 /* XXX: stringbuf logic is not present in APR */
+/**
+ * Return a cstring which is the concatenation of @a strings (an array
+ * of char *) each followed by @a separator (that is, @a separator
+ * will also end the resulting string). Allocate the result in @a pool.
+ * If @a strings is empty, then return the empty string.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(char *) apr_cstr_join(const apr_array_header_t *strings,
+ const char *separator,
+ apr_pool_t *pool);
+#endif
+
+/**
+ * Perform a case-insensitive comparison of two strings @a atr1 and @a atr2,
+ * treating upper and lower case values of the 26 standard C/POSIX alphabetic
+ * characters as equivalent. Extended latin characters outside of this set
+ * are treated as unique octets, irrespective of the current locale.
+ *
+ * Returns in integer greater than, equal to, or less than 0,
+ * according to whether @a str1 is considered greater than, equal to,
+ * or less than @a str2.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(int) apr_cstr_casecmp(const char *str1, const char *str2);
+
+/**
+ * Perform a case-insensitive comparison of two strings @a atr1 and @a atr2,
+ * treating upper and lower case values of the 26 standard C/POSIX alphabetic
+ * characters as equivalent. Extended latin characters outside of this set
+ * are treated as unique octets, irrespective of the current locale.
+ *
+ * Returns in integer greater than, equal to, or less than 0,
+ * according to whether @a str1 is considered greater than, equal to,
+ * or less than @a str2.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(int) apr_cstr_casecmpn(const char *str1,
+ const char *str2,
+ apr_size_t n);
+
+/**
+ * Parse the C string @a str into a 64 bit number, and return it in @a *n.
+ * Assume that the number is represented in base @a base.
+ * Raise an error if conversion fails (e.g. due to overflow), or if the
+ * converted number is smaller than @a minval or larger than @a maxval.
+ *
+ * Leading whitespace in @a str is skipped in a locale-dependent way.
+ * After that, the string may contain an optional '+' (positive, default)
+ * or '-' (negative) character, followed by an optional '0x' prefix if
+ * @a base is 0 or 16, followed by numeric digits appropriate for the base.
+ * If there are any more characters after the numeric digits, an error is
+ * returned.
+ *
+ * If @a base is zero, then a leading '0x' or '0X' prefix means hexadecimal,
+ * else a leading '0' means octal (implemented, though not documented, in
+ * apr_strtoi64() in APR 0.9.0 through 1.5.0), else use base ten.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(apr_status_t) apr_cstr_strtoi64(apr_int64_t *n, const char *str,
+ apr_int64_t minval,
+ apr_int64_t maxval,
+ int base);
+
+/**
+ * Parse the C string @a str into a 64 bit number, and return it in @a *n.
+ * Assume that the number is represented in base 10.
+ * Raise an error if conversion fails (e.g. due to overflow).
+ *
+ * The behaviour otherwise is as described for apr_cstr_strtoi64().
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(apr_status_t) apr_cstr_atoi64(apr_int64_t *n, const char *str);
+
+/**
+ * Parse the C string @a str into a 32 bit number, and return it in @a *n.
+ * Assume that the number is represented in base 10.
+ * Raise an error if conversion fails (e.g. due to overflow).
+ *
+ * The behaviour otherwise is as described for apr_cstr_strtoi64().
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(apr_status_t) apr_cstr_atoi(int *n, const char *str);
+
+/**
+ * Parse the C string @a str into an unsigned 64 bit number, and return
+ * it in @a *n. Assume that the number is represented in base @a base.
+ * Raise an error if conversion fails (e.g. due to overflow), or if the
+ * converted number is smaller than @a minval or larger than @a maxval.
+ *
+ * Leading whitespace in @a str is skipped in a locale-dependent way.
+ * After that, the string may contain an optional '+' (positive, default)
+ * or '-' (negative) character, followed by an optional '0x' prefix if
+ * @a base is 0 or 16, followed by numeric digits appropriate for the base.
+ * If there are any more characters after the numeric digits, an error is
+ * returned.
+ *
+ * If @a base is zero, then a leading '0x' or '0X' prefix means hexadecimal,
+ * else a leading '0' means octal (as implemented, though not documented, in
+ * apr_strtoi64(), else use base ten.
+ *
+ * @warning The implementation returns APR_ERANGE if the parsed number
+ * is greater than APR_INT64_MAX, even if it is not greater than @a maxval.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(apr_status_t) apr_cstr_strtoui64(apr_uint64_t *n, const char *str,
+ apr_uint64_t minval,
+ apr_uint64_t maxval,
+ int base);
+
+/**
+ * Parse the C string @a str into an unsigned 64 bit number, and return
+ * it in @a *n. Assume that the number is represented in base 10.
+ * Raise an error if conversion fails (e.g. due to overflow).
+ *
+ * The behaviour otherwise is as described for apr_cstr_strtoui64(),
+ * including the upper limit of APR_INT64_MAX.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(apr_status_t) apr_cstr_atoui64(apr_uint64_t *n, const char *str);
+
+/**
+ * Parse the C string @a str into an unsigned 32 bit number, and return
+ * it in @a *n. Assume that the number is represented in base 10.
+ * Raise an error if conversion fails (e.g. due to overflow).
+ *
+ * The behaviour otherwise is as described for apr_cstr_strtoui64(),
+ * including the upper limit of APR_INT64_MAX.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(apr_status_t) apr_cstr_atoui(unsigned int *n, const char *str);
+
+/**
+ * Skip the common prefix @a prefix from the C string @a str, and return
+ * a pointer to the next character after the prefix.
+ * Return @c NULL if @a str does not start with @a prefix.
+ *
+ * @since New in 1.6.
+ */
+APR_DECLARE(const char *) apr_cstr_skip_prefix(const char *str,
+ const char *prefix);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_STRING_H */
diff --git a/include/apr_dso.h b/include/apr_dso.h
new file mode 100644
index 0000000..ac701cf
--- /dev/null
+++ b/include/apr_dso.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 APR_DSO_DOT_H
+#define APR_DSO_DOT_H
+
+/**
+ * @file apr_dso.h
+ * @brief APR Dynamic Object Handling Routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup apr_dso Dynamic Object Handling
+ * @ingroup APR
+ * @{
+ */
+
+#if APR_HAS_DSO || defined(DOXYGEN)
+
+/**
+ * Structure for referencing dynamic objects
+ */
+typedef struct apr_dso_handle_t apr_dso_handle_t;
+
+/**
+ * Structure for referencing symbols from dynamic objects
+ */
+typedef void * apr_dso_handle_sym_t;
+
+/**
+ * Load a DSO library.
+ * @param res_handle Location to store new handle for the DSO.
+ * @param path Path to the DSO library
+ * @param ctx Pool to use.
+ * @bug We aught to provide an alternative to RTLD_GLOBAL, which
+ * is the only supported method of loading DSOs today.
+ */
+APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **res_handle,
+ const char *path, apr_pool_t *ctx);
+
+/**
+ * Close a DSO library.
+ * @param handle handle to close.
+ */
+APR_DECLARE(apr_status_t) apr_dso_unload(apr_dso_handle_t *handle);
+
+/**
+ * Load a symbol from a DSO handle.
+ * @param ressym Location to store the loaded symbol
+ * @param handle handle to load the symbol from.
+ * @param symname Name of the symbol to load.
+ */
+APR_DECLARE(apr_status_t) apr_dso_sym(apr_dso_handle_sym_t *ressym,
+ apr_dso_handle_t *handle,
+ const char *symname);
+
+/**
+ * Report more information when a DSO function fails.
+ * @param dso The dso handle that has been opened
+ * @param buf Location to store the dso error
+ * @param bufsize The size of the provided buffer
+ */
+APR_DECLARE(const char *) apr_dso_error(apr_dso_handle_t *dso, char *buf, apr_size_t bufsize);
+
+#endif /* APR_HAS_DSO */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/apr_encode.h b/include/apr_encode.h
new file mode 100644
index 0000000..8bae61f
--- /dev/null
+++ b/include/apr_encode.h
@@ -0,0 +1,650 @@
+/* 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.
+ */
+
+/**
+ * @file apr_encode.h
+ * @brief APR-UTIL Encoding
+ */
+#ifndef APR_ENCODE_H
+#define APR_ENCODE_H
+
+#include "apr.h"
+#include "apr_general.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup APR_Util_Encode Base64/Base64Url/Base32/Base32Hex/Base16 Encoding
+ * @ingroup APR_Util
+ * @{
+ */
+
+/**
+ * RFC4648 and RFC7515 compliant BASE64, BASE64URL, BASE32, BASE32HEX
+ * and BASE16 encode/decode functions.
+ *
+ * The following encodings are supported:
+ *
+ * - Base 64 Encoding
+ *
+ * o Use flag APR_ENCODE_NONE
+ * o https://tools.ietf.org/html/rfc4648#section-4
+ *
+ * - Base 64 Encoding with URL and Filename Safe Alphabet
+ *
+ * o Use flag APR_ENCODE_URL
+ * o https://tools.ietf.org/html/rfc4648#section-5
+ *
+ * - Base 64 URL Encoding without Padding
+ *
+ * o Use flag APR_ENCODE_BASE64URL
+ * o https://tools.ietf.org/html/rfc7515#appendix-C
+ *
+ * - Base 32 Encoding
+ *
+ * o Use flag APR_ENCODE_NONE
+ * o https://tools.ietf.org/html/rfc4648#section-6
+ *
+ * - Base 32 Encoding with Extended Hex Alphabet
+ *
+ * o Use flag APR_ENCODE_BASE32HEX
+ * o https://tools.ietf.org/html/rfc4648#section-7
+ *
+ * - Base 16 Encoding
+ *
+ * o Use flags APR_ENCODE_NONE/APR_ENCODE_COLON
+ * o https://tools.ietf.org/html/rfc4648#section-8
+ *
+ * If a non valid character of any kind including whitespace is passed to any
+ * of the decoder functions, APR_BADCH will be returned. In this case decoding
+ * will still take place, but the results can not be trusted.
+ *
+ * If APR_ENCODE_RELAXED is passed to the decoder functions, decoding will be
+ * attempted up until the first non valid character. If this results in an
+ * invalid state in the decoder, such as but not limited to an odd number of
+ * base16 characters, APR_BADCH will still be returned.
+ *
+ * If APR_ENCODE_RELAXED is not passed to a decoder function, the decoding will
+ * be done in constant time regardless of whether the result returns APR_SUCCESS
+ * or APR_BADCH.
+ *
+ * If the dest parameter is NULL, the maximum theoretical buffer size is
+ * returned in the len field, including space for a terminating zero character
+ * if the destination is a string. This value can be used to allocate buffers
+ * of a suitable safe size.
+ *
+ * If the dest parameter is provided, the encoding or decoding will take place,
+ * and the actual number of characters written is returned in the len field,
+ * ignoring any terminating zero.
+ *
+ * Plain strings are not assumed '\0' terminated unless APR_ENCODE_STRING is
+ * provided.
+ *
+ */
+
+/**
+ * When passing a string to one of the encode functions, this value can be
+ * passed to indicate a string-valued key, and have the length computed
+ * automatically.
+ */
+#define APR_ENCODE_STRING (-1)
+
+/**
+ * Generate RFC4648 base16/base32/base64.
+ */
+#define APR_ENCODE_NONE 0
+
+/**
+ * If relaxed, decode up until the first non base16/base32/base64 character.
+ */
+#define APR_ENCODE_RELAXED 1
+
+/**
+ * Omit the padding character (=) while encoding.
+ */
+#define APR_ENCODE_NOPADDING 2
+
+/**
+ * Generate RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet
+ */
+#define APR_ENCODE_URL 4
+
+/**
+ * Generate RFC7515 BASE64URL
+ */
+#define APR_ENCODE_BASE64URL (APR_ENCODE_NOPADDING | APR_ENCODE_URL)
+
+/**
+ * Generate base32hex encoding instead of base32 encoding
+ */
+#define APR_ENCODE_BASE32HEX 8
+
+/**
+ * Generate base16 with colons between each token.
+ */
+#define APR_ENCODE_COLON 16
+
+/**
+ * Generate base16 with lower case characters.
+ */
+#define APR_ENCODE_LOWER 32
+
+/**
+ * Convert text data to base64.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for encoding.
+ * @param src The original string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+ * @param len If not NULL, outputs the length of the buffer needed for encoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to encode.
+ */
+APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert binary data to base64.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for encoding.
+ * @param src The original buffer, can be NULL if \c dest is NULL.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+ * @param len If not NULL, outputs the length of the buffer needed for encoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
+ * if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
+ * and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
+ * encode.
+ */
+APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert text data to base64, and return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The original string.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the encoding is not
+ * possible (see apr_encode_base64 errors).
+ */
+APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));
+
+/**
+ * Convert binary data to base64, and return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The original buffer.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the encoding is not
+ * possible (see apr_encode_base64_binary errors).
+ */
+APR_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));
+
+/**
+ * Convert base64 or base64url with or without padding to text data.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for decoding.
+ * @param src The base64 string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the base64 string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, attempt to decode the full base64 string,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+ * @param len If not NULL, outputs the length of the buffer needed for decoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
+ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base64
+ * encoding, or APR_BADCH if a non base64 character is present and
+ * APR_ENCODE_RELAXED is not specified.
+ */
+APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert base64 or base64url with or without padding to binary data.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for decoding.
+ * @param src The base64 string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the base64 string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, attempt to decode the full base64 string,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+ * @param len If not NULL, outputs the length of the buffer needed for decoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
+ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base64
+ * encoding, or APR_BADCH if a non base64 character is present and
+ * APR_ENCODE_RELAXED is not specified.
+ */
+APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert base64 or base64url with or without padding to text data, and
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base64 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+ * @param len If not NULL, outputs the length of the decoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the decoding is not
+ * possible (see apr_decode_base64_binary errors).
+ */
+APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert base64 or base64url with or without padding to binary data, and
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base64 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+ * @param len If not NULL, outputs the length of the decoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the decoding is not
+ * possible (see apr_decode_base64_binary errors).
+ */
+APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert text data to base32.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for encoding.
+ * @param src The original string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+ * use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the buffer needed for encoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to encode.
+ */
+APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert binary data to base32.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for encoding.
+ * @param src The original buffer, can be NULL if \c dest is NULL.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+ * use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the buffer needed for encoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
+ * if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
+ * and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
+ * encode.
+ */
+APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert text data to base32, and return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The original string.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+ * use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the encoding is not
+ * possible (see apr_encode_base32 errors).
+ */
+APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert binary data to base32, and return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The original buffer.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+ * use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the encoding is not
+ * possible (see apr_encode_base32_binary errors).
+ */
+APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert base32 or base32hex with or without padding to text data.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for decoding.
+ * @param src The base32 string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the base32 string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the buffer needed for decoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
+ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base32
+ * encoding, or APR_BADCH if a non base32 character is present and
+ * APR_ENCODE_RELAXED is not specified.
+ */
+APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert base32 or base32hex with or without padding to binary data.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for decoding.
+ * @param src The base32 string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the base32 string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the buffer needed for decoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
+ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base32
+ * encoding, or APR_BADCH if a non base32 character is present and
+ * APR_ENCODE_RELAXED is not specified.
+ */
+APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert base32 or base32hex with or without padding to text data, and
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base32 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the decoding is not
+ * possible (see apr_decode_base32 errors).
+ */
+APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert base32 or base32hex with or without padding to binary data, and
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base32 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the decoding is not
+ * possible (see apr_decode_base32_binary errors).
+ */
+APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert text data to base16 (hex).
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for encoding.
+ * @param src The original string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+ * @param len If not NULL, outputs the length of the buffer needed for encoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to encode.
+ */
+APR_DECLARE(apr_status_t) apr_encode_base16(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert binary data to base16 (hex).
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for encoding.
+ * @param src The original buffer, can be NULL if \c dest is NULL.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+ * @param len If not NULL, outputs the length of the buffer needed for encoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
+ * if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
+ * and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
+ * encode.
+ */
+APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest,
+ const unsigned char *src, apr_ssize_t slen, int flags,
+ apr_size_t * len);
+
+/**
+ * Convert text data to base16 (hex), and return the results from a
+ * pool.
+ * @param p Pool to allocate from.
+ * @param src The original string.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the encoding is not
+ * possible (see apr_encode_base16 errors).
+ */
+APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert binary data to base16 (hex), and return the results from a
+ * pool.
+ * @param p Pool to allocate from.
+ * @param src The original buffer.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the encoding is not
+ * possible (see apr_encode_base16_binary errors).
+ */
+APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p,
+ const unsigned char *src, apr_ssize_t slen,
+ int flags, apr_size_t * len)__attribute__((nonnull(1)));
+
+/**
+ * Convert base16 (hex) to text data.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for decoding.
+ * @param src The base16 string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the base16 string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+ * @param len If not NULL, outputs the length of the buffer needed for decoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
+ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base16
+ * encoding, or APR_BADCH if a non base16 character is present and
+ * APR_ENCODE_RELAXED is not specified.
+ */
+APR_DECLARE(apr_status_t) apr_decode_base16(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert base16 (hex) to binary data.
+ * @param dest The destination string, can be NULL to output in \c len the
+ * needed buffer length for decoding.
+ * @param src The base16 string, can be NULL if \c dest is NULL and \c slen
+ * is positive or nul.
+ * @param slen The length of the base16 string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+ * @param len If not NULL, outputs the length of the buffer needed for decoding
+ * (including the trailing NUL) if \c dest is NULL, or the actual length of
+ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
+ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
+ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
+ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
+ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
+ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base16
+ * encoding, or APR_BADCH if a non base16 character is present and
+ * APR_ENCODE_RELAXED is not specified.
+ */
+APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
+
+/**
+ * Convert base16 (hex) and return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base16 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the decoding is not
+ * possible (see apr_decode_base16 errors).
+ */
+APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/**
+ * Convert base16 (hex) to binary data, and return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base16 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+ * @param len If not NULL, outputs the length of the encoding (excluding the
+ * trailing NUL).
+ * @return A NUL terminated string allocated from the pool on success,
+ * or NULL if src is NULL or allocation failed or the decoding is not
+ * possible (see apr_decode_base16_binary errors).
+ */
+APR_DECLARE(const unsigned char *)apr_pdecode_base16_binary(apr_pool_t * p,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ __attribute__((nonnull(1)));
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_ENCODE_H */
diff --git a/include/apr_env.h b/include/apr_env.h
new file mode 100644
index 0000000..85ab670
--- /dev/null
+++ b/include/apr_env.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 APR_ENV_H
+#define APR_ENV_H
+/**
+ * @file apr_env.h
+ * @brief APR Environment functions
+ */
+#include "apr_errno.h"
+#include "apr_pools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_env Functions for manipulating the environment
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * Get the value of an environment variable
+ * @param value the returned value, allocated from @a pool
+ * @param envvar the name of the environment variable
+ * @param pool where to allocate @a value and any temporary storage from
+ */
+APR_DECLARE(apr_status_t) apr_env_get(char **value, const char *envvar,
+ apr_pool_t *pool);
+
+/**
+ * Set the value of an environment variable
+ * @param envvar the name of the environment variable
+ * @param value the value to set
+ * @param pool where to allocate temporary storage from
+ */
+APR_DECLARE(apr_status_t) apr_env_set(const char *envvar, const char *value,
+ apr_pool_t *pool);
+
+/**
+ * Delete a variable from the environment
+ * @param envvar the name of the environment variable
+ * @param pool where to allocate temporary storage from
+ */
+APR_DECLARE(apr_status_t) apr_env_delete(const char *envvar, apr_pool_t *pool);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_ENV_H */
diff --git a/include/apr_errno.h b/include/apr_errno.h
new file mode 100644
index 0000000..8fa6628
--- /dev/null
+++ b/include/apr_errno.h
@@ -0,0 +1,1342 @@
+/* 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 APR_ERRNO_H
+#define APR_ERRNO_H
+
+/**
+ * @file apr_errno.h
+ * @brief APR Error Codes
+ */
+
+#include "apr.h"
+
+#if APR_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_errno Error Codes
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * Type for specifying an error or status code.
+ */
+typedef int apr_status_t;
+
+/**
+ * Return a human readable string describing the specified error.
+ * @param statcode The error code to get a string for.
+ * @param buf A buffer to hold the error string.
+ * @param bufsize Size of the buffer to hold the string.
+ */
+APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
+ apr_size_t bufsize);
+
+#if defined(DOXYGEN)
+/**
+ * @def APR_FROM_OS_ERROR(os_err_type syserr)
+ * Fold a platform specific error into an apr_status_t code.
+ * @return apr_status_t
+ * @param e The platform os error code.
+ * @warning macro implementation; the syserr argument may be evaluated
+ * multiple times.
+ */
+#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
+
+/**
+ * @def APR_TO_OS_ERROR(apr_status_t statcode)
+ * @return os_err_type
+ * Fold an apr_status_t code back to the native platform defined error.
+ * @param e The apr_status_t folded platform os error code.
+ * @warning macro implementation; the statcode argument may be evaluated
+ * multiple times. If the statcode was not created by apr_get_os_error
+ * or APR_FROM_OS_ERROR, the results are undefined.
+ */
+#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)
+
+/** @def apr_get_os_error()
+ * @return apr_status_t the last platform error, folded into apr_status_t, on most platforms
+ * @remark This retrieves errno, or calls a GetLastError() style function, and
+ * folds it with APR_FROM_OS_ERROR. Some platforms (such as OS2) have no
+ * such mechanism, so this call may be unsupported. Do NOT use this
+ * call for socket errors from socket, send, recv etc!
+ */
+
+/** @def apr_set_os_error(e)
+ * Reset the last platform error, unfolded from an apr_status_t, on some platforms
+ * @param e The OS error folded in a prior call to APR_FROM_OS_ERROR()
+ * @warning This is a macro implementation; the statcode argument may be evaluated
+ * multiple times. If the statcode was not created by apr_get_os_error
+ * or APR_FROM_OS_ERROR, the results are undefined. This macro sets
+ * errno, or calls a SetLastError() style function, unfolding statcode
+ * with APR_TO_OS_ERROR. Some platforms (such as OS2) have no such
+ * mechanism, so this call may be unsupported.
+ */
+
+/** @def apr_get_netos_error()
+ * Return the last socket error, folded into apr_status_t, on all platforms
+ * @remark This retrieves errno or calls a GetLastSocketError() style function,
+ * and folds it with APR_FROM_OS_ERROR.
+ */
+
+/** @def apr_set_netos_error(e)
+ * Reset the last socket error, unfolded from an apr_status_t
+ * @param e The socket error folded in a prior call to APR_FROM_OS_ERROR()
+ * @warning This is a macro implementation; the statcode argument may be evaluated
+ * multiple times. If the statcode was not created by apr_get_os_error
+ * or APR_FROM_OS_ERROR, the results are undefined. This macro sets
+ * errno, or calls a WSASetLastError() style function, unfolding
+ * socketcode with APR_TO_OS_ERROR.
+ */
+
+#endif /* defined(DOXYGEN) */
+
+/**
+ * APR_OS_START_ERROR is where the APR specific error values start.
+ */
+#define APR_OS_START_ERROR 20000
+/**
+ * APR_OS_ERRSPACE_SIZE is the maximum number of errors you can fit
+ * into one of the error/status ranges below -- except for
+ * APR_OS_START_USERERR, which see.
+ */
+#define APR_OS_ERRSPACE_SIZE 50000
+/**
+ * APR_UTIL_ERRSPACE_SIZE is the size of the space that is reserved for
+ * use within apr-util. This space is reserved above that used by APR
+ * internally.
+ * @note This number MUST be smaller than APR_OS_ERRSPACE_SIZE by a
+ * large enough amount that APR has sufficient room for its
+ * codes.
+ */
+#define APR_UTIL_ERRSPACE_SIZE 20000
+/**
+ * APR_OS_START_STATUS is where the APR specific status codes start.
+ */
+#define APR_OS_START_STATUS (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE)
+/**
+ * APR_UTIL_START_STATUS is where APR-Util starts defining its
+ * status codes.
+ */
+#define APR_UTIL_START_STATUS (APR_OS_START_STATUS + \
+ (APR_OS_ERRSPACE_SIZE - APR_UTIL_ERRSPACE_SIZE))
+/**
+ * APR_OS_START_USERERR are reserved for applications that use APR that
+ * layer their own error codes along with APR's. Note that the
+ * error immediately following this one is set ten times farther
+ * away than usual, so that users of apr have a lot of room in
+ * which to declare custom error codes.
+ *
+ * In general applications should try and create unique error codes. To try
+ * and assist in finding suitable ranges of numbers to use, the following
+ * ranges are known to be used by the listed applications. If your
+ * application defines error codes please advise the range of numbers it
+ * uses to dev@apr.apache.org for inclusion in this list.
+ *
+ * Ranges shown are in relation to APR_OS_START_USERERR
+ *
+ * Subversion - Defined ranges, of less than 100, at intervals of 5000
+ * starting at an offset of 5000, e.g.
+ * +5000 to 5100, +10000 to 10100
+ *
+ * Apache HTTPD - +2000 to 2999
+ */
+#define APR_OS_START_USERERR (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE)
+/**
+ * APR_OS_START_USEERR is obsolete, defined for compatibility only.
+ * Use APR_OS_START_USERERR instead.
+ */
+#define APR_OS_START_USEERR APR_OS_START_USERERR
+/**
+ * APR_OS_START_CANONERR is where APR versions of errno values are defined
+ * on systems which don't have the corresponding errno.
+ */
+#define APR_OS_START_CANONERR (APR_OS_START_USERERR \
+ + (APR_OS_ERRSPACE_SIZE * 10))
+/**
+ * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
+ * apr_status_t values.
+ */
+#define APR_OS_START_EAIERR (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)
+/**
+ * APR_OS_START_SYSERR folds platform-specific system error values into
+ * apr_status_t values.
+ */
+#define APR_OS_START_SYSERR (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)
+
+/**
+ * @defgroup APR_ERROR_map APR Error Space
+ * <PRE>
+ * The following attempts to show the relation of the various constants
+ * used for mapping APR Status codes.
+ *
+ * 0
+ *
+ * 20,000 APR_OS_START_ERROR
+ *
+ * + APR_OS_ERRSPACE_SIZE (50,000)
+ *
+ * 70,000 APR_OS_START_STATUS
+ *
+ * + APR_OS_ERRSPACE_SIZE - APR_UTIL_ERRSPACE_SIZE (30,000)
+ *
+ * 100,000 APR_UTIL_START_STATUS
+ *
+ * + APR_UTIL_ERRSPACE_SIZE (20,000)
+ *
+ * 120,000 APR_OS_START_USERERR
+ *
+ * + 10 x APR_OS_ERRSPACE_SIZE (50,000 * 10)
+ *
+ * 620,000 APR_OS_START_CANONERR
+ *
+ * + APR_OS_ERRSPACE_SIZE (50,000)
+ *
+ * 670,000 APR_OS_START_EAIERR
+ *
+ * + APR_OS_ERRSPACE_SIZE (50,000)
+ *
+ * 720,000 APR_OS_START_SYSERR
+ *
+ * </PRE>
+ */
+
+/** no error. */
+#define APR_SUCCESS 0
+
+/**
+ * @defgroup APR_Error APR Error Values
+ * <PRE>
+ * <b>APR ERROR VALUES</b>
+ * APR_ENOSTAT APR was unable to perform a stat on the file
+ * APR_ENOPOOL APR was not provided a pool with which to allocate memory
+ * APR_EBADDATE APR was given an invalid date
+ * APR_EINVALSOCK APR was given an invalid socket
+ * APR_ENOPROC APR was not given a process structure
+ * APR_ENOTIME APR was not given a time structure
+ * APR_ENODIR APR was not given a directory structure
+ * APR_ENOLOCK APR was not given a lock structure
+ * APR_ENOPOLL APR was not given a poll structure
+ * APR_ENOSOCKET APR was not given a socket
+ * APR_ENOTHREAD APR was not given a thread structure
+ * APR_ENOTHDKEY APR was not given a thread key structure
+ * APR_ENOSHMAVAIL There is no more shared memory available
+ * APR_EDSOOPEN APR was unable to open the dso object. For more
+ * information call apr_dso_error().
+ * APR_EGENERAL General failure (specific information not available)
+ * APR_EBADIP The specified IP address is invalid
+ * APR_EBADMASK The specified netmask is invalid
+ * APR_ESYMNOTFOUND Could not find the requested symbol
+ * APR_ENOTENOUGHENTROPY Not enough entropy to continue
+ * </PRE>
+ *
+ * <PRE>
+ * <b>APR STATUS VALUES</b>
+ * APR_INCHILD Program is currently executing in the child
+ * APR_INPARENT Program is currently executing in the parent
+ * APR_DETACH The thread is detached
+ * APR_NOTDETACH The thread is not detached
+ * APR_CHILD_DONE The child has finished executing
+ * APR_CHILD_NOTDONE The child has not finished executing
+ * APR_TIMEUP The operation did not finish before the timeout
+ * APR_INCOMPLETE The operation was incomplete although some processing
+ * was performed and the results are partially valid
+ * APR_BADCH Getopt found an option not in the option string
+ * APR_BADARG Getopt found an option that is missing an argument
+ * and an argument was specified in the option string
+ * APR_EOF APR has encountered the end of the file
+ * APR_NOTFOUND APR was unable to find the socket in the poll structure
+ * APR_ANONYMOUS APR is using anonymous shared memory
+ * APR_FILEBASED APR is using a file name as the key to the shared memory
+ * APR_KEYBASED APR is using a shared key as the key to the shared memory
+ * APR_EINIT Ininitalizer value. If no option has been found, but
+ * the status variable requires a value, this should be used
+ * APR_ENOTIMPL The APR function has not been implemented on this
+ * platform, either because nobody has gotten to it yet,
+ * or the function is impossible on this platform.
+ * APR_EMISMATCH Two passwords do not match.
+ * APR_EABSOLUTE The given path was absolute.
+ * APR_ERELATIVE The given path was relative.
+ * APR_EINCOMPLETE The given path was neither relative nor absolute.
+ * APR_EABOVEROOT The given path was above the root path.
+ * APR_EBUSY The given lock was busy.
+ * APR_EPROC_UNKNOWN The given process wasn't recognized by APR
+ * </PRE>
+ * @{
+ */
+/** @see APR_STATUS_IS_ENOSTAT */
+#define APR_ENOSTAT (APR_OS_START_ERROR + 1)
+/** @see APR_STATUS_IS_ENOPOOL */
+#define APR_ENOPOOL (APR_OS_START_ERROR + 2)
+/* empty slot: +3 */
+/** @see APR_STATUS_IS_EBADDATE */
+#define APR_EBADDATE (APR_OS_START_ERROR + 4)
+/** @see APR_STATUS_IS_EINVALSOCK */
+#define APR_EINVALSOCK (APR_OS_START_ERROR + 5)
+/** @see APR_STATUS_IS_ENOPROC */
+#define APR_ENOPROC (APR_OS_START_ERROR + 6)
+/** @see APR_STATUS_IS_ENOTIME */
+#define APR_ENOTIME (APR_OS_START_ERROR + 7)
+/** @see APR_STATUS_IS_ENODIR */
+#define APR_ENODIR (APR_OS_START_ERROR + 8)
+/** @see APR_STATUS_IS_ENOLOCK */
+#define APR_ENOLOCK (APR_OS_START_ERROR + 9)
+/** @see APR_STATUS_IS_ENOPOLL */
+#define APR_ENOPOLL (APR_OS_START_ERROR + 10)
+/** @see APR_STATUS_IS_ENOSOCKET */
+#define APR_ENOSOCKET (APR_OS_START_ERROR + 11)
+/** @see APR_STATUS_IS_ENOTHREAD */
+#define APR_ENOTHREAD (APR_OS_START_ERROR + 12)
+/** @see APR_STATUS_IS_ENOTHDKEY */
+#define APR_ENOTHDKEY (APR_OS_START_ERROR + 13)
+/** @see APR_STATUS_IS_EGENERAL */
+#define APR_EGENERAL (APR_OS_START_ERROR + 14)
+/** @see APR_STATUS_IS_ENOSHMAVAIL */
+#define APR_ENOSHMAVAIL (APR_OS_START_ERROR + 15)
+/** @see APR_STATUS_IS_EBADIP */
+#define APR_EBADIP (APR_OS_START_ERROR + 16)
+/** @see APR_STATUS_IS_EBADMASK */
+#define APR_EBADMASK (APR_OS_START_ERROR + 17)
+/* empty slot: +18 */
+/** @see APR_STATUS_IS_EDSOPEN */
+#define APR_EDSOOPEN (APR_OS_START_ERROR + 19)
+/** @see APR_STATUS_IS_EABSOLUTE */
+#define APR_EABSOLUTE (APR_OS_START_ERROR + 20)
+/** @see APR_STATUS_IS_ERELATIVE */
+#define APR_ERELATIVE (APR_OS_START_ERROR + 21)
+/** @see APR_STATUS_IS_EINCOMPLETE */
+#define APR_EINCOMPLETE (APR_OS_START_ERROR + 22)
+/** @see APR_STATUS_IS_EABOVEROOT */
+#define APR_EABOVEROOT (APR_OS_START_ERROR + 23)
+/** @see APR_STATUS_IS_EBADPATH */
+#define APR_EBADPATH (APR_OS_START_ERROR + 24)
+/** @see APR_STATUS_IS_EPATHWILD */
+#define APR_EPATHWILD (APR_OS_START_ERROR + 25)
+/** @see APR_STATUS_IS_ESYMNOTFOUND */
+#define APR_ESYMNOTFOUND (APR_OS_START_ERROR + 26)
+/** @see APR_STATUS_IS_EPROC_UNKNOWN */
+#define APR_EPROC_UNKNOWN (APR_OS_START_ERROR + 27)
+/** @see APR_STATUS_IS_ENOTENOUGHENTROPY */
+#define APR_ENOTENOUGHENTROPY (APR_OS_START_ERROR + 28)
+/** @} */
+
+/**
+ * @defgroup APR_STATUS_IS Status Value Tests
+ * @warning For any particular error condition, more than one of these tests
+ * may match. This is because platform-specific error codes may not
+ * always match the semantics of the POSIX codes these tests (and the
+ * corresponding APR error codes) are named after. A notable example
+ * are the APR_STATUS_IS_ENOENT and APR_STATUS_IS_ENOTDIR tests on
+ * Win32 platforms. The programmer should always be aware of this and
+ * adjust the order of the tests accordingly.
+ * @{
+ */
+/**
+ * APR was unable to perform a stat on the file
+ * @warning always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_ENOSTAT(s) ((s) == APR_ENOSTAT)
+/**
+ * APR was not provided a pool with which to allocate memory
+ * @warning always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_ENOPOOL(s) ((s) == APR_ENOPOOL)
+/** APR was given an invalid date */
+#define APR_STATUS_IS_EBADDATE(s) ((s) == APR_EBADDATE)
+/** APR was given an invalid socket */
+#define APR_STATUS_IS_EINVALSOCK(s) ((s) == APR_EINVALSOCK)
+/** APR was not given a process structure */
+#define APR_STATUS_IS_ENOPROC(s) ((s) == APR_ENOPROC)
+/** APR was not given a time structure */
+#define APR_STATUS_IS_ENOTIME(s) ((s) == APR_ENOTIME)
+/** APR was not given a directory structure */
+#define APR_STATUS_IS_ENODIR(s) ((s) == APR_ENODIR)
+/** APR was not given a lock structure */
+#define APR_STATUS_IS_ENOLOCK(s) ((s) == APR_ENOLOCK)
+/** APR was not given a poll structure */
+#define APR_STATUS_IS_ENOPOLL(s) ((s) == APR_ENOPOLL)
+/** APR was not given a socket */
+#define APR_STATUS_IS_ENOSOCKET(s) ((s) == APR_ENOSOCKET)
+/** APR was not given a thread structure */
+#define APR_STATUS_IS_ENOTHREAD(s) ((s) == APR_ENOTHREAD)
+/** APR was not given a thread key structure */
+#define APR_STATUS_IS_ENOTHDKEY(s) ((s) == APR_ENOTHDKEY)
+/** Generic Error which can not be put into another spot */
+#define APR_STATUS_IS_EGENERAL(s) ((s) == APR_EGENERAL)
+/** There is no more shared memory available */
+#define APR_STATUS_IS_ENOSHMAVAIL(s) ((s) == APR_ENOSHMAVAIL)
+/** The specified IP address is invalid */
+#define APR_STATUS_IS_EBADIP(s) ((s) == APR_EBADIP)
+/** The specified netmask is invalid */
+#define APR_STATUS_IS_EBADMASK(s) ((s) == APR_EBADMASK)
+/* empty slot: +18 */
+/**
+ * APR was unable to open the dso object.
+ * For more information call apr_dso_error().
+ */
+#if defined(WIN32)
+#define APR_STATUS_IS_EDSOOPEN(s) ((s) == APR_EDSOOPEN \
+ || APR_TO_OS_ERROR(s) == ERROR_MOD_NOT_FOUND)
+#else
+#define APR_STATUS_IS_EDSOOPEN(s) ((s) == APR_EDSOOPEN)
+#endif
+/** The given path was absolute. */
+#define APR_STATUS_IS_EABSOLUTE(s) ((s) == APR_EABSOLUTE)
+/** The given path was relative. */
+#define APR_STATUS_IS_ERELATIVE(s) ((s) == APR_ERELATIVE)
+/** The given path was neither relative nor absolute. */
+#define APR_STATUS_IS_EINCOMPLETE(s) ((s) == APR_EINCOMPLETE)
+/** The given path was above the root path. */
+#define APR_STATUS_IS_EABOVEROOT(s) ((s) == APR_EABOVEROOT)
+/** The given path was bad. */
+#define APR_STATUS_IS_EBADPATH(s) ((s) == APR_EBADPATH)
+/** The given path contained wildcards. */
+#define APR_STATUS_IS_EPATHWILD(s) ((s) == APR_EPATHWILD)
+/** Could not find the requested symbol.
+ * For more information call apr_dso_error().
+ */
+#if defined(WIN32)
+#define APR_STATUS_IS_ESYMNOTFOUND(s) ((s) == APR_ESYMNOTFOUND \
+ || APR_TO_OS_ERROR(s) == ERROR_PROC_NOT_FOUND)
+#else
+#define APR_STATUS_IS_ESYMNOTFOUND(s) ((s) == APR_ESYMNOTFOUND)
+#endif
+/** The given process was not recognized by APR. */
+#define APR_STATUS_IS_EPROC_UNKNOWN(s) ((s) == APR_EPROC_UNKNOWN)
+/** APR could not gather enough entropy to continue. */
+#define APR_STATUS_IS_ENOTENOUGHENTROPY(s) ((s) == APR_ENOTENOUGHENTROPY)
+
+/** @} */
+
+/**
+ * @addtogroup APR_Error
+ * @{
+ */
+/** @see APR_STATUS_IS_INCHILD */
+#define APR_INCHILD (APR_OS_START_STATUS + 1)
+/** @see APR_STATUS_IS_INPARENT */
+#define APR_INPARENT (APR_OS_START_STATUS + 2)
+/** @see APR_STATUS_IS_DETACH */
+#define APR_DETACH (APR_OS_START_STATUS + 3)
+/** @see APR_STATUS_IS_NOTDETACH */
+#define APR_NOTDETACH (APR_OS_START_STATUS + 4)
+/** @see APR_STATUS_IS_CHILD_DONE */
+#define APR_CHILD_DONE (APR_OS_START_STATUS + 5)
+/** @see APR_STATUS_IS_CHILD_NOTDONE */
+#define APR_CHILD_NOTDONE (APR_OS_START_STATUS + 6)
+/** @see APR_STATUS_IS_TIMEUP */
+#define APR_TIMEUP (APR_OS_START_STATUS + 7)
+/** @see APR_STATUS_IS_INCOMPLETE */
+#define APR_INCOMPLETE (APR_OS_START_STATUS + 8)
+/* empty slot: +9 */
+/* empty slot: +10 */
+/* empty slot: +11 */
+/** @see APR_STATUS_IS_BADCH */
+#define APR_BADCH (APR_OS_START_STATUS + 12)
+/** @see APR_STATUS_IS_BADARG */
+#define APR_BADARG (APR_OS_START_STATUS + 13)
+/** @see APR_STATUS_IS_EOF */
+#define APR_EOF (APR_OS_START_STATUS + 14)
+/** @see APR_STATUS_IS_NOTFOUND */
+#define APR_NOTFOUND (APR_OS_START_STATUS + 15)
+/* empty slot: +16 */
+/* empty slot: +17 */
+/* empty slot: +18 */
+/** @see APR_STATUS_IS_ANONYMOUS */
+#define APR_ANONYMOUS (APR_OS_START_STATUS + 19)
+/** @see APR_STATUS_IS_FILEBASED */
+#define APR_FILEBASED (APR_OS_START_STATUS + 20)
+/** @see APR_STATUS_IS_KEYBASED */
+#define APR_KEYBASED (APR_OS_START_STATUS + 21)
+/** @see APR_STATUS_IS_EINIT */
+#define APR_EINIT (APR_OS_START_STATUS + 22)
+/** @see APR_STATUS_IS_ENOTIMPL */
+#define APR_ENOTIMPL (APR_OS_START_STATUS + 23)
+/** @see APR_STATUS_IS_EMISMATCH */
+#define APR_EMISMATCH (APR_OS_START_STATUS + 24)
+/** @see APR_STATUS_IS_EBUSY */
+#define APR_EBUSY (APR_OS_START_STATUS + 25)
+/** @} */
+
+/**
+ * @addtogroup APR_STATUS_IS
+ * @{
+ */
+/**
+ * Program is currently executing in the child
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code */
+#define APR_STATUS_IS_INCHILD(s) ((s) == APR_INCHILD)
+/**
+ * Program is currently executing in the parent
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_INPARENT(s) ((s) == APR_INPARENT)
+/**
+ * The thread is detached
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_DETACH(s) ((s) == APR_DETACH)
+/**
+ * The thread is not detached
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_NOTDETACH(s) ((s) == APR_NOTDETACH)
+/**
+ * The child has finished executing
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_CHILD_DONE(s) ((s) == APR_CHILD_DONE)
+/**
+ * The child has not finished executing
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_CHILD_NOTDONE(s) ((s) == APR_CHILD_NOTDONE)
+/**
+ * The operation did not finish before the timeout
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP)
+/**
+ * The operation was incomplete although some processing was performed
+ * and the results are partially valid.
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_INCOMPLETE(s) ((s) == APR_INCOMPLETE)
+/* empty slot: +9 */
+/* empty slot: +10 */
+/* empty slot: +11 */
+/**
+ * Getopt found an option not in the option string
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_BADCH(s) ((s) == APR_BADCH)
+/**
+ * Getopt found an option not in the option string and an argument was
+ * specified in the option string
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_BADARG(s) ((s) == APR_BADARG)
+/**
+ * APR has encountered the end of the file
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_EOF(s) ((s) == APR_EOF)
+/**
+ * APR was unable to find the socket in the poll structure
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_NOTFOUND(s) ((s) == APR_NOTFOUND)
+/* empty slot: +16 */
+/* empty slot: +17 */
+/* empty slot: +18 */
+/**
+ * APR is using anonymous shared memory
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_ANONYMOUS(s) ((s) == APR_ANONYMOUS)
+/**
+ * APR is using a file name as the key to the shared memory
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_FILEBASED(s) ((s) == APR_FILEBASED)
+/**
+ * APR is using a shared key as the key to the shared memory
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_KEYBASED(s) ((s) == APR_KEYBASED)
+/**
+ * Ininitalizer value. If no option has been found, but
+ * the status variable requires a value, this should be used
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_EINIT(s) ((s) == APR_EINIT)
+/**
+ * The APR function has not been implemented on this
+ * platform, either because nobody has gotten to it yet,
+ * or the function is impossible on this platform.
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_ENOTIMPL(s) ((s) == APR_ENOTIMPL)
+/**
+ * Two passwords do not match.
+ * @warning
+ * always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_EMISMATCH(s) ((s) == APR_EMISMATCH)
+/**
+ * The given lock was busy
+ * @warning always use this test, as platform-specific variances may meet this
+ * more than one error code
+ */
+#define APR_STATUS_IS_EBUSY(s) ((s) == APR_EBUSY)
+
+/** @} */
+
+/**
+ * @addtogroup APR_Error APR Error Values
+ * @{
+ */
+/* APR CANONICAL ERROR VALUES */
+/** @see APR_STATUS_IS_EACCES */
+#ifdef EACCES
+#define APR_EACCES EACCES
+#else
+#define APR_EACCES (APR_OS_START_CANONERR + 1)
+#endif
+
+/** @see APR_STATUS_IS_EEXIST */
+#ifdef EEXIST
+#define APR_EEXIST EEXIST
+#else
+#define APR_EEXIST (APR_OS_START_CANONERR + 2)
+#endif
+
+/** @see APR_STATUS_IS_ENAMETOOLONG */
+#ifdef ENAMETOOLONG
+#define APR_ENAMETOOLONG ENAMETOOLONG
+#else
+#define APR_ENAMETOOLONG (APR_OS_START_CANONERR + 3)
+#endif
+
+/** @see APR_STATUS_IS_ENOENT */
+#ifdef ENOENT
+#define APR_ENOENT ENOENT
+#else
+#define APR_ENOENT (APR_OS_START_CANONERR + 4)
+#endif
+
+/** @see APR_STATUS_IS_ENOTDIR */
+#ifdef ENOTDIR
+#define APR_ENOTDIR ENOTDIR
+#else
+#define APR_ENOTDIR (APR_OS_START_CANONERR + 5)
+#endif
+
+/** @see APR_STATUS_IS_ENOSPC */
+#ifdef ENOSPC
+#define APR_ENOSPC ENOSPC
+#else
+#define APR_ENOSPC (APR_OS_START_CANONERR + 6)
+#endif
+
+/** @see APR_STATUS_IS_ENOMEM */
+#ifdef ENOMEM
+#define APR_ENOMEM ENOMEM
+#else
+#define APR_ENOMEM (APR_OS_START_CANONERR + 7)
+#endif
+
+/** @see APR_STATUS_IS_EMFILE */
+#ifdef EMFILE
+#define APR_EMFILE EMFILE
+#else
+#define APR_EMFILE (APR_OS_START_CANONERR + 8)
+#endif
+
+/** @see APR_STATUS_IS_ENFILE */
+#ifdef ENFILE
+#define APR_ENFILE ENFILE
+#else
+#define APR_ENFILE (APR_OS_START_CANONERR + 9)
+#endif
+
+/** @see APR_STATUS_IS_EBADF */
+#ifdef EBADF
+#define APR_EBADF EBADF
+#else
+#define APR_EBADF (APR_OS_START_CANONERR + 10)
+#endif
+
+/** @see APR_STATUS_IS_EINVAL */
+#ifdef EINVAL
+#define APR_EINVAL EINVAL
+#else
+#define APR_EINVAL (APR_OS_START_CANONERR + 11)
+#endif
+
+/** @see APR_STATUS_IS_ESPIPE */
+#ifdef ESPIPE
+#define APR_ESPIPE ESPIPE
+#else
+#define APR_ESPIPE (APR_OS_START_CANONERR + 12)
+#endif
+
+/**
+ * @see APR_STATUS_IS_EAGAIN
+ * @warning use APR_STATUS_IS_EAGAIN instead of just testing this value
+ */
+#ifdef EAGAIN
+#define APR_EAGAIN EAGAIN
+#elif defined(EWOULDBLOCK)
+#define APR_EAGAIN EWOULDBLOCK
+#else
+#define APR_EAGAIN (APR_OS_START_CANONERR + 13)
+#endif
+
+/** @see APR_STATUS_IS_EINTR */
+#ifdef EINTR
+#define APR_EINTR EINTR
+#else
+#define APR_EINTR (APR_OS_START_CANONERR + 14)
+#endif
+
+/** @see APR_STATUS_IS_ENOTSOCK */
+#ifdef ENOTSOCK
+#define APR_ENOTSOCK ENOTSOCK
+#else
+#define APR_ENOTSOCK (APR_OS_START_CANONERR + 15)
+#endif
+
+/** @see APR_STATUS_IS_ECONNREFUSED */
+#ifdef ECONNREFUSED
+#define APR_ECONNREFUSED ECONNREFUSED
+#else
+#define APR_ECONNREFUSED (APR_OS_START_CANONERR + 16)
+#endif
+
+/** @see APR_STATUS_IS_EINPROGRESS */
+#ifdef EINPROGRESS
+#define APR_EINPROGRESS EINPROGRESS
+#else
+#define APR_EINPROGRESS (APR_OS_START_CANONERR + 17)
+#endif
+
+/**
+ * @see APR_STATUS_IS_ECONNABORTED
+ * @warning use APR_STATUS_IS_ECONNABORTED instead of just testing this value
+ */
+
+#ifdef ECONNABORTED
+#define APR_ECONNABORTED ECONNABORTED
+#else
+#define APR_ECONNABORTED (APR_OS_START_CANONERR + 18)
+#endif
+
+/** @see APR_STATUS_IS_ECONNRESET */
+#ifdef ECONNRESET
+#define APR_ECONNRESET ECONNRESET
+#else
+#define APR_ECONNRESET (APR_OS_START_CANONERR + 19)
+#endif
+
+/** @see APR_STATUS_IS_ETIMEDOUT
+ * @deprecated */
+#ifdef ETIMEDOUT
+#define APR_ETIMEDOUT ETIMEDOUT
+#else
+#define APR_ETIMEDOUT (APR_OS_START_CANONERR + 20)
+#endif
+
+/** @see APR_STATUS_IS_EHOSTUNREACH */
+#ifdef EHOSTUNREACH
+#define APR_EHOSTUNREACH EHOSTUNREACH
+#else
+#define APR_EHOSTUNREACH (APR_OS_START_CANONERR + 21)
+#endif
+
+/** @see APR_STATUS_IS_ENETUNREACH */
+#ifdef ENETUNREACH
+#define APR_ENETUNREACH ENETUNREACH
+#else
+#define APR_ENETUNREACH (APR_OS_START_CANONERR + 22)
+#endif
+
+/** @see APR_STATUS_IS_EFTYPE */
+#ifdef EFTYPE
+#define APR_EFTYPE EFTYPE
+#else
+#define APR_EFTYPE (APR_OS_START_CANONERR + 23)
+#endif
+
+/** @see APR_STATUS_IS_EPIPE */
+#ifdef EPIPE
+#define APR_EPIPE EPIPE
+#else
+#define APR_EPIPE (APR_OS_START_CANONERR + 24)
+#endif
+
+/** @see APR_STATUS_IS_EXDEV */
+#ifdef EXDEV
+#define APR_EXDEV EXDEV
+#else
+#define APR_EXDEV (APR_OS_START_CANONERR + 25)
+#endif
+
+/** @see APR_STATUS_IS_ENOTEMPTY */
+#ifdef ENOTEMPTY
+#define APR_ENOTEMPTY ENOTEMPTY
+#else
+#define APR_ENOTEMPTY (APR_OS_START_CANONERR + 26)
+#endif
+
+/** @see APR_STATUS_IS_EAFNOSUPPORT */
+#ifdef EAFNOSUPPORT
+#define APR_EAFNOSUPPORT EAFNOSUPPORT
+#else
+#define APR_EAFNOSUPPORT (APR_OS_START_CANONERR + 27)
+#endif
+
+/** @see APR_STATUS_IS_EOPNOTSUPP */
+#ifdef EOPNOTSUPP
+#define APR_EOPNOTSUPP EOPNOTSUPP
+#else
+#define APR_EOPNOTSUPP (APR_OS_START_CANONERR + 28)
+#endif
+
+/** @see APR_STATUS_IS_ERANGE */
+#ifdef ERANGE
+#define APR_ERANGE ERANGE
+#else
+#define APR_ERANGE (APR_OS_START_CANONERR + 29)
+#endif
+
+/** @} */
+
+#if defined(OS2) && !defined(DOXYGEN)
+
+#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
+#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)
+
+#define INCL_DOSERRORS
+#define INCL_DOS
+
+/* Leave these undefined.
+ * OS2 doesn't rely on the errno concept.
+ * The API calls always return a result codes which
+ * should be filtered through APR_FROM_OS_ERROR().
+ *
+ * #define apr_get_os_error() (APR_FROM_OS_ERROR(GetLastError()))
+ * #define apr_set_os_error(e) (SetLastError(APR_TO_OS_ERROR(e)))
+ */
+
+/* A special case, only socket calls require this;
+ */
+#define apr_get_netos_error() (APR_FROM_OS_ERROR(errno))
+#define apr_set_netos_error(e) (errno = APR_TO_OS_ERROR(e))
+
+/* And this needs to be greped away for good:
+ */
+#define APR_OS2_STATUS(e) (APR_FROM_OS_ERROR(e))
+
+/* These can't sit in a private header, so in spite of the extra size,
+ * they need to be made available here.
+ */
+#define SOCBASEERR 10000
+#define SOCEPERM (SOCBASEERR+1) /* Not owner */
+#define SOCESRCH (SOCBASEERR+3) /* No such process */
+#define SOCEINTR (SOCBASEERR+4) /* Interrupted system call */
+#define SOCENXIO (SOCBASEERR+6) /* No such device or address */
+#define SOCEBADF (SOCBASEERR+9) /* Bad file number */
+#define SOCEACCES (SOCBASEERR+13) /* Permission denied */
+#define SOCEFAULT (SOCBASEERR+14) /* Bad address */
+#define SOCEINVAL (SOCBASEERR+22) /* Invalid argument */
+#define SOCEMFILE (SOCBASEERR+24) /* Too many open files */
+#define SOCEPIPE (SOCBASEERR+32) /* Broken pipe */
+#define SOCEOS2ERR (SOCBASEERR+100) /* OS/2 Error */
+#define SOCEWOULDBLOCK (SOCBASEERR+35) /* Operation would block */
+#define SOCEINPROGRESS (SOCBASEERR+36) /* Operation now in progress */
+#define SOCEALREADY (SOCBASEERR+37) /* Operation already in progress */
+#define SOCENOTSOCK (SOCBASEERR+38) /* Socket operation on non-socket */
+#define SOCEDESTADDRREQ (SOCBASEERR+39) /* Destination address required */
+#define SOCEMSGSIZE (SOCBASEERR+40) /* Message too long */
+#define SOCEPROTOTYPE (SOCBASEERR+41) /* Protocol wrong type for socket */
+#define SOCENOPROTOOPT (SOCBASEERR+42) /* Protocol not available */
+#define SOCEPROTONOSUPPORT (SOCBASEERR+43) /* Protocol not supported */
+#define SOCESOCKTNOSUPPORT (SOCBASEERR+44) /* Socket type not supported */
+#define SOCEOPNOTSUPP (SOCBASEERR+45) /* Operation not supported on socket */
+#define SOCEPFNOSUPPORT (SOCBASEERR+46) /* Protocol family not supported */
+#define SOCEAFNOSUPPORT (SOCBASEERR+47) /* Address family not supported by protocol family */
+#define SOCEADDRINUSE (SOCBASEERR+48) /* Address already in use */
+#define SOCEADDRNOTAVAIL (SOCBASEERR+49) /* Can't assign requested address */
+#define SOCENETDOWN (SOCBASEERR+50) /* Network is down */
+#define SOCENETUNREACH (SOCBASEERR+51) /* Network is unreachable */
+#define SOCENETRESET (SOCBASEERR+52) /* Network dropped connection on reset */
+#define SOCECONNABORTED (SOCBASEERR+53) /* Software caused connection abort */
+#define SOCECONNRESET (SOCBASEERR+54) /* Connection reset by peer */
+#define SOCENOBUFS (SOCBASEERR+55) /* No buffer space available */
+#define SOCEISCONN (SOCBASEERR+56) /* Socket is already connected */
+#define SOCENOTCONN (SOCBASEERR+57) /* Socket is not connected */
+#define SOCESHUTDOWN (SOCBASEERR+58) /* Can't send after socket shutdown */
+#define SOCETOOMANYREFS (SOCBASEERR+59) /* Too many references: can't splice */
+#define SOCETIMEDOUT (SOCBASEERR+60) /* Connection timed out */
+#define SOCECONNREFUSED (SOCBASEERR+61) /* Connection refused */
+#define SOCELOOP (SOCBASEERR+62) /* Too many levels of symbolic links */
+#define SOCENAMETOOLONG (SOCBASEERR+63) /* File name too long */
+#define SOCEHOSTDOWN (SOCBASEERR+64) /* Host is down */
+#define SOCEHOSTUNREACH (SOCBASEERR+65) /* No route to host */
+#define SOCENOTEMPTY (SOCBASEERR+66) /* Directory not empty */
+
+/* APR CANONICAL ERROR TESTS */
+#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES \
+ || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \
+ || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION)
+#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST \
+ || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \
+ || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \
+ || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS \
+ || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED)
+#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG \
+ || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \
+ || (s) == APR_OS_START_SYSERR + SOCENAMETOOLONG)
+#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \
+ || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \
+ || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
+ || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES \
+ || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED)
+#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR)
+#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \
+ || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL)
+#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM)
+#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE \
+ || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES)
+#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE)
+#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE)
+#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION)
+#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE \
+ || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
+#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \
+ || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \
+ || (s) == APR_OS_START_SYSERR + SOCEWOULDBLOCK \
+ || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION)
+#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \
+ || (s) == APR_OS_START_SYSERR + SOCEINTR)
+#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \
+ || (s) == APR_OS_START_SYSERR + SOCENOTSOCK)
+#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \
+ || (s) == APR_OS_START_SYSERR + SOCECONNREFUSED)
+#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \
+ || (s) == APR_OS_START_SYSERR + SOCEINPROGRESS)
+#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \
+ || (s) == APR_OS_START_SYSERR + SOCECONNABORTED)
+#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \
+ || (s) == APR_OS_START_SYSERR + SOCECONNRESET)
+/* XXX deprecated */
+#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \
+ || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
+#undef APR_STATUS_IS_TIMEUP
+#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \
+ || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
+#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \
+ || (s) == APR_OS_START_SYSERR + SOCEHOSTUNREACH)
+#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \
+ || (s) == APR_OS_START_SYSERR + SOCENETUNREACH)
+#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE)
+#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE \
+ || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE \
+ || (s) == APR_OS_START_SYSERR + SOCEPIPE)
+#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV \
+ || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE)
+#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY \
+ || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY \
+ || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED)
+#define APR_STATUS_IS_EAFNOSUPPORT(s) ((s) == APR_AFNOSUPPORT \
+ || (s) == APR_OS_START_SYSERR + SOCEAFNOSUPPORT)
+#define APR_STATUS_IS_EOPNOTSUPP(s) ((s) == APR_EOPNOTSUPP \
+ || (s) == APR_OS_START_SYSERR + SOCEOPNOTSUPP)
+#define APR_STATUS_IS_ERANGE(s) ((s) == APR_ERANGE)
+
+/*
+ Sorry, too tired to wrap this up for OS2... feel free to
+ fit the following into their best matches.
+
+ { ERROR_NO_SIGNAL_SENT, ESRCH },
+ { SOCEALREADY, EALREADY },
+ { SOCEDESTADDRREQ, EDESTADDRREQ },
+ { SOCEMSGSIZE, EMSGSIZE },
+ { SOCEPROTOTYPE, EPROTOTYPE },
+ { SOCENOPROTOOPT, ENOPROTOOPT },
+ { SOCEPROTONOSUPPORT, EPROTONOSUPPORT },
+ { SOCESOCKTNOSUPPORT, ESOCKTNOSUPPORT },
+ { SOCEPFNOSUPPORT, EPFNOSUPPORT },
+ { SOCEADDRINUSE, EADDRINUSE },
+ { SOCEADDRNOTAVAIL, EADDRNOTAVAIL },
+ { SOCENETDOWN, ENETDOWN },
+ { SOCENETRESET, ENETRESET },
+ { SOCENOBUFS, ENOBUFS },
+ { SOCEISCONN, EISCONN },
+ { SOCENOTCONN, ENOTCONN },
+ { SOCESHUTDOWN, ESHUTDOWN },
+ { SOCETOOMANYREFS, ETOOMANYREFS },
+ { SOCELOOP, ELOOP },
+ { SOCEHOSTDOWN, EHOSTDOWN },
+ { SOCENOTEMPTY, ENOTEMPTY },
+ { SOCEPIPE, EPIPE }
+*/
+
+#elif defined(WIN32) && !defined(DOXYGEN) /* !defined(OS2) */
+
+#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
+#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)
+
+#define apr_get_os_error() (APR_FROM_OS_ERROR(GetLastError()))
+#define apr_set_os_error(e) (SetLastError(APR_TO_OS_ERROR(e)))
+
+/* A special case, only socket calls require this:
+ */
+#define apr_get_netos_error() (APR_FROM_OS_ERROR(WSAGetLastError()))
+#define apr_set_netos_error(e) (WSASetLastError(APR_TO_OS_ERROR(e)))
+
+/* APR CANONICAL ERROR TESTS */
+#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES \
+ || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \
+ || (s) == APR_OS_START_SYSERR + ERROR_CANNOT_MAKE \
+ || (s) == APR_OS_START_SYSERR + ERROR_CURRENT_DIRECTORY \
+ || (s) == APR_OS_START_SYSERR + ERROR_DRIVE_LOCKED \
+ || (s) == APR_OS_START_SYSERR + ERROR_FAIL_I24 \
+ || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \
+ || (s) == APR_OS_START_SYSERR + ERROR_LOCK_FAILED \
+ || (s) == APR_OS_START_SYSERR + ERROR_NOT_LOCKED \
+ || (s) == APR_OS_START_SYSERR + ERROR_NETWORK_ACCESS_DENIED \
+ || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION)
+#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST \
+ || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \
+ || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS)
+#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG \
+ || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \
+ || (s) == APR_OS_START_SYSERR + WSAENAMETOOLONG)
+#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \
+ || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \
+ || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
+ || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \
+ || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES)
+#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR \
+ || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
+ || (s) == APR_OS_START_SYSERR + ERROR_BAD_NETPATH \
+ || (s) == APR_OS_START_SYSERR + ERROR_BAD_NET_NAME \
+ || (s) == APR_OS_START_SYSERR + ERROR_BAD_PATHNAME \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DRIVE \
+ || (s) == APR_OS_START_SYSERR + ERROR_DIRECTORY)
+#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \
+ || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL)
+#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM \
+ || (s) == APR_OS_START_SYSERR + ERROR_ARENA_TRASHED \
+ || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_MEMORY \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_BLOCK \
+ || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_QUOTA \
+ || (s) == APR_OS_START_SYSERR + ERROR_OUTOFMEMORY)
+#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE \
+ || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES)
+#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE)
+#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_TARGET_HANDLE)
+#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_ACCESS \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DATA \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \
+ || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
+#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE \
+ || (s) == APR_OS_START_SYSERR + ERROR_SEEK_ON_DEVICE \
+ || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
+#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \
+ || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \
+ || (s) == APR_OS_START_SYSERR + ERROR_NO_PROC_SLOTS \
+ || (s) == APR_OS_START_SYSERR + ERROR_NESTING_NOT_ALLOWED \
+ || (s) == APR_OS_START_SYSERR + ERROR_MAX_THRDS_REACHED \
+ || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \
+ || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK)
+#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \
+ || (s) == APR_OS_START_SYSERR + WSAEINTR)
+#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \
+ || (s) == APR_OS_START_SYSERR + WSAENOTSOCK)
+#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \
+ || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED)
+#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \
+ || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS)
+#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \
+ || (s) == APR_OS_START_SYSERR + WSAECONNABORTED)
+#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \
+ || (s) == APR_OS_START_SYSERR + ERROR_NETNAME_DELETED \
+ || (s) == APR_OS_START_SYSERR + WSAECONNRESET)
+/* XXX deprecated */
+#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \
+ || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
+ || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
+#undef APR_STATUS_IS_TIMEUP
+#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \
+ || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
+ || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
+#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \
+ || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH)
+#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \
+ || (s) == APR_OS_START_SYSERR + WSAENETUNREACH)
+#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE \
+ || (s) == APR_OS_START_SYSERR + ERROR_EXE_MACHINE_TYPE_MISMATCH \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DLL \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_MODULETYPE \
+ || (s) == APR_OS_START_SYSERR + ERROR_BAD_EXE_FORMAT \
+ || (s) == APR_OS_START_SYSERR + ERROR_INVALID_EXE_SIGNATURE \
+ || (s) == APR_OS_START_SYSERR + ERROR_FILE_CORRUPT \
+ || (s) == APR_OS_START_SYSERR + ERROR_BAD_FORMAT)
+#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE \
+ || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE)
+#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV \
+ || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE)
+#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY \
+ || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY)
+#define APR_STATUS_IS_EAFNOSUPPORT(s) ((s) == APR_EAFNOSUPPORT \
+ || (s) == APR_OS_START_SYSERR + WSAEAFNOSUPPORT)
+#define APR_STATUS_IS_EOPNOTSUPP(s) ((s) == APR_EOPNOTSUPP \
+ || (s) == APR_OS_START_SYSERR + WSAEOPNOTSUPP)
+#define APR_STATUS_IS_ERANGE(s) ((s) == APR_ERANGE)
+
+#elif defined(NETWARE) && defined(USE_WINSOCK) && !defined(DOXYGEN) /* !defined(OS2) && !defined(WIN32) */
+
+#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
+#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)
+
+#define apr_get_os_error() (errno)
+#define apr_set_os_error(e) (errno = (e))
+
+/* A special case, only socket calls require this: */
+#define apr_get_netos_error() (APR_FROM_OS_ERROR(WSAGetLastError()))
+#define apr_set_netos_error(e) (WSASetLastError(APR_TO_OS_ERROR(e)))
+
+/* APR CANONICAL ERROR TESTS */
+#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES)
+#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST)
+#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG)
+#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT)
+#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR)
+#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC)
+#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM)
+#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE)
+#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE)
+#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF)
+#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL)
+#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE)
+
+#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \
+ || (s) == EWOULDBLOCK \
+ || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK)
+#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR \
+ || (s) == APR_OS_START_SYSERR + WSAEINTR)
+#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK \
+ || (s) == APR_OS_START_SYSERR + WSAENOTSOCK)
+#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED \
+ || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED)
+#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS \
+ || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS)
+#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \
+ || (s) == APR_OS_START_SYSERR + WSAECONNABORTED)
+#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET \
+ || (s) == APR_OS_START_SYSERR + WSAECONNRESET)
+/* XXX deprecated */
+#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT \
+ || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
+ || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
+#undef APR_STATUS_IS_TIMEUP
+#define APR_STATUS_IS_TIMEUP(s) ((s) == APR_TIMEUP \
+ || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
+ || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
+#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH \
+ || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH)
+#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH \
+ || (s) == APR_OS_START_SYSERR + WSAENETUNREACH)
+#define APR_STATUS_IS_ENETDOWN(s) ((s) == APR_OS_START_SYSERR + WSAENETDOWN)
+#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE)
+#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE)
+#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV)
+#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY)
+#define APR_STATUS_IS_EAFNOSUPPORT(s) ((s) == APR_EAFNOSUPPORT \
+ || (s) == APR_OS_START_SYSERR + WSAEAFNOSUPPORT)
+#define APR_STATUS_IS_EOPNOTSUPP(s) ((s) == APR_EOPNOTSUPP \
+ || (s) == APR_OS_START_SYSERR + WSAEOPNOTSUPP)
+#define APR_STATUS_IS_ERANGE(s) ((s) == APR_ERANGE)
+
+#else /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */
+
+/*
+ * os error codes are clib error codes
+ */
+#define APR_FROM_OS_ERROR(e) (e)
+#define APR_TO_OS_ERROR(e) (e)
+
+#define apr_get_os_error() (errno)
+#define apr_set_os_error(e) (errno = (e))
+
+/* A special case, only socket calls require this:
+ */
+#define apr_get_netos_error() (errno)
+#define apr_set_netos_error(e) (errno = (e))
+
+/**
+ * @addtogroup APR_STATUS_IS
+ * @{
+ */
+
+/** permission denied */
+#define APR_STATUS_IS_EACCES(s) ((s) == APR_EACCES)
+/** file exists */
+#define APR_STATUS_IS_EEXIST(s) ((s) == APR_EEXIST)
+/** path name is too long */
+#define APR_STATUS_IS_ENAMETOOLONG(s) ((s) == APR_ENAMETOOLONG)
+/**
+ * no such file or directory
+ * @remark
+ * EMVSCATLG can be returned by the automounter on z/OS for
+ * paths which do not exist.
+ */
+#ifdef EMVSCATLG
+#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT \
+ || (s) == EMVSCATLG)
+#else
+#define APR_STATUS_IS_ENOENT(s) ((s) == APR_ENOENT)
+#endif
+/** not a directory */
+#define APR_STATUS_IS_ENOTDIR(s) ((s) == APR_ENOTDIR)
+/** no space left on device */
+#ifdef EDQUOT
+#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC \
+ || (s) == EDQUOT)
+#else
+#define APR_STATUS_IS_ENOSPC(s) ((s) == APR_ENOSPC)
+#endif
+/** not enough memory */
+#define APR_STATUS_IS_ENOMEM(s) ((s) == APR_ENOMEM)
+/** too many open files */
+#define APR_STATUS_IS_EMFILE(s) ((s) == APR_EMFILE)
+/** file table overflow */
+#define APR_STATUS_IS_ENFILE(s) ((s) == APR_ENFILE)
+/** bad file # */
+#define APR_STATUS_IS_EBADF(s) ((s) == APR_EBADF)
+/** invalid argument */
+#define APR_STATUS_IS_EINVAL(s) ((s) == APR_EINVAL)
+/** illegal seek */
+#define APR_STATUS_IS_ESPIPE(s) ((s) == APR_ESPIPE)
+
+/** operation would block */
+#if !defined(EWOULDBLOCK) || !defined(EAGAIN)
+#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN)
+#elif (EWOULDBLOCK == EAGAIN)
+#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN)
+#else
+#define APR_STATUS_IS_EAGAIN(s) ((s) == APR_EAGAIN \
+ || (s) == EWOULDBLOCK)
+#endif
+
+/** interrupted system call */
+#define APR_STATUS_IS_EINTR(s) ((s) == APR_EINTR)
+/** socket operation on a non-socket */
+#define APR_STATUS_IS_ENOTSOCK(s) ((s) == APR_ENOTSOCK)
+/** Connection Refused */
+#define APR_STATUS_IS_ECONNREFUSED(s) ((s) == APR_ECONNREFUSED)
+/** operation now in progress */
+#define APR_STATUS_IS_EINPROGRESS(s) ((s) == APR_EINPROGRESS)
+
+/**
+ * Software caused connection abort
+ * @remark
+ * EPROTO on certain older kernels really means ECONNABORTED, so we need to
+ * ignore it for them. See discussion in new-httpd archives nh.9701 & nh.9603
+ *
+ * There is potentially a bug in Solaris 2.x x<6, and other boxes that
+ * implement tcp sockets in userland (i.e. on top of STREAMS). On these
+ * systems, EPROTO can actually result in a fatal loop. See PR#981 for
+ * example. It's hard to handle both uses of EPROTO.
+ */
+#ifdef EPROTO
+#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED \
+ || (s) == EPROTO)
+#else
+#define APR_STATUS_IS_ECONNABORTED(s) ((s) == APR_ECONNABORTED)
+#endif
+
+/** Connection Reset by peer */
+#define APR_STATUS_IS_ECONNRESET(s) ((s) == APR_ECONNRESET)
+/** Operation timed out
+ * @deprecated */
+#define APR_STATUS_IS_ETIMEDOUT(s) ((s) == APR_ETIMEDOUT)
+/** no route to host */
+#define APR_STATUS_IS_EHOSTUNREACH(s) ((s) == APR_EHOSTUNREACH)
+/** network is unreachable */
+#define APR_STATUS_IS_ENETUNREACH(s) ((s) == APR_ENETUNREACH)
+/** inappropriate file type or format */
+#define APR_STATUS_IS_EFTYPE(s) ((s) == APR_EFTYPE)
+/** broken pipe */
+#define APR_STATUS_IS_EPIPE(s) ((s) == APR_EPIPE)
+/** cross device link */
+#define APR_STATUS_IS_EXDEV(s) ((s) == APR_EXDEV)
+/** Directory Not Empty */
+#define APR_STATUS_IS_ENOTEMPTY(s) ((s) == APR_ENOTEMPTY || \
+ (s) == APR_EEXIST)
+/** Address Family not supported */
+#define APR_STATUS_IS_EAFNOSUPPORT(s) ((s) == APR_EAFNOSUPPORT)
+/** Socket operation not supported */
+#define APR_STATUS_IS_EOPNOTSUPP(s) ((s) == APR_EOPNOTSUPP)
+
+/** Numeric value not representable */
+#define APR_STATUS_IS_ERANGE(s) ((s) == APR_ERANGE)
+/** @} */
+
+#endif /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_ERRNO_H */
diff --git a/include/apr_escape.h b/include/apr_escape.h
new file mode 100644
index 0000000..ed048c9
--- /dev/null
+++ b/include/apr_escape.h
@@ -0,0 +1,431 @@
+/* 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.
+ */
+/**
+ * @file apr_escape.h
+ * @brief APR-UTIL Escaping
+ */
+#ifndef APR_ESCAPE_H
+#define APR_ESCAPE_H
+#include "apr.h"
+#include "apr_general.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup APR_Util_Escaping Escape functions
+ * @ingroup APR
+ * @{
+ */
+
+/* Simple escape/unescape functions.
+ *
+ * The design goal of these functions are:
+ *
+ * - Avoid unnecessary work.
+ *
+ * In most cases the strings passed in do not need to be escaped at all. In
+ * these cases the original string will be returned.
+ *
+ * - Lowest possible memory footprint.
+ *
+ * The amount of memory allocated for a given encoding is calculated based
+ * on the exact amount of memory needed, and not the theoretical worst case
+ * scenario.
+ *
+ */
+
+/**
+ * When passing a string to one of the escape functions, this value can be
+ * passed to indicate a string-valued key, and have the length computed
+ * automatically.
+ */
+#define APR_ESCAPE_STRING (-1)
+
+/**
+ * Apply LDAP distinguished name escaping as per RFC4514.
+ */
+#define APR_ESCAPE_LDAP_DN (0x01)
+
+/**
+ * Apply LDAP filter escaping as per RFC4515.
+ */
+#define APR_ESCAPE_LDAP_FILTER (0x02)
+
+/**
+ * Apply both RFC4514 and RFC4515 LDAP escaping.
+ */
+#define APR_ESCAPE_LDAP_ALL (0x03)
+
+/**
+ * Perform shell escaping on the provided string.
+ *
+ * Shell escaping causes characters to be prefixed with a '\' character.
+ * @param escaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param str The original string
+ * @param slen The length of the original string, or APR_ESCAPE_STRING
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
+ * detected or the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_shell(char *escaped, const char *str,
+ apr_ssize_t slen, apr_size_t *len);
+
+/**
+ * Perform shell escaping on the provided string, returning the result
+ * from the pool.
+ *
+ * Shell escaping causes characters to be prefixed with a '\' character.
+ *
+ * If no characters were escaped, the original string is returned.
+ * @param p Pool to allocate from
+ * @param str The original string
+ * @return the encoded string, allocated from the pool, or the original
+ * string if no escaping took place or the string was NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_shell(apr_pool_t *p, const char *str)
+ __attribute__((nonnull(1)));
+
+/**
+ * Unescapes a URL, leaving reserved characters intact.
+ * @param escaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param url String to be unescaped
+ * @param slen The length of the original url, or APR_ESCAPE_STRING
+ * @param forbid Optional list of forbidden characters, in addition to
+ * 0x00
+ * @param reserved Optional list of reserved characters that will be
+ * left unescaped
+ * @param plus If non zero, '+' is converted to ' ' as per
+ * application/x-www-form-urlencoded encoding
+ * @param len If set, the length of the escaped string will be returned
+ * @return APR_SUCCESS on success, APR_NOTFOUND if no characters are
+ * decoded or the string is NULL, APR_EINVAL if a bad escape sequence is
+ * found, APR_BADCH if a character on the forbid list is found.
+ */
+APR_DECLARE(apr_status_t) apr_unescape_url(char *escaped, const char *url,
+ apr_ssize_t slen, const char *forbid, const char *reserved, int plus,
+ apr_size_t *len);
+
+/**
+ * Unescapes a URL, leaving reserved characters intact, returning the
+ * result from a pool.
+ * @param p Pool to allocate from
+ * @param url String to be unescaped in place
+ * @param forbid Optional list of forbidden characters, in addition to
+ * 0x00
+ * @param reserved Optional list of reserved characters that will be
+ * left unescaped
+ * @param plus If non zero, '+' is converted to ' ' as per
+ * application/x-www-form-urlencoded encoding
+ * @return A string allocated from the pool on success, the original string
+ * if no characters are decoded, or NULL if a bad escape sequence is found
+ * or if a character on the forbid list is found, or if the original string
+ * was NULL.
+ */
+APR_DECLARE(const char *) apr_punescape_url(apr_pool_t *p, const char *url,
+ const char *forbid, const char *reserved, int plus)
+ __attribute__((nonnull(1)));
+
+/**
+ * Escape a path segment, as defined in RFC1808.
+ * @param escaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param str The original string
+ * @param slen The length of the original string, or APR_ESCAPE_STRING
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
+ * detected or the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_path_segment(char *escaped,
+ const char *str, apr_ssize_t slen, apr_size_t *len);
+
+/**
+ * Escape a path segment, as defined in RFC1808, returning the result from a
+ * pool.
+ * @param p Pool to allocate from
+ * @param str String to be escaped
+ * @return A string allocated from the pool on success, the original string
+ * if no characters are encoded or the string is NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_path_segment(apr_pool_t *p,
+ const char *str) __attribute__((nonnull(1)));
+
+/**
+ * Converts an OS path to a URL, in an OS dependent way, as defined in RFC1808.
+ * In all cases if a ':' occurs before the first '/' in the URL, the URL should
+ * be prefixed with "./" (or the ':' escaped). In the case of Unix, this means
+ * leaving '/' alone, but otherwise doing what escape_path_segment() does. For
+ * efficiency reasons, we don't use escape_path_segment(), which is provided for
+ * reference. Again, RFC 1808 is where this stuff is defined.
+ *
+ * If partial is set, os_escape_path() assumes that the path will be appended to
+ * something with a '/' in it (and thus does not prefix "./").
+ * @param escaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param path The original string
+ * @param slen The length of the original string, or APR_ESCAPE_STRING
+ * @param partial If non zero, suppresses the prepending of "./"
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
+ * detected or if the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_path(char *escaped, const char *path,
+ apr_ssize_t slen, int partial, apr_size_t *len);
+
+/**
+ * Converts an OS path to a URL, in an OS dependent way, as defined in RFC1808,
+ * returning the result from a pool.
+ *
+ * In all cases if a ':' occurs before the first '/' in the URL, the URL should
+ * be prefixed with "./" (or the ':' escaped). In the case of Unix, this means
+ * leaving '/' alone, but otherwise doing what escape_path_segment() does. For
+ * efficiency reasons, we don't use escape_path_segment(), which is provided for
+ * reference. Again, RFC 1808 is where this stuff is defined.
+ *
+ * If partial is set, os_escape_path() assumes that the path will be appended to
+ * something with a '/' in it (and thus does not prefix "./").
+ * @param p Pool to allocate from
+ * @param str The original string
+ * @param partial If non zero, suppresses the prepending of "./"
+ * @return A string allocated from the pool on success, the original string
+ * if no characters are encoded or if the string was NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_path(apr_pool_t *p, const char *str,
+ int partial) __attribute__((nonnull(1)));
+
+/**
+ * Urlencode a string, as defined in
+ * http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1.
+ * @param escaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param str The original string
+ * @param slen The length of the original string, or APR_ESCAPE_STRING
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
+ * detected or if the stirng was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_urlencoded(char *escaped, const char *str,
+ apr_ssize_t slen, apr_size_t *len);
+
+/**
+ * Urlencode a string, as defined in
+ * http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1, returning
+ * the result from a pool.
+ * @param p Pool to allocate from
+ * @param str String to be escaped
+ * @return A string allocated from the pool on success, the original string
+ * if no characters are encoded or if the string was NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_urlencoded(apr_pool_t *p,
+ const char *str) __attribute__((nonnull(1)));
+
+/**
+ * Apply entity encoding to a string. Characters are replaced as follows:
+ * '<' becomes '\&lt;', '>' becomes '\&gt;', '&' becomes '\&amp;', the
+ * double quote becomes '\&quot;" and the single quote becomes '\&apos;'.
+ *
+ * If toasc is not zero, any non ascii character will be encoded as
+ * '%\#ddd;', where ddd is the decimal code of the character.
+ * @param escaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param str The original string
+ * @param slen The length of the original string, or APR_ESCAPE_STRING
+ * @param toasc If non zero, encode non ascii characters
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
+ * detected or the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_entity(char *escaped, const char *str,
+ apr_ssize_t slen, int toasc, apr_size_t *len);
+
+/**
+ * Apply entity encoding to a string, returning the result from a pool.
+ * Characters are replaced as follows: '<' becomes '\&lt;', '>' becomes
+ * '\&gt;', '&' becomes '\&amp;', the double quote becomes '\&quot;" and the
+ * single quote becomes '\&apos;'.
+ * @param p Pool to allocate from
+ * @param str The original string
+ * @param toasc If non zero, encode non ascii characters
+ * @return A string allocated from the pool on success, the original string
+ * if no characters are encoded or the string is NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_entity(apr_pool_t *p, const char *str,
+ int toasc) __attribute__((nonnull(1)));
+
+/**
+ * Decodes html entities or numeric character references in a string. If
+ * the string to be unescaped is syntactically incorrect, then the
+ * following fixups will be made:
+ * unknown entities will be left undecoded;
+ * references to unused numeric characters will be deleted.
+ * In particular, &#00; will not be decoded, but will be deleted.
+ * @param unescaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param str The original string
+ * @param slen The length of the original string, or APR_ESCAPE_STRING
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
+ * detected or the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_unescape_entity(char *unescaped, const char *str,
+ apr_ssize_t slen, apr_size_t *len);
+
+/**
+ * Decodes html entities or numeric character references in a string. If
+ * the string to be unescaped is syntactically incorrect, then the
+ * following fixups will be made:
+ * unknown entities will be left undecoded;
+ * references to unused numeric characters will be deleted.
+ * In particular, &#00; will not be decoded, but will be deleted.
+ * @param p Pool to allocate from
+ * @param str The original string
+ * @return A string allocated from the pool on success, the original string
+ * if no characters are encoded or the string is NULL.
+ */
+APR_DECLARE(const char *) apr_punescape_entity(apr_pool_t *p, const char *str)
+ __attribute__((nonnull(1)));
+
+/**
+ * Escape control characters in a string, as performed by the shell's
+ * 'echo' command. Characters are replaced as follows:
+ * \\a alert (bell), \\b backspace, \\f form feed, \\n new line, \\r carriage
+ * return, \\t horizontal tab, \\v vertical tab, \\ backslash.
+ *
+ * Any non ascii character will be encoded as '\\xHH', where HH is the hex
+ * code of the character.
+ *
+ * If quote is not zero, the double quote character will also be escaped.
+ * @param escaped Optional buffer to write the encoded string, can be
+ * NULL
+ * @param str The original string
+ * @param slen The length of the original string, or APR_ESCAPE_STRING
+ * @param quote If non zero, encode double quotes
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
+ * detected or the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_echo(char *escaped, const char *str,
+ apr_ssize_t slen, int quote, apr_size_t *len);
+
+/**
+ * Escape control characters in a string, as performed by the shell's
+ * 'echo' command, and return the results from a pool. Characters are
+ * replaced as follows: \\a alert (bell), \\b backspace, \\f form feed,
+ * \\n new line, \\r carriage return, \\t horizontal tab, \\v vertical tab,
+ * \\ backslash.
+ *
+ * Any non ascii character will be encoded as '\\xHH', where HH is the hex
+ * code of the character.
+ *
+ * If quote is not zero, the double quote character will also be escaped.
+ * @param p Pool to allocate from
+ * @param str The original string
+ * @param quote If non zero, encode double quotes
+ * @return A string allocated from the pool on success, the original string
+ * if no characters are encoded or the string is NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_echo(apr_pool_t *p, const char *str,
+ int quote);
+
+/**
+ * Convert binary data to a hex encoding.
+ * @param dest The destination buffer, can be NULL
+ * @param src The original buffer
+ * @param srclen The length of the original buffer
+ * @param colon If not zero, insert colon characters between hex digits.
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_hex(char *dest, const void *src,
+ apr_size_t srclen, int colon, apr_size_t *len);
+
+/**
+ * Convert binary data to a hex encoding, and return the results from a
+ * pool.
+ * @param p Pool to allocate from
+ * @param src The original buffer
+ * @param slen The length of the original buffer
+ * @param colon If not zero, insert colon characters between hex digits.
+ * @return A zero padded buffer allocated from the pool on success, or
+ * NULL if src was NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_hex(apr_pool_t *p, const void *src,
+ apr_size_t slen, int colon) __attribute__((nonnull(1)));
+
+/**
+ * Convert hex encoded string to binary data.
+ * @param dest The destination buffer, can be NULL
+ * @param str The original buffer
+ * @param slen The length of the original buffer
+ * @param colon If not zero, ignore colon characters between hex digits.
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
+ * if a non hex character is present.
+ */
+APR_DECLARE(apr_status_t) apr_unescape_hex(void *dest, const char *str,
+ apr_ssize_t slen, int colon, apr_size_t *len);
+
+/**
+ * Convert hex encoding to binary data, and return the results from a pool.
+ * If the colon character appears between pairs of hex digits, it will be
+ * ignored.
+ * @param p Pool to allocate from
+ * @param str The original string
+ * @param colon If not zero, ignore colon characters between hex digits.
+ * @param len If present, returns the length of the final buffer
+ * @return A buffer allocated from the pool on success, or NULL if src was
+ * NULL, or a bad character was present.
+ */
+APR_DECLARE(const void *) apr_punescape_hex(apr_pool_t *p, const char *str,
+ int colon, apr_size_t *len);
+
+/**
+ * Apply LDAP escaping to binary data. Characters from RFC4514 and RFC4515
+ * are escaped with their hex equivalents.
+ * @param dest The destination buffer, can be NULL
+ * @param src The original buffer
+ * @param srclen The length of the original buffer
+ * @param flags APR_ESCAPE_LDAP_DN for RFC4514, APR_ESCAPE_LDAP_FILTER for
+ * RFC4515, APR_ESCAPE_LDAP_ALL for both
+ * @param len If present, returns the length of the string
+ * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL
+ */
+APR_DECLARE(apr_status_t) apr_escape_ldap(char *dest, const void *src,
+ apr_ssize_t srclen, int flags, apr_size_t *len);
+
+/**
+ * Apply LDAP escaping to binary data, and return the results from a
+ * pool. Characters from RFC4514 and RFC4515 are escaped with their hex
+ * equivalents.
+ * @param p Pool to allocate from
+ * @param src The original buffer
+ * @param slen The length of the original buffer
+ * @param flags APR_ESCAPE_LDAP_DN for RFC4514, APR_ESCAPE_LDAP_FILTER for
+ * RFC4515, APR_ESCAPE_LDAP_ALL for both
+ * @return A zero padded buffer allocated from the pool on success, or
+ * NULL if src was NULL.
+ */
+APR_DECLARE(const char *) apr_pescape_ldap(apr_pool_t *p, const void *src,
+ apr_ssize_t slen, int flags) __attribute__((nonnull(1)));
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_ESCAPE_H */
diff --git a/include/apr_file_info.h b/include/apr_file_info.h
new file mode 100644
index 0000000..cfddc68
--- /dev/null
+++ b/include/apr_file_info.h
@@ -0,0 +1,428 @@
+/* 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 APR_FILE_INFO_H
+#define APR_FILE_INFO_H
+
+/**
+ * @file apr_file_info.h
+ * @brief APR File Information
+ */
+
+#include "apr.h"
+#include "apr_user.h"
+#include "apr_pools.h"
+#include "apr_tables.h"
+#include "apr_time.h"
+#include "apr_errno.h"
+
+#if APR_HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_file_info File Information
+ * @ingroup APR
+ * @{
+ */
+
+/* Many applications use the type member to determine the
+ * existance of a file or initialization of the file info,
+ * so the APR_NOFILE value must be distinct from APR_UNKFILE.
+ */
+
+/** apr_filetype_e values for the filetype member of the
+ * apr_file_info_t structure
+ * @warning Not all of the filetypes below can be determined.
+ * For example, a given platform might not correctly report
+ * a socket descriptor as APR_SOCK if that type isn't
+ * well-identified on that platform. In such cases where
+ * a filetype exists but cannot be described by the recognized
+ * flags below, the filetype will be APR_UNKFILE. If the
+ * filetype member is not determined, the type will be APR_NOFILE.
+ */
+
+typedef enum {
+ APR_NOFILE = 0, /**< no file type determined */
+ APR_REG, /**< a regular file */
+ APR_DIR, /**< a directory */
+ APR_CHR, /**< a character device */
+ APR_BLK, /**< a block device */
+ APR_PIPE, /**< a FIFO / pipe */
+ APR_LNK, /**< a symbolic link */
+ APR_SOCK, /**< a [unix domain] socket */
+ APR_UNKFILE = 127 /**< a file of some other unknown type */
+} apr_filetype_e;
+
+/**
+ * @defgroup apr_file_permissions File Permissions flags
+ * @{
+ */
+
+#define APR_FPROT_USETID 0x8000 /**< Set user id */
+#define APR_FPROT_UREAD 0x0400 /**< Read by user */
+#define APR_FPROT_UWRITE 0x0200 /**< Write by user */
+#define APR_FPROT_UEXECUTE 0x0100 /**< Execute by user */
+
+#define APR_FPROT_GSETID 0x4000 /**< Set group id */
+#define APR_FPROT_GREAD 0x0040 /**< Read by group */
+#define APR_FPROT_GWRITE 0x0020 /**< Write by group */
+#define APR_FPROT_GEXECUTE 0x0010 /**< Execute by group */
+
+#define APR_FPROT_WSTICKY 0x2000 /**< Sticky bit */
+#define APR_FPROT_WREAD 0x0004 /**< Read by others */
+#define APR_FPROT_WWRITE 0x0002 /**< Write by others */
+#define APR_FPROT_WEXECUTE 0x0001 /**< Execute by others */
+
+#define APR_FPROT_OS_DEFAULT 0x0FFF /**< use OS's default permissions */
+
+/* additional permission flags for apr_file_copy and apr_file_append */
+#define APR_FPROT_FILE_SOURCE_PERMS 0x1000 /**< Copy source file's permissions */
+
+/* backcompat */
+#define APR_USETID APR_FPROT_USETID /**< @deprecated @see APR_FPROT_USETID */
+#define APR_UREAD APR_FPROT_UREAD /**< @deprecated @see APR_FPROT_UREAD */
+#define APR_UWRITE APR_FPROT_UWRITE /**< @deprecated @see APR_FPROT_UWRITE */
+#define APR_UEXECUTE APR_FPROT_UEXECUTE /**< @deprecated @see APR_FPROT_UEXECUTE */
+#define APR_GSETID APR_FPROT_GSETID /**< @deprecated @see APR_FPROT_GSETID */
+#define APR_GREAD APR_FPROT_GREAD /**< @deprecated @see APR_FPROT_GREAD */
+#define APR_GWRITE APR_FPROT_GWRITE /**< @deprecated @see APR_FPROT_GWRITE */
+#define APR_GEXECUTE APR_FPROT_GEXECUTE /**< @deprecated @see APR_FPROT_GEXECUTE */
+#define APR_WSTICKY APR_FPROT_WSTICKY /**< @deprecated @see APR_FPROT_WSTICKY */
+#define APR_WREAD APR_FPROT_WREAD /**< @deprecated @see APR_FPROT_WREAD */
+#define APR_WWRITE APR_FPROT_WWRITE /**< @deprecated @see APR_FPROT_WWRITE */
+#define APR_WEXECUTE APR_FPROT_WEXECUTE /**< @deprecated @see APR_FPROT_WEXECUTE */
+#define APR_OS_DEFAULT APR_FPROT_OS_DEFAULT /**< @deprecated @see APR_FPROT_OS_DEFAULT */
+#define APR_FILE_SOURCE_PERMS APR_FPROT_FILE_SOURCE_PERMS /**< @deprecated @see APR_FPROT_FILE_SOURCE_PERMS */
+
+/** @} */
+
+
+/**
+ * Structure for referencing directories.
+ */
+typedef struct apr_dir_t apr_dir_t;
+/**
+ * Structure for determining file permissions.
+ */
+typedef apr_int32_t apr_fileperms_t;
+#if (defined WIN32) || (defined NETWARE)
+/**
+ * Structure for determining the device the file is on.
+ */
+typedef apr_uint32_t apr_dev_t;
+#else
+/**
+ * Structure for determining the device the file is on.
+ */
+typedef dev_t apr_dev_t;
+#endif
+
+/**
+ * @defgroup apr_file_stat Stat Functions
+ * @{
+ */
+/** file info structure */
+typedef struct apr_finfo_t apr_finfo_t;
+
+#define APR_FINFO_LINK 0x00000001 /**< Stat the link not the file itself if it is a link */
+#define APR_FINFO_MTIME 0x00000010 /**< Modification Time */
+#define APR_FINFO_CTIME 0x00000020 /**< Creation or inode-changed time */
+#define APR_FINFO_ATIME 0x00000040 /**< Access Time */
+#define APR_FINFO_SIZE 0x00000100 /**< Size of the file */
+#define APR_FINFO_CSIZE 0x00000200 /**< Storage size consumed by the file */
+#define APR_FINFO_DEV 0x00001000 /**< Device */
+#define APR_FINFO_INODE 0x00002000 /**< Inode */
+#define APR_FINFO_NLINK 0x00004000 /**< Number of links */
+#define APR_FINFO_TYPE 0x00008000 /**< Type */
+#define APR_FINFO_USER 0x00010000 /**< User */
+#define APR_FINFO_GROUP 0x00020000 /**< Group */
+#define APR_FINFO_UPROT 0x00100000 /**< User protection bits */
+#define APR_FINFO_GPROT 0x00200000 /**< Group protection bits */
+#define APR_FINFO_WPROT 0x00400000 /**< World protection bits */
+#define APR_FINFO_ICASE 0x01000000 /**< if dev is case insensitive */
+#define APR_FINFO_NAME 0x02000000 /**< ->name in proper case */
+
+#define APR_FINFO_MIN 0x00008170 /**< type, mtime, ctime, atime, size */
+#define APR_FINFO_IDENT 0x00003000 /**< dev and inode */
+#define APR_FINFO_OWNER 0x00030000 /**< user and group */
+#define APR_FINFO_PROT 0x00700000 /**< all protections */
+#define APR_FINFO_NORM 0x0073b170 /**< an atomic unix apr_stat() */
+#define APR_FINFO_DIRENT 0x02000000 /**< an atomic unix apr_dir_read() */
+
+/**
+ * The file information structure. This is analogous to the POSIX
+ * stat structure.
+ */
+struct apr_finfo_t {
+ /** Allocates memory and closes lingering handles in the specified pool */
+ apr_pool_t *pool;
+ /** The bitmask describing valid fields of this apr_finfo_t structure
+ * including all available 'wanted' fields and potentially more */
+ apr_int32_t valid;
+ /** The access permissions of the file. Mimics Unix access rights. */
+ apr_fileperms_t protection;
+ /** The type of file. One of APR_REG, APR_DIR, APR_CHR, APR_BLK, APR_PIPE,
+ * APR_LNK or APR_SOCK. If the type is undetermined, the value is APR_NOFILE.
+ * If the type cannot be determined, the value is APR_UNKFILE.
+ */
+ apr_filetype_e filetype;
+ /** The user id that owns the file */
+ apr_uid_t user;
+ /** The group id that owns the file */
+ apr_gid_t group;
+ /** The inode of the file. */
+ apr_ino_t inode;
+ /** The id of the device the file is on. */
+ apr_dev_t device;
+ /** The number of hard links to the file. */
+ apr_int32_t nlink;
+ /** The size of the file */
+ apr_off_t size;
+ /** The storage size consumed by the file */
+ apr_off_t csize;
+ /** The time the file was last accessed */
+ apr_time_t atime;
+ /** The time the file was last modified */
+ apr_time_t mtime;
+ /** The time the file was created, or the inode was last changed */
+ apr_time_t ctime;
+ /** The pathname of the file (possibly unrooted) */
+ const char *fname;
+ /** The file's name (no path) in filesystem case */
+ const char *name;
+ /** Unused */
+ struct apr_file_t *filehand;
+};
+
+/**
+ * get the specified file's stats. The file is specified by filename,
+ * instead of using a pre-opened file.
+ * @param finfo Where to store the information about the file, which is
+ * never touched if the call fails.
+ * @param fname The name of the file to stat.
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
+ values
+ * @param pool the pool to use to allocate the new file.
+ *
+ * @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
+ * not be filled in, and you need to check the @c finfo->valid bitmask
+ * to verify that what you're looking for is there.
+ */
+APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname,
+ apr_int32_t wanted, apr_pool_t *pool);
+
+/** @} */
+/**
+ * @defgroup apr_dir Directory Manipulation Functions
+ * @{
+ */
+
+/**
+ * Open the specified directory.
+ * @param new_dir The opened directory descriptor.
+ * @param dirname The full path to the directory (use / on all systems)
+ * @param pool The pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new_dir,
+ const char *dirname,
+ apr_pool_t *pool);
+
+/**
+ * close the specified directory.
+ * @param thedir the directory descriptor to close.
+ */
+APR_DECLARE(apr_status_t) apr_dir_close(apr_dir_t *thedir);
+
+/**
+ * Read the next entry from the specified directory.
+ * @param finfo the file info structure and filled in by apr_dir_read
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
+ values
+ * @param thedir the directory descriptor returned from apr_dir_open
+ * @remark No ordering is guaranteed for the entries read.
+ *
+ * @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
+ * not be filled in, and you need to check the @c finfo->valid bitmask
+ * to verify that what you're looking for is there. When no more
+ * entries are available, APR_ENOENT is returned.
+ */
+APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
+ apr_dir_t *thedir);
+
+/**
+ * Rewind the directory to the first entry.
+ * @param thedir the directory descriptor to rewind.
+ */
+APR_DECLARE(apr_status_t) apr_dir_rewind(apr_dir_t *thedir);
+/** @} */
+
+/**
+ * @defgroup apr_filepath Filepath Manipulation Functions
+ * @{
+ */
+
+/** Cause apr_filepath_merge to fail if addpath is above rootpath
+ * @bug in APR 0.9 and 1.x, this flag's behavior is undefined
+ * if the rootpath is NULL or empty. In APR 2.0 this should be
+ * changed to imply NOTABSOLUTE if the rootpath is NULL or empty.
+ */
+#define APR_FILEPATH_NOTABOVEROOT 0x01
+
+/** internal: Only meaningful with APR_FILEPATH_NOTABOVEROOT */
+#define APR_FILEPATH_SECUREROOTTEST 0x02
+
+/** Cause apr_filepath_merge to fail if addpath is above rootpath,
+ * even given a rootpath /foo/bar and an addpath ../bar/bash
+ */
+#define APR_FILEPATH_SECUREROOT 0x03
+
+/** Fail apr_filepath_merge if the merged path is relative */
+#define APR_FILEPATH_NOTRELATIVE 0x04
+
+/** Fail apr_filepath_merge if the merged path is absolute */
+#define APR_FILEPATH_NOTABSOLUTE 0x08
+
+/** Return the file system's native path format (e.g. path delimiters
+ * of ':' on MacOS9, '\' on Win32, etc.) */
+#define APR_FILEPATH_NATIVE 0x10
+
+/** Resolve the true case of existing directories and file elements
+ * of addpath, (resolving any aliases on Win32) and append a proper
+ * trailing slash if a directory
+ */
+#define APR_FILEPATH_TRUENAME 0x20
+
+/**
+ * Extract the rootpath from the given filepath
+ * @param rootpath the root file path returned with APR_SUCCESS or APR_EINCOMPLETE
+ * @param filepath the pathname to parse for its root component
+ * @param flags the desired rules to apply, from
+ * <PRE>
+ * APR_FILEPATH_NATIVE Use native path separators (e.g. '\' on Win32)
+ * APR_FILEPATH_TRUENAME Tests that the root exists, and makes it proper
+ * </PRE>
+ * @param p the pool to allocate the new path string from
+ * @remark on return, filepath points to the first non-root character in the
+ * given filepath. In the simplest example, given a filepath of "/foo",
+ * returns the rootpath of "/" and filepath points at "foo". This is far
+ * more complex on other platforms, which will canonicalize the root form
+ * to a consistant format, given the APR_FILEPATH_TRUENAME flag, and also
+ * test for the validity of that root (e.g., that a drive d:/ or network
+ * share //machine/foovol/).
+ * The function returns APR_ERELATIVE if filepath isn't rooted (an
+ * error), APR_EINCOMPLETE if the root path is ambiguous (but potentially
+ * legitimate, e.g. "/" on Windows is incomplete because it doesn't specify
+ * the drive letter), or APR_EBADPATH if the root is simply invalid.
+ * APR_SUCCESS is returned if filepath is an absolute path.
+ */
+APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
+ const char **filepath,
+ apr_int32_t flags,
+ apr_pool_t *p);
+
+/**
+ * Merge additional file path onto the previously processed rootpath
+ * @param newpath the merged paths returned
+ * @param rootpath the root file path (NULL uses the current working path)
+ * @param addpath the path to add to the root path
+ * @param flags the desired APR_FILEPATH_ rules to apply when merging
+ * @param p the pool to allocate the new path string from
+ * @remark if the flag APR_FILEPATH_TRUENAME is given, and the addpath
+ * contains wildcard characters ('*', '?') on platforms that don't support
+ * such characters within filenames, the paths will be merged, but the
+ * result code will be APR_EPATHWILD, and all further segments will not
+ * reflect the true filenames including the wildcard and following segments.
+ */
+APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
+ const char *rootpath,
+ const char *addpath,
+ apr_int32_t flags,
+ apr_pool_t *p);
+
+/**
+ * Split a search path into separate components
+ * @param pathelts the returned components of the search path
+ * @param liststr the search path (e.g., <tt>getenv("PATH")</tt>)
+ * @param p the pool to allocate the array and path components from
+ * @remark empty path components do not become part of @a pathelts.
+ * @remark the path separator in @a liststr is system specific;
+ * e.g., ':' on Unix, ';' on Windows, etc.
+ */
+APR_DECLARE(apr_status_t) apr_filepath_list_split(apr_array_header_t **pathelts,
+ const char *liststr,
+ apr_pool_t *p);
+
+/**
+ * Merge a list of search path components into a single search path
+ * @param liststr the returned search path; may be NULL if @a pathelts is empty
+ * @param pathelts the components of the search path
+ * @param p the pool to allocate the search path from
+ * @remark emtpy strings in the source array are ignored.
+ * @remark the path separator in @a liststr is system specific;
+ * e.g., ':' on Unix, ';' on Windows, etc.
+ */
+APR_DECLARE(apr_status_t) apr_filepath_list_merge(char **liststr,
+ apr_array_header_t *pathelts,
+ apr_pool_t *p);
+
+/**
+ * Return the default file path (for relative file names)
+ * @param path the default path string returned
+ * @param flags optional flag APR_FILEPATH_NATIVE to retrieve the
+ * default file path in os-native format.
+ * @param p the pool to allocate the default path string from
+ */
+APR_DECLARE(apr_status_t) apr_filepath_get(char **path, apr_int32_t flags,
+ apr_pool_t *p);
+
+/**
+ * Set the default file path (for relative file names)
+ * @param path the default path returned
+ * @param p the pool to allocate any working storage
+ */
+APR_DECLARE(apr_status_t) apr_filepath_set(const char *path, apr_pool_t *p);
+
+/** The FilePath character encoding is unknown */
+#define APR_FILEPATH_ENCODING_UNKNOWN 0
+
+/** The FilePath character encoding is locale-dependent */
+#define APR_FILEPATH_ENCODING_LOCALE 1
+
+/** The FilePath character encoding is UTF-8 */
+#define APR_FILEPATH_ENCODING_UTF8 2
+
+/**
+ * Determine the encoding used internally by the FilePath functions
+ * @param style points to a variable which receives the encoding style flag
+ * @param p the pool to allocate any working storage
+ * @remark Use apr_os_locale_encoding() and/or apr_os_default_encoding()
+ * to get the name of the path encoding if it's not UTF-8.
+ */
+APR_DECLARE(apr_status_t) apr_filepath_encoding(int *style, apr_pool_t *p);
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_FILE_INFO_H */
diff --git a/include/apr_file_io.h b/include/apr_file_io.h
new file mode 100644
index 0000000..af93193
--- /dev/null
+++ b/include/apr_file_io.h
@@ -0,0 +1,1005 @@
+/* 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 APR_FILE_IO_H
+#define APR_FILE_IO_H
+
+/**
+ * @file apr_file_io.h
+ * @brief APR File I/O Handling
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_time.h"
+#include "apr_errno.h"
+#include "apr_file_info.h"
+#include "apr_inherit.h"
+
+#define APR_WANT_STDIO /**< for SEEK_* */
+#define APR_WANT_IOVEC /**< for apr_file_writev */
+#include "apr_want.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_file_io File I/O Handling Functions
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * @defgroup apr_file_open_flags File Open Flags/Routines
+ * @{
+ */
+
+/* Note to implementors: Values in the range 0x00100000--0x80000000
+ are reserved for platform-specific values. */
+
+#define APR_FOPEN_READ 0x00001 /**< Open the file for reading */
+#define APR_FOPEN_WRITE 0x00002 /**< Open the file for writing */
+#define APR_FOPEN_CREATE 0x00004 /**< Create the file if not there */
+#define APR_FOPEN_APPEND 0x00008 /**< Append to the end of the file */
+#define APR_FOPEN_TRUNCATE 0x00010 /**< Open the file and truncate
+ to 0 length */
+#define APR_FOPEN_BINARY 0x00020 /**< Open the file in binary mode
+ (This flag is ignored on UNIX
+ because it has no meaning)*/
+#define APR_FOPEN_EXCL 0x00040 /**< Open should fail if #APR_FOPEN_CREATE
+ and file exists. */
+#define APR_FOPEN_BUFFERED 0x00080 /**< Open the file for buffered I/O */
+#define APR_FOPEN_DELONCLOSE 0x00100 /**< Delete the file after close */
+#define APR_FOPEN_XTHREAD 0x00200 /**< Platform dependent tag to open
+ the file for use across multiple
+ threads */
+#define APR_FOPEN_SHARELOCK 0x00400 /**< Platform dependent support for
+ higher level locked read/write
+ access to support writes across
+ process/machines */
+#define APR_FOPEN_NOCLEANUP 0x00800 /**< Do not register a cleanup
+ when the file is opened. The
+ apr_os_file_t handle in apr_file_t
+ will not be closed when the pool
+ is destroyed. */
+#define APR_FOPEN_SENDFILE_ENABLED 0x01000 /**< Advisory flag that this
+ file should support
+ apr_socket_sendfile operation */
+#define APR_FOPEN_LARGEFILE 0x04000 /**< Platform dependent flag to enable
+ * large file support, see WARNING below
+ */
+#define APR_FOPEN_SPARSE 0x08000 /**< Platform dependent flag to enable
+ * sparse file support, see WARNING below
+ */
+#define APR_FOPEN_NONBLOCK 0x40000 /**< Platform dependent flag to enable
+ * non blocking file io */
+
+
+/* backcompat */
+#define APR_READ APR_FOPEN_READ /**< @deprecated @see APR_FOPEN_READ */
+#define APR_WRITE APR_FOPEN_WRITE /**< @deprecated @see APR_FOPEN_WRITE */
+#define APR_CREATE APR_FOPEN_CREATE /**< @deprecated @see APR_FOPEN_CREATE */
+#define APR_APPEND APR_FOPEN_APPEND /**< @deprecated @see APR_FOPEN_APPEND */
+#define APR_TRUNCATE APR_FOPEN_TRUNCATE /**< @deprecated @see APR_FOPEN_TRUNCATE */
+#define APR_BINARY APR_FOPEN_BINARY /**< @deprecated @see APR_FOPEN_BINARY */
+#define APR_EXCL APR_FOPEN_EXCL /**< @deprecated @see APR_FOPEN_EXCL */
+#define APR_BUFFERED APR_FOPEN_BUFFERED /**< @deprecated @see APR_FOPEN_BUFFERED */
+#define APR_DELONCLOSE APR_FOPEN_DELONCLOSE /**< @deprecated @see APR_FOPEN_DELONCLOSE */
+#define APR_XTHREAD APR_FOPEN_XTHREAD /**< @deprecated @see APR_FOPEN_XTHREAD */
+#define APR_SHARELOCK APR_FOPEN_SHARELOCK /**< @deprecated @see APR_FOPEN_SHARELOCK */
+#define APR_FILE_NOCLEANUP APR_FOPEN_NOCLEANUP /**< @deprecated @see APR_FOPEN_NOCLEANUP */
+#define APR_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED /**< @deprecated @see APR_FOPEN_SENDFILE_ENABLED */
+#define APR_LARGEFILE APR_FOPEN_LARGEFILE /**< @deprecated @see APR_FOPEN_LARGEFILE */
+
+/** @def APR_FOPEN_LARGEFILE
+ * @warning APR_FOPEN_LARGEFILE flag only has effect on some
+ * platforms where sizeof(apr_off_t) == 4. Where implemented, it
+ * allows opening and writing to a file which exceeds the size which
+ * can be represented by apr_off_t (2 gigabytes). When a file's size
+ * does exceed 2Gb, apr_file_info_get() will fail with an error on the
+ * descriptor, likewise apr_stat()/apr_lstat() will fail on the
+ * filename. apr_dir_read() will fail with #APR_INCOMPLETE on a
+ * directory entry for a large file depending on the particular
+ * APR_FINFO_* flags. Generally, it is not recommended to use this
+ * flag.
+ *
+ * @def APR_FOPEN_SPARSE
+ * @warning APR_FOPEN_SPARSE may, depending on platform, convert a
+ * normal file to a sparse file. Some applications may be unable
+ * to decipher a sparse file, so it's critical that the sparse file
+ * flag should only be used for files accessed only by APR or other
+ * applications known to be able to decipher them. APR does not
+ * guarantee that it will compress the file into sparse segments
+ * if it was previously created and written without the sparse flag.
+ * On platforms which do not understand, or on file systems which
+ * cannot handle sparse files, the flag is ignored by apr_file_open().
+ *
+ * @def APR_FOPEN_NONBLOCK
+ * @warning APR_FOPEN_NONBLOCK is not implemented on all platforms.
+ * Callers should be prepared for it to fail with #APR_ENOTIMPL.
+ */
+
+/** @} */
+
+/**
+ * @defgroup apr_file_seek_flags File Seek Flags
+ * @{
+ */
+
+/* flags for apr_file_seek */
+/** Set the file position */
+#define APR_SET SEEK_SET
+/** Current */
+#define APR_CUR SEEK_CUR
+/** Go to end of file */
+#define APR_END SEEK_END
+/** @} */
+
+/**
+ * @defgroup apr_file_attrs_set_flags File Attribute Flags
+ * @{
+ */
+
+/* flags for apr_file_attrs_set */
+#define APR_FILE_ATTR_READONLY 0x01 /**< File is read-only */
+#define APR_FILE_ATTR_EXECUTABLE 0x02 /**< File is executable */
+#define APR_FILE_ATTR_HIDDEN 0x04 /**< File is hidden */
+/** @} */
+
+/**
+ * @defgroup apr_file_writev{_full} max iovec size
+ * @{
+ */
+#if defined(DOXYGEN)
+#define APR_MAX_IOVEC_SIZE 1024 /**< System dependent maximum
+ size of an iovec array */
+#elif defined(IOV_MAX)
+#define APR_MAX_IOVEC_SIZE IOV_MAX
+#elif defined(MAX_IOVEC)
+#define APR_MAX_IOVEC_SIZE MAX_IOVEC
+#else
+#define APR_MAX_IOVEC_SIZE 1024
+#endif
+/** @} */
+
+/** File attributes */
+typedef apr_uint32_t apr_fileattrs_t;
+
+/** Type to pass as whence argument to apr_file_seek. */
+typedef int apr_seek_where_t;
+
+/**
+ * Structure for referencing files.
+ */
+typedef struct apr_file_t apr_file_t;
+
+/* File lock types/flags */
+/**
+ * @defgroup apr_file_lock_types File Lock Types
+ * @{
+ */
+
+#define APR_FLOCK_SHARED 1 /**< Shared lock. More than one process
+ or thread can hold a shared lock
+ at any given time. Essentially,
+ this is a "read lock", preventing
+ writers from establishing an
+ exclusive lock. */
+#define APR_FLOCK_EXCLUSIVE 2 /**< Exclusive lock. Only one process
+ may hold an exclusive lock at any
+ given time. This is analogous to
+ a "write lock". */
+
+#define APR_FLOCK_TYPEMASK 0x000F /**< mask to extract lock type */
+#define APR_FLOCK_NONBLOCK 0x0010 /**< do not block while acquiring the
+ file lock */
+/** @} */
+
+/**
+ * Open the specified file.
+ * @param newf The opened file descriptor.
+ * @param fname The full path to the file (using / on all systems)
+ * @param flag Or'ed value of:
+ * @li #APR_FOPEN_READ open for reading
+ * @li #APR_FOPEN_WRITE open for writing
+ * @li #APR_FOPEN_CREATE create the file if not there
+ * @li #APR_FOPEN_APPEND file ptr is set to end prior to all writes
+ * @li #APR_FOPEN_TRUNCATE set length to zero if file exists
+ * @li #APR_FOPEN_BINARY not a text file
+ * @li #APR_FOPEN_BUFFERED buffer the data. Default is non-buffered
+ * @li #APR_FOPEN_EXCL return error if #APR_FOPEN_CREATE and file exists
+ * @li #APR_FOPEN_DELONCLOSE delete the file after closing
+ * @li #APR_FOPEN_XTHREAD Platform dependent tag to open the file
+ * for use across multiple threads
+ * @li #APR_FOPEN_SHARELOCK Platform dependent support for higher
+ * level locked read/write access to support
+ * writes across process/machines
+ * @li #APR_FOPEN_NOCLEANUP Do not register a cleanup with the pool
+ * passed in on the @a pool argument (see below)
+ * @li #APR_FOPEN_SENDFILE_ENABLED Open with appropriate platform semantics
+ * for sendfile operations. Advisory only,
+ * apr_socket_sendfile does not check this flag
+ * @li #APR_FOPEN_LARGEFILE Platform dependent flag to enable large file
+ * support, see WARNING below
+ * @li #APR_FOPEN_SPARSE Platform dependent flag to enable sparse file
+ * support, see WARNING below
+ * @li #APR_FOPEN_NONBLOCK Platform dependent flag to enable
+ * non blocking file io
+ * @param perm Access permissions for file.
+ * @param pool The pool to use.
+ * @remark If perm is #APR_FPROT_OS_DEFAULT and the file is being created,
+ * appropriate default permissions will be used.
+ * @remark By default, the returned file descriptor will not be
+ * inherited by child processes created by apr_proc_create(). This
+ * can be changed using apr_file_inherit_set().
+ */
+APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **newf, const char *fname,
+ apr_int32_t flag, apr_fileperms_t perm,
+ apr_pool_t *pool);
+
+/**
+ * Close the specified file.
+ * @param file The file descriptor to close.
+ */
+APR_DECLARE(apr_status_t) apr_file_close(apr_file_t *file);
+
+/**
+ * Delete the specified file.
+ * @param path The full path to the file (using / on all systems)
+ * @param pool The pool to use.
+ * @remark If the file is open, it won't be removed until all
+ * instances are closed.
+ */
+APR_DECLARE(apr_status_t) apr_file_remove(const char *path, apr_pool_t *pool);
+
+/**
+ * Rename the specified file.
+ * @param from_path The full path to the original file (using / on all systems)
+ * @param to_path The full path to the new file (using / on all systems)
+ * @param pool The pool to use.
+ * @warning If a file exists at the new location, then it will be
+ * overwritten. Moving files or directories across devices may not be
+ * possible.
+ */
+APR_DECLARE(apr_status_t) apr_file_rename(const char *from_path,
+ const char *to_path,
+ apr_pool_t *pool);
+
+/**
+ * Create a hard link to the specified file.
+ * @param from_path The full path to the original file (using / on all systems)
+ * @param to_path The full path to the new file (using / on all systems)
+ * @remark Both files must reside on the same device.
+ */
+APR_DECLARE(apr_status_t) apr_file_link(const char *from_path,
+ const char *to_path);
+
+/**
+ * Copy the specified file to another file.
+ * @param from_path The full path to the original file (using / on all systems)
+ * @param to_path The full path to the new file (using / on all systems)
+ * @param perms Access permissions for the new file if it is created.
+ * In place of the usual or'd combination of file permissions, the
+ * value #APR_FPROT_FILE_SOURCE_PERMS may be given, in which case the source
+ * file's permissions are copied.
+ * @param pool The pool to use.
+ * @remark The new file does not need to exist, it will be created if required.
+ * @warning If the new file already exists, its contents will be overwritten.
+ */
+APR_DECLARE(apr_status_t) apr_file_copy(const char *from_path,
+ const char *to_path,
+ apr_fileperms_t perms,
+ apr_pool_t *pool);
+
+/**
+ * Append the specified file to another file.
+ * @param from_path The full path to the source file (use / on all systems)
+ * @param to_path The full path to the destination file (use / on all systems)
+ * @param perms Access permissions for the destination file if it is created.
+ * In place of the usual or'd combination of file permissions, the
+ * value #APR_FPROT_FILE_SOURCE_PERMS may be given, in which case the source
+ * file's permissions are copied.
+ * @param pool The pool to use.
+ * @remark The new file does not need to exist, it will be created if required.
+ * @remark Note that advanced filesystem permissions such as ACLs are not
+ * duplicated by this API. The target permissions (including duplicating the
+ * source file permissions) are assigned only when the target file does not yet
+ * exist.
+ */
+APR_DECLARE(apr_status_t) apr_file_append(const char *from_path,
+ const char *to_path,
+ apr_fileperms_t perms,
+ apr_pool_t *pool);
+
+/**
+ * Are we at the end of the file
+ * @param fptr The apr file we are testing.
+ * @remark Returns #APR_EOF if we are at the end of file, #APR_SUCCESS otherwise.
+ */
+APR_DECLARE(apr_status_t) apr_file_eof(apr_file_t *fptr);
+
+/**
+ * Open standard error as an apr file pointer.
+ * @param thefile The apr file to use as stderr.
+ * @param pool The pool to allocate the file out of.
+ *
+ * @remark The only reason that the apr_file_open_std* functions exist
+ * is that you may not always have a stderr/out/in on Windows. This
+ * is generally a problem with newer versions of Windows and services.
+ *
+ * @remark The other problem is that the C library functions generally work
+ * differently on Windows and Unix. So, by using apr_file_open_std*
+ * functions, you can get a handle to an APR struct that works with
+ * the APR functions which are supposed to work identically on all
+ * platforms.
+ */
+APR_DECLARE(apr_status_t) apr_file_open_stderr(apr_file_t **thefile,
+ apr_pool_t *pool);
+
+/**
+ * open standard output as an apr file pointer.
+ * @param thefile The apr file to use as stdout.
+ * @param pool The pool to allocate the file out of.
+ *
+ * @remark See remarks for apr_file_open_stderr().
+ */
+APR_DECLARE(apr_status_t) apr_file_open_stdout(apr_file_t **thefile,
+ apr_pool_t *pool);
+
+/**
+ * open standard input as an apr file pointer.
+ * @param thefile The apr file to use as stdin.
+ * @param pool The pool to allocate the file out of.
+ *
+ * @remark See remarks for apr_file_open_stderr().
+ */
+APR_DECLARE(apr_status_t) apr_file_open_stdin(apr_file_t **thefile,
+ apr_pool_t *pool);
+
+/**
+ * open standard error as an apr file pointer, with flags.
+ * @param thefile The apr file to use as stderr.
+ * @param flags The flags to open the file with. Only the
+ * @li #APR_FOPEN_EXCL
+ * @li #APR_FOPEN_BUFFERED
+ * @li #APR_FOPEN_XTHREAD
+ * @li #APR_FOPEN_SHARELOCK
+ * @li #APR_FOPEN_SENDFILE_ENABLED
+ * @li #APR_FOPEN_LARGEFILE
+ *
+ * flags should be used. The #APR_FOPEN_WRITE flag will
+ * be set unconditionally.
+ * @param pool The pool to allocate the file out of.
+ *
+ * @remark See remarks for apr_file_open_stderr().
+ */
+APR_DECLARE(apr_status_t) apr_file_open_flags_stderr(apr_file_t **thefile,
+ apr_int32_t flags,
+ apr_pool_t *pool);
+
+/**
+ * open standard output as an apr file pointer, with flags.
+ * @param thefile The apr file to use as stdout.
+ * @param flags The flags to open the file with. Only the
+ * @li #APR_FOPEN_EXCL
+ * @li #APR_FOPEN_BUFFERED
+ * @li #APR_FOPEN_XTHREAD
+ * @li #APR_FOPEN_SHARELOCK
+ * @li #APR_FOPEN_SENDFILE_ENABLED
+ * @li #APR_FOPEN_LARGEFILE
+ *
+ * flags should be used. The #APR_FOPEN_WRITE flag will
+ * be set unconditionally.
+ * @param pool The pool to allocate the file out of.
+ *
+ * @remark See remarks for apr_file_open_stderr().
+ */
+APR_DECLARE(apr_status_t) apr_file_open_flags_stdout(apr_file_t **thefile,
+ apr_int32_t flags,
+ apr_pool_t *pool);
+
+/**
+ * open standard input as an apr file pointer, with flags.
+ * @param thefile The apr file to use as stdin.
+ * @param flags The flags to open the file with. Only the
+ * @li #APR_FOPEN_EXCL
+ * @li #APR_FOPEN_BUFFERED
+ * @li #APR_FOPEN_XTHREAD
+ * @li #APR_FOPEN_SHARELOCK
+ * @li #APR_FOPEN_SENDFILE_ENABLED
+ * @li #APR_FOPEN_LARGEFILE
+ *
+ * flags should be used. The #APR_FOPEN_WRITE flag will
+ * be set unconditionally.
+ * @param pool The pool to allocate the file out of.
+ *
+ * @remark See remarks for apr_file_open_stderr().
+ */
+APR_DECLARE(apr_status_t) apr_file_open_flags_stdin(apr_file_t **thefile,
+ apr_int32_t flags,
+ apr_pool_t *pool);
+
+/**
+ * Read data from the specified file.
+ * @param thefile The file descriptor to read from.
+ * @param buf The buffer to store the data to.
+ * @param nbytes On entry, the number of bytes to read; on exit, the number
+ * of bytes read.
+ *
+ * @remark apr_file_read() will read up to the specified number of
+ * bytes, but never more. If there isn't enough data to fill that
+ * number of bytes, all of the available data is read. The third
+ * argument is modified to reflect the number of bytes read. If a
+ * char was put back into the stream via ungetc, it will be the first
+ * character returned.
+ *
+ * @remark It is not possible for both bytes to be read and an #APR_EOF
+ * or other error to be returned. #APR_EINTR is never returned.
+ */
+APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf,
+ apr_size_t *nbytes);
+
+/**
+ * Write data to the specified file.
+ * @param thefile The file descriptor to write to.
+ * @param buf The buffer which contains the data.
+ * @param nbytes On entry, the number of bytes to write; on exit, the number
+ * of bytes written.
+ *
+ * @remark apr_file_write() will write up to the specified number of
+ * bytes, but never more. If the OS cannot write that many bytes, it
+ * will write as many as it can. The third argument is modified to
+ * reflect the * number of bytes written.
+ *
+ * @remark It is possible for both bytes to be written and an error to
+ * be returned. #APR_EINTR is never returned.
+ */
+APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf,
+ apr_size_t *nbytes);
+
+/**
+ * Write data from iovec array to the specified file.
+ * @param thefile The file descriptor to write to.
+ * @param vec The array from which to get the data to write to the file.
+ * @param nvec The number of elements in the struct iovec array. This must
+ * be smaller than #APR_MAX_IOVEC_SIZE. If it isn't, the function
+ * will fail with #APR_EINVAL.
+ * @param nbytes The number of bytes written.
+ *
+ * @remark It is possible for both bytes to be written and an error to
+ * be returned. #APR_EINTR is never returned.
+ *
+ * @remark apr_file_writev() is available even if the underlying
+ * operating system doesn't provide writev().
+ */
+APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
+ const struct iovec *vec,
+ apr_size_t nvec, apr_size_t *nbytes);
+
+/**
+ * Read data from the specified file, ensuring that the buffer is filled
+ * before returning.
+ * @param thefile The file descriptor to read from.
+ * @param buf The buffer to store the data to.
+ * @param nbytes The number of bytes to read.
+ * @param bytes_read If non-NULL, this will contain the number of bytes read.
+ *
+ * @remark apr_file_read_full() will read up to the specified number of
+ * bytes, but never more. If there isn't enough data to fill that
+ * number of bytes, then the process/thread will block until it is
+ * available or EOF is reached. If a char was put back into the
+ * stream via ungetc, it will be the first character returned.
+ *
+ * @remark It is possible for both bytes to be read and an error to be
+ * returned. And if *bytes_read is less than nbytes, an accompanying
+ * error is _always_ returned.
+ *
+ * @remark #APR_EINTR is never returned.
+ */
+APR_DECLARE(apr_status_t) apr_file_read_full(apr_file_t *thefile, void *buf,
+ apr_size_t nbytes,
+ apr_size_t *bytes_read);
+
+/**
+ * Write data to the specified file, ensuring that all of the data is
+ * written before returning.
+ * @param thefile The file descriptor to write to.
+ * @param buf The buffer which contains the data.
+ * @param nbytes The number of bytes to write.
+ * @param bytes_written If non-NULL, set to the number of bytes written.
+ *
+ * @remark apr_file_write_full() will write up to the specified number of
+ * bytes, but never more. If the OS cannot write that many bytes, the
+ * process/thread will block until they can be written. Exceptional
+ * error such as "out of space" or "pipe closed" will terminate with
+ * an error.
+ *
+ * @remark It is possible for both bytes to be written and an error to
+ * be returned. And if *bytes_written is less than nbytes, an
+ * accompanying error is _always_ returned.
+ *
+ * @remark #APR_EINTR is never returned.
+ */
+APR_DECLARE(apr_status_t) apr_file_write_full(apr_file_t *thefile,
+ const void *buf,
+ apr_size_t nbytes,
+ apr_size_t *bytes_written);
+
+
+/**
+ * Write data from iovec array to the specified file, ensuring that all of the
+ * data is written before returning.
+ * @param thefile The file descriptor to write to.
+ * @param vec The array from which to get the data to write to the file.
+ * @param nvec The number of elements in the struct iovec array. This must
+ * be smaller than #APR_MAX_IOVEC_SIZE. If it isn't, the function
+ * will fail with #APR_EINVAL.
+ * @param nbytes The number of bytes written.
+ *
+ * @remark apr_file_writev_full() is available even if the underlying
+ * operating system doesn't provide writev().
+ */
+APR_DECLARE(apr_status_t) apr_file_writev_full(apr_file_t *thefile,
+ const struct iovec *vec,
+ apr_size_t nvec,
+ apr_size_t *nbytes);
+/**
+ * Write a character into the specified file.
+ * @param ch The character to write.
+ * @param thefile The file descriptor to write to
+ */
+APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile);
+
+/**
+ * Read a character from the specified file.
+ * @param ch The character to read into
+ * @param thefile The file descriptor to read from
+ */
+APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile);
+
+/**
+ * Put a character back onto a specified stream.
+ * @param ch The character to write.
+ * @param thefile The file descriptor to write to
+ */
+APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile);
+
+/**
+ * Read a line from the specified file
+ * @param str The buffer to store the string in.
+ * @param len The length of the string
+ * @param thefile The file descriptor to read from
+ * @remark The buffer will be NUL-terminated if any characters are stored.
+ * The newline at the end of the line will not be stripped.
+ */
+APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len,
+ apr_file_t *thefile);
+
+/**
+ * Write the string into the specified file.
+ * @param str The string to write.
+ * @param thefile The file descriptor to write to
+ */
+APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile);
+
+/**
+ * Flush the file's buffer.
+ * @param thefile The file descriptor to flush
+ */
+APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile);
+
+/**
+ * Transfer all file modified data and metadata to disk.
+ * @param thefile The file descriptor to sync
+ */
+APR_DECLARE(apr_status_t) apr_file_sync(apr_file_t *thefile);
+
+/**
+ * Transfer all file modified data to disk.
+ * @param thefile The file descriptor to sync
+ */
+APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile);
+
+/**
+ * Duplicate the specified file descriptor.
+ * @param new_file The structure to duplicate into.
+ * @param old_file The file to duplicate.
+ * @param p The pool to use for the new file.
+ * @remark *new_file must point to a valid apr_file_t, or point to NULL.
+ */
+APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
+ apr_file_t *old_file,
+ apr_pool_t *p);
+
+/**
+ * Duplicate the specified file descriptor and close the original
+ * @param new_file The old file that is to be closed and reused
+ * @param old_file The file to duplicate
+ * @param p The pool to use for the new file
+ *
+ * @remark new_file MUST point at a valid apr_file_t. It cannot be NULL.
+ */
+APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file,
+ apr_file_t *old_file,
+ apr_pool_t *p);
+
+/**
+ * Move the specified file descriptor to a new pool
+ * @param new_file Pointer in which to return the new apr_file_t
+ * @param old_file The file to move
+ * @param p The pool to which the descriptor is to be moved
+ * @remark Unlike apr_file_dup2(), this function doesn't do an
+ * OS dup() operation on the underlying descriptor; it just
+ * moves the descriptor's apr_file_t wrapper to a new pool.
+ * @remark The new pool need not be an ancestor of old_file's pool.
+ * @remark After calling this function, old_file may not be used
+ */
+APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file,
+ apr_file_t *old_file,
+ apr_pool_t *p);
+
+/**
+ * Give the specified apr file handle a new buffer
+ * @param thefile The file handle that is to be modified
+ * @param buffer The buffer
+ * @param bufsize The size of the buffer
+ * @remark It is possible to add a buffer to previously unbuffered
+ * file handles, the #APR_FOPEN_BUFFERED flag will be added to
+ * the file handle's flags. Likewise, with buffer=NULL and
+ * bufsize=0 arguments it is possible to make a previously
+ * buffered file handle unbuffered.
+ */
+APR_DECLARE(apr_status_t) apr_file_buffer_set(apr_file_t *thefile,
+ char * buffer,
+ apr_size_t bufsize);
+
+/**
+ * Get the size of any buffer for the specified apr file handle
+ * @param thefile The file handle
+ */
+APR_DECLARE(apr_size_t) apr_file_buffer_size_get(apr_file_t *thefile);
+
+/**
+ * Move the read/write file offset to a specified byte within a file.
+ * @param thefile The file descriptor
+ * @param where How to move the pointer, one of:
+ * @li #APR_SET -- set the offset to offset
+ * @li #APR_CUR -- add the offset to the current position
+ * @li #APR_END -- add the offset to the current file size
+ * @param offset The offset to move the pointer to.
+ * @remark The third argument is modified to be the offset the pointer
+ was actually moved to.
+ */
+APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile,
+ apr_seek_where_t where,
+ apr_off_t *offset);
+
+/**
+ * Create an anonymous pipe.
+ * @param in The newly created pipe's file for reading.
+ * @param out The newly created pipe's file for writing.
+ * @param pool The pool to operate on.
+ * @remark By default, the returned file descriptors will be inherited
+ * by child processes created using apr_proc_create(). This can be
+ * changed using apr_file_inherit_unset().
+ * @bug Some platforms cannot toggle between blocking and nonblocking,
+ * and when passing a pipe as a standard handle to an application which
+ * does not expect it, a non-blocking stream will fluxor the client app.
+ * @deprecated @see apr_file_pipe_create_pools()
+ */
+APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in,
+ apr_file_t **out,
+ apr_pool_t *pool);
+
+/**
+ * Create an anonymous pipe which portably supports async timeout options.
+ * @param in The newly created pipe's file for reading.
+ * @param out The newly created pipe's file for writing.
+ * @param blocking one of these values defined in apr_thread_proc.h;
+ * @li #APR_FULL_BLOCK
+ * @li #APR_READ_BLOCK
+ * @li #APR_WRITE_BLOCK
+ * @li #APR_FULL_NONBLOCK
+ * @param pool The pool to operate on.
+ * @remark By default, the returned file descriptors will be inherited
+ * by child processes created using apr_proc_create(). This can be
+ * changed using apr_file_inherit_unset().
+ * @remark Some platforms cannot toggle between blocking and nonblocking,
+ * and when passing a pipe as a standard handle to an application which
+ * does not expect it, a non-blocking stream will fluxor the client app.
+ * Use this function rather than apr_file_pipe_create() to create pipes
+ * where one or both ends require non-blocking semantics.
+ * @deprecated @see apr_file_pipe_create_pools()
+ */
+APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
+ apr_file_t **out,
+ apr_int32_t blocking,
+ apr_pool_t *pool);
+
+/**
+ * Create an anonymous pipe which portably supports async timeout options,
+ * placing each side of the pipe in a different pool.
+ * @param in The newly created pipe's file for reading.
+ * @param out The newly created pipe's file for writing.
+ * @param blocking one of these values defined in apr_thread_proc.h;
+ * @li #APR_FULL_BLOCK
+ * @li #APR_READ_BLOCK
+ * @li #APR_WRITE_BLOCK
+ * @li #APR_FULL_NONBLOCK
+ * @param pool_in The pool for the reading pipe.
+ * @param pool_out The pool for the writing pipe.
+ * @remark By default, the returned file descriptors will be inherited
+ * by child processes created using apr_proc_create(). This can be
+ * changed using apr_file_inherit_unset().
+ * @remark Some platforms cannot toggle between blocking and nonblocking,
+ * and when passing a pipe as a standard handle to an application which
+ * does not expect it, a non-blocking stream will fluxor the client app.
+ * Use this function rather than apr_file_pipe_create() to create pipes
+ * where one or both ends require non-blocking semantics.
+ */
+APR_DECLARE(apr_status_t) apr_file_pipe_create_pools(apr_file_t **in,
+ apr_file_t **out,
+ apr_int32_t blocking,
+ apr_pool_t *pool_in,
+ apr_pool_t *pool_out);
+
+/**
+ * Create a named pipe.
+ * @param filename The filename of the named pipe
+ * @param perm The permissions for the newly created pipe.
+ * @param pool The pool to operate on.
+ */
+APR_DECLARE(apr_status_t) apr_file_namedpipe_create(const char *filename,
+ apr_fileperms_t perm,
+ apr_pool_t *pool);
+
+/**
+ * Get the timeout value for a pipe or manipulate the blocking state.
+ * @param thepipe The pipe we are getting a timeout for.
+ * @param timeout The current timeout value in microseconds.
+ */
+APR_DECLARE(apr_status_t) apr_file_pipe_timeout_get(apr_file_t *thepipe,
+ apr_interval_time_t *timeout);
+
+/**
+ * Set the timeout value for a pipe or manipulate the blocking state.
+ * @param thepipe The pipe we are setting a timeout on.
+ * @param timeout The timeout value in microseconds. Values < 0 mean wait
+ * forever, 0 means do not wait at all.
+ */
+APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe,
+ apr_interval_time_t timeout);
+
+/** file (un)locking functions. */
+
+/**
+ * Establish a lock on the specified, open file. The lock may be advisory
+ * or mandatory, at the discretion of the platform. The lock applies to
+ * the file as a whole, rather than a specific range. Locks are established
+ * on a per-thread/process basis; a second lock by the same thread will not
+ * block.
+ * @param thefile The file to lock.
+ * @param type The type of lock to establish on the file.
+ */
+APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type);
+
+/**
+ * Remove any outstanding locks on the file.
+ * @param thefile The file to unlock.
+ */
+APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *thefile);
+
+/**accessor and general file_io functions. */
+
+/**
+ * return the file name of the current file.
+ * @param new_path The path of the file.
+ * @param thefile The currently open file.
+ */
+APR_DECLARE(apr_status_t) apr_file_name_get(const char **new_path,
+ apr_file_t *thefile);
+
+/**
+ * Return the data associated with the current file.
+ * @param data The user data associated with the file.
+ * @param key The key to use for retrieving data associated with this file.
+ * @param file The currently open file.
+ */
+APR_DECLARE(apr_status_t) apr_file_data_get(void **data, const char *key,
+ apr_file_t *file);
+
+/**
+ * Set the data associated with the current file.
+ * @param file The currently open file.
+ * @param data The user data to associate with the file.
+ * @param key The key to use for associating data with the file.
+ * @param cleanup The cleanup routine to use when the file is destroyed.
+ */
+APR_DECLARE(apr_status_t) apr_file_data_set(apr_file_t *file, void *data,
+ const char *key,
+ apr_status_t (*cleanup)(void *));
+
+/**
+ * Write a string to a file using a printf format.
+ * @param fptr The file to write to.
+ * @param format The format string
+ * @param ... The values to substitute in the format string
+ * @return The number of bytes written
+ */
+APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr,
+ const char *format, ...)
+ __attribute__((format(printf,2,3)));
+
+/**
+ * set the specified file's permission bits.
+ * @param fname The file (name) to apply the permissions to.
+ * @param perms The permission bits to apply to the file.
+ *
+ * @warning Some platforms may not be able to apply all of the
+ * available permission bits; #APR_INCOMPLETE will be returned if some
+ * permissions are specified which could not be set.
+ *
+ * @warning Platforms which do not implement this feature will return
+ * #APR_ENOTIMPL.
+ */
+APR_DECLARE(apr_status_t) apr_file_perms_set(const char *fname,
+ apr_fileperms_t perms);
+
+/**
+ * Set attributes of the specified file.
+ * @param fname The full path to the file (using / on all systems)
+ * @param attributes Or'd combination of
+ * @li #APR_FILE_ATTR_READONLY - make the file readonly
+ * @li #APR_FILE_ATTR_EXECUTABLE - make the file executable
+ * @li #APR_FILE_ATTR_HIDDEN - make the file hidden
+ * @param attr_mask Mask of valid bits in attributes.
+ * @param pool the pool to use.
+ * @remark This function should be used in preference to explicit manipulation
+ * of the file permissions, because the operations to provide these
+ * attributes are platform specific and may involve more than simply
+ * setting permission bits.
+ * @warning Platforms which do not implement this feature will return
+ * #APR_ENOTIMPL.
+ */
+APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname,
+ apr_fileattrs_t attributes,
+ apr_fileattrs_t attr_mask,
+ apr_pool_t *pool);
+
+/**
+ * Set the mtime of the specified file.
+ * @param fname The full path to the file (using / on all systems)
+ * @param mtime The mtime to apply to the file.
+ * @param pool The pool to use.
+ * @warning Platforms which do not implement this feature will return
+ * #APR_ENOTIMPL.
+ */
+APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname,
+ apr_time_t mtime,
+ apr_pool_t *pool);
+
+/**
+ * Create a new directory on the file system.
+ * @param path the path for the directory to be created. (use / on all systems)
+ * @param perm Permissions for the new directory.
+ * @param pool the pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_dir_make(const char *path, apr_fileperms_t perm,
+ apr_pool_t *pool);
+
+/** Creates a new directory on the file system, but behaves like
+ * 'mkdir -p'. Creates intermediate directories as required. No error
+ * will be reported if PATH already exists.
+ * @param path the path for the directory to be created. (use / on all systems)
+ * @param perm Permissions for the new directory.
+ * @param pool the pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_dir_make_recursive(const char *path,
+ apr_fileperms_t perm,
+ apr_pool_t *pool);
+
+/**
+ * Remove directory from the file system.
+ * @param path the path for the directory to be removed. (use / on all systems)
+ * @param pool the pool to use.
+ * @remark Removing a directory which is in-use (e.g., the current working
+ * directory, or during apr_dir_read, or with an open file) is not portable.
+ */
+APR_DECLARE(apr_status_t) apr_dir_remove(const char *path, apr_pool_t *pool);
+
+/**
+ * get the specified file's stats.
+ * @param finfo Where to store the information about the file.
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_* values
+ * @param thefile The file to get information about.
+ */
+APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
+ apr_int32_t wanted,
+ apr_file_t *thefile);
+
+
+/**
+ * Truncate the file's length to the specified offset
+ * @param fp The file to truncate
+ * @param offset The offset to truncate to.
+ * @remark The read/write file offset is repositioned to offset.
+ */
+APR_DECLARE(apr_status_t) apr_file_trunc(apr_file_t *fp, apr_off_t offset);
+
+/**
+ * Retrieve the flags that were passed into apr_file_open()
+ * when the file was opened.
+ * @return apr_int32_t the flags
+ */
+APR_DECLARE(apr_int32_t) apr_file_flags_get(apr_file_t *f);
+
+/**
+ * Get the pool used by the file.
+ */
+APR_POOL_DECLARE_ACCESSOR(file);
+
+/**
+ * Set a file to be inherited by child processes.
+ *
+ */
+APR_DECLARE_INHERIT_SET(file);
+
+/**
+ * Unset a file from being inherited by child processes.
+ */
+APR_DECLARE_INHERIT_UNSET(file);
+
+/**
+ * Open a temporary file
+ * @param fp The apr file to use as a temporary file.
+ * @param templ The template to use when creating a temp file.
+ * @param flags The flags to open the file with. If this is zero,
+ * the file is opened with
+ * #APR_FOPEN_CREATE | #APR_FOPEN_READ | #APR_FOPEN_WRITE |
+ * #APR_FOPEN_EXCL | #APR_FOPEN_DELONCLOSE
+ * @param p The pool to allocate the file out of.
+ * @remark
+ * This function generates a unique temporary file name from template.
+ * The last six characters of template must be XXXXXX and these are replaced
+ * with a string that makes the filename unique. Since it will be modified,
+ * template must not be a string constant, but should be declared as a character
+ * array.
+ *
+ */
+APR_DECLARE(apr_status_t) apr_file_mktemp(apr_file_t **fp, char *templ,
+ apr_int32_t flags, apr_pool_t *p);
+
+
+/**
+ * Find an existing directory suitable as a temporary storage location.
+ * @param temp_dir The temp directory.
+ * @param p The pool to use for any necessary allocations.
+ * @remark
+ * This function uses an algorithm to search for a directory that an
+ * an application can use for temporary storage.
+ *
+ */
+APR_DECLARE(apr_status_t) apr_temp_dir_get(const char **temp_dir,
+ apr_pool_t *p);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_FILE_IO_H */
diff --git a/include/apr_fnmatch.h b/include/apr_fnmatch.h
new file mode 100644
index 0000000..e8f6b03
--- /dev/null
+++ b/include/apr_fnmatch.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
+ */
+
+/* This file has been modified by the Apache Software Foundation. */
+#ifndef _APR_FNMATCH_H_
+#define _APR_FNMATCH_H_
+
+/**
+ * @file apr_fnmatch.h
+ * @brief APR FNMatch Functions
+ */
+
+#include "apr_errno.h"
+#include "apr_tables.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup apr_fnmatch Filename Matching Functions
+ * @ingroup APR
+ * @{
+ */
+
+#define APR_FNM_NOMATCH 1 /**< Match failed. */
+
+#define APR_FNM_NOESCAPE 0x01 /**< Disable backslash escaping. */
+#define APR_FNM_PATHNAME 0x02 /**< Slash must be matched by slash. */
+#define APR_FNM_PERIOD 0x04 /**< Period must be matched by period. */
+#define APR_FNM_CASE_BLIND 0x08 /**< Compare characters case-insensitively. */
+
+/**
+ * Try to match the string to the given pattern, return APR_SUCCESS if
+ * match, else return APR_FNM_NOMATCH. Note that there is no such thing as
+ * an illegal pattern.
+ *
+ * With all flags unset, a pattern is interpreted as such:
+ *
+ * PATTERN: Backslash followed by any character, including another
+ * backslash.<br/>
+ * MATCHES: That character exactly.
+ *
+ * <p>
+ * PATTERN: ?<br/>
+ * MATCHES: Any single character.
+ * </p>
+ *
+ * <p>
+ * PATTERN: *<br/>
+ * MATCHES: Any sequence of zero or more characters. (Note that multiple
+ * *s in a row are equivalent to one.)
+ *
+ * PATTERN: Any character other than \?*[ or a \ at the end of the pattern<br/>
+ * MATCHES: That character exactly. (Case sensitive.)
+ *
+ * PATTERN: [ followed by a class description followed by ]<br/>
+ * MATCHES: A single character described by the class description.
+ * (Never matches, if the class description reaches until the
+ * end of the string without a ].) If the first character of
+ * the class description is ^ or !, the sense of the description
+ * is reversed. The rest of the class description is a list of
+ * single characters or pairs of characters separated by -. Any
+ * of those characters can have a backslash in front of them,
+ * which is ignored; this lets you use the characters ] and -
+ * in the character class, as well as ^ and ! at the
+ * beginning. The pattern matches a single character if it
+ * is one of the listed characters or falls into one of the
+ * listed ranges (inclusive, case sensitive). Ranges with
+ * the first character larger than the second are legal but
+ * never match. Edge cases: [] never matches, and [^] and [!]
+ * always match without consuming a character.
+ *
+ * Note that these patterns attempt to match the entire string, not
+ * just find a substring matching the pattern.
+ *
+ * @param pattern The pattern to match to
+ * @param strings The string we are trying to match
+ * @param flags flags to use in the match. Bitwise OR of:
+ * <pre>
+ * APR_FNM_NOESCAPE Disable backslash escaping
+ * APR_FNM_PATHNAME Slash must be matched by slash
+ * APR_FNM_PERIOD Period must be matched by period
+ * APR_FNM_CASE_BLIND Compare characters case-insensitively.
+ * </pre>
+ */
+
+APR_DECLARE(apr_status_t) apr_fnmatch(const char *pattern,
+ const char *strings, int flags);
+
+/**
+ * Determine if the given pattern is a regular expression.
+ * @param pattern The pattern to search for glob characters.
+ * @return non-zero if pattern has any glob characters in it
+ */
+APR_DECLARE(int) apr_fnmatch_test(const char *pattern);
+
+/**
+ * Find all files that match a specified pattern in a directory.
+ * @param dir_pattern The pattern to use for finding files, appended
+ * to the search directory. The pattern is anything following the
+ * final forward or backward slash in the parameter. If no slash
+ * is found, the current directory is searched.
+ * @param result Array to use when storing the results
+ * @param p The pool to use.
+ * @return APR_SUCCESS if no processing errors occurred, APR error
+ * code otherwise
+ * @remark The returned array may be empty even if APR_SUCCESS was
+ * returned.
+ */
+APR_DECLARE(apr_status_t) apr_match_glob(const char *dir_pattern,
+ apr_array_header_t **result,
+ apr_pool_t *p);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_APR_FNMATCH_H_ */
diff --git a/include/apr_general.h b/include/apr_general.h
new file mode 100644
index 0000000..fa073c8
--- /dev/null
+++ b/include/apr_general.h
@@ -0,0 +1,244 @@
+/* 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 APR_GENERAL_H
+#define APR_GENERAL_H
+
+/**
+ * @file apr_general.h
+ * This is collection of oddballs that didn't fit anywhere else,
+ * and might move to more appropriate headers with the release
+ * of APR 1.0.
+ * @brief APR Miscellaneous library routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+
+#if APR_HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_general Miscellaneous library routines
+ * @ingroup APR
+ * This is collection of oddballs that didn't fit anywhere else,
+ * and might move to more appropriate headers with the release
+ * of APR 1.0.
+ * @{
+ */
+
+/** FALSE */
+#ifndef FALSE
+#define FALSE 0
+#endif
+/** TRUE */
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+/** a space */
+#define APR_ASCII_BLANK '\040'
+/** a carrige return */
+#define APR_ASCII_CR '\015'
+/** a line feed */
+#define APR_ASCII_LF '\012'
+/** a tab */
+#define APR_ASCII_TAB '\011'
+
+/** signal numbers typedef */
+typedef int apr_signum_t;
+
+/**
+ * Finding offsets of elements within structures.
+ * Taken from the X code... they've sweated portability of this stuff
+ * so we don't have to. Sigh...
+ * @param p_type pointer type name
+ * @param field data field within the structure pointed to
+ * @return offset
+ */
+
+#if defined(CRAY) || (defined(__arm) && !(defined(LINUX) || defined(__FreeBSD__)))
+#ifdef __STDC__
+#define APR_OFFSET(p_type,field) _Offsetof(p_type,field)
+#else
+#ifdef CRAY2
+#define APR_OFFSET(p_type,field) \
+ (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
+
+#else /* !CRAY2 */
+
+#define APR_OFFSET(p_type,field) ((unsigned int)&(((p_type)NULL)->field))
+
+#endif /* !CRAY2 */
+#endif /* __STDC__ */
+#else /* ! (CRAY || __arm) */
+
+#define APR_OFFSET(p_type,field) \
+ ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
+
+#endif /* !CRAY */
+
+/**
+ * Finding offsets of elements within structures.
+ * @param s_type structure type name
+ * @param field data field within the structure
+ * @return offset
+ */
+#if defined(offsetof) && !defined(__cplusplus)
+#define APR_OFFSETOF(s_type,field) offsetof(s_type,field)
+#else
+#define APR_OFFSETOF(s_type,field) APR_OFFSET(s_type*,field)
+#endif
+
+#ifndef DOXYGEN
+
+/* A couple of prototypes for functions in case some platform doesn't
+ * have it
+ */
+#if (!APR_HAVE_STRCASECMP) && (APR_HAVE_STRICMP)
+#define strcasecmp(s1, s2) stricmp(s1, s2)
+#elif (!APR_HAVE_STRCASECMP)
+int strcasecmp(const char *a, const char *b);
+#endif
+
+#if (!APR_HAVE_STRNCASECMP) && (APR_HAVE_STRNICMP)
+#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
+#elif (!APR_HAVE_STRNCASECMP)
+int strncasecmp(const char *a, const char *b, size_t n);
+#endif
+
+#endif
+
+/**
+ * Alignment macros
+ */
+
+/* APR_ALIGN() is only to be used to align on a power of 2 boundary */
+#define APR_ALIGN(size, boundary) \
+ (((size) + ((boundary) - 1)) & ~((boundary) - 1))
+
+/** Default alignment */
+#define APR_ALIGN_DEFAULT(size) APR_ALIGN(size, 8)
+
+
+/**
+ * String and memory functions
+ */
+
+/* APR_STRINGIFY is defined here, and also in apr_release.h, so wrap it */
+#ifndef APR_STRINGIFY
+/** Properly quote a value as a string in the C preprocessor */
+#define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
+/** Helper macro for APR_STRINGIFY */
+#define APR_STRINGIFY_HELPER(n) #n
+#endif
+
+#if (!APR_HAVE_MEMMOVE)
+#define memmove(a,b,c) bcopy(b,a,c)
+#endif
+
+#if (!APR_HAVE_MEMCHR)
+void *memchr(const void *s, int c, size_t n);
+#endif
+
+/** @} */
+
+/**
+ * @defgroup apr_library Library initialization and termination
+ * @{
+ */
+
+/**
+ * Setup any APR internal data structures. This MUST be the first function
+ * called for any APR library. It is safe to call apr_initialize several
+ * times as long as apr_terminate() is called the same number of times.
+ * @remark See apr_app_initialize() if this is an application, rather than
+ * a library consumer of apr.
+ */
+APR_DECLARE(apr_status_t) apr_initialize(void);
+
+/**
+ * Set up an application with normalized argc, argv (and optionally env) in
+ * order to deal with platform-specific oddities, such as Win32 services,
+ * code pages and signals. This must be the first function called for any
+ * APR program.
+ * @param argc Pointer to the argc that may be corrected
+ * @param argv Pointer to the argv that may be corrected
+ * @param env Pointer to the env that may be corrected, may be NULL
+ * @remark See apr_initialize() if this is a library consumer of apr.
+ * Otherwise, this call is identical to apr_initialize(), and must be closed
+ * with a call to apr_terminate() at the end of program execution.
+ */
+APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
+ char const * const * *argv,
+ char const * const * *env);
+
+/**
+ * Tear down any APR internal data structures which aren't torn down
+ * automatically. apr_terminate must be called once for every call to
+ * apr_initialize() or apr_app_initialize().
+ * @remark An APR program must call this function at termination once it
+ * has stopped using APR services. The APR developers suggest using
+ * @c atexit(apr_terminate) to ensure this is called. When using APR
+ * from a language other than C that has problems with the calling
+ * convention, use apr_terminate2() instead.
+ * @see apr_terminate2
+ */
+APR_DECLARE_NONSTD(void) apr_terminate(void);
+
+/**
+ * Tear down any APR internal data structures which aren't torn down
+ * automatically, same as apr_terminate()
+ * @remark An APR program must call either the apr_terminate() or apr_terminate2
+ * function once it it has finished using APR services. The APR
+ * developers suggest using @c atexit(apr_terminate) to ensure this is done.
+ * apr_terminate2 exists to allow non-c language apps to tear down apr,
+ * while apr_terminate() is recommended from c language applications.
+ */
+APR_DECLARE(void) apr_terminate2(void);
+
+/** @} */
+
+/**
+ * @defgroup apr_random Random Functions
+ * @{
+ */
+
+#if APR_HAS_RANDOM || defined(DOXYGEN)
+
+/* TODO: I'm not sure this is the best place to put this prototype...*/
+/**
+ * Generate random bytes.
+ * @param buf Buffer to fill with random bytes
+ * @param length Length of buffer in bytes
+ */
+APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char * buf,
+ apr_size_t length);
+
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_GENERAL_H */
diff --git a/include/apr_getopt.h b/include/apr_getopt.h
new file mode 100644
index 0000000..75ad566
--- /dev/null
+++ b/include/apr_getopt.h
@@ -0,0 +1,160 @@
+/* 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 APR_GETOPT_H
+#define APR_GETOPT_H
+
+/**
+ * @file apr_getopt.h
+ * @brief APR Command Arguments (getopt)
+ */
+
+#include "apr_pools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_getopt Command Argument Parsing
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * An @c apr_getopt_t error callback function.
+ *
+ * @a arg is this @c apr_getopt_t's @c errarg member.
+ */
+typedef void (apr_getopt_err_fn_t)(void *arg, const char *err, ...);
+
+/** @see apr_getopt_t */
+typedef struct apr_getopt_t apr_getopt_t;
+
+/**
+ * Structure to store command line argument information.
+ */
+struct apr_getopt_t {
+ /** context for processing */
+ apr_pool_t *cont;
+ /** function to print error message (NULL == no messages) */
+ apr_getopt_err_fn_t *errfn;
+ /** user defined first arg to pass to error message */
+ void *errarg;
+ /** index into parent argv vector */
+ int ind;
+ /** character checked for validity */
+ int opt;
+ /** reset getopt */
+ int reset;
+ /** count of arguments */
+ int argc;
+ /** array of pointers to arguments */
+ const char **argv;
+ /** argument associated with option */
+ char const* place;
+ /** set to nonzero to support interleaving options with regular args */
+ int interleave;
+ /** start of non-option arguments skipped for interleaving */
+ int skip_start;
+ /** end of non-option arguments skipped for interleaving */
+ int skip_end;
+};
+
+/** @see apr_getopt_option_t */
+typedef struct apr_getopt_option_t apr_getopt_option_t;
+
+/**
+ * Structure used to describe options that getopt should search for.
+ */
+struct apr_getopt_option_t {
+ /** long option name, or NULL if option has no long name */
+ const char *name;
+ /** option letter, or a value greater than 255 if option has no letter */
+ int optch;
+ /** nonzero if option takes an argument */
+ int has_arg;
+ /** a description of the option */
+ const char *description;
+};
+
+/**
+ * Initialize the arguments for parsing by apr_getopt().
+ * @param os The options structure created for apr_getopt()
+ * @param cont The pool to operate on
+ * @param argc The number of arguments to parse
+ * @param argv The array of arguments to parse
+ * @remark Arguments 3 and 4 are most commonly argc and argv from main(argc, argv)
+ * The (*os)->errfn is initialized to fprintf(stderr... but may be overridden.
+ */
+APR_DECLARE(apr_status_t) apr_getopt_init(apr_getopt_t **os, apr_pool_t *cont,
+ int argc, const char * const *argv);
+
+/**
+ * Parse the options initialized by apr_getopt_init().
+ * @param os The apr_opt_t structure returned by apr_getopt_init()
+ * @param opts A string of characters that are acceptable options to the
+ * program. Characters followed by ":" are required to have an
+ * option associated
+ * @param option_ch The next option character parsed
+ * @param option_arg The argument following the option character:
+ * @return There are four potential status values on exit. They are:
+ * <PRE>
+ * APR_EOF -- No more options to parse
+ * APR_BADCH -- Found a bad option character
+ * APR_BADARG -- No argument followed the option flag
+ * APR_SUCCESS -- The next option was found.
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_getopt(apr_getopt_t *os, const char *opts,
+ char *option_ch, const char **option_arg);
+
+/**
+ * Parse the options initialized by apr_getopt_init(), accepting long
+ * options beginning with "--" in addition to single-character
+ * options beginning with "-".
+ * @param os The apr_getopt_t structure created by apr_getopt_init()
+ * @param opts A pointer to a list of apr_getopt_option_t structures, which
+ * can be initialized with { "name", optch, has_args }. has_args
+ * is nonzero if the option requires an argument. A structure
+ * with an optch value of 0 terminates the list.
+ * @param option_ch Receives the value of "optch" from the apr_getopt_option_t
+ * structure corresponding to the next option matched.
+ * @param option_arg Receives the argument following the option, if any.
+ * @return There are four potential status values on exit. They are:
+ * <PRE>
+ * APR_EOF -- No more options to parse
+ * APR_BADCH -- Found a bad option character
+ * APR_BADARG -- No argument followed the option flag
+ * APR_SUCCESS -- The next option was found.
+ * </PRE>
+ * When APR_SUCCESS is returned, os->ind gives the index of the first
+ * non-option argument. On error, a message will be printed to stdout unless
+ * os->err is set to 0. If os->interleave is set to nonzero, options can come
+ * after arguments, and os->argv will be permuted to leave non-option arguments
+ * at the end (the original argv is unaffected).
+ */
+APR_DECLARE(apr_status_t) apr_getopt_long(apr_getopt_t *os,
+ const apr_getopt_option_t *opts,
+ int *option_ch,
+ const char **option_arg);
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_GETOPT_H */
diff --git a/include/apr_global_mutex.h b/include/apr_global_mutex.h
new file mode 100644
index 0000000..e3cba23
--- /dev/null
+++ b/include/apr_global_mutex.h
@@ -0,0 +1,195 @@
+/* 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 APR_GLOBAL_MUTEX_H
+#define APR_GLOBAL_MUTEX_H
+
+/**
+ * @file apr_global_mutex.h
+ * @brief APR Global Locking Routines
+ */
+
+#include "apr.h"
+#include "apr_proc_mutex.h" /* only for apr_lockmech_e */
+#include "apr_pools.h"
+#include "apr_errno.h"
+#if APR_PROC_MUTEX_IS_GLOBAL
+#include "apr_proc_mutex.h"
+#endif
+#include "apr_time.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup APR_GlobalMutex Global Locking Routines
+ * @ingroup APR
+ * @{
+ */
+
+#if !APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN)
+
+/** Opaque global mutex structure. */
+typedef struct apr_global_mutex_t apr_global_mutex_t;
+
+/* Function definitions */
+
+/**
+ * Create and initialize a mutex that can be used to synchronize both
+ * processes and threads. Note: There is considerable overhead in using
+ * this API if only cross-process or cross-thread mutual exclusion is
+ * required. See apr_proc_mutex.h and apr_thread_mutex.h for more
+ * specialized lock routines.
+ * @param mutex the memory address where the newly created mutex will be
+ * stored.
+ * @param fname A file name to use if the lock mechanism requires one. This
+ * argument should always be provided. The lock code itself will
+ * determine if it should be used.
+ * @param mech The mechanism to use for the interprocess lock, if any; one of
+ * <PRE>
+ * APR_LOCK_FCNTL
+ * APR_LOCK_FLOCK
+ * APR_LOCK_SYSVSEM
+ * APR_LOCK_POSIXSEM
+ * APR_LOCK_PROC_PTHREAD
+ * APR_LOCK_DEFAULT pick the default mechanism for the platform
+ * APR_LOCK_DEFAULT_TIMED pick the default timed mechanism
+ * </PRE>
+ * @param pool the pool from which to allocate the mutex.
+ * @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
+ * APR_LOCK_foo. Only APR_LOCK_DEFAULT is portable.
+ */
+APR_DECLARE(apr_status_t) apr_global_mutex_create(apr_global_mutex_t **mutex,
+ const char *fname,
+ apr_lockmech_e mech,
+ apr_pool_t *pool);
+
+/**
+ * Re-open a mutex in a child process.
+ * @param mutex The newly re-opened mutex structure.
+ * @param fname A file name to use if the mutex mechanism requires one. This
+ * argument should always be provided. The mutex code itself will
+ * determine if it should be used. This filename should be the
+ * same one that was passed to apr_global_mutex_create().
+ * @param pool The pool to operate on.
+ * @remark This function must be called to maintain portability, even
+ * if the underlying lock mechanism does not require it.
+ */
+APR_DECLARE(apr_status_t) apr_global_mutex_child_init(
+ apr_global_mutex_t **mutex,
+ const char *fname,
+ apr_pool_t *pool);
+
+/**
+ * Acquire the lock for the given mutex. If the mutex is already locked,
+ * the current thread will be put to sleep until the lock becomes available.
+ * @param mutex the mutex on which to acquire the lock.
+ */
+APR_DECLARE(apr_status_t) apr_global_mutex_lock(apr_global_mutex_t *mutex);
+
+/**
+ * Attempt to acquire the lock for the given mutex. If the mutex has already
+ * been acquired, the call returns immediately with APR_EBUSY. Note: it
+ * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
+ * if the return value was APR_EBUSY, for portability reasons.
+ * @param mutex the mutex on which to attempt the lock acquiring.
+ */
+APR_DECLARE(apr_status_t) apr_global_mutex_trylock(apr_global_mutex_t *mutex);
+
+/**
+ * Attempt to acquire the lock for the given mutex until timeout expires.
+ * If the acquisition time outs, the call returns with APR_TIMEUP.
+ * @param mutex the mutex on which to attempt the lock acquiring.
+ * @param timeout the relative timeout (microseconds).
+ * @note A negative or nul timeout means immediate attempt, returning
+ * APR_TIMEUP without blocking if it the lock is already acquired.
+ */
+APR_DECLARE(apr_status_t) apr_global_mutex_timedlock(apr_global_mutex_t *mutex,
+ apr_interval_time_t timeout);
+
+/**
+ * Release the lock for the given mutex.
+ * @param mutex the mutex from which to release the lock.
+ */
+APR_DECLARE(apr_status_t) apr_global_mutex_unlock(apr_global_mutex_t *mutex);
+
+/**
+ * Destroy the mutex and free the memory associated with the lock.
+ * @param mutex the mutex to destroy.
+ */
+APR_DECLARE(apr_status_t) apr_global_mutex_destroy(apr_global_mutex_t *mutex);
+
+/**
+ * Return the name of the lockfile for the mutex, or NULL
+ * if the mutex doesn't use a lock file
+ */
+APR_DECLARE(const char *) apr_global_mutex_lockfile(apr_global_mutex_t *mutex);
+
+/**
+ * Get the mechanism of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism from.
+ */
+APR_DECLARE(apr_lockmech_e) apr_global_mutex_mech(apr_global_mutex_t *mutex);
+
+/**
+ * Get the mechanism's name of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism's name from.
+ */
+APR_DECLARE(const char *) apr_global_mutex_name(apr_global_mutex_t *mutex);
+
+/**
+ * Set mutex permissions.
+ */
+APR_PERMS_SET_IMPLEMENT(global_mutex);
+
+/**
+ * Get the pool used by this global_mutex.
+ * @return apr_pool_t the pool
+ */
+APR_POOL_DECLARE_ACCESSOR(global_mutex);
+
+#else /* APR_PROC_MUTEX_IS_GLOBAL */
+
+/* Some platforms [e.g. Win32] have cross process locks that are truly
+ * global locks, since there isn't the concept of cross-process locks.
+ * Define these platforms in terms of an apr_proc_mutex_t.
+ */
+
+#define apr_global_mutex_t apr_proc_mutex_t
+#define apr_global_mutex_create apr_proc_mutex_create
+#define apr_global_mutex_child_init apr_proc_mutex_child_init
+#define apr_global_mutex_lock apr_proc_mutex_lock
+#define apr_global_mutex_trylock apr_proc_mutex_trylock
+#define apr_global_mutex_unlock apr_proc_mutex_unlock
+#define apr_global_mutex_destroy apr_proc_mutex_destroy
+#define apr_global_mutex_lockfile apr_proc_mutex_lockfile
+#define apr_global_mutex_mech apr_proc_mutex_mech
+#define apr_global_mutex_name apr_proc_mutex_name
+#define apr_global_mutex_perms_set apr_proc_mutex_perms_set
+#define apr_global_mutex_pool_get apr_proc_mutex_pool_get
+
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef APR_GLOBAL_MUTEX_H */
diff --git a/include/apr_hash.h b/include/apr_hash.h
new file mode 100644
index 0000000..cced5be
--- /dev/null
+++ b/include/apr_hash.h
@@ -0,0 +1,283 @@
+/* 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 APR_HASH_H
+#define APR_HASH_H
+
+/**
+ * @file apr_hash.h
+ * @brief APR Hash Tables
+ */
+
+#include "apr_pools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup apr_hash Hash Tables
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * When passing a key to apr_hash_set or apr_hash_get, this value can be
+ * passed to indicate a string-valued key, and have apr_hash compute the
+ * length automatically.
+ *
+ * @remark apr_hash will use strlen(key) for the length. The NUL terminator
+ * is not included in the hash value (why throw a constant in?).
+ * Since the hash table merely references the provided key (rather
+ * than copying it), apr_hash_this() will return the NUL-term'd key.
+ */
+#define APR_HASH_KEY_STRING (-1)
+
+/**
+ * Abstract type for hash tables.
+ */
+typedef struct apr_hash_t apr_hash_t;
+
+/**
+ * Abstract type for scanning hash tables.
+ */
+typedef struct apr_hash_index_t apr_hash_index_t;
+
+/**
+ * Callback functions for calculating hash values.
+ * @param key The key.
+ * @param klen The length of the key, or APR_HASH_KEY_STRING to use the string
+ * length. If APR_HASH_KEY_STRING then returns the actual key length.
+ */
+typedef unsigned int (*apr_hashfunc_t)(const char *key, apr_ssize_t *klen);
+
+/**
+ * The default hash function.
+ */
+APR_DECLARE_NONSTD(unsigned int) apr_hashfunc_default(const char *key,
+ apr_ssize_t *klen);
+
+/**
+ * Create a hash table.
+ * @param pool The pool to allocate the hash table out of
+ * @return The hash table just created
+ */
+APR_DECLARE(apr_hash_t *) apr_hash_make(apr_pool_t *pool);
+
+/**
+ * Create a hash table with a custom hash function
+ * @param pool The pool to allocate the hash table out of
+ * @param hash_func A custom hash function.
+ * @return The hash table just created
+ */
+APR_DECLARE(apr_hash_t *) apr_hash_make_custom(apr_pool_t *pool,
+ apr_hashfunc_t hash_func);
+
+/**
+ * Make a copy of a hash table
+ * @param pool The pool from which to allocate the new hash table
+ * @param h The hash table to clone
+ * @return The hash table just created
+ * @remark Makes a shallow copy
+ */
+APR_DECLARE(apr_hash_t *) apr_hash_copy(apr_pool_t *pool,
+ const apr_hash_t *h);
+
+/**
+ * Associate a value with a key in a hash table.
+ * @param ht The hash table
+ * @param key Pointer to the key
+ * @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
+ * @param val Value to associate with the key
+ * @remark If the value is NULL the hash entry is deleted. The key is stored as is,
+ * and so must have a lifetime at least as long as the hash table's pool.
+ */
+APR_DECLARE(void) apr_hash_set(apr_hash_t *ht, const void *key,
+ apr_ssize_t klen, const void *val);
+
+/**
+ * Look up the value associated with a key in a hash table.
+ * @param ht The hash table
+ * @param key Pointer to the key
+ * @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
+ * @return Returns NULL if the key is not present.
+ */
+APR_DECLARE(void *) apr_hash_get(apr_hash_t *ht, const void *key,
+ apr_ssize_t klen);
+
+/**
+ * Start iterating over the entries in a hash table.
+ * @param p The pool to allocate the apr_hash_index_t iterator. If this
+ * pool is NULL, then an internal, non-thread-safe iterator is used.
+ * @param ht The hash table
+ * @return The iteration state
+ * @remark There is no restriction on adding or deleting hash entries during
+ * an iteration (although the results may be unpredictable unless all you do
+ * is delete the current entry) and multiple iterations can be in
+ * progress at the same time.
+ *
+ * @par Example:
+ *
+ * @code
+ * int sum_values(apr_pool_t *p, apr_hash_t *ht)
+ * {
+ * apr_hash_index_t *hi;
+ * void *val;
+ * int sum = 0;
+ * for (hi = apr_hash_first(p, ht); hi; hi = apr_hash_next(hi)) {
+ * apr_hash_this(hi, NULL, NULL, &val);
+ * sum += *(int *)val;
+ * }
+ * return sum;
+ * }
+ * @endcode
+ */
+APR_DECLARE(apr_hash_index_t *) apr_hash_first(apr_pool_t *p, apr_hash_t *ht);
+
+/**
+ * Continue iterating over the entries in a hash table.
+ * @param hi The iteration state
+ * @return a pointer to the updated iteration state. NULL if there are no more
+ * entries.
+ */
+APR_DECLARE(apr_hash_index_t *) apr_hash_next(apr_hash_index_t *hi);
+
+/**
+ * Get the current entry's details from the iteration state.
+ * @param hi The iteration state
+ * @param key Return pointer for the pointer to the key.
+ * @param klen Return pointer for the key length.
+ * @param val Return pointer for the associated value.
+ * @remark The return pointers should point to a variable that will be set to the
+ * corresponding data, or they may be NULL if the data isn't interesting.
+ */
+APR_DECLARE(void) apr_hash_this(apr_hash_index_t *hi, const void **key,
+ apr_ssize_t *klen, void **val);
+
+/**
+ * Get the current entry's key from the iteration state.
+ * @param hi The iteration state
+ * @return The pointer to the key
+ */
+APR_DECLARE(const void*) apr_hash_this_key(apr_hash_index_t *hi);
+
+/**
+ * Get the current entry's key length from the iteration state.
+ * @param hi The iteration state
+ * @return The key length
+ */
+APR_DECLARE(apr_ssize_t) apr_hash_this_key_len(apr_hash_index_t *hi);
+
+/**
+ * Get the current entry's value from the iteration state.
+ * @param hi The iteration state
+ * @return The pointer to the value
+ */
+APR_DECLARE(void*) apr_hash_this_val(apr_hash_index_t *hi);
+
+/**
+ * Get the number of key/value pairs in the hash table.
+ * @param ht The hash table
+ * @return The number of key/value pairs in the hash table.
+ */
+APR_DECLARE(unsigned int) apr_hash_count(apr_hash_t *ht);
+
+/**
+ * Clear any key/value pairs in the hash table.
+ * @param ht The hash table
+ */
+APR_DECLARE(void) apr_hash_clear(apr_hash_t *ht);
+
+/**
+ * Merge two hash tables into one new hash table. The values of the overlay
+ * hash override the values of the base if both have the same key. Both
+ * hash tables must use the same hash function.
+ * @param p The pool to use for the new hash table
+ * @param overlay The table to add to the initial table
+ * @param base The table that represents the initial values of the new table
+ * @return A new hash table containing all of the data from the two passed in
+ */
+APR_DECLARE(apr_hash_t *) apr_hash_overlay(apr_pool_t *p,
+ const apr_hash_t *overlay,
+ const apr_hash_t *base);
+
+/**
+ * Merge two hash tables into one new hash table. If the same key
+ * is present in both tables, call the supplied merge function to
+ * produce a merged value for the key in the new table. Both
+ * hash tables must use the same hash function.
+ * @param p The pool to use for the new hash table
+ * @param h1 The first of the tables to merge
+ * @param h2 The second of the tables to merge
+ * @param merger A callback function to merge values, or NULL to
+ * make values from h1 override values from h2 (same semantics as
+ * apr_hash_overlay())
+ * @param data Client data to pass to the merger function
+ * @return A new hash table containing all of the data from the two passed in
+ */
+APR_DECLARE(apr_hash_t *) apr_hash_merge(apr_pool_t *p,
+ const apr_hash_t *h1,
+ const apr_hash_t *h2,
+ void * (*merger)(apr_pool_t *p,
+ const void *key,
+ apr_ssize_t klen,
+ const void *h1_val,
+ const void *h2_val,
+ const void *data),
+ const void *data);
+
+/**
+ * Declaration prototype for the iterator callback function of apr_hash_do().
+ *
+ * @param rec The data passed as the first argument to apr_hash_[v]do()
+ * @param key The key from this iteration of the hash table
+ * @param klen The key length from this iteration of the hash table
+ * @param value The value from this iteration of the hash table
+ * @remark Iteration continues while this callback function returns non-zero.
+ * To export the callback function for apr_hash_do() it must be declared
+ * in the _NONSTD convention.
+ */
+typedef int (apr_hash_do_callback_fn_t)(void *rec, const void *key,
+ apr_ssize_t klen,
+ const void *value);
+
+/**
+ * Iterate over a hash table running the provided function once for every
+ * element in the hash table. The @p comp function will be invoked for
+ * every element in the hash table.
+ *
+ * @param comp The function to run
+ * @param rec The data to pass as the first argument to the function
+ * @param ht The hash table to iterate over
+ * @return FALSE if one of the comp() iterations returned zero; TRUE if all
+ * iterations returned non-zero
+ * @see apr_hash_do_callback_fn_t
+ */
+APR_DECLARE(int) apr_hash_do(apr_hash_do_callback_fn_t *comp,
+ void *rec, const apr_hash_t *ht);
+
+/**
+ * Get a pointer to the pool which the hash table was created in
+ */
+APR_POOL_DECLARE_ACCESSOR(hash);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_HASH_H */
diff --git a/include/apr_inherit.h b/include/apr_inherit.h
new file mode 100644
index 0000000..b9fe56f
--- /dev/null
+++ b/include/apr_inherit.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 APR_INHERIT_H
+#define APR_INHERIT_H
+
+/**
+ * @file apr_inherit.h
+ * @brief APR File Handle Inheritance Helpers
+ * @remark This internal header includes internal declaration helpers
+ * for other headers to declare apr_foo_inherit_[un]set functions.
+ */
+
+/**
+ * Prototype for type-specific declarations of apr_foo_inherit_set
+ * functions.
+ * @remark Doxygen unwraps this macro (via doxygen.conf) to provide
+ * actual help for each specific occurrence of apr_foo_inherit_set.
+ * @remark the linkage is specified for APR. It would be possible to expand
+ * the macros to support other linkages.
+ */
+#define APR_DECLARE_INHERIT_SET(type) \
+ APR_DECLARE(apr_status_t) apr_##type##_inherit_set( \
+ apr_##type##_t *the##type)
+
+/**
+ * Prototype for type-specific declarations of apr_foo_inherit_unset
+ * functions.
+ * @remark Doxygen unwraps this macro (via doxygen.conf) to provide
+ * actual help for each specific occurrence of apr_foo_inherit_unset.
+ * @remark the linkage is specified for APR. It would be possible to expand
+ * the macros to support other linkages.
+ */
+#define APR_DECLARE_INHERIT_UNSET(type) \
+ APR_DECLARE(apr_status_t) apr_##type##_inherit_unset( \
+ apr_##type##_t *the##type)
+
+#endif /* ! APR_INHERIT_H */
diff --git a/include/apr_lib.h b/include/apr_lib.h
new file mode 100644
index 0000000..466e818
--- /dev/null
+++ b/include/apr_lib.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.
+ */
+
+#ifndef APR_LIB_H
+#define APR_LIB_H
+
+/**
+ * @file apr_lib.h
+ * This is collection of oddballs that didn't fit anywhere else,
+ * and might move to more appropriate headers with the release
+ * of APR 1.0.
+ * @brief APR general purpose library routines
+ */
+
+#include "apr.h"
+#include "apr_errno.h"
+
+#if APR_HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#if APR_HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_lib General Purpose Library Routines
+ * @ingroup APR
+ * This is collection of oddballs that didn't fit anywhere else,
+ * and might move to more appropriate headers with the release
+ * of APR 1.0.
+ * @{
+ */
+
+/** A constant representing a 'large' string. */
+#define HUGE_STRING_LEN 8192
+
+/*
+ * Define the structures used by the APR general-purpose library.
+ */
+
+/** @see apr_vformatter_buff_t */
+typedef struct apr_vformatter_buff_t apr_vformatter_buff_t;
+
+/**
+ * Structure used by the variable-formatter routines.
+ */
+struct apr_vformatter_buff_t {
+ /** The current position */
+ char *curpos;
+ /** The end position of the format string */
+ char *endpos;
+};
+
+/**
+ * return the final element of the pathname
+ * @param pathname The path to get the final element of
+ * @return the final element of the path
+ * @remark
+ * <PRE>
+ * For example:
+ * "/foo/bar/gum" -> "gum"
+ * "/foo/bar/gum/" -> ""
+ * "gum" -> "gum"
+ * "bs\\path\\stuff" -> "stuff"
+ * </PRE>
+ */
+APR_DECLARE(const char *) apr_filepath_name_get(const char *pathname);
+
+/**
+ * apr_killpg
+ * Small utility macros to make things easier to read. Not usually a
+ * goal, to be sure..
+ */
+
+#ifdef WIN32
+#define apr_killpg(x, y)
+#else /* WIN32 */
+#ifdef NO_KILLPG
+#define apr_killpg(x, y) (kill (-(x), (y)))
+#else /* NO_KILLPG */
+#define apr_killpg(x, y) (killpg ((x), (y)))
+#endif /* NO_KILLPG */
+#endif /* WIN32 */
+
+/**
+ * apr_vformatter() is a generic printf-style formatting routine
+ * with some extensions.
+ * @param flush_func The function to call when the buffer is full
+ * @param c The buffer to write to
+ * @param fmt The format string
+ * @param ap The arguments to use to fill out the format string.
+ *
+ * @remark
+ * <PRE>
+ * The extensions are:
+ *
+ * - %%pA takes a struct in_addr *, and prints it as a.b.c.d
+ * - %%pI takes an apr_sockaddr_t * and prints it as a.b.c.d:port or
+ * \[ipv6-address\]:port
+ * - %%pT takes an apr_os_thread_t * and prints it in decimal
+ * ('0' is printed if !APR_HAS_THREADS)
+ * - %%pt takes an apr_os_thread_t * and prints it in hexadecimal
+ * ('0' is printed if !APR_HAS_THREADS)
+ * - %%pm takes an apr_status_t * and prints the appropriate error
+ * string (from apr_strerror) corresponding to that error code.
+ * - %%pp takes a void * and outputs it in hex
+ * - %%pB takes a apr_uint32_t * as bytes and outputs it's apr_strfsize
+ * - %%pF same as above, but takes a apr_off_t *
+ * - %%pS same as above, but takes a apr_size_t *
+ *
+ * %%pA, %%pI, %%pT, %%pp are available from APR 1.0.0 onwards (and in 0.9.x).
+ * %%pt is only available from APR 1.2.0 onwards.
+ * %%pm, %%pB, %%pF and %%pS are only available from APR 1.3.0 onwards.
+ *
+ * The %%p hacks are to force gcc's printf warning code to skip
+ * over a pointer argument without complaining. This does
+ * mean that the ANSI-style %%p (output a void * in hex format) won't
+ * work as expected at all, but that seems to be a fair trade-off
+ * for the increased robustness of having printf-warnings work.
+ *
+ * Additionally, apr_vformatter allows for arbitrary output methods
+ * using the apr_vformatter_buff and flush_func.
+ *
+ * The apr_vformatter_buff has two elements curpos and endpos.
+ * curpos is where apr_vformatter will write the next byte of output.
+ * It proceeds writing output to curpos, and updating curpos, until
+ * either the end of output is reached, or curpos == endpos (i.e. the
+ * buffer is full).
+ *
+ * If the end of output is reached, apr_vformatter returns the
+ * number of bytes written.
+ *
+ * When the buffer is full, the flush_func is called. The flush_func
+ * can return -1 to indicate that no further output should be attempted,
+ * and apr_vformatter will return immediately with -1. Otherwise
+ * the flush_func should flush the buffer in whatever manner is
+ * appropriate, re apr_pool_t nitialize curpos and endpos, and return 0.
+ *
+ * Note that flush_func is only invoked as a result of attempting to
+ * write another byte at curpos when curpos >= endpos. So for
+ * example, it's possible when the output exactly matches the buffer
+ * space available that curpos == endpos will be true when
+ * apr_vformatter returns.
+ *
+ * apr_vformatter does not call out to any other code, it is entirely
+ * self-contained. This allows the callers to do things which are
+ * otherwise "unsafe". For example, apr_psprintf uses the "scratch"
+ * space at the unallocated end of a block, and doesn't actually
+ * complete the allocation until apr_vformatter returns. apr_psprintf
+ * would be completely broken if apr_vformatter were to call anything
+ * that used this same pool. Similarly http_bprintf() uses the "scratch"
+ * space at the end of its output buffer, and doesn't actually note
+ * that the space is in use until it either has to flush the buffer
+ * or until apr_vformatter returns.
+ * </PRE>
+ */
+APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *b),
+ apr_vformatter_buff_t *c, const char *fmt,
+ va_list ap);
+
+/**
+ * Display a prompt and read in the password from stdin.
+ * @param prompt The prompt to display
+ * @param pwbuf Buffer to store the password
+ * @param bufsize The length of the password buffer.
+ * @remark If the password entered must be truncated to fit in
+ * the provided buffer, APR_ENAMETOOLONG will be returned.
+ * Note that the bufsize paramater is passed by reference for no
+ * reason; its value will never be modified by the apr_password_get()
+ * function.
+ */
+APR_DECLARE(apr_status_t) apr_password_get(const char *prompt, char *pwbuf,
+ apr_size_t *bufsize);
+
+/** @} */
+
+/**
+ * @defgroup apr_ctype ctype functions
+ * These macros allow correct support of 8-bit characters on systems which
+ * support 8-bit characters. Pretty dumb how the cast is required, but
+ * that's legacy libc for ya. These new macros do not support EOF like
+ * the standard macros do. Tough.
+ * @{
+ */
+/** @see isalnum */
+#define apr_isalnum(c) (isalnum(((unsigned char)(c))))
+/** @see isalpha */
+#define apr_isalpha(c) (isalpha(((unsigned char)(c))))
+/** @see iscntrl */
+#define apr_iscntrl(c) (iscntrl(((unsigned char)(c))))
+/** @see isdigit */
+#define apr_isdigit(c) (isdigit(((unsigned char)(c))))
+/** @see isgraph */
+#define apr_isgraph(c) (isgraph(((unsigned char)(c))))
+/** @see islower*/
+#define apr_islower(c) (islower(((unsigned char)(c))))
+/** @see isascii */
+#ifdef isascii
+#define apr_isascii(c) (isascii(((unsigned char)(c))))
+#else
+#define apr_isascii(c) (((c) & ~0x7f)==0)
+#endif
+/** @see isprint */
+#define apr_isprint(c) (isprint(((unsigned char)(c))))
+/** @see ispunct */
+#define apr_ispunct(c) (ispunct(((unsigned char)(c))))
+/** @see isspace */
+#define apr_isspace(c) (isspace(((unsigned char)(c))))
+/** @see isupper */
+#define apr_isupper(c) (isupper(((unsigned char)(c))))
+/** @see isxdigit */
+#define apr_isxdigit(c) (isxdigit(((unsigned char)(c))))
+/** @see tolower */
+#define apr_tolower(c) (tolower(((unsigned char)(c))))
+/** @see toupper */
+#define apr_toupper(c) (toupper(((unsigned char)(c))))
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_LIB_H */
diff --git a/include/apr_mmap.h b/include/apr_mmap.h
new file mode 100644
index 0000000..c14de19
--- /dev/null
+++ b/include/apr_mmap.h
@@ -0,0 +1,171 @@
+/* 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 APR_MMAP_H
+#define APR_MMAP_H
+
+/**
+ * @file apr_mmap.h
+ * @brief APR MMAP routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_ring.h"
+#include "apr_file_io.h" /* for apr_file_t */
+
+#ifdef BEOS
+#include <kernel/OS.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_mmap MMAP (Memory Map) Routines
+ * @ingroup APR
+ * @{
+ */
+
+/** MMap opened for reading */
+#define APR_MMAP_READ 1
+/** MMap opened for writing */
+#define APR_MMAP_WRITE 2
+
+/** @see apr_mmap_t */
+typedef struct apr_mmap_t apr_mmap_t;
+
+/**
+ * @remark
+ * As far as I can tell the only really sane way to store an MMAP is as a
+ * void * and a length. BeOS requires this area_id, but that's just a little
+ * something extra. I am exposing this type, because it doesn't make much
+ * sense to keep it private, and opening it up makes some stuff easier in
+ * Apache.
+ */
+/** The MMAP structure */
+struct apr_mmap_t {
+ /** The pool the mmap structure was allocated out of. */
+ apr_pool_t *cntxt;
+#ifdef BEOS
+ /** An area ID. Only valid on BeOS */
+ area_id area;
+#endif
+#ifdef WIN32
+ /** The handle of the file mapping */
+ HANDLE mhandle;
+ /** The start of the real memory page area (mapped view) */
+ void *mv;
+ /** The physical start, size and offset */
+ apr_off_t pstart;
+ apr_size_t psize;
+ apr_off_t poffset;
+#endif
+ /** The start of the memory mapped area */
+ void *mm;
+ /** The amount of data in the mmap */
+ apr_size_t size;
+ /** ring of apr_mmap_t's that reference the same
+ * mmap'ed region; acts in place of a reference count */
+ APR_RING_ENTRY(apr_mmap_t) link;
+};
+
+#if APR_HAS_MMAP || defined(DOXYGEN)
+
+/** @def APR_MMAP_THRESHOLD
+ * Files have to be at least this big before they're mmap()d. This is to deal
+ * with systems where the expense of doing an mmap() and an munmap() outweighs
+ * the benefit for small files. It shouldn't be set lower than 1.
+ */
+#ifdef MMAP_THRESHOLD
+# define APR_MMAP_THRESHOLD MMAP_THRESHOLD
+#else
+# ifdef SUNOS4
+# define APR_MMAP_THRESHOLD (8*1024)
+# else
+# define APR_MMAP_THRESHOLD 1
+# endif /* SUNOS4 */
+#endif /* MMAP_THRESHOLD */
+
+/** @def APR_MMAP_LIMIT
+ * Maximum size of MMap region
+ */
+#ifdef MMAP_LIMIT
+# define APR_MMAP_LIMIT MMAP_LIMIT
+#else
+# define APR_MMAP_LIMIT (4*1024*1024)
+#endif /* MMAP_LIMIT */
+
+/** Can this file be MMaped */
+#define APR_MMAP_CANDIDATE(filelength) \
+ ((filelength >= APR_MMAP_THRESHOLD) && (filelength < APR_MMAP_LIMIT))
+
+/* Function definitions */
+
+/**
+ * Create a new mmap'ed file out of an existing APR file.
+ * @param newmmap The newly created mmap'ed file.
+ * @param file The file to turn into an mmap.
+ * @param offset The offset into the file to start the data pointer at.
+ * @param size The size of the file
+ * @param flag bit-wise or of:
+ * <PRE>
+ * APR_MMAP_READ MMap opened for reading
+ * APR_MMAP_WRITE MMap opened for writing
+ * </PRE>
+ * @param cntxt The pool to use when creating the mmap.
+ */
+APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **newmmap,
+ apr_file_t *file, apr_off_t offset,
+ apr_size_t size, apr_int32_t flag,
+ apr_pool_t *cntxt);
+
+/**
+ * Duplicate the specified MMAP.
+ * @param new_mmap The structure to duplicate into.
+ * @param old_mmap The mmap to duplicate.
+ * @param p The pool to use for new_mmap.
+ */
+APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap,
+ apr_mmap_t *old_mmap,
+ apr_pool_t *p);
+
+/**
+ * Remove a mmap'ed.
+ * @param mm The mmap'ed file.
+ */
+APR_DECLARE(apr_status_t) apr_mmap_delete(apr_mmap_t *mm);
+
+/**
+ * Move the pointer into the mmap'ed file to the specified offset.
+ * @param addr The pointer to the offset specified.
+ * @param mm The mmap'ed file.
+ * @param offset The offset to move to.
+ */
+APR_DECLARE(apr_status_t) apr_mmap_offset(void **addr, apr_mmap_t *mm,
+ apr_off_t offset);
+
+#endif /* APR_HAS_MMAP */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_MMAP_H */
diff --git a/include/apr_network_io.h b/include/apr_network_io.h
new file mode 100644
index 0000000..d61e424
--- /dev/null
+++ b/include/apr_network_io.h
@@ -0,0 +1,953 @@
+/* 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 APR_NETWORK_IO_H
+#define APR_NETWORK_IO_H
+/**
+ * @file apr_network_io.h
+ * @brief APR Network library
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_file_io.h"
+#include "apr_errno.h"
+#include "apr_inherit.h"
+#include "apr_perms_set.h"
+
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if APR_HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_network_io Network Routines
+ * @ingroup APR
+ * @{
+ */
+
+#ifndef APR_MAX_SECS_TO_LINGER
+/** Maximum seconds to linger */
+#define APR_MAX_SECS_TO_LINGER 30
+#endif
+
+#ifndef APRMAXHOSTLEN
+/** Maximum hostname length */
+#define APRMAXHOSTLEN 256
+#endif
+
+#ifndef APR_ANYADDR
+/** Default 'any' address */
+#define APR_ANYADDR "0.0.0.0"
+#endif
+
+/**
+ * @defgroup apr_sockopt Socket option definitions
+ * @{
+ */
+#define APR_SO_LINGER 1 /**< Linger */
+#define APR_SO_KEEPALIVE 2 /**< Keepalive */
+#define APR_SO_DEBUG 4 /**< Debug */
+#define APR_SO_NONBLOCK 8 /**< Non-blocking IO */
+#define APR_SO_REUSEADDR 16 /**< Reuse addresses */
+#define APR_SO_SNDBUF 64 /**< Send buffer */
+#define APR_SO_RCVBUF 128 /**< Receive buffer */
+#define APR_SO_DISCONNECTED 256 /**< Disconnected */
+#define APR_TCP_NODELAY 512 /**< For SCTP sockets, this is mapped
+ * to STCP_NODELAY internally.
+ */
+#define APR_TCP_NOPUSH 1024 /**< No push */
+#define APR_RESET_NODELAY 2048 /**< This flag is ONLY set internally
+ * when we set APR_TCP_NOPUSH with
+ * APR_TCP_NODELAY set to tell us that
+ * APR_TCP_NODELAY should be turned on
+ * again when NOPUSH is turned off
+ */
+#define APR_INCOMPLETE_READ 4096 /**< Set on non-blocking sockets
+ * (timeout != 0) on which the
+ * previous read() did not fill a buffer
+ * completely. the next apr_socket_recv()
+ * will first call select()/poll() rather than
+ * going straight into read(). (Can also
+ * be set by an application to force a
+ * select()/poll() call before the next
+ * read, in cases where the app expects
+ * that an immediate read would fail.)
+ */
+#define APR_INCOMPLETE_WRITE 8192 /**< like APR_INCOMPLETE_READ, but for write
+ * @see APR_INCOMPLETE_READ
+ */
+#define APR_IPV6_V6ONLY 16384 /**< Don't accept IPv4 connections on an
+ * IPv6 listening socket.
+ */
+#define APR_TCP_DEFER_ACCEPT 32768 /**< Delay accepting of new connections
+ * until data is available.
+ * @see apr_socket_accept_filter
+ */
+#define APR_SO_BROADCAST 65536 /**< Allow broadcast
+ */
+#define APR_SO_FREEBIND 131072 /**< Allow binding to addresses not owned
+ * by any interface
+ */
+
+/** @} */
+
+/** Define what type of socket shutdown should occur. */
+typedef enum {
+ APR_SHUTDOWN_READ, /**< no longer allow read request */
+ APR_SHUTDOWN_WRITE, /**< no longer allow write requests */
+ APR_SHUTDOWN_READWRITE /**< no longer allow read or write requests */
+} apr_shutdown_how_e;
+
+#define APR_IPV4_ADDR_OK 0x01 /**< @see apr_sockaddr_info_get() */
+#define APR_IPV6_ADDR_OK 0x02 /**< @see apr_sockaddr_info_get() */
+
+#if (!APR_HAVE_IN_ADDR)
+/**
+ * We need to make sure we always have an in_addr type, so APR will just
+ * define it ourselves, if the platform doesn't provide it.
+ */
+struct in_addr {
+ apr_uint32_t s_addr; /**< storage to hold the IP# */
+};
+#endif
+
+/** @def APR_INADDR_NONE
+ * Not all platforms have a real INADDR_NONE. This macro replaces
+ * INADDR_NONE on all platforms.
+ */
+#ifdef INADDR_NONE
+#define APR_INADDR_NONE INADDR_NONE
+#else
+#define APR_INADDR_NONE ((unsigned int) 0xffffffff)
+#endif
+
+/**
+ * @def APR_INET
+ * Not all platforms have these defined, so we'll define them here
+ * The default values come from FreeBSD 4.1.1
+ */
+#define APR_INET AF_INET
+/** @def APR_UNSPEC
+ * Let the system decide which address family to use
+ */
+#ifdef AF_UNSPEC
+#define APR_UNSPEC AF_UNSPEC
+#else
+#define APR_UNSPEC 0
+#endif
+#if APR_HAVE_IPV6
+/** @def APR_INET6
+* IPv6 Address Family. Not all platforms may have this defined.
+*/
+
+#define APR_INET6 AF_INET6
+#endif
+
+#if APR_HAVE_SOCKADDR_UN
+#if defined (AF_UNIX)
+#define APR_UNIX AF_UNIX
+#elif defined(AF_LOCAL)
+#define APR_UNIX AF_LOCAL
+#else
+#error "Neither AF_UNIX nor AF_LOCAL is defined"
+#endif
+#else /* !APR_HAVE_SOCKADDR_UN */
+#if defined (AF_UNIX)
+#define APR_UNIX AF_UNIX
+#elif defined(AF_LOCAL)
+#define APR_UNIX AF_LOCAL
+#else
+/* TODO: Use a smarter way to detect unique APR_UNIX value */
+#define APR_UNIX 1234
+#endif
+#endif
+
+/**
+ * @defgroup IP_Proto IP Protocol Definitions for use when creating sockets
+ * @{
+ */
+#define APR_PROTO_TCP 6 /**< TCP */
+#define APR_PROTO_UDP 17 /**< UDP */
+#define APR_PROTO_SCTP 132 /**< SCTP */
+/** @} */
+
+/**
+ * Enum used to denote either the local and remote endpoint of a
+ * connection.
+ */
+typedef enum {
+ APR_LOCAL, /**< Socket information for local end of connection */
+ APR_REMOTE /**< Socket information for remote end of connection */
+} apr_interface_e;
+
+/**
+ * The specific declaration of inet_addr's ... some platforms fall back
+ * inet_network (this is not good, but necessary)
+ */
+
+#if APR_HAVE_INET_ADDR
+#define apr_inet_addr inet_addr
+#elif APR_HAVE_INET_NETWORK /* only DGUX, as far as I know */
+/**
+ * @warning
+ * not generally safe... inet_network() and inet_addr() perform
+ * different functions */
+#define apr_inet_addr inet_network
+#endif
+
+/** A structure to represent sockets */
+typedef struct apr_socket_t apr_socket_t;
+/**
+ * A structure to encapsulate headers and trailers for apr_socket_sendfile
+ */
+typedef struct apr_hdtr_t apr_hdtr_t;
+/** A structure to represent in_addr */
+typedef struct in_addr apr_in_addr_t;
+/** A structure to represent an IP subnet */
+typedef struct apr_ipsubnet_t apr_ipsubnet_t;
+
+/** @remark use apr_uint16_t just in case some system has a short that isn't 16 bits... */
+typedef apr_uint16_t apr_port_t;
+
+/** @remark It's defined here as I think it should all be platform safe...
+ * @see apr_sockaddr_t
+ */
+typedef struct apr_sockaddr_t apr_sockaddr_t;
+/**
+ * APRs socket address type, used to ensure protocol independence
+ */
+struct apr_sockaddr_t {
+ /** The pool to use... */
+ apr_pool_t *pool;
+ /** The hostname */
+ char *hostname;
+ /** Either a string of the port number or the service name for the port */
+ char *servname;
+ /** The numeric port */
+ apr_port_t port;
+ /** The family */
+ apr_int32_t family;
+ /** How big is the sockaddr we're using? */
+ apr_socklen_t salen;
+ /** How big is the ip address structure we're using? */
+ int ipaddr_len;
+ /** How big should the address buffer be? 16 for v4 or 46 for v6
+ * used in inet_ntop... */
+ int addr_str_len;
+ /** This points to the IP address structure within the appropriate
+ * sockaddr structure. */
+ void *ipaddr_ptr;
+ /** If multiple addresses were found by apr_sockaddr_info_get(), this
+ * points to a representation of the next address. */
+ apr_sockaddr_t *next;
+ /** Union of either IPv4 or IPv6 sockaddr. */
+ union {
+ /** IPv4 sockaddr structure */
+ struct sockaddr_in sin;
+#if APR_HAVE_IPV6
+ /** IPv6 sockaddr structure */
+ struct sockaddr_in6 sin6;
+#endif
+#if APR_HAVE_SA_STORAGE
+ /** Placeholder to ensure that the size of this union is not
+ * dependent on whether APR_HAVE_IPV6 is defined. */
+ struct sockaddr_storage sas;
+#endif
+#if APR_HAVE_SOCKADDR_UN
+ /** Unix domain socket sockaddr structure */
+ struct sockaddr_un unx;
+#endif
+ } sa;
+};
+
+#if APR_HAS_SENDFILE
+/**
+ * Support reusing the socket on platforms which support it (from disconnect,
+ * specifically Win32.
+ * @remark Optional flag passed into apr_socket_sendfile()
+ */
+#define APR_SENDFILE_DISCONNECT_SOCKET 1
+#endif
+
+/** A structure to encapsulate headers and trailers for apr_socket_sendfile */
+struct apr_hdtr_t {
+ /** An iovec to store the headers sent before the file. */
+ struct iovec* headers;
+ /** number of headers in the iovec */
+ int numheaders;
+ /** An iovec to store the trailers sent after the file. */
+ struct iovec* trailers;
+ /** number of trailers in the iovec */
+ int numtrailers;
+};
+
+/* function definitions */
+
+/**
+ * Create a socket.
+ * @param new_sock The new socket that has been set up.
+ * @param family The address family of the socket (e.g., APR_INET).
+ * @param type The type of the socket (e.g., SOCK_STREAM).
+ * @param protocol The protocol of the socket (e.g., APR_PROTO_TCP).
+ * @param cont The pool for the apr_socket_t and associated storage.
+ * @note The pool will be used by various functions that operate on the
+ * socket. The caller must ensure that it is not used by other threads
+ * at the same time.
+ */
+APR_DECLARE(apr_status_t) apr_socket_create(apr_socket_t **new_sock,
+ int family, int type,
+ int protocol,
+ apr_pool_t *cont);
+
+/**
+ * Shutdown either reading, writing, or both sides of a socket.
+ * @param thesocket The socket to close
+ * @param how How to shutdown the socket. One of:
+ * <PRE>
+ * APR_SHUTDOWN_READ no longer allow read requests
+ * APR_SHUTDOWN_WRITE no longer allow write requests
+ * APR_SHUTDOWN_READWRITE no longer allow read or write requests
+ * </PRE>
+ * @see apr_shutdown_how_e
+ * @remark This does not actually close the socket descriptor, it just
+ * controls which calls are still valid on the socket.
+ */
+APR_DECLARE(apr_status_t) apr_socket_shutdown(apr_socket_t *thesocket,
+ apr_shutdown_how_e how);
+
+/**
+ * Close a socket.
+ * @param thesocket The socket to close
+ */
+APR_DECLARE(apr_status_t) apr_socket_close(apr_socket_t *thesocket);
+
+/**
+ * Bind the socket to its associated port
+ * @param sock The socket to bind
+ * @param sa The socket address to bind to
+ * @remark This may be where we will find out if there is any other process
+ * using the selected port.
+ */
+APR_DECLARE(apr_status_t) apr_socket_bind(apr_socket_t *sock,
+ apr_sockaddr_t *sa);
+
+/**
+ * Listen to a bound socket for connections.
+ * @param sock The socket to listen on
+ * @param backlog The number of outstanding connections allowed in the sockets
+ * listen queue. If this value is less than zero, the listen
+ * queue size is set to zero.
+ */
+APR_DECLARE(apr_status_t) apr_socket_listen(apr_socket_t *sock,
+ apr_int32_t backlog);
+
+/**
+ * Accept a new connection request
+ * @param new_sock A copy of the socket that is connected to the socket that
+ * made the connection request. This is the socket which should
+ * be used for all future communication.
+ * @param sock The socket we are listening on.
+ * @param connection_pool The pool for the new socket.
+ * @note The pool will be used by various functions that operate on the
+ * socket. The caller must ensure that it is not used by other threads
+ * at the same time.
+ */
+APR_DECLARE(apr_status_t) apr_socket_accept(apr_socket_t **new_sock,
+ apr_socket_t *sock,
+ apr_pool_t *connection_pool);
+
+/**
+ * Issue a connection request to a socket either on the same machine
+ * or a different one.
+ * @param sock The socket we wish to use for our side of the connection
+ * @param sa The address of the machine we wish to connect to.
+ */
+APR_DECLARE(apr_status_t) apr_socket_connect(apr_socket_t *sock,
+ apr_sockaddr_t *sa);
+
+/**
+ * Determine whether the receive part of the socket has been closed by
+ * the peer (such that a subsequent call to apr_socket_read would
+ * return APR_EOF), if the socket's receive buffer is empty. This
+ * function does not block waiting for I/O.
+ *
+ * @param sock The socket to check
+ * @param atreadeof If APR_SUCCESS is returned, *atreadeof is set to
+ * non-zero if a subsequent read would return APR_EOF
+ * @return an error is returned if it was not possible to determine the
+ * status, in which case *atreadeof is not changed.
+ */
+APR_DECLARE(apr_status_t) apr_socket_atreadeof(apr_socket_t *sock,
+ int *atreadeof);
+
+/**
+ * Create apr_sockaddr_t from hostname, address family, and port.
+ * @param sa The new apr_sockaddr_t.
+ * @param hostname The hostname or numeric address string to resolve/parse, or
+ * NULL to build an address that corresponds to 0.0.0.0 or ::
+ * or in case of APR_UNIX family it is absolute socket filename.
+ * @param family The address family to use, or APR_UNSPEC if the system should
+ * decide.
+ * @param port The port number.
+ * @param flags Special processing flags:
+ * <PRE>
+ * APR_IPV4_ADDR_OK first query for IPv4 addresses; only look
+ * for IPv6 addresses if the first query failed;
+ * only valid if family is APR_UNSPEC and hostname
+ * isn't NULL; mutually exclusive with
+ * APR_IPV6_ADDR_OK
+ * APR_IPV6_ADDR_OK first query for IPv6 addresses; only look
+ * for IPv4 addresses if the first query failed;
+ * only valid if family is APR_UNSPEC and hostname
+ * isn't NULL and APR_HAVE_IPV6; mutually exclusive
+ * with APR_IPV4_ADDR_OK
+ * </PRE>
+ * @param p The pool for the apr_sockaddr_t and associated storage.
+ */
+APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
+ const char *hostname,
+ apr_int32_t family,
+ apr_port_t port,
+ apr_int32_t flags,
+ apr_pool_t *p);
+
+/**
+ * Copy apr_sockaddr_t src to dst on pool p.
+ * @param dst The destination apr_sockaddr_t.
+ * @param src The source apr_sockaddr_t.
+ * @param p The pool for the apr_sockaddr_t and associated storage.
+ */
+APR_DECLARE(apr_status_t) apr_sockaddr_info_copy(apr_sockaddr_t **dst,
+ const apr_sockaddr_t *src,
+ apr_pool_t *p);
+
+/**
+ * Set the zone of an IPv6 link-local address object.
+ * @param sa Socket address object
+ * @param zone_id Zone ID (textual "eth0" or numeric "3").
+ * @return Returns APR_EBADIP for non-IPv6 socket or an IPv6 address
+ * which isn't link-local.
+ */
+APR_DECLARE(apr_status_t) apr_sockaddr_zone_set(apr_sockaddr_t *sa,
+ const char *zone_id);
+
+
+/**
+ * Retrieve the zone of an IPv6 link-local address object.
+ * @param sa Socket address object
+ * @param name If non-NULL, set to the textual representation of the zone id
+ * @param id If non-NULL, set to the integer zone id
+ * @param p Pool from which *name is allocated if used.
+ * @return Returns APR_EBADIP for non-IPv6 socket or socket without any zone id
+ * set, or other error if the interface could not be mapped to a name.
+ * @remark Both name and id may be NULL, neither are modified if
+ * non-NULL in error cases.
+ */
+APR_DECLARE(apr_status_t) apr_sockaddr_zone_get(const apr_sockaddr_t *sa,
+ const char **name,
+ apr_uint32_t *id,
+ apr_pool_t *p);
+
+/**
+ * Look up the host name from an apr_sockaddr_t.
+ * @param hostname The hostname.
+ * @param sa The apr_sockaddr_t.
+ * @param flags Special processing flags.
+ * @remark Results can vary significantly between platforms
+ * when processing wildcard socket addresses.
+ */
+APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname,
+ apr_sockaddr_t *sa,
+ apr_int32_t flags);
+
+/**
+ * Parse hostname/IP address with scope id and port.
+ *
+ * Any of the following strings are accepted:
+ * 8080 (just the port number)
+ * www.apache.org (just the hostname)
+ * www.apache.org:8080 (hostname and port number)
+ * [fe80::1]:80 (IPv6 numeric address string only)
+ * [fe80::1%eth0] (IPv6 numeric address string and scope id)
+ *
+ * Invalid strings:
+ * (empty string)
+ * [abc] (not valid IPv6 numeric address string)
+ * abc:65536 (invalid port number)
+ *
+ * @param addr The new buffer containing just the hostname. On output, *addr
+ * will be NULL if no hostname/IP address was specfied.
+ * @param scope_id The new buffer containing just the scope id. On output,
+ * *scope_id will be NULL if no scope id was specified.
+ * @param port The port number. On output, *port will be 0 if no port was
+ * specified.
+ * ### FIXME: 0 is a legal port (per RFC 1700). this should
+ * ### return something besides zero if the port is missing.
+ * @param str The input string to be parsed.
+ * @param p The pool from which *addr and *scope_id are allocated.
+ * @remark If scope id shouldn't be allowed, check for scope_id != NULL in
+ * addition to checking the return code. If addr/hostname should be
+ * required, check for addr == NULL in addition to checking the
+ * return code.
+ */
+APR_DECLARE(apr_status_t) apr_parse_addr_port(char **addr,
+ char **scope_id,
+ apr_port_t *port,
+ const char *str,
+ apr_pool_t *p);
+
+/**
+ * Get name of the current machine
+ * @param buf A buffer to store the hostname in.
+ * @param len The maximum length of the hostname that can be stored in the
+ * buffer provided. The suggested length is APRMAXHOSTLEN + 1.
+ * @param cont The pool to use.
+ * @remark If the buffer was not large enough, an error will be returned.
+ */
+APR_DECLARE(apr_status_t) apr_gethostname(char *buf, int len, apr_pool_t *cont);
+
+/**
+ * Return the data associated with the current socket
+ * @param data The user data associated with the socket.
+ * @param key The key to associate with the user data.
+ * @param sock The currently open socket.
+ */
+APR_DECLARE(apr_status_t) apr_socket_data_get(void **data, const char *key,
+ apr_socket_t *sock);
+
+/**
+ * Set the data associated with the current socket.
+ * @param sock The currently open socket.
+ * @param data The user data to associate with the socket.
+ * @param key The key to associate with the data.
+ * @param cleanup The cleanup to call when the socket is destroyed.
+ */
+APR_DECLARE(apr_status_t) apr_socket_data_set(apr_socket_t *sock, void *data,
+ const char *key,
+ apr_status_t (*cleanup)(void*));
+
+/**
+ * Send data over a network.
+ * @param sock The socket to send the data over.
+ * @param buf The buffer which contains the data to be sent.
+ * @param len On entry, the number of bytes to send; on exit, the number
+ * of bytes sent.
+ * @remark
+ * <PRE>
+ * This functions acts like a blocking write by default. To change
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
+ *
+ * It is possible for both bytes to be sent and an error to be returned.
+ *
+ * APR_EINTR is never returned.
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
+ apr_size_t *len);
+
+/**
+ * Send multiple buffers over a network.
+ * @param sock The socket to send the data over.
+ * @param vec The array of iovec structs containing the data to send
+ * @param nvec The number of iovec structs in the array
+ * @param len Receives the number of bytes actually written
+ * @remark
+ * <PRE>
+ * This functions acts like a blocking write by default. To change
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
+ * The number of bytes actually sent is stored in argument 4.
+ *
+ * It is possible for both bytes to be sent and an error to be returned.
+ *
+ * APR_EINTR is never returned.
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
+ const struct iovec *vec,
+ apr_int32_t nvec, apr_size_t *len);
+
+/**
+ * @param sock The socket to send from
+ * @param where The apr_sockaddr_t describing where to send the data
+ * @param flags The flags to use
+ * @param buf The data to send
+ * @param len The length of the data to send
+ */
+APR_DECLARE(apr_status_t) apr_socket_sendto(apr_socket_t *sock,
+ apr_sockaddr_t *where,
+ apr_int32_t flags, const char *buf,
+ apr_size_t *len);
+
+/**
+ * Read data from a socket. On success, the address of the peer from
+ * which the data was sent is copied into the @a from parameter, and the
+ * @a len parameter is updated to give the number of bytes written to
+ * @a buf.
+ *
+ * @param from Updated with the address from which the data was received
+ * @param sock The socket to use
+ * @param flags The flags to use
+ * @param buf The buffer to use
+ * @param len The length of the available buffer
+ */
+
+APR_DECLARE(apr_status_t) apr_socket_recvfrom(apr_sockaddr_t *from,
+ apr_socket_t *sock,
+ apr_int32_t flags, char *buf,
+ apr_size_t *len);
+
+#if APR_HAS_SENDFILE || defined(DOXYGEN)
+
+/**
+ * Send a file from an open file descriptor to a socket, along with
+ * optional headers and trailers
+ * @param sock The socket to which we're writing
+ * @param file The open file from which to read
+ * @param hdtr A structure containing the headers and trailers to send
+ * @param offset Offset into the file where we should begin writing
+ * @param len (input) - Number of bytes to send from the file
+ * (output) - Number of bytes actually sent,
+ * including headers, file, and trailers
+ * @param flags APR flags that are mapped to OS specific flags
+ * @remark This functions acts like a blocking write by default. To change
+ * this behavior, use apr_socket_timeout_set() or the
+ * APR_SO_NONBLOCK socket option.
+ * The number of bytes actually sent is stored in the len parameter.
+ * The offset parameter is passed by reference for no reason; its
+ * value will never be modified by the apr_socket_sendfile() function.
+ */
+APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
+ apr_file_t *file,
+ apr_hdtr_t *hdtr,
+ apr_off_t *offset,
+ apr_size_t *len,
+ apr_int32_t flags);
+
+#endif /* APR_HAS_SENDFILE */
+
+/**
+ * Read data from a network.
+ * @param sock The socket to read the data from.
+ * @param buf The buffer to store the data in.
+ * @param len On entry, the number of bytes to receive; on exit, the number
+ * of bytes received.
+ * @remark
+ * <PRE>
+ * This functions acts like a blocking read by default. To change
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
+ * The number of bytes actually received is stored in argument 3.
+ *
+ * It is possible for both bytes to be received and an APR_EOF or
+ * other error to be returned.
+ *
+ * APR_EINTR is never returned.
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock,
+ char *buf, apr_size_t *len);
+
+/**
+ * Setup socket options for the specified socket
+ * @param sock The socket to set up.
+ * @param opt The option we would like to configure. One of:
+ * <PRE>
+ * APR_SO_DEBUG -- turn on debugging information
+ * APR_SO_KEEPALIVE -- keep connections active
+ * APR_SO_LINGER -- lingers on close if data is present
+ * APR_SO_NONBLOCK -- Turns blocking on/off for socket
+ * When this option is enabled, use
+ * the APR_STATUS_IS_EAGAIN() macro to
+ * see if a send or receive function
+ * could not transfer data without
+ * blocking.
+ * APR_SO_REUSEADDR -- The rules used in validating addresses
+ * supplied to bind should allow reuse
+ * of local addresses.
+ * APR_SO_SNDBUF -- Set the SendBufferSize
+ * APR_SO_RCVBUF -- Set the ReceiveBufferSize
+ * APR_SO_FREEBIND -- Allow binding to non-local IP address.
+ * </PRE>
+ * @param on Value for the option.
+ */
+APR_DECLARE(apr_status_t) apr_socket_opt_set(apr_socket_t *sock,
+ apr_int32_t opt, apr_int32_t on);
+
+/**
+ * Setup socket timeout for the specified socket
+ * @param sock The socket to set up.
+ * @param t Value for the timeout.
+ * <PRE>
+ * t > 0 -- read and write calls return APR_TIMEUP if specified time
+ * elapsess with no data read or written
+ * t == 0 -- read and write calls never block
+ * t < 0 -- read and write calls block
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_socket_timeout_set(apr_socket_t *sock,
+ apr_interval_time_t t);
+
+/**
+ * Query socket options for the specified socket
+ * @param sock The socket to query
+ * @param opt The option we would like to query. One of:
+ * <PRE>
+ * APR_SO_DEBUG -- turn on debugging information
+ * APR_SO_KEEPALIVE -- keep connections active
+ * APR_SO_LINGER -- lingers on close if data is present
+ * APR_SO_NONBLOCK -- Turns blocking on/off for socket
+ * APR_SO_REUSEADDR -- The rules used in validating addresses
+ * supplied to bind should allow reuse
+ * of local addresses.
+ * APR_SO_SNDBUF -- Set the SendBufferSize
+ * APR_SO_RCVBUF -- Set the ReceiveBufferSize
+ * APR_SO_DISCONNECTED -- Query the disconnected state of the socket.
+ * (Currently only used on Windows)
+ * </PRE>
+ * @param on Socket option returned on the call.
+ */
+APR_DECLARE(apr_status_t) apr_socket_opt_get(apr_socket_t *sock,
+ apr_int32_t opt, apr_int32_t *on);
+
+/**
+ * Query socket timeout for the specified socket
+ * @param sock The socket to query
+ * @param t Socket timeout returned from the query.
+ */
+APR_DECLARE(apr_status_t) apr_socket_timeout_get(apr_socket_t *sock,
+ apr_interval_time_t *t);
+
+/**
+ * Query the specified socket if at the OOB/Urgent data mark
+ * @param sock The socket to query
+ * @param atmark Is set to true if socket is at the OOB/urgent mark,
+ * otherwise is set to false.
+ */
+APR_DECLARE(apr_status_t) apr_socket_atmark(apr_socket_t *sock,
+ int *atmark);
+
+/**
+ * Return an address associated with a socket; either the address to
+ * which the socket is bound locally or the address of the peer
+ * to which the socket is connected.
+ * @param sa The returned apr_sockaddr_t.
+ * @param which Whether to retrieve the local or remote address
+ * @param sock The socket to use
+ */
+APR_DECLARE(apr_status_t) apr_socket_addr_get(apr_sockaddr_t **sa,
+ apr_interface_e which,
+ apr_socket_t *sock);
+
+/**
+ * Return the IP address (in numeric address string format) in
+ * an APR socket address. APR will allocate storage for the IP address
+ * string from the pool of the apr_sockaddr_t.
+ * @param addr The IP address.
+ * @param sockaddr The socket address to reference.
+ */
+APR_DECLARE(apr_status_t) apr_sockaddr_ip_get(char **addr,
+ apr_sockaddr_t *sockaddr);
+
+/**
+ * Write the IP address (in numeric address string format) of the APR
+ * socket address @a sockaddr into the buffer @a buf (of size @a buflen).
+ * @param sockaddr The socket address to reference.
+ */
+APR_DECLARE(apr_status_t) apr_sockaddr_ip_getbuf(char *buf, apr_size_t buflen,
+ apr_sockaddr_t *sockaddr);
+
+/**
+ * See if the IP addresses in two APR socket addresses are
+ * equivalent. Appropriate logic is present for comparing
+ * IPv4-mapped IPv6 addresses with IPv4 addresses.
+ *
+ * @param addr1 One of the APR socket addresses.
+ * @param addr2 The other APR socket address.
+ * @remark The return value will be non-zero if the addresses
+ * are equivalent.
+ */
+APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1,
+ const apr_sockaddr_t *addr2);
+
+/**
+ * See if the IP address in an APR socket address refers to the wildcard
+ * address for the protocol family (e.g., INADDR_ANY for IPv4).
+ *
+ * @param addr The APR socket address to examine.
+ * @remark The return value will be non-zero if the address is
+ * initialized and is the wildcard address.
+ */
+APR_DECLARE(int) apr_sockaddr_is_wildcard(const apr_sockaddr_t *addr);
+
+/**
+* Return the type of the socket.
+* @param sock The socket to query.
+* @param type The returned type (e.g., SOCK_STREAM).
+*/
+APR_DECLARE(apr_status_t) apr_socket_type_get(apr_socket_t *sock,
+ int *type);
+
+/**
+ * Given an apr_sockaddr_t and a service name, set the port for the service
+ * @param sockaddr The apr_sockaddr_t that will have its port set
+ * @param servname The name of the service you wish to use
+ */
+APR_DECLARE(apr_status_t) apr_getservbyname(apr_sockaddr_t *sockaddr,
+ const char *servname);
+/**
+ * Build an ip-subnet representation from an IP address and optional netmask or
+ * number-of-bits.
+ * @param ipsub The new ip-subnet representation
+ * @param ipstr The input IP address string
+ * @param mask_or_numbits The input netmask or number-of-bits string, or NULL
+ * @param p The pool to allocate from
+ */
+APR_DECLARE(apr_status_t) apr_ipsubnet_create(apr_ipsubnet_t **ipsub,
+ const char *ipstr,
+ const char *mask_or_numbits,
+ apr_pool_t *p);
+
+/**
+ * Test the IP address in an apr_sockaddr_t against a pre-built ip-subnet
+ * representation.
+ * @param ipsub The ip-subnet representation
+ * @param sa The socket address to test
+ * @return non-zero if the socket address is within the subnet, 0 otherwise
+ */
+APR_DECLARE(int) apr_ipsubnet_test(apr_ipsubnet_t *ipsub, apr_sockaddr_t *sa);
+
+#if APR_HAS_SO_ACCEPTFILTER || defined(DOXYGEN)
+/**
+ * Set an OS level accept filter.
+ * @param sock The socket to put the accept filter on.
+ * @param name The accept filter
+ * @param args Any extra args to the accept filter. Passing NULL here removes
+ * the accept filter.
+ * @bug name and args should have been declared as const char *, as they are in
+ * APR 2.0
+ */
+apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *name,
+ char *args);
+#endif
+
+/**
+ * Return the protocol of the socket.
+ * @param sock The socket to query.
+ * @param protocol The returned protocol (e.g., APR_PROTO_TCP).
+ */
+APR_DECLARE(apr_status_t) apr_socket_protocol_get(apr_socket_t *sock,
+ int *protocol);
+
+/**
+ * Get the pool used by the socket.
+ */
+APR_POOL_DECLARE_ACCESSOR(socket);
+
+/**
+ * Set a socket to be inherited by child processes.
+ */
+APR_DECLARE_INHERIT_SET(socket);
+
+/**
+ * Unset a socket from being inherited by child processes.
+ */
+APR_DECLARE_INHERIT_UNSET(socket);
+
+/**
+ * Set socket permissions.
+ */
+APR_PERMS_SET_IMPLEMENT(socket);
+
+/**
+ * @defgroup apr_mcast IP Multicast
+ * @{
+ */
+
+/**
+ * Join a Multicast Group
+ * @param sock The socket to join a multicast group
+ * @param join The address of the multicast group to join
+ * @param iface Address of the interface to use. If NULL is passed, the
+ * default multicast interface will be used. (OS Dependent)
+ * @param source Source Address to accept transmissions from (non-NULL
+ * implies Source-Specific Multicast)
+ */
+APR_DECLARE(apr_status_t) apr_mcast_join(apr_socket_t *sock,
+ apr_sockaddr_t *join,
+ apr_sockaddr_t *iface,
+ apr_sockaddr_t *source);
+
+/**
+ * Leave a Multicast Group. All arguments must be the same as
+ * apr_mcast_join.
+ * @param sock The socket to leave a multicast group
+ * @param addr The address of the multicast group to leave
+ * @param iface Address of the interface to use. If NULL is passed, the
+ * default multicast interface will be used. (OS Dependent)
+ * @param source Source Address to accept transmissions from (non-NULL
+ * implies Source-Specific Multicast)
+ */
+APR_DECLARE(apr_status_t) apr_mcast_leave(apr_socket_t *sock,
+ apr_sockaddr_t *addr,
+ apr_sockaddr_t *iface,
+ apr_sockaddr_t *source);
+
+/**
+ * Set the Multicast Time to Live (ttl) for a multicast transmission.
+ * @param sock The socket to set the multicast ttl
+ * @param ttl Time to live to Assign. 0-255, default=1
+ * @remark If the TTL is 0, packets will only be seen by sockets on
+ * the local machine, and only when multicast loopback is enabled.
+ */
+APR_DECLARE(apr_status_t) apr_mcast_hops(apr_socket_t *sock,
+ apr_byte_t ttl);
+
+/**
+ * Toggle IP Multicast Loopback
+ * @param sock The socket to set multicast loopback
+ * @param opt 0=disable, 1=enable
+ */
+APR_DECLARE(apr_status_t) apr_mcast_loopback(apr_socket_t *sock,
+ apr_byte_t opt);
+
+
+/**
+ * Set the Interface to be used for outgoing Multicast Transmissions.
+ * @param sock The socket to set the multicast interface on
+ * @param iface Address of the interface to use for Multicast
+ */
+APR_DECLARE(apr_status_t) apr_mcast_interface(apr_socket_t *sock,
+ apr_sockaddr_t *iface);
+
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_NETWORK_IO_H */
+
diff --git a/include/apr_perms_set.h b/include/apr_perms_set.h
new file mode 100644
index 0000000..92a1362
--- /dev/null
+++ b/include/apr_perms_set.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 APR_PERMS_SET_H
+#define APR_PERMS_SET_H
+
+/**
+ * @file apr_perms_set.h
+ * @brief APR Process Locking Routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_user.h"
+#include "apr_file_info.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_perms_set Object permission set functions
+ * @ingroup APR
+ * @{
+ */
+
+/** Permission set callback function. */
+typedef apr_status_t (apr_perms_setfn_t)(void *object, apr_fileperms_t perms,
+ apr_uid_t uid, apr_gid_t gid);
+
+#define APR_PERMS_SET_IMPLEMENT(type) \
+ APR_DECLARE(apr_status_t) apr_##type##_perms_set \
+ (void *the##type, apr_fileperms_t perms, \
+ apr_uid_t uid, apr_gid_t gid)
+
+#define APR_PERMS_SET_ENOTIMPL(type) \
+ APR_DECLARE(apr_status_t) apr_##type##_perms_set \
+ (void *the##type, apr_fileperms_t perms, \
+ apr_uid_t uid, apr_gid_t gid) \
+ { return APR_ENOTIMPL ; }
+
+#define APR_PERMS_SET_FN(type) apr_##type##_perms_set
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_PERMS_SET */
diff --git a/include/apr_poll.h b/include/apr_poll.h
new file mode 100644
index 0000000..482d6ee
--- /dev/null
+++ b/include/apr_poll.h
@@ -0,0 +1,446 @@
+/* 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 APR_POLL_H
+#define APR_POLL_H
+/**
+ * @file apr_poll.h
+ * @brief APR Poll interface
+ */
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_inherit.h"
+#include "apr_file_io.h"
+#include "apr_network_io.h"
+
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_poll Poll Routines
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * @defgroup pollopts Poll options
+ * @ingroup apr_poll
+ * @{
+ */
+#define APR_POLLIN 0x001 /**< Can read without blocking */
+#define APR_POLLPRI 0x002 /**< Priority data available */
+#define APR_POLLOUT 0x004 /**< Can write without blocking */
+#define APR_POLLERR 0x010 /**< Pending error */
+#define APR_POLLHUP 0x020 /**< Hangup occurred */
+#define APR_POLLNVAL 0x040 /**< Descriptor invalid */
+/** @} */
+
+/**
+ * @defgroup pollflags Pollset Flags
+ * @ingroup apr_poll
+ * @{
+ */
+#define APR_POLLSET_THREADSAFE 0x001 /**< Adding or removing a descriptor is
+ * thread-safe
+ */
+#define APR_POLLSET_NOCOPY 0x002 /**< Descriptors passed to apr_pollset_add()
+ * are not copied
+ */
+#define APR_POLLSET_WAKEABLE 0x004 /**< Poll operations are interruptable by
+ * apr_pollset_wakeup() or apr_pollcb_wakeup()
+ */
+#define APR_POLLSET_NODEFAULT 0x010 /**< Do not try to use the default method if
+ * the specified non-default method cannot be
+ * used
+ */
+/** @} */
+
+/**
+ * Pollset Methods
+ */
+typedef enum {
+ APR_POLLSET_DEFAULT, /**< Platform default poll method */
+ APR_POLLSET_SELECT, /**< Poll uses select method */
+ APR_POLLSET_KQUEUE, /**< Poll uses kqueue method */
+ APR_POLLSET_PORT, /**< Poll uses Solaris event port method */
+ APR_POLLSET_EPOLL, /**< Poll uses epoll method */
+ APR_POLLSET_POLL, /**< Poll uses poll method */
+ APR_POLLSET_AIO_MSGQ /**< Poll uses z/OS asio method */
+} apr_pollset_method_e;
+
+/** Used in apr_pollfd_t to determine what the apr_descriptor is */
+typedef enum {
+ APR_NO_DESC, /**< nothing here */
+ APR_POLL_SOCKET, /**< descriptor refers to a socket */
+ APR_POLL_FILE, /**< descriptor refers to a file */
+ APR_POLL_LASTDESC /**< @deprecated descriptor is the last one in the list */
+} apr_datatype_e ;
+
+/** Union of either an APR file or socket. */
+typedef union {
+ apr_file_t *f; /**< file */
+ apr_socket_t *s; /**< socket */
+} apr_descriptor;
+
+/** @see apr_pollfd_t */
+typedef struct apr_pollfd_t apr_pollfd_t;
+
+/** Poll descriptor set. */
+struct apr_pollfd_t {
+ apr_pool_t *p; /**< associated pool */
+ apr_datatype_e desc_type; /**< descriptor type */
+ apr_int16_t reqevents; /**< requested events */
+ apr_int16_t rtnevents; /**< returned events */
+ apr_descriptor desc; /**< @see apr_descriptor */
+ void *client_data; /**< allows app to associate context */
+};
+
+
+/* General-purpose poll API for arbitrarily large numbers of
+ * file descriptors
+ */
+
+/** Opaque structure used for pollset API */
+typedef struct apr_pollset_t apr_pollset_t;
+
+/**
+ * Set up a pollset object
+ * @param pollset The pointer in which to return the newly created object
+ * @param size The maximum number of descriptors that this pollset can hold
+ * @param p The pool from which to allocate the pollset
+ * @param flags Optional flags to modify the operation of the pollset.
+ *
+ * @remark If flags contains APR_POLLSET_THREADSAFE, then a pollset is
+ * created on which it is safe to make concurrent calls to
+ * apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll()
+ * from separate threads. This feature is only supported on some
+ * platforms; the apr_pollset_create() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollset is
+ * created with an additional internal pipe object used for the
+ * apr_pollset_wakeup() call. The actual size of pollset is
+ * in that case @a size + 1. This feature is only supported on some
+ * platforms; the apr_pollset_create() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_NOCOPY, then the apr_pollfd_t
+ * structures passed to apr_pollset_add() are not copied and
+ * must have a lifetime at least as long as the pollset.
+ * @remark Some poll methods (including APR_POLLSET_KQUEUE,
+ * APR_POLLSET_PORT, and APR_POLLSET_EPOLL) do not have a
+ * fixed limit on the size of the pollset. For these methods,
+ * the size parameter controls the maximum number of
+ * descriptors that will be returned by a single call to
+ * apr_pollset_poll().
+ */
+APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
+ apr_uint32_t size,
+ apr_pool_t *p,
+ apr_uint32_t flags);
+
+/**
+ * Set up a pollset object
+ * @param pollset The pointer in which to return the newly created object
+ * @param size The maximum number of descriptors that this pollset can hold
+ * @param p The pool from which to allocate the pollset
+ * @param flags Optional flags to modify the operation of the pollset.
+ * @param method Poll method to use. See #apr_pollset_method_e. If this
+ * method cannot be used, the default method will be used unless the
+ * APR_POLLSET_NODEFAULT flag has been specified.
+ *
+ * @remark If flags contains APR_POLLSET_THREADSAFE, then a pollset is
+ * created on which it is safe to make concurrent calls to
+ * apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll()
+ * from separate threads. This feature is only supported on some
+ * platforms; the apr_pollset_create_ex() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollset is
+ * created with additional internal pipe object used for the
+ * apr_pollset_wakeup() call. The actual size of pollset is
+ * in that case size + 1. This feature is only supported on some
+ * platforms; the apr_pollset_create_ex() call will fail with
+ * APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contains APR_POLLSET_NOCOPY, then the apr_pollfd_t
+ * structures passed to apr_pollset_add() are not copied and
+ * must have a lifetime at least as long as the pollset.
+ * @remark Some poll methods (including APR_POLLSET_KQUEUE,
+ * APR_POLLSET_PORT, and APR_POLLSET_EPOLL) do not have a
+ * fixed limit on the size of the pollset. For these methods,
+ * the size parameter controls the maximum number of
+ * descriptors that will be returned by a single call to
+ * apr_pollset_poll().
+ */
+APR_DECLARE(apr_status_t) apr_pollset_create_ex(apr_pollset_t **pollset,
+ apr_uint32_t size,
+ apr_pool_t *p,
+ apr_uint32_t flags,
+ apr_pollset_method_e method);
+
+/**
+ * Destroy a pollset object
+ * @param pollset The pollset to destroy
+ */
+APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset);
+
+/**
+ * Add a socket or file descriptor to a pollset
+ * @param pollset The pollset to which to add the descriptor
+ * @param descriptor The descriptor to add
+ * @remark If you set client_data in the descriptor, that value
+ * will be returned in the client_data field whenever this
+ * descriptor is signalled in apr_pollset_poll().
+ * @remark If the pollset has been created with APR_POLLSET_THREADSAFE
+ * and thread T1 is blocked in a call to apr_pollset_poll() for
+ * this same pollset that is being modified via apr_pollset_add()
+ * in thread T2, the currently executing apr_pollset_poll() call in
+ * T1 will either: (1) automatically include the newly added descriptor
+ * in the set of descriptors it is watching or (2) return immediately
+ * with APR_EINTR. Option (1) is recommended, but option (2) is
+ * allowed for implementations where option (1) is impossible
+ * or impractical.
+ * @remark If the pollset has been created with APR_POLLSET_NOCOPY, the
+ * apr_pollfd_t structure referenced by descriptor will not be copied
+ * and must have a lifetime at least as long as the pollset.
+ * @remark Do not add the same socket or file descriptor to the same pollset
+ * multiple times, even if the requested events differ for the
+ * different calls to apr_pollset_add(). If the events of interest
+ * for a descriptor change, you must first remove the descriptor
+ * from the pollset with apr_pollset_remove(), then add it again
+ * specifying all requested events.
+ */
+APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
+ const apr_pollfd_t *descriptor);
+
+/**
+ * Remove a descriptor from a pollset
+ * @param pollset The pollset from which to remove the descriptor
+ * @param descriptor The descriptor to remove
+ * @remark If the descriptor is not found, APR_NOTFOUND is returned.
+ * @remark If the pollset has been created with APR_POLLSET_THREADSAFE
+ * and thread T1 is blocked in a call to apr_pollset_poll() for
+ * this same pollset that is being modified via apr_pollset_remove()
+ * in thread T2, the currently executing apr_pollset_poll() call in
+ * T1 will either: (1) automatically exclude the newly added descriptor
+ * in the set of descriptors it is watching or (2) return immediately
+ * with APR_EINTR. Option (1) is recommended, but option (2) is
+ * allowed for implementations where option (1) is impossible
+ * or impractical.
+ * @remark apr_pollset_remove() cannot be used to remove a subset of requested
+ * events for a descriptor. The reqevents field in the apr_pollfd_t
+ * parameter must contain the same value when removing as when adding.
+ */
+APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+ const apr_pollfd_t *descriptor);
+
+/**
+ * Block for activity on the descriptor(s) in a pollset
+ * @param pollset The pollset to use
+ * @param timeout The amount of time in microseconds to wait. This is a
+ * maximum, not a minimum. If a descriptor is signalled, the
+ * function will return before this time. If timeout is
+ * negative, the function will block until a descriptor is
+ * signalled or until apr_pollset_wakeup() has been called.
+ * @param num Number of signalled descriptors (output parameter)
+ * @param descriptors Array of signalled descriptors (output parameter)
+ * @remark APR_EINTR will be returned if the pollset has been created with
+ * APR_POLLSET_WAKEABLE, apr_pollset_wakeup() has been called while
+ * waiting for activity, and there were no signalled descriptors at the
+ * time of the wakeup call.
+ * @remark Multiple signalled conditions for the same descriptor may be reported
+ * in one or more returned apr_pollfd_t structures, depending on the
+ * implementation.
+ */
+APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
+ apr_interval_time_t timeout,
+ apr_int32_t *num,
+ const apr_pollfd_t **descriptors);
+
+/**
+ * Interrupt the blocked apr_pollset_poll() call.
+ * @param pollset The pollset to use
+ * @remark If the pollset was not created with APR_POLLSET_WAKEABLE the
+ * return value is APR_EINIT.
+ */
+APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset);
+
+/**
+ * Poll the descriptors in the poll structure
+ * @param aprset The poll structure we will be using.
+ * @param numsock The number of descriptors we are polling
+ * @param nsds The number of descriptors signalled (output parameter)
+ * @param timeout The amount of time in microseconds to wait. This is a
+ * maximum, not a minimum. If a descriptor is signalled, the
+ * function will return before this time. If timeout is
+ * negative, the function will block until a descriptor is
+ * signalled or until apr_pollset_wakeup() has been called.
+ * @remark The number of descriptors signalled is returned in the third argument.
+ * This is a blocking call, and it will not return until either a
+ * descriptor has been signalled or the timeout has expired.
+ * @remark The rtnevents field in the apr_pollfd_t array will only be filled-
+ * in if the return value is APR_SUCCESS.
+ */
+APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t numsock,
+ apr_int32_t *nsds,
+ apr_interval_time_t timeout);
+
+/**
+ * Return a printable representation of the pollset method.
+ * @param pollset The pollset to use
+ */
+APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset);
+
+/**
+ * Return a printable representation of the default pollset method
+ * (APR_POLLSET_DEFAULT).
+ */
+APR_DECLARE(const char *) apr_poll_method_defname(void);
+
+/** Opaque structure used for pollcb API */
+typedef struct apr_pollcb_t apr_pollcb_t;
+
+/**
+ * Set up a pollcb object
+ * @param pollcb The pointer in which to return the newly created object
+ * @param size The maximum number of descriptors that a single _poll can return.
+ * @param p The pool from which to allocate the pollcb
+ * @param flags Optional flags to modify the operation of the pollcb.
+ *
+ * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollcb is
+ * created with an additional internal pipe object used for the
+ * apr_pollcb_wakeup() call. The actual size of pollcb is
+ * in that case @a size + 1.
+ * @remark Pollcb is only supported on some platforms; the apr_pollcb_create()
+ * call will fail with APR_ENOTIMPL on platforms where it is not supported.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
+ apr_uint32_t size,
+ apr_pool_t *p,
+ apr_uint32_t flags);
+
+/**
+ * Set up a pollcb object
+ * @param pollcb The pointer in which to return the newly created object
+ * @param size The maximum number of descriptors that a single _poll can return.
+ * @param p The pool from which to allocate the pollcb
+ * @param flags Optional flags to modify the operation of the pollcb.
+ * @param method Poll method to use. See #apr_pollset_method_e. If this
+ * method cannot be used, the default method will be used unless the
+ * APR_POLLSET_NODEFAULT flag has been specified.
+ *
+ * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollcb is
+ * created with an additional internal pipe object used for the
+ * apr_pollcb_wakeup() call. The actual size of pollcb is
+ * in that case @a size + 1.
+ * @remark Pollcb is only supported on some platforms; the apr_pollcb_create_ex()
+ * call will fail with APR_ENOTIMPL on platforms where it is not supported.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb,
+ apr_uint32_t size,
+ apr_pool_t *p,
+ apr_uint32_t flags,
+ apr_pollset_method_e method);
+
+/**
+ * Add a socket or file descriptor to a pollcb
+ * @param pollcb The pollcb to which to add the descriptor
+ * @param descriptor The descriptor to add
+ * @remark If you set client_data in the descriptor, that value will be
+ * returned in the client_data field whenever this descriptor is
+ * signalled in apr_pollcb_poll().
+ * @remark Unlike the apr_pollset API, the descriptor is not copied, and users
+ * must retain the memory used by descriptor, as the same pointer will
+ * be returned to them from apr_pollcb_poll.
+ * @remark Do not add the same socket or file descriptor to the same pollcb
+ * multiple times, even if the requested events differ for the
+ * different calls to apr_pollcb_add(). If the events of interest
+ * for a descriptor change, you must first remove the descriptor
+ * from the pollcb with apr_pollcb_remove(), then add it again
+ * specifying all requested events.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
+ apr_pollfd_t *descriptor);
+/**
+ * Remove a descriptor from a pollcb
+ * @param pollcb The pollcb from which to remove the descriptor
+ * @param descriptor The descriptor to remove
+ * @remark If the descriptor is not found, APR_NOTFOUND is returned.
+ * @remark apr_pollcb_remove() cannot be used to remove a subset of requested
+ * events for a descriptor. The reqevents field in the apr_pollfd_t
+ * parameter must contain the same value when removing as when adding.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
+ apr_pollfd_t *descriptor);
+
+/**
+ * Function prototype for pollcb handlers
+ * @param baton Opaque baton passed into apr_pollcb_poll()
+ * @param descriptor Contains the notification for an active descriptor.
+ * The @a rtnevents member describes which events were triggered
+ * for this descriptor.
+ * @remark If the pollcb handler does not return APR_SUCCESS, the apr_pollcb_poll()
+ * call returns with the handler's return value.
+ */
+typedef apr_status_t (*apr_pollcb_cb_t)(void *baton, apr_pollfd_t *descriptor);
+
+/**
+ * Block for activity on the descriptor(s) in a pollcb
+ * @param pollcb The pollcb to use
+ * @param timeout The amount of time in microseconds to wait. This is a
+ * maximum, not a minimum. If a descriptor is signalled, the
+ * function will return before this time. If timeout is
+ * negative, the function will block until a descriptor is
+ * signalled or until apr_pollcb_wakeup() has been called.
+ * @param func Callback function to call for each active descriptor.
+ * @param baton Opaque baton passed to the callback function.
+ * @remark Multiple signalled conditions for the same descriptor may be reported
+ * in one or more calls to the callback function, depending on the
+ * implementation.
+ * @remark APR_EINTR will be returned if the pollset has been created with
+ * APR_POLLSET_WAKEABLE and apr_pollcb_wakeup() has been called while
+ * waiting for activity.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
+ apr_interval_time_t timeout,
+ apr_pollcb_cb_t func,
+ void *baton);
+
+/**
+ * Interrupt the blocked apr_pollcb_poll() call.
+ * @param pollcb The pollcb to use
+ * @remark If the pollcb was not created with APR_POLLSET_WAKEABLE the
+ * return value is APR_EINIT.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_wakeup(apr_pollcb_t *pollcb);
+
+/**
+ * Return a printable representation of the pollcb method.
+ * @param pollcb The pollcb to use
+ */
+APR_DECLARE(const char *) apr_pollcb_method_name(apr_pollcb_t *pollcb);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_POLL_H */
+
diff --git a/include/apr_pools.h b/include/apr_pools.h
new file mode 100644
index 0000000..eae9c21
--- /dev/null
+++ b/include/apr_pools.h
@@ -0,0 +1,815 @@
+/* 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 APR_POOLS_H
+#define APR_POOLS_H
+
+/**
+ * @file apr_pools.h
+ * @brief APR memory allocation
+ *
+ * Resource allocation routines...
+ *
+ * designed so that we don't have to keep track of EVERYTHING so that
+ * it can be explicitly freed later (a fundamentally unsound strategy ---
+ * particularly in the presence of die()).
+ *
+ * Instead, we maintain pools, and allocate items (both memory and I/O
+ * handlers) from the pools --- currently there are two, one for
+ * per-transaction info, and one for config info. When a transaction is
+ * over, we can delete everything in the per-transaction apr_pool_t without
+ * fear, and without thinking too hard about it either.
+ *
+ * Note that most operations on pools are not thread-safe: a single pool
+ * should only be accessed by a single thread at any given time. The one
+ * exception to this rule is creating a subpool of a given pool: one or more
+ * threads can safely create subpools at the same time that another thread
+ * accesses the parent pool.
+ */
+
+#include "apr.h"
+#include "apr_errno.h"
+#include "apr_general.h" /* for APR_STRINGIFY */
+#define APR_WANT_MEMFUNC /**< for no good reason? */
+#include "apr_want.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup apr_pools Memory Pool Functions
+ * @ingroup APR
+ * @{
+ */
+
+/** The fundamental pool type */
+typedef struct apr_pool_t apr_pool_t;
+
+
+/**
+ * Declaration helper macro to construct apr_foo_pool_get()s.
+ *
+ * This standardized macro is used by opaque (APR) data types to return
+ * the apr_pool_t that is associated with the data type.
+ *
+ * APR_POOL_DECLARE_ACCESSOR() is used in a header file to declare the
+ * accessor function. A typical usage and result would be:
+ * <pre>
+ * APR_POOL_DECLARE_ACCESSOR(file);
+ * becomes:
+ * APR_DECLARE(apr_pool_t *) apr_file_pool_get(const apr_file_t *thefile);
+ * </pre>
+ * @remark Doxygen unwraps this macro (via doxygen.conf) to provide
+ * actual help for each specific occurrence of apr_foo_pool_get.
+ * @remark the linkage is specified for APR. It would be possible to expand
+ * the macros to support other linkages.
+ */
+#define APR_POOL_DECLARE_ACCESSOR(type) \
+ APR_DECLARE(apr_pool_t *) apr_##type##_pool_get \
+ (const apr_##type##_t *the##type)
+
+/**
+ * Implementation helper macro to provide apr_foo_pool_get()s.
+ *
+ * In the implementation, the APR_POOL_IMPLEMENT_ACCESSOR() is used to
+ * actually define the function. It assumes the field is named "pool".
+ */
+#define APR_POOL_IMPLEMENT_ACCESSOR(type) \
+ APR_DECLARE(apr_pool_t *) apr_##type##_pool_get \
+ (const apr_##type##_t *the##type) \
+ { return the##type->pool; }
+
+
+/**
+ * Pool debug levels
+ *
+ * <pre>
+ * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+ * ---------------------------------
+ * | | | | | | | | x | General debug code enabled (useful in
+ * combination with --with-efence).
+ *
+ * | | | | | | | x | | Verbose output on stderr (report
+ * CREATE, CLEAR, DESTROY).
+ *
+ * | | | | x | | | | | Verbose output on stderr (report
+ * PALLOC, PCALLOC).
+ *
+ * | | | | | | x | | | Lifetime checking. On each use of a
+ * pool, check its lifetime. If the pool
+ * is out of scope, abort().
+ * In combination with the verbose flag
+ * above, it will output LIFE in such an
+ * event prior to aborting.
+ *
+ * | | | | | x | | | | Pool owner checking. On each use of a
+ * pool, check if the current thread is the
+ * pool's owner. If not, abort(). In
+ * combination with the verbose flag above,
+ * it will output OWNER in such an event
+ * prior to aborting. Use the debug
+ * function apr_pool_owner_set() to switch
+ * a pool's ownership.
+ *
+ * When no debug level was specified, assume general debug mode.
+ * If level 0 was specified, debugging is switched off.
+ * </pre>
+ */
+#if defined(APR_POOL_DEBUG)
+/* If APR_POOL_DEBUG is blank, we get 1; if it is a number, we get -1. */
+#if (APR_POOL_DEBUG - APR_POOL_DEBUG -1 == 1)
+#undef APR_POOL_DEBUG
+#define APR_POOL_DEBUG 1
+#endif
+#else
+#define APR_POOL_DEBUG 0
+#endif
+
+/** the place in the code where the particular function was called */
+#define APR_POOL__FILE_LINE__ __FILE__ ":" APR_STRINGIFY(__LINE__)
+
+
+
+/** A function that is called when allocation fails. */
+typedef int (*apr_abortfunc_t)(int retcode);
+
+/*
+ * APR memory structure manipulators (pools, tables, and arrays).
+ */
+
+/*
+ * Initialization
+ */
+
+/**
+ * Setup all of the internal structures required to use pools
+ * @remark Programs do NOT need to call this directly. APR will call this
+ * automatically from apr_initialize.
+ * @internal
+ */
+APR_DECLARE(apr_status_t) apr_pool_initialize(void);
+
+/**
+ * Tear down all of the internal structures required to use pools
+ * @remark Programs do NOT need to call this directly. APR will call this
+ * automatically from apr_terminate.
+ * @internal
+ */
+APR_DECLARE(void) apr_pool_terminate(void);
+
+
+/*
+ * Pool creation/destruction
+ */
+
+#include "apr_allocator.h"
+
+/**
+ * Create a new pool.
+ * @param newpool The pool we have just created.
+ * @param parent The parent pool. If this is NULL, the new pool is a root
+ * pool. If it is non-NULL, the new pool will inherit all
+ * of its parent pool's attributes, except the apr_pool_t will
+ * be a sub-pool.
+ * @param abort_fn A function to use if the pool cannot allocate more memory.
+ * @param allocator The allocator to use with the new pool. If NULL the
+ * allocator of the parent pool will be used.
+ * @remark This function is thread-safe, in the sense that multiple threads
+ * can safely create subpools of the same parent pool concurrently.
+ * Similarly, a subpool can be created by one thread at the same
+ * time that another thread accesses the parent pool.
+ */
+APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool,
+ apr_pool_t *parent,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator)
+ __attribute__((nonnull(1)));
+
+/**
+ * Create a new pool.
+ * @deprecated @see apr_pool_create_unmanaged_ex.
+ */
+APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator);
+
+/**
+ * Create a new unmanaged pool.
+ * @param newpool The pool we have just created.
+ * @param abort_fn A function to use if the pool cannot allocate more memory.
+ * @param allocator The allocator to use with the new pool. If NULL a
+ * new allocator will be created with the new pool as owner.
+ * @remark An unmanaged pool is a special pool without a parent; it will
+ * NOT be destroyed upon apr_terminate. It must be explicitly
+ * destroyed by calling apr_pool_destroy, to prevent memory leaks.
+ * Use of this function is discouraged, think twice about whether
+ * you really really need it.
+ * @warning Any child cleanups registered against the new pool, or
+ * against sub-pools thereof, will not be executed during an
+ * invocation of apr_proc_create(), so resources created in an
+ * "unmanaged" pool hierarchy will leak to child processes.
+ */
+APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex(apr_pool_t **newpool,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator)
+ __attribute__((nonnull(1)));
+
+/**
+ * Debug version of apr_pool_create_ex.
+ * @param newpool @see apr_pool_create.
+ * @param parent @see apr_pool_create.
+ * @param abort_fn @see apr_pool_create.
+ * @param allocator @see apr_pool_create.
+ * @param file_line Where the function is called from.
+ * This is usually APR_POOL__FILE_LINE__.
+ * @remark Only available when APR_POOL_DEBUG is defined.
+ * Call this directly if you have your apr_pool_create_ex
+ * calls in a wrapper function and wish to override
+ * the file_line argument to reflect the caller of
+ * your wrapper function. If you do not have
+ * apr_pool_create_ex in a wrapper, trust the macro
+ * and don't call apr_pool_create_ex_debug directly.
+ */
+APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool,
+ apr_pool_t *parent,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator,
+ const char *file_line)
+ __attribute__((nonnull(1)));
+
+#if APR_POOL_DEBUG
+#define apr_pool_create_ex(newpool, parent, abort_fn, allocator) \
+ apr_pool_create_ex_debug(newpool, parent, abort_fn, allocator, \
+ APR_POOL__FILE_LINE__)
+#endif
+
+/**
+ * Debug version of apr_pool_create_core_ex.
+ * @deprecated @see apr_pool_create_unmanaged_ex_debug.
+ */
+APR_DECLARE(apr_status_t) apr_pool_create_core_ex_debug(apr_pool_t **newpool,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator,
+ const char *file_line);
+
+/**
+ * Debug version of apr_pool_create_unmanaged_ex.
+ * @param newpool @see apr_pool_create_unmanaged.
+ * @param abort_fn @see apr_pool_create_unmanaged.
+ * @param allocator @see apr_pool_create_unmanaged.
+ * @param file_line Where the function is called from.
+ * This is usually APR_POOL__FILE_LINE__.
+ * @remark Only available when APR_POOL_DEBUG is defined.
+ * Call this directly if you have your apr_pool_create_unmanaged_ex
+ * calls in a wrapper function and wish to override
+ * the file_line argument to reflect the caller of
+ * your wrapper function. If you do not have
+ * apr_pool_create_core_ex in a wrapper, trust the macro
+ * and don't call apr_pool_create_core_ex_debug directly.
+ */
+APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex_debug(apr_pool_t **newpool,
+ apr_abortfunc_t abort_fn,
+ apr_allocator_t *allocator,
+ const char *file_line)
+ __attribute__((nonnull(1)));
+
+#if APR_POOL_DEBUG
+#define apr_pool_create_core_ex(newpool, abort_fn, allocator) \
+ apr_pool_create_unmanaged_ex_debug(newpool, abort_fn, allocator, \
+ APR_POOL__FILE_LINE__)
+
+#define apr_pool_create_unmanaged_ex(newpool, abort_fn, allocator) \
+ apr_pool_create_unmanaged_ex_debug(newpool, abort_fn, allocator, \
+ APR_POOL__FILE_LINE__)
+
+#endif
+
+/**
+ * Create a new pool.
+ * @param newpool The pool we have just created.
+ * @param parent The parent pool. If this is NULL, the new pool is a root
+ * pool. If it is non-NULL, the new pool will inherit all
+ * of its parent pool's attributes, except the apr_pool_t will
+ * be a sub-pool.
+ * @remark This function is thread-safe, in the sense that multiple threads
+ * can safely create subpools of the same parent pool concurrently.
+ * Similarly, a subpool can be created by one thread at the same
+ * time that another thread accesses the parent pool.
+ */
+#if defined(DOXYGEN)
+APR_DECLARE(apr_status_t) apr_pool_create(apr_pool_t **newpool,
+ apr_pool_t *parent);
+#else
+#if APR_POOL_DEBUG
+#define apr_pool_create(newpool, parent) \
+ apr_pool_create_ex_debug(newpool, parent, NULL, NULL, \
+ APR_POOL__FILE_LINE__)
+#else
+#define apr_pool_create(newpool, parent) \
+ apr_pool_create_ex(newpool, parent, NULL, NULL)
+#endif
+#endif
+
+/**
+ * Create a new unmanaged pool.
+ * @param newpool The pool we have just created.
+ */
+#if defined(DOXYGEN)
+APR_DECLARE(apr_status_t) apr_pool_create_core(apr_pool_t **newpool);
+APR_DECLARE(apr_status_t) apr_pool_create_unmanaged(apr_pool_t **newpool);
+#else
+#if APR_POOL_DEBUG
+#define apr_pool_create_core(newpool) \
+ apr_pool_create_unmanaged_ex_debug(newpool, NULL, NULL, \
+ APR_POOL__FILE_LINE__)
+#define apr_pool_create_unmanaged(newpool) \
+ apr_pool_create_unmanaged_ex_debug(newpool, NULL, NULL, \
+ APR_POOL__FILE_LINE__)
+#else
+#define apr_pool_create_core(newpool) \
+ apr_pool_create_unmanaged_ex(newpool, NULL, NULL)
+#define apr_pool_create_unmanaged(newpool) \
+ apr_pool_create_unmanaged_ex(newpool, NULL, NULL)
+#endif
+#endif
+
+/**
+ * Find the pool's allocator
+ * @param pool The pool to get the allocator from.
+ */
+APR_DECLARE(apr_allocator_t *) apr_pool_allocator_get(apr_pool_t *pool)
+ __attribute__((nonnull(1)));
+
+/**
+ * Clear all memory in the pool and run all the cleanups. This also destroys all
+ * subpools.
+ * @param p The pool to clear
+ * @remark This does not actually free the memory, it just allows the pool
+ * to re-use this memory for the next allocation.
+ * @see apr_pool_destroy()
+ */
+APR_DECLARE(void) apr_pool_clear(apr_pool_t *p) __attribute__((nonnull(1)));
+
+/**
+ * Debug version of apr_pool_clear.
+ * @param p See: apr_pool_clear.
+ * @param file_line Where the function is called from.
+ * This is usually APR_POOL__FILE_LINE__.
+ * @remark Only available when APR_POOL_DEBUG is defined.
+ * Call this directly if you have your apr_pool_clear
+ * calls in a wrapper function and wish to override
+ * the file_line argument to reflect the caller of
+ * your wrapper function. If you do not have
+ * apr_pool_clear in a wrapper, trust the macro
+ * and don't call apr_pool_destroy_clear directly.
+ */
+APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *p,
+ const char *file_line)
+ __attribute__((nonnull(1)));
+
+#if APR_POOL_DEBUG
+#define apr_pool_clear(p) \
+ apr_pool_clear_debug(p, APR_POOL__FILE_LINE__)
+#endif
+
+/**
+ * Destroy the pool. This takes similar action as apr_pool_clear() and then
+ * frees all the memory.
+ * @param p The pool to destroy
+ * @remark This will actually free the memory
+ */
+APR_DECLARE(void) apr_pool_destroy(apr_pool_t *p) __attribute__((nonnull(1)));
+
+/**
+ * Debug version of apr_pool_destroy.
+ * @param p See: apr_pool_destroy.
+ * @param file_line Where the function is called from.
+ * This is usually APR_POOL__FILE_LINE__.
+ * @remark Only available when APR_POOL_DEBUG is defined.
+ * Call this directly if you have your apr_pool_destroy
+ * calls in a wrapper function and wish to override
+ * the file_line argument to reflect the caller of
+ * your wrapper function. If you do not have
+ * apr_pool_destroy in a wrapper, trust the macro
+ * and don't call apr_pool_destroy_debug directly.
+ */
+APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *p,
+ const char *file_line)
+ __attribute__((nonnull(1)));
+
+#if APR_POOL_DEBUG
+#define apr_pool_destroy(p) \
+ apr_pool_destroy_debug(p, APR_POOL__FILE_LINE__)
+#endif
+
+
+/*
+ * Memory allocation
+ */
+
+/**
+ * Allocate a block of memory from a pool
+ * @param p The pool to allocate from
+ * @param size The amount of memory to allocate
+ * @return The allocated memory
+ */
+APR_DECLARE(void *) apr_palloc(apr_pool_t *p, apr_size_t size)
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+ __attribute__((alloc_size(2)))
+#endif
+ __attribute__((nonnull(1)));
+
+/**
+ * Debug version of apr_palloc
+ * @param p See: apr_palloc
+ * @param size See: apr_palloc
+ * @param file_line Where the function is called from.
+ * This is usually APR_POOL__FILE_LINE__.
+ * @return See: apr_palloc
+ */
+APR_DECLARE(void *) apr_palloc_debug(apr_pool_t *p, apr_size_t size,
+ const char *file_line)
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+ __attribute__((alloc_size(2)))
+#endif
+ __attribute__((nonnull(1)));
+
+#if APR_POOL_DEBUG
+#define apr_palloc(p, size) \
+ apr_palloc_debug(p, size, APR_POOL__FILE_LINE__)
+#endif
+
+/**
+ * Allocate a block of memory from a pool and set all of the memory to 0
+ * @param p The pool to allocate from
+ * @param size The amount of memory to allocate
+ * @return The allocated memory
+ */
+#if defined(DOXYGEN)
+APR_DECLARE(void *) apr_pcalloc(apr_pool_t *p, apr_size_t size);
+#elif !APR_POOL_DEBUG
+#define apr_pcalloc(p, size) memset(apr_palloc(p, size), 0, size)
+#endif
+
+/**
+ * Debug version of apr_pcalloc
+ * @param p See: apr_pcalloc
+ * @param size See: apr_pcalloc
+ * @param file_line Where the function is called from.
+ * This is usually APR_POOL__FILE_LINE__.
+ * @return See: apr_pcalloc
+ */
+APR_DECLARE(void *) apr_pcalloc_debug(apr_pool_t *p, apr_size_t size,
+ const char *file_line)
+ __attribute__((nonnull(1)));
+
+#if APR_POOL_DEBUG
+#define apr_pcalloc(p, size) \
+ apr_pcalloc_debug(p, size, APR_POOL__FILE_LINE__)
+#endif
+
+
+/*
+ * Pool Properties
+ */
+
+/**
+ * Set the function to be called when an allocation failure occurs.
+ * @remark If the program wants APR to exit on a memory allocation error,
+ * then this function can be called to set the callback to use (for
+ * performing cleanup and then exiting). If this function is not called,
+ * then APR will return an error and expect the calling program to
+ * deal with the error accordingly.
+ */
+APR_DECLARE(void) apr_pool_abort_set(apr_abortfunc_t abortfunc,
+ apr_pool_t *pool)
+ __attribute__((nonnull(2)));
+
+/**
+ * Get the abort function associated with the specified pool.
+ * @param pool The pool for retrieving the abort function.
+ * @return The abort function for the given pool.
+ */
+APR_DECLARE(apr_abortfunc_t) apr_pool_abort_get(apr_pool_t *pool)
+ __attribute__((nonnull(1)));
+
+/**
+ * Get the parent pool of the specified pool.
+ * @param pool The pool for retrieving the parent pool.
+ * @return The parent of the given pool.
+ */
+APR_DECLARE(apr_pool_t *) apr_pool_parent_get(apr_pool_t *pool)
+ __attribute__((nonnull(1)));
+
+/**
+ * Determine if pool a is an ancestor of pool b.
+ * @param a The pool to search
+ * @param b The pool to search for
+ * @return True if a is an ancestor of b, NULL is considered an ancestor
+ * of all pools.
+ * @remark if compiled with APR_POOL_DEBUG, this function will also
+ * return true if A is a pool which has been guaranteed by the caller
+ * (using apr_pool_join) to have a lifetime at least as long as some
+ * ancestor of pool B.
+ */
+APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b);
+
+/**
+ * Tag a pool (give it a name)
+ * @param pool The pool to tag
+ * @param tag The tag
+ */
+APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag)
+ __attribute__((nonnull(1)));
+
+
+/*
+ * User data management
+ */
+
+/**
+ * Set the data associated with the current pool
+ * @param data The user data associated with the pool.
+ * @param key The key to use for association
+ * @param cleanup The cleanup program to use to cleanup the data (NULL if none)
+ * @param pool The current pool
+ * @warning The data to be attached to the pool should have a life span
+ * at least as long as the pool it is being attached to.
+ *
+ * Users of APR must take EXTREME care when choosing a key to
+ * use for their data. It is possible to accidentally overwrite
+ * data by choosing a key that another part of the program is using.
+ * Therefore it is advised that steps are taken to ensure that unique
+ * keys are used for all of the userdata objects in a particular pool
+ * (the same key in two different pools or a pool and one of its
+ * subpools is okay) at all times. Careful namespace prefixing of
+ * key names is a typical way to help ensure this uniqueness.
+ *
+ */
+APR_DECLARE(apr_status_t) apr_pool_userdata_set(const void *data,
+ const char *key,
+ apr_status_t (*cleanup)(void *),
+ apr_pool_t *pool)
+ __attribute__((nonnull(2,4)));
+
+/**
+ * Set the data associated with the current pool
+ * @param data The user data associated with the pool.
+ * @param key The key to use for association
+ * @param cleanup The cleanup program to use to cleanup the data (NULL if none)
+ * @param pool The current pool
+ * @note same as apr_pool_userdata_set(), except that this version doesn't
+ * make a copy of the key (this function is useful, for example, when
+ * the key is a string literal)
+ * @warning This should NOT be used if the key could change addresses by
+ * any means between the apr_pool_userdata_setn() call and a
+ * subsequent apr_pool_userdata_get() on that key, such as if a
+ * static string is used as a userdata key in a DSO and the DSO could
+ * be unloaded and reloaded between the _setn() and the _get(). You
+ * MUST use apr_pool_userdata_set() in such cases.
+ * @warning More generally, the key and the data to be attached to the
+ * pool should have a life span at least as long as the pool itself.
+ *
+ */
+APR_DECLARE(apr_status_t) apr_pool_userdata_setn(
+ const void *data, const char *key,
+ apr_status_t (*cleanup)(void *),
+ apr_pool_t *pool)
+ __attribute__((nonnull(2,4)));
+
+/**
+ * Return the data associated with the current pool.
+ * @param data The user data associated with the pool.
+ * @param key The key for the data to retrieve
+ * @param pool The current pool.
+ */
+APR_DECLARE(apr_status_t) apr_pool_userdata_get(void **data, const char *key,
+ apr_pool_t *pool)
+ __attribute__((nonnull(1,2,3)));
+
+
+/**
+ * @defgroup PoolCleanup Pool Cleanup Functions
+ *
+ * Cleanups are performed in the reverse order they were registered. That is:
+ * Last In, First Out. A cleanup function can safely allocate memory from
+ * the pool that is being cleaned up. It can also safely register additional
+ * cleanups which will be run LIFO, directly after the current cleanup
+ * terminates. Cleanups have to take caution in calling functions that
+ * create subpools. Subpools, created during cleanup will NOT automatically
+ * be cleaned up. In other words, cleanups are to clean up after themselves.
+ *
+ * @{
+ */
+
+/**
+ * Register a function to be called when a pool is cleared or destroyed
+ * @param p The pool to register the cleanup with
+ * @param data The data to pass to the cleanup function.
+ * @param plain_cleanup The function to call when the pool is cleared
+ * or destroyed
+ * @param child_cleanup The function to call when a child process is about
+ * to exec - this function is called in the child, obviously!
+ */
+APR_DECLARE(void) apr_pool_cleanup_register(
+ apr_pool_t *p, const void *data,
+ apr_status_t (*plain_cleanup)(void *),
+ apr_status_t (*child_cleanup)(void *))
+ __attribute__((nonnull(3,4)));
+
+/**
+ * Register a function to be called when a pool is cleared or destroyed.
+ *
+ * Unlike apr_pool_cleanup_register which registers a cleanup
+ * that is called AFTER all subpools are destroyed, this function registers
+ * a function that will be called before any of the subpools are destroyed.
+ *
+ * @param p The pool to register the cleanup with
+ * @param data The data to pass to the cleanup function.
+ * @param plain_cleanup The function to call when the pool is cleared
+ * or destroyed
+ */
+APR_DECLARE(void) apr_pool_pre_cleanup_register(
+ apr_pool_t *p, const void *data,
+ apr_status_t (*plain_cleanup)(void *))
+ __attribute__((nonnull(3)));
+
+/**
+ * Remove a previously registered cleanup function.
+ *
+ * The cleanup most recently registered with @a p having the same values of
+ * @a data and @a cleanup will be removed.
+ *
+ * @param p The pool to remove the cleanup from
+ * @param data The data of the registered cleanup
+ * @param cleanup The function to remove from cleanup
+ * @remarks For some strange reason only the plain_cleanup is handled by this
+ * function
+ */
+APR_DECLARE(void) apr_pool_cleanup_kill(apr_pool_t *p, const void *data,
+ apr_status_t (*cleanup)(void *))
+ __attribute__((nonnull(3)));
+
+/**
+ * Replace the child cleanup function of a previously registered cleanup.
+ *
+ * The cleanup most recently registered with @a p having the same values of
+ * @a data and @a plain_cleanup will have the registered child cleanup
+ * function replaced with @a child_cleanup.
+ *
+ * @param p The pool of the registered cleanup
+ * @param data The data of the registered cleanup
+ * @param plain_cleanup The plain cleanup function of the registered cleanup
+ * @param child_cleanup The function to register as the child cleanup
+ */
+APR_DECLARE(void) apr_pool_child_cleanup_set(
+ apr_pool_t *p, const void *data,
+ apr_status_t (*plain_cleanup)(void *),
+ apr_status_t (*child_cleanup)(void *))
+ __attribute__((nonnull(3,4)));
+
+/**
+ * Run the specified cleanup function immediately and unregister it.
+ *
+ * The cleanup most recently registered with @a p having the same values of
+ * @a data and @a cleanup will be removed and @a cleanup will be called
+ * with @a data as the argument.
+ *
+ * @param p The pool to remove the cleanup from
+ * @param data The data to remove from cleanup
+ * @param cleanup The function to remove from cleanup
+ */
+APR_DECLARE(apr_status_t) apr_pool_cleanup_run(apr_pool_t *p, void *data,
+ apr_status_t (*cleanup)(void *))
+ __attribute__((nonnull(3)));
+
+/**
+ * An empty cleanup function.
+ *
+ * Passed to apr_pool_cleanup_register() when no cleanup is required.
+ *
+ * @param data The data to cleanup, will not be used by this function.
+ */
+APR_DECLARE_NONSTD(apr_status_t) apr_pool_cleanup_null(void *data);
+
+/**
+ * Run all registered child cleanups, in preparation for an exec()
+ * call in a forked child -- close files, etc., but *don't* flush I/O
+ * buffers, *don't* wait for subprocesses, and *don't* free any
+ * memory.
+ */
+APR_DECLARE(void) apr_pool_cleanup_for_exec(void);
+
+/** @} */
+
+/**
+ * @defgroup PoolDebug Pool Debugging functions
+ *
+ * pools have nested lifetimes -- sub_pools are destroyed when the
+ * parent pool is cleared. We allow certain liberties with operations
+ * on things such as tables (and on other structures in a more general
+ * sense) where we allow the caller to insert values into a table which
+ * were not allocated from the table's pool. The table's data will
+ * remain valid as long as all the pools from which its values are
+ * allocated remain valid.
+ *
+ * For example, if B is a sub pool of A, and you build a table T in
+ * pool B, then it's safe to insert data allocated in A or B into T
+ * (because B lives at most as long as A does, and T is destroyed when
+ * B is cleared/destroyed). On the other hand, if S is a table in
+ * pool A, it is safe to insert data allocated in A into S, but it
+ * is *not safe* to insert data allocated from B into S... because
+ * B can be cleared/destroyed before A is (which would leave dangling
+ * pointers in T's data structures).
+ *
+ * In general we say that it is safe to insert data into a table T
+ * if the data is allocated in any ancestor of T's pool. This is the
+ * basis on which the APR_POOL_DEBUG code works -- it tests these ancestor
+ * relationships for all data inserted into tables. APR_POOL_DEBUG also
+ * provides tools (apr_pool_find, and apr_pool_is_ancestor) for other
+ * folks to implement similar restrictions for their own data
+ * structures.
+ *
+ * However, sometimes this ancestor requirement is inconvenient --
+ * sometimes it's necessary to create a sub pool where the sub pool is
+ * guaranteed to have the same lifetime as the parent pool. This is a
+ * guarantee implemented by the *caller*, not by the pool code. That
+ * is, the caller guarantees they won't destroy the sub pool
+ * individually prior to destroying the parent pool.
+ *
+ * In this case the caller must call apr_pool_join() to indicate this
+ * guarantee to the APR_POOL_DEBUG code.
+ *
+ * These functions are only implemented when #APR_POOL_DEBUG is set.
+ *
+ * @{
+ */
+#if APR_POOL_DEBUG || defined(DOXYGEN)
+/**
+ * Guarantee that a subpool has the same lifetime as the parent.
+ * @param p The parent pool
+ * @param sub The subpool
+ */
+APR_DECLARE(void) apr_pool_join(apr_pool_t *p, apr_pool_t *sub)
+ __attribute__((nonnull(2)));
+
+/**
+ * Find a pool from something allocated in it.
+ * @param mem The thing allocated in the pool
+ * @return The pool it is allocated in
+ */
+APR_DECLARE(apr_pool_t *) apr_pool_find(const void *mem);
+
+/**
+ * Report the number of bytes currently in the pool
+ * @param p The pool to inspect
+ * @param recurse Recurse/include the subpools' sizes
+ * @return The number of bytes
+ */
+APR_DECLARE(apr_size_t) apr_pool_num_bytes(apr_pool_t *p, int recurse)
+ __attribute__((nonnull(1)));
+
+/**
+ * Lock a pool
+ * @param pool The pool to lock
+ * @param flag The flag
+ */
+APR_DECLARE(void) apr_pool_lock(apr_pool_t *pool, int flag);
+
+/** @} */
+
+#else /* APR_POOL_DEBUG or DOXYGEN */
+
+#ifdef apr_pool_join
+#undef apr_pool_join
+#endif
+#define apr_pool_join(a,b)
+
+#ifdef apr_pool_lock
+#undef apr_pool_lock
+#endif
+#define apr_pool_lock(pool, lock)
+
+#endif /* APR_POOL_DEBUG or DOXYGEN */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_POOLS_H */
diff --git a/include/apr_portable.h b/include/apr_portable.h
new file mode 100644
index 0000000..f56997e
--- /dev/null
+++ b/include/apr_portable.h
@@ -0,0 +1,549 @@
+/* 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 header file is where you should put ANY platform specific information.
+ * This should be the only header file that programs need to include that
+ * actually has platform dependent code which refers to the .
+ */
+#ifndef APR_PORTABLE_H
+#define APR_PORTABLE_H
+/**
+ * @file apr_portable.h
+ * @brief APR Portability Routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+#include "apr_network_io.h"
+#include "apr_errno.h"
+#include "apr_global_mutex.h"
+#include "apr_proc_mutex.h"
+#include "apr_time.h"
+#include "apr_dso.h"
+#include "apr_shm.h"
+
+#if APR_HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#if APR_HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if APR_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#if APR_HAVE_SEMAPHORE_H
+#include <semaphore.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_portabile Portability Routines
+ * @ingroup APR
+ * @{
+ */
+
+#ifdef WIN32
+/* The primitives for Windows types */
+typedef HANDLE apr_os_file_t;
+typedef HANDLE apr_os_dir_t;
+typedef SOCKET apr_os_sock_t;
+typedef HANDLE apr_os_proc_mutex_t;
+typedef HANDLE apr_os_thread_t;
+typedef HANDLE apr_os_proc_t;
+typedef DWORD apr_os_threadkey_t;
+typedef FILETIME apr_os_imp_time_t;
+typedef SYSTEMTIME apr_os_exp_time_t;
+typedef HANDLE apr_os_dso_handle_t;
+typedef HANDLE apr_os_shm_t;
+
+#elif defined(OS2)
+typedef HFILE apr_os_file_t;
+typedef HDIR apr_os_dir_t;
+typedef int apr_os_sock_t;
+typedef HMTX apr_os_proc_mutex_t;
+typedef TID apr_os_thread_t;
+typedef PID apr_os_proc_t;
+typedef PULONG apr_os_threadkey_t;
+typedef struct timeval apr_os_imp_time_t;
+typedef struct tm apr_os_exp_time_t;
+typedef HMODULE apr_os_dso_handle_t;
+typedef void* apr_os_shm_t;
+
+#elif defined(__BEOS__)
+#include <kernel/OS.h>
+#include <kernel/image.h>
+
+struct apr_os_proc_mutex_t {
+ sem_id sem;
+ int32 ben;
+};
+
+typedef int apr_os_file_t;
+typedef DIR apr_os_dir_t;
+typedef int apr_os_sock_t;
+typedef struct apr_os_proc_mutex_t apr_os_proc_mutex_t;
+typedef thread_id apr_os_thread_t;
+typedef thread_id apr_os_proc_t;
+typedef int apr_os_threadkey_t;
+typedef struct timeval apr_os_imp_time_t;
+typedef struct tm apr_os_exp_time_t;
+typedef image_id apr_os_dso_handle_t;
+typedef void* apr_os_shm_t;
+
+#elif defined(NETWARE)
+typedef int apr_os_file_t;
+typedef DIR apr_os_dir_t;
+typedef int apr_os_sock_t;
+typedef NXMutex_t apr_os_proc_mutex_t;
+typedef NXThreadId_t apr_os_thread_t;
+typedef long apr_os_proc_t;
+typedef NXKey_t apr_os_threadkey_t;
+typedef struct timeval apr_os_imp_time_t;
+typedef struct tm apr_os_exp_time_t;
+typedef void * apr_os_dso_handle_t;
+typedef void* apr_os_shm_t;
+
+#else
+/* Any other OS should go above this one. This is the lowest common
+ * denominator typedefs for all UNIX-like systems. :)
+ */
+
+/** Basic OS process mutex structure. */
+struct apr_os_proc_mutex_t {
+#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
+ /** Value used for SYS V Semaphore, FCNTL and FLOCK serialization */
+ int crossproc;
+#endif
+#if APR_HAS_PROC_PTHREAD_SERIALIZE
+ /** Value used for PTHREAD serialization */
+ pthread_mutex_t *pthread_interproc;
+#endif
+#if APR_HAS_THREADS
+ /* If no threads, no need for thread locks */
+#if APR_USE_PTHREAD_SERIALIZE
+ /** This value is currently unused within APR and Apache */
+ pthread_mutex_t *intraproc;
+#endif
+#endif
+#if APR_HAS_POSIXSEM_SERIALIZE
+ /** Value used for POSIX semaphores serialization */
+ sem_t *psem_interproc;
+#endif
+};
+
+typedef int apr_os_file_t; /**< native file */
+typedef DIR apr_os_dir_t; /**< native dir */
+typedef int apr_os_sock_t; /**< native dir */
+typedef struct apr_os_proc_mutex_t apr_os_proc_mutex_t; /**< native process
+ * mutex
+ */
+#if APR_HAS_THREADS && APR_HAVE_PTHREAD_H
+typedef pthread_t apr_os_thread_t; /**< native thread */
+typedef pthread_key_t apr_os_threadkey_t; /**< native thread address
+ * space */
+#endif
+typedef pid_t apr_os_proc_t; /**< native pid */
+typedef struct timeval apr_os_imp_time_t; /**< native timeval */
+typedef struct tm apr_os_exp_time_t; /**< native tm */
+/** @var apr_os_dso_handle_t
+ * native dso types
+ */
+#if defined(HPUX) || defined(HPUX10) || defined(HPUX11)
+#include <dl.h>
+typedef shl_t apr_os_dso_handle_t;
+#elif defined(DARWIN)
+#include <mach-o/dyld.h>
+typedef NSModule apr_os_dso_handle_t;
+#else
+typedef void * apr_os_dso_handle_t;
+#endif
+typedef void* apr_os_shm_t; /**< native SHM */
+
+#endif
+
+/**
+ * @typedef apr_os_sock_info_t
+ * @brief alias for local OS socket
+ */
+/**
+ * everything APR needs to know about an active socket to construct
+ * an APR socket from it; currently, this is platform-independent
+ */
+struct apr_os_sock_info_t {
+ apr_os_sock_t *os_sock; /**< always required */
+ struct sockaddr *local; /**< NULL if not yet bound */
+ struct sockaddr *remote; /**< NULL if not connected */
+ int family; /**< always required (APR_INET, APR_INET6, etc.) */
+ int type; /**< always required (SOCK_STREAM, SOCK_DGRAM, etc.) */
+ int protocol; /**< 0 or actual protocol (APR_PROTO_SCTP, APR_PROTO_TCP, etc.) */
+};
+
+typedef struct apr_os_sock_info_t apr_os_sock_info_t;
+
+#if APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN)
+/** Opaque global mutex type */
+#define apr_os_global_mutex_t apr_os_proc_mutex_t
+/** @return apr_os_global_mutex */
+#define apr_os_global_mutex_get apr_os_proc_mutex_get
+#else
+ /** Thread and process mutex for those platforms where process mutexes
+ * are not held in threads.
+ */
+ struct apr_os_global_mutex_t {
+ apr_pool_t *pool;
+ apr_proc_mutex_t *proc_mutex;
+#if APR_HAS_THREADS
+ apr_thread_mutex_t *thread_mutex;
+#endif /* APR_HAS_THREADS */
+ };
+ typedef struct apr_os_global_mutex_t apr_os_global_mutex_t;
+
+APR_DECLARE(apr_status_t) apr_os_global_mutex_get(apr_os_global_mutex_t *ospmutex,
+ apr_global_mutex_t *pmutex);
+#endif
+
+
+/**
+ * convert the file from apr type to os specific type.
+ * @param thefile The os specific file we are converting to
+ * @param file The apr file to convert.
+ * @remark On Unix, it is only possible to get a file descriptor from
+ * an apr file type.
+ */
+APR_DECLARE(apr_status_t) apr_os_file_get(apr_os_file_t *thefile,
+ apr_file_t *file);
+
+/**
+ * convert the dir from apr type to os specific type.
+ * @param thedir The os specific dir we are converting to
+ * @param dir The apr dir to convert.
+ */
+APR_DECLARE(apr_status_t) apr_os_dir_get(apr_os_dir_t **thedir,
+ apr_dir_t *dir);
+
+/**
+ * Convert the socket from an apr type to an OS specific socket
+ * @param thesock The socket to convert.
+ * @param sock The os specific equivalent of the apr socket..
+ */
+APR_DECLARE(apr_status_t) apr_os_sock_get(apr_os_sock_t *thesock,
+ apr_socket_t *sock);
+
+/**
+ * Convert the proc mutex from apr type to os specific type
+ * @param ospmutex The os specific proc mutex we are converting to.
+ * @param pmutex The apr proc mutex to convert.
+ */
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
+ apr_proc_mutex_t *pmutex);
+
+/**
+ * Convert the proc mutex from apr type to os specific type, also
+ * providing the mechanism used by the apr mutex.
+ * @param ospmutex The os specific proc mutex we are converting to.
+ * @param pmutex The apr proc mutex to convert.
+ * @param mech The mechanism used by the apr proc mutex (if not NULL).
+ * @remark Allows for disambiguation for platforms with multiple mechanisms
+ * available.
+ */
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_get_ex(apr_os_proc_mutex_t *ospmutex,
+ apr_proc_mutex_t *pmutex,
+ apr_lockmech_e *mech);
+
+/**
+ * Get the exploded time in the platforms native format.
+ * @param ostime the native time format
+ * @param aprtime the time to convert
+ */
+APR_DECLARE(apr_status_t) apr_os_exp_time_get(apr_os_exp_time_t **ostime,
+ apr_time_exp_t *aprtime);
+
+/**
+ * Get the imploded time in the platforms native format.
+ * @param ostime the native time format
+ * @param aprtime the time to convert
+ */
+APR_DECLARE(apr_status_t) apr_os_imp_time_get(apr_os_imp_time_t **ostime,
+ apr_time_t *aprtime);
+
+/**
+ * convert the shm from apr type to os specific type.
+ * @param osshm The os specific shm representation
+ * @param shm The apr shm to convert.
+ */
+APR_DECLARE(apr_status_t) apr_os_shm_get(apr_os_shm_t *osshm,
+ apr_shm_t *shm);
+
+#if APR_HAS_THREADS || defined(DOXYGEN)
+/**
+ * @defgroup apr_os_thread Thread portability Routines
+ * @{
+ */
+/**
+ * convert the thread to os specific type from apr type.
+ * @param thethd The apr thread to convert
+ * @param thd The os specific thread we are converting to
+ */
+APR_DECLARE(apr_status_t) apr_os_thread_get(apr_os_thread_t **thethd,
+ apr_thread_t *thd);
+
+/**
+ * convert the thread private memory key to os specific type from an apr type.
+ * @param thekey The apr handle we are converting from.
+ * @param key The os specific handle we are converting to.
+ */
+APR_DECLARE(apr_status_t) apr_os_threadkey_get(apr_os_threadkey_t *thekey,
+ apr_threadkey_t *key);
+
+/**
+ * convert the thread from os specific type to apr type.
+ * @param thd The apr thread we are converting to.
+ * @param thethd The os specific thread to convert
+ * @param cont The pool to use if it is needed.
+ */
+APR_DECLARE(apr_status_t) apr_os_thread_put(apr_thread_t **thd,
+ apr_os_thread_t *thethd,
+ apr_pool_t *cont);
+
+/**
+ * convert the thread private memory key from os specific type to apr type.
+ * @param key The apr handle we are converting to.
+ * @param thekey The os specific handle to convert
+ * @param cont The pool to use if it is needed.
+ */
+APR_DECLARE(apr_status_t) apr_os_threadkey_put(apr_threadkey_t **key,
+ apr_os_threadkey_t *thekey,
+ apr_pool_t *cont);
+/**
+ * Get the thread ID
+ */
+APR_DECLARE(apr_os_thread_t) apr_os_thread_current(void);
+
+/**
+ * Compare two thread id's
+ * @param tid1 1st Thread ID to compare
+ * @param tid2 2nd Thread ID to compare
+ * @return non-zero if the two threads are equal, zero otherwise
+ */
+APR_DECLARE(int) apr_os_thread_equal(apr_os_thread_t tid1,
+ apr_os_thread_t tid2);
+
+/** @} */
+#endif /* APR_HAS_THREADS */
+
+/**
+ * convert the file from os specific type to apr type.
+ * @param file The apr file we are converting to.
+ * @param thefile The os specific file to convert
+ * @param flags The flags that were used to open this file.
+ * @param cont The pool to use if it is needed.
+ * @remark On Unix, it is only possible to put a file descriptor into
+ * an apr file type.
+ */
+APR_DECLARE(apr_status_t) apr_os_file_put(apr_file_t **file,
+ apr_os_file_t *thefile,
+ apr_int32_t flags, apr_pool_t *cont);
+
+/**
+ * convert the file from os specific type to apr type.
+ * @param file The apr file we are converting to.
+ * @param thefile The os specific pipe to convert
+ * @param cont The pool to use if it is needed.
+ * @remark On Unix, it is only possible to put a file descriptor into
+ * an apr file type.
+ */
+APR_DECLARE(apr_status_t) apr_os_pipe_put(apr_file_t **file,
+ apr_os_file_t *thefile,
+ apr_pool_t *cont);
+
+/**
+ * convert the file from os specific type to apr type.
+ * @param file The apr file we are converting to.
+ * @param thefile The os specific pipe to convert
+ * @param register_cleanup A cleanup will be registered on the apr_file_t
+ * to issue apr_file_close().
+ * @param cont The pool to use if it is needed.
+ * @remark On Unix, it is only possible to put a file descriptor into
+ * an apr file type.
+ */
+APR_DECLARE(apr_status_t) apr_os_pipe_put_ex(apr_file_t **file,
+ apr_os_file_t *thefile,
+ int register_cleanup,
+ apr_pool_t *cont);
+
+/**
+ * convert the dir from os specific type to apr type.
+ * @param dir The apr dir we are converting to.
+ * @param thedir The os specific dir to convert
+ * @param cont The pool to use when creating to apr directory.
+ */
+APR_DECLARE(apr_status_t) apr_os_dir_put(apr_dir_t **dir,
+ apr_os_dir_t *thedir,
+ apr_pool_t *cont);
+
+/**
+ * Convert a socket from the os specific type to the APR type. If
+ * sock points to NULL, a socket will be created from the pool
+ * provided. If **sock does not point to NULL, the structure pointed
+ * to by sock will be reused and updated with the given socket.
+ * @param sock The pool to use.
+ * @param thesock The socket to convert to.
+ * @param cont The socket we are converting to an apr type.
+ * @remark If it is a true socket, it is best to call apr_os_sock_make()
+ * and provide APR with more information about the socket.
+ */
+APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock,
+ apr_os_sock_t *thesock,
+ apr_pool_t *cont);
+
+/**
+ * Create a socket from an existing descriptor and local and remote
+ * socket addresses.
+ * @param apr_sock The new socket that has been set up
+ * @param os_sock_info The os representation of the socket handle and
+ * other characteristics of the socket
+ * @param cont The pool to use
+ * @remark If you only know the descriptor/handle or if it isn't really
+ * a true socket, use apr_os_sock_put() instead.
+ */
+APR_DECLARE(apr_status_t) apr_os_sock_make(apr_socket_t **apr_sock,
+ apr_os_sock_info_t *os_sock_info,
+ apr_pool_t *cont);
+
+/**
+ * Convert the proc mutex from os specific type to apr type
+ * @param pmutex The apr proc mutex we are converting to.
+ * @param ospmutex The os specific proc mutex to convert.
+ * @param cont The pool to use if it is needed.
+ */
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
+ apr_os_proc_mutex_t *ospmutex,
+ apr_pool_t *cont);
+
+/**
+ * Convert the proc mutex from os specific type to apr type, using the
+ * specified mechanism.
+ * @param pmutex The apr proc mutex we are converting to.
+ * @param ospmutex The os specific proc mutex to convert.
+ * @param mech The apr mutex locking mechanism
+ * @param register_cleanup Whether to destroy the os mutex with the apr
+ * one (either on explicit destroy or pool cleanup).
+ * @param cont The pool to use if it is needed.
+ * @remark Allows for disambiguation for platforms with multiple mechanisms
+ * available.
+ */
+APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
+ apr_os_proc_mutex_t *ospmutex,
+ apr_lockmech_e mech,
+ int register_cleanup,
+ apr_pool_t *cont);
+
+/**
+ * Put the imploded time in the APR format.
+ * @param aprtime the APR time format
+ * @param ostime the time to convert
+ * @param cont the pool to use if necessary
+ */
+APR_DECLARE(apr_status_t) apr_os_imp_time_put(apr_time_t *aprtime,
+ apr_os_imp_time_t **ostime,
+ apr_pool_t *cont);
+
+/**
+ * Put the exploded time in the APR format.
+ * @param aprtime the APR time format
+ * @param ostime the time to convert
+ * @param cont the pool to use if necessary
+ */
+APR_DECLARE(apr_status_t) apr_os_exp_time_put(apr_time_exp_t *aprtime,
+ apr_os_exp_time_t **ostime,
+ apr_pool_t *cont);
+
+/**
+ * convert the shared memory from os specific type to apr type.
+ * @param shm The apr shm representation of osshm
+ * @param osshm The os specific shm identity
+ * @param cont The pool to use if it is needed.
+ * @remark On fork()ed architectures, this is typically nothing more than
+ * the memory block mapped. On non-fork architectures, this is typically
+ * some internal handle to pass the mapping from process to process.
+ */
+APR_DECLARE(apr_status_t) apr_os_shm_put(apr_shm_t **shm,
+ apr_os_shm_t *osshm,
+ apr_pool_t *cont);
+
+
+#if APR_HAS_DSO || defined(DOXYGEN)
+/**
+ * @defgroup apr_os_dso DSO (Dynamic Loading) Portability Routines
+ * @{
+ */
+/**
+ * convert the dso handle from os specific to apr
+ * @param dso The apr handle we are converting to
+ * @param thedso the os specific handle to convert
+ * @param pool the pool to use if it is needed
+ */
+APR_DECLARE(apr_status_t) apr_os_dso_handle_put(apr_dso_handle_t **dso,
+ apr_os_dso_handle_t thedso,
+ apr_pool_t *pool);
+
+/**
+ * convert the apr dso handle into an os specific one
+ * @param aprdso The apr dso handle to convert
+ * @param dso The os specific dso to return
+ */
+APR_DECLARE(apr_status_t) apr_os_dso_handle_get(apr_os_dso_handle_t *dso,
+ apr_dso_handle_t *aprdso);
+
+/** @} */
+#endif /* APR_HAS_DSO */
+
+
+#if APR_HAS_OS_UUID
+/**
+ * Private: apr-util's apr_uuid module when supported by the platform
+ */
+APR_DECLARE(apr_status_t) apr_os_uuid_get(unsigned char *uuid_data);
+#endif
+
+
+/**
+ * Get the name of the system default character set.
+ * @param pool the pool to allocate the name from, if needed
+ */
+APR_DECLARE(const char*) apr_os_default_encoding(apr_pool_t *pool);
+
+
+/**
+ * Get the name of the current locale character set.
+ * @param pool the pool to allocate the name from, if needed
+ * @remark Defers to apr_os_default_encoding() if the current locale's
+ * data can't be retrieved on this system.
+ */
+APR_DECLARE(const char*) apr_os_locale_encoding(apr_pool_t *pool);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_PORTABLE_H */
diff --git a/include/apr_proc_mutex.h b/include/apr_proc_mutex.h
new file mode 100644
index 0000000..418c950
--- /dev/null
+++ b/include/apr_proc_mutex.h
@@ -0,0 +1,192 @@
+/* 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 APR_PROC_MUTEX_H
+#define APR_PROC_MUTEX_H
+
+/**
+ * @file apr_proc_mutex.h
+ * @brief APR Process Locking Routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_perms_set.h"
+#include "apr_time.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_proc_mutex Process Locking Routines
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * Enumerated potential types for APR process locking methods
+ * @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
+ * APR_LOCK_foo. Only APR_LOCK_DEFAULT is portable.
+ */
+typedef enum {
+ APR_LOCK_FCNTL, /**< fcntl() */
+ APR_LOCK_FLOCK, /**< flock() */
+ APR_LOCK_SYSVSEM, /**< System V Semaphores */
+ APR_LOCK_PROC_PTHREAD, /**< POSIX pthread process-based locking */
+ APR_LOCK_POSIXSEM, /**< POSIX semaphore process-based locking */
+ APR_LOCK_DEFAULT, /**< Use the default process lock */
+ APR_LOCK_DEFAULT_TIMED /**< Use the default process timed lock */
+} apr_lockmech_e;
+
+/** Opaque structure representing a process mutex. */
+typedef struct apr_proc_mutex_t apr_proc_mutex_t;
+
+/* Function definitions */
+
+/**
+ * Create and initialize a mutex that can be used to synchronize processes.
+ * @param mutex the memory address where the newly created mutex will be
+ * stored.
+ * @param fname A file name to use if the lock mechanism requires one. This
+ * argument should always be provided. The lock code itself will
+ * determine if it should be used.
+ * @param mech The mechanism to use for the interprocess lock, if any; one of
+ * <PRE>
+ * APR_LOCK_FCNTL
+ * APR_LOCK_FLOCK
+ * APR_LOCK_SYSVSEM
+ * APR_LOCK_POSIXSEM
+ * APR_LOCK_PROC_PTHREAD
+ * APR_LOCK_DEFAULT pick the default mechanism for the platform
+ * </PRE>
+ * @param pool the pool from which to allocate the mutex.
+ * @see apr_lockmech_e
+ * @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
+ * APR_LOCK_foo. Only APR_LOCK_DEFAULT is portable.
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
+ const char *fname,
+ apr_lockmech_e mech,
+ apr_pool_t *pool);
+
+/**
+ * Re-open a mutex in a child process.
+ * @param mutex The newly re-opened mutex structure.
+ * @param fname A file name to use if the mutex mechanism requires one. This
+ * argument should always be provided. The mutex code itself will
+ * determine if it should be used. This filename should be the
+ * same one that was passed to apr_proc_mutex_create().
+ * @param pool The pool to operate on.
+ * @remark This function must be called to maintain portability, even
+ * if the underlying lock mechanism does not require it.
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
+ const char *fname,
+ apr_pool_t *pool);
+
+/**
+ * Acquire the lock for the given mutex. If the mutex is already locked,
+ * the current thread will be put to sleep until the lock becomes available.
+ * @param mutex the mutex on which to acquire the lock.
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex);
+
+/**
+ * Attempt to acquire the lock for the given mutex. If the mutex has already
+ * been acquired, the call returns immediately with APR_EBUSY. Note: it
+ * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
+ * if the return value was APR_EBUSY, for portability reasons.
+ * @param mutex the mutex on which to attempt the lock acquiring.
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex);
+
+/**
+ * Attempt to acquire the lock for the given mutex until timeout expires.
+ * If the acquisition time outs, the call returns with APR_TIMEUP.
+ * @param mutex the mutex on which to attempt the lock acquiring.
+ * @param timeout the relative timeout (microseconds).
+ * @note A negative or nul timeout means immediate attempt, returning
+ * APR_TIMEUP without blocking if it the lock is already acquired.
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_timedlock(apr_proc_mutex_t *mutex,
+ apr_interval_time_t timeout);
+
+/**
+ * Release the lock for the given mutex.
+ * @param mutex the mutex from which to release the lock.
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex);
+
+/**
+ * Destroy the mutex and free the memory associated with the lock.
+ * @param mutex the mutex to destroy.
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex);
+
+/**
+ * Destroy the mutex and free the memory associated with the lock.
+ * @param mutex the mutex to destroy.
+ * @note This function is generally used to kill a cleanup on an already
+ * created mutex
+ */
+APR_DECLARE(apr_status_t) apr_proc_mutex_cleanup(void *mutex);
+
+/**
+ * Return the name of the lockfile for the mutex, or NULL
+ * if the mutex doesn't use a lock file
+ */
+
+APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex);
+
+/**
+ * Get the mechanism of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism from.
+ */
+APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex);
+
+/**
+ * Get the mechanism's name of the mutex, as it relates to the actual method
+ * used for the underlying apr_proc_mutex_t.
+ * @param mutex the mutex to get the mechanism's name from.
+ */
+APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex);
+
+/**
+ * Display the name of the default mutex: APR_LOCK_DEFAULT
+ */
+APR_DECLARE(const char *) apr_proc_mutex_defname(void);
+
+/**
+ * Set mutex permissions.
+ */
+APR_PERMS_SET_IMPLEMENT(proc_mutex);
+
+/**
+ * Get the pool used by this proc_mutex.
+ * @return apr_pool_t the pool
+ */
+APR_POOL_DECLARE_ACCESSOR(proc_mutex);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_PROC_MUTEX_H */
diff --git a/include/apr_random.h b/include/apr_random.h
new file mode 100644
index 0000000..2915435
--- /dev/null
+++ b/include/apr_random.h
@@ -0,0 +1,153 @@
+/* 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 APR_RANDOM_H
+#define APR_RANDOM_H
+
+/**
+ * @file apr_random.h
+ * @brief APR PRNG routines
+ */
+
+#include "apr_pools.h"
+#include "apr_thread_proc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_random PRNG Routines
+ * @ingroup APR
+ * @{
+ */
+
+typedef struct apr_crypto_hash_t apr_crypto_hash_t;
+
+typedef void apr_crypto_hash_init_t(apr_crypto_hash_t *hash);
+typedef void apr_crypto_hash_add_t(apr_crypto_hash_t *hash, const void *data,
+ apr_size_t bytes);
+typedef void apr_crypto_hash_finish_t(apr_crypto_hash_t *hash,
+ unsigned char *result);
+
+
+/* FIXME: make this opaque */
+struct apr_crypto_hash_t {
+ apr_crypto_hash_init_t *init;
+ apr_crypto_hash_add_t *add;
+ apr_crypto_hash_finish_t *finish;
+ apr_size_t size;
+ void *data;
+};
+
+/**
+ * Allocate and initialize the SHA-256 context
+ * @param p The pool to allocate from
+ */
+APR_DECLARE(apr_crypto_hash_t *) apr_crypto_sha256_new(apr_pool_t *p);
+
+/** Opaque PRNG structure. */
+typedef struct apr_random_t apr_random_t;
+
+/**
+ * Initialize a PRNG state
+ * @param g The PRNG state
+ * @param p The pool to allocate from
+ * @param pool_hash Pool hash functions
+ * @param key_hash Key hash functions
+ * @param prng_hash PRNG hash functions
+ */
+APR_DECLARE(void) apr_random_init(apr_random_t *g, apr_pool_t *p,
+ apr_crypto_hash_t *pool_hash,
+ apr_crypto_hash_t *key_hash,
+ apr_crypto_hash_t *prng_hash);
+/**
+ * Allocate and initialize (apr_crypto_sha256_new) a new PRNG state.
+ * @param p The pool to allocate from
+ */
+APR_DECLARE(apr_random_t *) apr_random_standard_new(apr_pool_t *p);
+
+/**
+ * Mix the randomness pools.
+ * @param g The PRNG state
+ * @param entropy_ Entropy buffer
+ * @param bytes Length of entropy_ in bytes
+ */
+APR_DECLARE(void) apr_random_add_entropy(apr_random_t *g,
+ const void *entropy_,
+ apr_size_t bytes);
+/**
+ * Generate cryptographically insecure random bytes.
+ * @param g The RNG state
+ * @param random Buffer to fill with random bytes
+ * @param bytes Length of buffer in bytes
+ */
+APR_DECLARE(apr_status_t) apr_random_insecure_bytes(apr_random_t *g,
+ void *random,
+ apr_size_t bytes);
+
+/**
+ * Generate cryptographically secure random bytes.
+ * @param g The RNG state
+ * @param random Buffer to fill with random bytes
+ * @param bytes Length of buffer in bytes
+ */
+APR_DECLARE(apr_status_t) apr_random_secure_bytes(apr_random_t *g,
+ void *random,
+ apr_size_t bytes);
+/**
+ * Ensures that E bits of conditional entropy are mixed into the PRNG
+ * before any further randomness is extracted.
+ * @param g The RNG state
+ */
+APR_DECLARE(void) apr_random_barrier(apr_random_t *g);
+
+/**
+ * Return APR_SUCCESS if the cryptographic PRNG has been seeded with
+ * enough data, APR_ENOTENOUGHENTROPY otherwise.
+ * @param r The RNG state
+ */
+APR_DECLARE(apr_status_t) apr_random_secure_ready(apr_random_t *r);
+
+/**
+ * Return APR_SUCCESS if the PRNG has been seeded with enough data,
+ * APR_ENOTENOUGHENTROPY otherwise.
+ * @param r The PRNG state
+ */
+APR_DECLARE(apr_status_t) apr_random_insecure_ready(apr_random_t *r);
+
+/**
+ * Mix the randomness pools after forking.
+ * @param proc The resulting process handle from apr_proc_fork()
+ * @remark Call this in the child after forking to mix the randomness
+ * pools. Note that its generally a bad idea to fork a process with a
+ * real PRNG in it - better to have the PRNG externally and get the
+ * randomness from there. However, if you really must do it, then you
+ * should supply all your entropy to all the PRNGs - don't worry, they
+ * won't produce the same output.
+ * @remark Note that apr_proc_fork() calls this for you, so only weird
+ * applications need ever call it themselves.
+ * @internal
+ */
+APR_DECLARE(void) apr_random_after_fork(apr_proc_t *proc);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_RANDOM_H */
diff --git a/include/apr_ring.h b/include/apr_ring.h
new file mode 100644
index 0000000..7280245
--- /dev/null
+++ b/include/apr_ring.h
@@ -0,0 +1,517 @@
+/* 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 code draws heavily from the 4.4BSD <sys/queue.h> macros
+ * and Dean Gaudet's "splim/ring.h".
+ * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h>
+ * <http://www.arctic.org/~dean/splim/>
+ *
+ * We'd use Dean's code directly if we could guarantee the
+ * availability of inline functions.
+ */
+
+#ifndef APR_RING_H
+#define APR_RING_H
+
+/**
+ * @file apr_ring.h
+ * @brief APR Rings
+ */
+
+/*
+ * for offsetof()
+ */
+#include "apr_general.h"
+
+/**
+ * @defgroup apr_ring Ring Macro Implementations
+ * @ingroup APR
+ * A ring is a kind of doubly-linked list that can be manipulated
+ * without knowing where its head is.
+ * @{
+ */
+
+/**
+ * The Ring Element
+ *
+ * A ring element struct is linked to the other elements in the ring
+ * through its ring entry field, e.g.
+ * <pre>
+ * struct my_element_t {
+ * APR_RING_ENTRY(my_element_t) link;
+ * int foo;
+ * char *bar;
+ * };
+ * </pre>
+ *
+ * An element struct may be put on more than one ring if it has more
+ * than one APR_RING_ENTRY field. Each APR_RING_ENTRY has a corresponding
+ * APR_RING_HEAD declaration.
+ *
+ * @warning For strict C standards compliance you should put the APR_RING_ENTRY
+ * first in the element struct unless the head is always part of a larger
+ * object with enough earlier fields to accommodate the offsetof() used
+ * to compute the ring sentinel below. You can usually ignore this caveat.
+ */
+#define APR_RING_ENTRY(elem) \
+ struct { \
+ struct elem * volatile next; \
+ struct elem * volatile prev; \
+ }
+
+/**
+ * The Ring Head
+ *
+ * Each ring is managed via its head, which is a struct declared like this:
+ * <pre>
+ * APR_RING_HEAD(my_ring_t, my_element_t);
+ * struct my_ring_t ring, *ringp;
+ * </pre>
+ *
+ * This struct looks just like the element link struct so that we can
+ * be sure that the typecasting games will work as expected.
+ *
+ * The first element in the ring is next after the head, and the last
+ * element is just before the head.
+ */
+#define APR_RING_HEAD(head, elem) \
+ struct head { \
+ struct elem * volatile next; \
+ struct elem * volatile prev; \
+ }
+
+/**
+ * The Ring Sentinel
+ *
+ * This is the magic pointer value that occurs before the first and
+ * after the last elements in the ring, computed from the address of
+ * the ring's head. The head itself isn't an element, but in order to
+ * get rid of all the special cases when dealing with the ends of the
+ * ring, we play typecasting games to make it look like one.
+ *
+ * Here is a diagram to illustrate the arrangements of the next and
+ * prev pointers of each element in a single ring. Note that they point
+ * to the start of each element, not to the APR_RING_ENTRY structure.
+ *
+ * <pre>
+ * +->+------+<-+ +->+------+<-+ +->+------+<-+
+ * | |struct| | | |struct| | | |struct| |
+ * / | elem | \/ | elem | \/ | elem | \
+ * ... | | /\ | | /\ | | ...
+ * +------+ | | +------+ | | +------+
+ * ...--|prev | | +--|ring | | +--|prev |
+ * | next|--+ | entry|--+ | next|--...
+ * +------+ +------+ +------+
+ * | etc. | | etc. | | etc. |
+ * : : : : : :
+ * </pre>
+ *
+ * The APR_RING_HEAD is nothing but a bare APR_RING_ENTRY. The prev
+ * and next pointers in the first and last elements don't actually
+ * point to the head, they point to a phantom place called the
+ * sentinel. Its value is such that last->next->next == first because
+ * the offset from the sentinel to the head's next pointer is the same
+ * as the offset from the start of an element to its next pointer.
+ * This also works in the opposite direction.
+ *
+ * <pre>
+ * last first
+ * +->+------+<-+ +->sentinel<-+ +->+------+<-+
+ * | |struct| | | | | |struct| |
+ * / | elem | \/ \/ | elem | \
+ * ... | | /\ /\ | | ...
+ * +------+ | | +------+ | | +------+
+ * ...--|prev | | +--|ring | | +--|prev |
+ * | next|--+ | head|--+ | next|--...
+ * +------+ +------+ +------+
+ * | etc. | | etc. |
+ * : : : :
+ * </pre>
+ *
+ * Note that the offset mentioned above is different for each kind of
+ * ring that the element may be on, and each kind of ring has a unique
+ * name for its APR_RING_ENTRY in each element, and has its own type
+ * for its APR_RING_HEAD.
+ *
+ * Note also that if the offset is non-zero (which is required if an
+ * element has more than one APR_RING_ENTRY), the unreality of the
+ * sentinel may have bad implications on very perverse implementations
+ * of C -- see the warning in APR_RING_ENTRY.
+ *
+ * @param hp The head of the ring
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_SENTINEL(hp, elem, link) \
+ (struct elem *)((char *)(&(hp)->next) - APR_OFFSETOF(struct elem, link))
+
+/**
+ * The first element of the ring
+ * @param hp The head of the ring
+ */
+#define APR_RING_FIRST(hp) (hp)->next
+/**
+ * The last element of the ring
+ * @param hp The head of the ring
+ */
+#define APR_RING_LAST(hp) (hp)->prev
+/**
+ * The next element in the ring
+ * @param ep The current element
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_NEXT(ep, link) (ep)->link.next
+/**
+ * The previous element in the ring
+ * @param ep The current element
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_PREV(ep, link) (ep)->link.prev
+
+
+/**
+ * Initialize a ring
+ * @param hp The head of the ring
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_INIT(hp, elem, link) do { \
+ APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
+ APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); \
+ } while (0)
+
+/**
+ * Determine if a ring is empty
+ * @param hp The head of the ring
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ * @return true or false
+ */
+#define APR_RING_EMPTY(hp, elem, link) \
+ (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))
+
+/**
+ * Initialize a singleton element
+ * @param ep The element
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_ELEM_INIT(ep, link) do { \
+ APR_RING_NEXT((ep), link) = (ep); \
+ APR_RING_PREV((ep), link) = (ep); \
+ } while (0)
+
+
+/**
+ * Splice the sequence ep1..epN into the ring before element lep
+ * (..lep.. becomes ..ep1..epN..lep..)
+ * @warning This doesn't work for splicing before the first element or on
+ * empty rings... see APR_RING_SPLICE_HEAD for one that does
+ * @param lep Element in the ring to splice before
+ * @param ep1 First element in the sequence to splice in
+ * @param epN Last element in the sequence to splice in
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do { \
+ APR_RING_NEXT((epN), link) = (lep); \
+ APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link); \
+ APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1); \
+ APR_RING_PREV((lep), link) = (epN); \
+ } while (0)
+
+/**
+ * Splice the sequence ep1..epN into the ring after element lep
+ * (..lep.. becomes ..lep..ep1..epN..)
+ * @warning This doesn't work for splicing after the last element or on
+ * empty rings... see APR_RING_SPLICE_TAIL for one that does
+ * @param lep Element in the ring to splice after
+ * @param ep1 First element in the sequence to splice in
+ * @param epN Last element in the sequence to splice in
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do { \
+ APR_RING_PREV((ep1), link) = (lep); \
+ APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link); \
+ APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN); \
+ APR_RING_NEXT((lep), link) = (ep1); \
+ } while (0)
+
+/**
+ * Insert the element nep into the ring before element lep
+ * (..lep.. becomes ..nep..lep..)
+ * @warning This doesn't work for inserting before the first element or on
+ * empty rings... see APR_RING_INSERT_HEAD for one that does
+ * @param lep Element in the ring to insert before
+ * @param nep Element to insert
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_INSERT_BEFORE(lep, nep, link) \
+ APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)
+
+/**
+ * Insert the element nep into the ring after element lep
+ * (..lep.. becomes ..lep..nep..)
+ * @warning This doesn't work for inserting after the last element or on
+ * empty rings... see APR_RING_INSERT_TAIL for one that does
+ * @param lep Element in the ring to insert after
+ * @param nep Element to insert
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_INSERT_AFTER(lep, nep, link) \
+ APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)
+
+
+/**
+ * Splice the sequence ep1..epN into the ring before the first element
+ * (..hp.. becomes ..hp..ep1..epN..)
+ * @param hp Head of the ring
+ * @param ep1 First element in the sequence to splice in
+ * @param epN Last element in the sequence to splice in
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) do { \
+ APR_RING_PREV((ep1), link) = APR_RING_SENTINEL((hp), elem, link);\
+ APR_RING_NEXT((epN), link) = APR_RING_FIRST((hp)); \
+ APR_RING_PREV(APR_RING_FIRST((hp)), link) = (epN); \
+ APR_RING_FIRST((hp)) = (ep1); \
+ } while (0)
+
+/**
+ * Splice the sequence ep1..epN into the ring after the last element
+ * (..hp.. becomes ..ep1..epN..hp..)
+ * @param hp Head of the ring
+ * @param ep1 First element in the sequence to splice in
+ * @param epN Last element in the sequence to splice in
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) do { \
+ APR_RING_NEXT((epN), link) = APR_RING_SENTINEL((hp), elem, link);\
+ APR_RING_PREV((ep1), link) = APR_RING_LAST((hp)); \
+ APR_RING_NEXT(APR_RING_LAST((hp)), link) = (ep1); \
+ APR_RING_LAST((hp)) = (epN); \
+ } while (0)
+
+/**
+ * Insert the element nep into the ring before the first element
+ * (..hp.. becomes ..hp..nep..)
+ * @param hp Head of the ring
+ * @param nep Element to insert
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_INSERT_HEAD(hp, nep, elem, link) \
+ APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)
+
+/**
+ * Insert the element nep into the ring after the last element
+ * (..hp.. becomes ..nep..hp..)
+ * @param hp Head of the ring
+ * @param nep Element to insert
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_INSERT_TAIL(hp, nep, elem, link) \
+ APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)
+
+/**
+ * Concatenate ring h2 onto the end of ring h1, leaving h2 empty.
+ * @param h1 Head of the ring to concatenate onto
+ * @param h2 Head of the ring to concatenate
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_CONCAT(h1, h2, elem, link) do { \
+ if (!APR_RING_EMPTY((h2), elem, link)) { \
+ APR_RING_SPLICE_TAIL((h1), APR_RING_FIRST((h2)), \
+ APR_RING_LAST((h2)), elem, link); \
+ APR_RING_INIT((h2), elem, link); \
+ } \
+ } while (0)
+
+/**
+ * Prepend ring h2 onto the beginning of ring h1, leaving h2 empty.
+ * @param h1 Head of the ring to prepend onto
+ * @param h2 Head of the ring to prepend
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_PREPEND(h1, h2, elem, link) do { \
+ if (!APR_RING_EMPTY((h2), elem, link)) { \
+ APR_RING_SPLICE_HEAD((h1), APR_RING_FIRST((h2)), \
+ APR_RING_LAST((h2)), elem, link); \
+ APR_RING_INIT((h2), elem, link); \
+ } \
+ } while (0)
+
+/**
+ * Unsplice a sequence of elements from a ring
+ * @warning The unspliced sequence is left with dangling pointers at either end
+ * @param ep1 First element in the sequence to unsplice
+ * @param epN Last element in the sequence to unsplice
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_UNSPLICE(ep1, epN, link) do { \
+ APR_RING_NEXT(APR_RING_PREV((ep1), link), link) = \
+ APR_RING_NEXT((epN), link); \
+ APR_RING_PREV(APR_RING_NEXT((epN), link), link) = \
+ APR_RING_PREV((ep1), link); \
+ } while (0)
+
+/**
+ * Remove a single element from a ring
+ * @warning The unspliced element is left with dangling pointers at either end
+ * @param ep Element to remove
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_REMOVE(ep, link) \
+ APR_RING_UNSPLICE((ep), (ep), link)
+
+/**
+ * Iterate over a ring
+ * @param ep The current element
+ * @param head The head of the ring
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_FOREACH(ep, head, elem, link) \
+ for (ep = APR_RING_FIRST(head); \
+ ep != APR_RING_SENTINEL(head, elem, link); \
+ ep = APR_RING_NEXT(ep, link))
+
+/**
+ * Iterate over a ring safe against removal of the current element
+ * @param ep1 The current element
+ * @param ep2 Iteration cursor
+ * @param head The head of the ring
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link) \
+ for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link); \
+ ep1 != APR_RING_SENTINEL(head, elem, link); \
+ ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link))
+
+/* Debugging tools: */
+
+#ifdef APR_RING_DEBUG
+#include <stdio.h>
+#include <assert.h>
+
+#define APR_RING_CHECK_ONE(msg, ptr) \
+ fprintf(stderr, "*** %s %p\n", msg, ptr)
+
+#define APR_RING_CHECK(hp, elem, link, msg) \
+ APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)
+
+#define APR_RING_CHECK_ELEM(ep, elem, link, msg) do { \
+ struct elem *start = (ep); \
+ struct elem *here = start; \
+ fprintf(stderr, "*** ring check start -- %s\n", msg); \
+ do { \
+ fprintf(stderr, "\telem %p\n", here); \
+ fprintf(stderr, "\telem->next %p\n", \
+ APR_RING_NEXT(here, link)); \
+ fprintf(stderr, "\telem->prev %p\n", \
+ APR_RING_PREV(here, link)); \
+ fprintf(stderr, "\telem->next->prev %p\n", \
+ APR_RING_PREV(APR_RING_NEXT(here, link), link)); \
+ fprintf(stderr, "\telem->prev->next %p\n", \
+ APR_RING_NEXT(APR_RING_PREV(here, link), link)); \
+ if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
+ fprintf(stderr, "\t*** elem->next->prev != elem\n"); \
+ break; \
+ } \
+ if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
+ fprintf(stderr, "\t*** elem->prev->next != elem\n"); \
+ break; \
+ } \
+ here = APR_RING_NEXT(here, link); \
+ } while (here != start); \
+ fprintf(stderr, "*** ring check end\n"); \
+ } while (0)
+
+#define APR_RING_CHECK_CONSISTENCY(hp, elem, link) \
+ APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
+ elem, link)
+
+#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do { \
+ struct elem *start = (ep); \
+ struct elem *here = start; \
+ do { \
+ assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
+ assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
+ here = APR_RING_NEXT(here, link); \
+ } while (here != start); \
+ } while (0)
+
+#else
+/**
+ * Print a single pointer value to STDERR
+ * (This is a no-op unless APR_RING_DEBUG is defined.)
+ * @param msg Descriptive message
+ * @param ptr Pointer value to print
+ */
+#define APR_RING_CHECK_ONE(msg, ptr)
+/**
+ * Dump all ring pointers to STDERR, starting with the head and looping all
+ * the way around the ring back to the head. Aborts if an inconsistency
+ * is found.
+ * (This is a no-op unless APR_RING_DEBUG is defined.)
+ * @param hp Head of the ring
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ * @param msg Descriptive message
+ */
+#define APR_RING_CHECK(hp, elem, link, msg)
+/**
+ * Loops around a ring and checks all the pointers for consistency. Pops
+ * an assertion if any inconsistency is found. Same idea as APR_RING_CHECK()
+ * except that it's silent if all is well.
+ * (This is a no-op unless APR_RING_DEBUG is defined.)
+ * @param hp Head of the ring
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
+/**
+ * Dump all ring pointers to STDERR, starting with the given element and
+ * looping all the way around the ring back to that element. Aborts if
+ * an inconsistency is found.
+ * (This is a no-op unless APR_RING_DEBUG is defined.)
+ * @param ep The element
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ * @param msg Descriptive message
+ */
+#define APR_RING_CHECK_ELEM(ep, elem, link, msg)
+/**
+ * Loops around a ring, starting with the given element, and checks all
+ * the pointers for consistency. Pops an assertion if any inconsistency
+ * is found. Same idea as APR_RING_CHECK_ELEM() except that it's silent
+ * if all is well.
+ * (This is a no-op unless APR_RING_DEBUG is defined.)
+ * @param ep The element
+ * @param elem The name of the element struct
+ * @param link The name of the APR_RING_ENTRY in the element struct
+ */
+#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
+#endif
+
+/** @} */
+
+#endif /* !APR_RING_H */
diff --git a/include/apr_shm.h b/include/apr_shm.h
new file mode 100644
index 0000000..635c654
--- /dev/null
+++ b/include/apr_shm.h
@@ -0,0 +1,229 @@
+/* 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 APR_SHM_H
+#define APR_SHM_H
+
+/**
+ * @file apr_shm.h
+ * @brief APR Shared Memory Routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_perms_set.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_shm Shared Memory Routines
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * Private, platform-specific data struture representing a shared memory
+ * segment.
+ */
+typedef struct apr_shm_t apr_shm_t;
+
+/**
+ * Create and make accessible a shared memory segment with default
+ * properties.
+ * @param m The shared memory structure to create.
+ * @param reqsize The desired size of the segment.
+ * @param filename The file to use for shared memory on platforms that
+ * require it.
+ * @param pool the pool from which to allocate the shared memory
+ * structure.
+ * @remark A note about Anonymous vs. Named shared memory segments:
+ * Not all plaforms support anonymous shared memory segments, but in
+ * some cases it is prefered over other types of shared memory
+ * implementations. Passing a NULL 'file' parameter to this function
+ * will cause the subsystem to use anonymous shared memory segments.
+ * If such a system is not available, APR_ENOTIMPL is returned.
+ * @remark A note about allocation sizes:
+ * On some platforms it is necessary to store some metainformation
+ * about the segment within the actual segment. In order to supply
+ * the caller with the requested size it may be necessary for the
+ * implementation to request a slightly greater segment length
+ * from the subsystem. In all cases, the apr_shm_baseaddr_get()
+ * function will return the first usable byte of memory.
+ *
+ */
+APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m,
+ apr_size_t reqsize,
+ const char *filename,
+ apr_pool_t *pool);
+
+/**
+ * Special processing flags for apr_shm_create_ex() and apr_shm_attach_ex().
+ */
+#define APR_SHM_NS_LOCAL 1 /* Create or attach to named shared memory
+ * segment in the "Local" namespace on
+ * Windows. (Ignored on other platforms.)
+ * By default, the "Global" namespace is
+ * used for privileged processes and the
+ * "Local" namespace is used otherwise.
+ */
+#define APR_SHM_NS_GLOBAL 2 /* Create or attach to named shared memory
+ * segment in the "Global" namespace on
+ * Windows. (Ignored on other platforms.)
+ */
+
+/**
+ * Create and make accessible a shared memory segment with platform-
+ * specific processing.
+ * @param m The shared memory structure to create.
+ * @param reqsize The desired size of the segment.
+ * @param filename The file to use for shared memory on platforms that
+ * require it.
+ * @param pool the pool from which to allocate the shared memory
+ * structure.
+ * @param flags mask of APR_SHM_* (defined above)
+ * @remark A note about Anonymous vs. Named shared memory segments:
+ * Not all plaforms support anonymous shared memory segments, but in
+ * some cases it is prefered over other types of shared memory
+ * implementations. Passing a NULL 'file' parameter to this function
+ * will cause the subsystem to use anonymous shared memory segments.
+ * If such a system is not available, APR_ENOTIMPL is returned.
+ * @remark A note about allocation sizes:
+ * On some platforms it is necessary to store some metainformation
+ * about the segment within the actual segment. In order to supply
+ * the caller with the requested size it may be necessary for the
+ * implementation to request a slightly greater segment length
+ * from the subsystem. In all cases, the apr_shm_baseaddr_get()
+ * function will return the first usable byte of memory.
+ *
+ */
+APR_DECLARE(apr_status_t) apr_shm_create_ex(apr_shm_t **m,
+ apr_size_t reqsize,
+ const char *filename,
+ apr_pool_t *pool,
+ apr_int32_t flags);
+
+/**
+ * Remove named resource associated with a shared memory segment,
+ * preventing attachments to the resource, but not destroying it.
+ * @param filename The filename associated with shared-memory segment which
+ * needs to be removed
+ * @param pool The pool used for file operations
+ * @remark This function is only supported on platforms which support
+ * name-based shared memory segments, and will return APR_ENOTIMPL on
+ * platforms without such support. Removing the file while the shm
+ * is in use is not entirely portable, caller may use this to enhance
+ * obscurity of the resource, but be prepared for the call to fail,
+ * and for concurrent attempts to create a resource of the same name
+ * to also fail. The pool cleanup of apr_shm_create (apr_shm_destroy)
+ * also removes the named resource.
+ */
+APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
+ apr_pool_t *pool);
+
+/**
+ * Delete named resource associated with a shared memory segment,
+ * preventing attachments to the resource.
+ * @param m The shared memory segment structure to delete.
+ * @remark This function is only supported on platforms which support
+ * name-based shared memory segments, and will return APR_ENOTIMPL on
+ * platforms without such support. Removing the file while the shm
+ * is in use is not entirely portable, caller may use this to enhance
+ * obscurity of the resource, but be prepared for the call to fail,
+ * and for concurrent attempts to create a resource of the same name
+ * to also fail. The pool cleanup of apr_shm_create (apr_shm_destroy)
+ * also removes the named resource.
+ */
+APR_DECLARE(apr_status_t) apr_shm_delete(apr_shm_t *m);
+
+/**
+ * Destroy a shared memory segment and associated memory.
+ * @param m The shared memory segment structure to destroy.
+ */
+APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m);
+
+/**
+ * Attach to a shared memory segment that was created
+ * by another process.
+ * @param m The shared memory structure to create.
+ * @param filename The file used to create the original segment.
+ * (This MUST match the original filename.)
+ * @param pool the pool from which to allocate the shared memory
+ * structure for this process.
+ */
+APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
+ const char *filename,
+ apr_pool_t *pool);
+
+/**
+ * Attach to a shared memory segment that was created
+ * by another process, with platform-specific processing.
+ * @param m The shared memory structure to create.
+ * @param filename The file used to create the original segment.
+ * (This MUST match the original filename.)
+ * @param pool the pool from which to allocate the shared memory
+ * structure for this process.
+ * @param flags mask of APR_SHM_* (defined above)
+ */
+APR_DECLARE(apr_status_t) apr_shm_attach_ex(apr_shm_t **m,
+ const char *filename,
+ apr_pool_t *pool,
+ apr_int32_t flags);
+
+/**
+ * Detach from a shared memory segment without destroying it.
+ * @param m The shared memory structure representing the segment
+ * to detach from.
+ */
+APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m);
+
+/**
+ * Retrieve the base address of the shared memory segment.
+ * NOTE: This address is only usable within the callers address
+ * space, since this API does not guarantee that other attaching
+ * processes will maintain the same address mapping.
+ * @param m The shared memory segment from which to retrieve
+ * the base address.
+ * @return address, aligned by APR_ALIGN_DEFAULT.
+ */
+APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m);
+
+/**
+ * Retrieve the length of a shared memory segment in bytes.
+ * @param m The shared memory segment from which to retrieve
+ * the segment length.
+ */
+APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m);
+
+/**
+ * Set shared memory permissions.
+ */
+APR_PERMS_SET_IMPLEMENT(shm);
+
+/**
+ * Get the pool used by this shared memory segment.
+ */
+APR_POOL_DECLARE_ACCESSOR(shm);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APR_SHM_T */
diff --git a/include/apr_signal.h b/include/apr_signal.h
new file mode 100644
index 0000000..2063133
--- /dev/null
+++ b/include/apr_signal.h
@@ -0,0 +1,109 @@
+/* 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 APR_SIGNAL_H
+#define APR_SIGNAL_H
+
+/**
+ * @file apr_signal.h
+ * @brief APR Signal Handling
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+
+#if APR_HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_signal Signal Handling
+ * @ingroup APR
+ * @{
+ */
+
+#if APR_HAVE_SIGACTION || defined(DOXYGEN)
+
+#if defined(DARWIN) && !defined(__cplusplus) && !defined(_ANSI_SOURCE)
+/* work around Darwin header file bugs
+ * http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2657228.html
+ */
+#undef SIG_DFL
+#undef SIG_IGN
+#undef SIG_ERR
+#define SIG_DFL (void (*)(int))0
+#define SIG_IGN (void (*)(int))1
+#define SIG_ERR (void (*)(int))-1
+#endif
+
+/** Function prototype for signal handlers */
+typedef void apr_sigfunc_t(int);
+
+/**
+ * Set the signal handler function for a given signal
+ * @param signo The signal (eg... SIGWINCH)
+ * @param func the function to get called
+ */
+APR_DECLARE(apr_sigfunc_t *) apr_signal(int signo, apr_sigfunc_t * func);
+
+#if defined(SIG_IGN) && !defined(SIG_ERR)
+#define SIG_ERR ((apr_sigfunc_t *) -1)
+#endif
+
+#else /* !APR_HAVE_SIGACTION */
+#define apr_signal(a, b) signal(a, b)
+#endif
+
+
+/**
+ * Get the description for a specific signal number
+ * @param signum The signal number
+ * @return The description of the signal
+ */
+APR_DECLARE(const char *) apr_signal_description_get(int signum);
+
+/**
+ * APR-private function for initializing the signal package
+ * @internal
+ * @param pglobal The internal, global pool
+ */
+void apr_signal_init(apr_pool_t *pglobal);
+
+/**
+ * Block the delivery of a particular signal
+ * @param signum The signal number
+ * @return status
+ */
+APR_DECLARE(apr_status_t) apr_signal_block(int signum);
+
+/**
+ * Enable the delivery of a particular signal
+ * @param signum The signal number
+ * @return status
+ */
+APR_DECLARE(apr_status_t) apr_signal_unblock(int signum);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* APR_SIGNAL_H */
diff --git a/include/apr_skiplist.h b/include/apr_skiplist.h
new file mode 100644
index 0000000..eeab10b
--- /dev/null
+++ b/include/apr_skiplist.h
@@ -0,0 +1,381 @@
+/* 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 APR_SKIPLIST_H
+#define APR_SKIPLIST_H
+/**
+ * @file apr_skiplist.h
+ * @brief APR skip list implementation
+ */
+
+#include "apr.h"
+#include "apr_portable.h"
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_skiplist Skip list implementation
+ * Refer to http://en.wikipedia.org/wiki/Skip_list for information
+ * about the purpose of and ideas behind skip lists.
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * apr_skiplist_compare is the function type that must be implemented
+ * per object type that is used in a skip list for comparisons to maintain
+ * order
+ * */
+typedef int (*apr_skiplist_compare) (void *, void *);
+
+/**
+ * apr_skiplist_freefunc is the function type that must be implemented
+ * to handle elements as they are removed from a skip list.
+ */
+typedef void (*apr_skiplist_freefunc) (void *);
+
+/** Opaque structure used to represent the skip list */
+struct apr_skiplist;
+/** Opaque structure used to represent the skip list */
+typedef struct apr_skiplist apr_skiplist;
+
+/**
+ * Opaque structure used to represent abstract nodes in the skip list
+ * (an abstraction above the raw elements which are collected in the
+ * skip list).
+ */
+struct apr_skiplistnode;
+/** Opaque structure */
+typedef struct apr_skiplistnode apr_skiplistnode;
+
+/**
+ * Allocate memory using the same mechanism as the skip list.
+ * @param sl The skip list
+ * @param size The amount to allocate
+ * @remark If a pool was provided to apr_skiplist_init(), memory will
+ * be allocated from the pool or from a free list maintained with
+ * the skip list. Otherwise, memory will be allocated using the
+ * C standard library heap functions.
+ */
+APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size);
+
+/**
+ * Free memory using the same mechanism as the skip list.
+ * @param sl The skip list
+ * @param mem The object to free
+ * @remark If a pool was provided to apr_skiplist_init(), memory will
+ * be added to a free list maintained with the skip list and be available
+ * to operations on the skip list or to other calls to apr_skiplist_alloc().
+ * Otherwise, memory will be freed using the C standard library heap
+ * functions.
+ */
+APR_DECLARE(void) apr_skiplist_free(apr_skiplist *sl, void *mem);
+
+/**
+ * Allocate a new skip list
+ * @param sl The pointer in which to return the newly created skip list
+ * @param p The pool from which to allocate the skip list (optional).
+ * @remark Unlike most APR functions, a pool is optional. If no pool
+ * is provided, the C standard library heap functions will be used instead.
+ */
+APR_DECLARE(apr_status_t) apr_skiplist_init(apr_skiplist **sl, apr_pool_t *p);
+
+/**
+ * Set the comparison functions to be used for searching the skip list.
+ * @param sl The skip list
+ * @param XXX1 FIXME
+ * @param XXX2 FIXME
+ *
+ * @remark If existing comparison functions are being replaced, the index
+ * will be replaced during this call. That is a potentially expensive
+ * operation.
+ */
+APR_DECLARE(void) apr_skiplist_set_compare(apr_skiplist *sl, apr_skiplist_compare XXX1,
+ apr_skiplist_compare XXX2);
+
+/**
+ * Set the indexing functions to the specified comparison functions and
+ * rebuild the index.
+ * @param sl The skip list
+ * @param XXX1 FIXME
+ * @param XXX2 FIXME
+ *
+ * @remark If an index already exists, it will not be replaced and the
+ * comparison functions will not be changed.
+ */
+APR_DECLARE(void) apr_skiplist_add_index(apr_skiplist *sl, apr_skiplist_compare XXX1,
+ apr_skiplist_compare XXX2);
+
+/**
+ * Return the list maintained by the skip list abstraction.
+ * @param sl The skip list
+ */
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl);
+
+/**
+ * Return the next matching element in the skip list using the specified
+ * comparison function.
+ * @param sl The skip list
+ * @param data The value to search for
+ * @param iter A pointer to the returned skip list node representing the element
+ * found
+ * @param func The comparison function to use
+ */
+APR_DECLARE(void *) apr_skiplist_find_compare(apr_skiplist *sl,
+ void *data,
+ apr_skiplistnode **iter,
+ apr_skiplist_compare func);
+
+/**
+ * Return the next matching element in the skip list using the current comparison
+ * function.
+ * @param sl The skip list
+ * @param data The value to search for
+ * @param iter A pointer to the returned skip list node representing the element
+ * found
+ */
+APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter);
+
+/**
+ * Return the last matching element in the skip list using the specified
+ * comparison function.
+ * @param sl The skip list
+ * @param data The value to search for
+ * @param iter A pointer to the returned skip list node representing the element
+ * found
+ * @param comp The comparison function to use
+ */
+APR_DECLARE(void *) apr_skiplist_last_compare(apr_skiplist *sl, void *data,
+ apr_skiplistnode **iter,
+ apr_skiplist_compare comp);
+
+/**
+ * Return the last matching element in the skip list using the current comparison
+ * function.
+ * @param sl The skip list
+ * @param data The value to search for
+ * @param iter A pointer to the returned skip list node representing the element
+ * found
+ */
+APR_DECLARE(void *) apr_skiplist_last(apr_skiplist *sl, void *data,
+ apr_skiplistnode **iter);
+
+/**
+ * Return the next element in the skip list.
+ * @param sl The skip list
+ * @param iter On entry, a pointer to the skip list node to start with; on return,
+ * a pointer to the skip list node representing the element returned
+ * @remark If iter points to a NULL value on entry, NULL will be returned.
+ */
+APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter);
+
+/**
+ * Return the previous element in the skip list.
+ * @param sl The skip list
+ * @param iter On entry, a pointer to the skip list node to start with; on return,
+ * a pointer to the skip list node representing the element returned
+ * @remark If iter points to a NULL value on entry, NULL will be returned.
+ */
+APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **iter);
+
+/**
+ * Return the element of the skip list node
+ * @param iter The skip list node
+ */
+APR_DECLARE(void *) apr_skiplist_element(apr_skiplistnode *iter);
+
+/**
+ * Insert an element into the skip list using the specified comparison function
+ * if it does not already exist.
+ * @param sl The skip list
+ * @param data The element to insert
+ * @param comp The comparison function to use for placement into the skip list
+ */
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl,
+ void *data, apr_skiplist_compare comp);
+
+/**
+ * Insert an element into the skip list using the existing comparison function
+ * if it does not already exist.
+ * @param sl The skip list
+ * @param data The element to insert
+ * @remark If no comparison function has been set for the skip list, the element
+ * will not be inserted and NULL will be returned.
+ */
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist* sl, void *data);
+
+/**
+ * Add an element into the skip list using the specified comparison function
+ * allowing for duplicates.
+ * @param sl The skip list
+ * @param data The element to add
+ * @param comp The comparison function to use for placement into the skip list
+ */
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_add_compare(apr_skiplist *sl,
+ void *data, apr_skiplist_compare comp);
+
+/**
+ * Add an element into the skip list using the existing comparison function
+ * allowing for duplicates.
+ * @param sl The skip list
+ * @param data The element to insert
+ * @remark If no comparison function has been set for the skip list, the element
+ * will not be inserted and NULL will be returned.
+ */
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_add(apr_skiplist* sl, void *data);
+
+/**
+ * Add an element into the skip list using the specified comparison function
+ * removing the existing duplicates.
+ * @param sl The skip list
+ * @param data The element to insert
+ * @param comp The comparison function to use for placement into the skip list
+ * @param myfree A function to be called for each removed duplicate
+ * @remark If no comparison function has been set for the skip list, the element
+ * will not be inserted, none will be replaced, and NULL will be returned.
+ */
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_replace_compare(apr_skiplist *sl,
+ void *data, apr_skiplist_freefunc myfree,
+ apr_skiplist_compare comp);
+
+/**
+ * Add an element into the skip list using the existing comparison function
+ * removing the existing duplicates.
+ * @param sl The skip list
+ * @param data The element to insert
+ * @param myfree A function to be called for each removed duplicate
+ * @remark If no comparison function has been set for the skip list, the element
+ * will not be inserted, none will be replaced, and NULL will be returned.
+ */
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_replace(apr_skiplist *sl,
+ void *data, apr_skiplist_freefunc myfree);
+
+/**
+ * Remove a node from the skip list.
+ * @param sl The skip list
+ * @param iter The skip list node to remove
+ * @param myfree A function to be called for the removed element
+ */
+APR_DECLARE(int) apr_skiplist_remove_node(apr_skiplist *sl,
+ apr_skiplistnode *iter,
+ apr_skiplist_freefunc myfree);
+
+/**
+ * Remove an element from the skip list using the specified comparison function for
+ * locating the element. In the case of duplicates, the 1st entry will be removed.
+ * @param sl The skip list
+ * @param data The element to remove
+ * @param myfree A function to be called for each removed element
+ * @param comp The comparison function to use for placement into the skip list
+ * @remark If the element is not found, 0 will be returned. Otherwise, the heightXXX
+ * will be returned.
+ */
+APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sl, void *data,
+ apr_skiplist_freefunc myfree, apr_skiplist_compare comp);
+
+/**
+ * Remove an element from the skip list using the existing comparison function for
+ * locating the element. In the case of duplicates, the 1st entry will be removed.
+ * @param sl The skip list
+ * @param data The element to remove
+ * @param myfree A function to be called for each removed element
+ * @remark If the element is not found, 0 will be returned. Otherwise, the heightXXX
+ * will be returned.
+ * @remark If no comparison function has been set for the skip list, the element
+ * will not be removed and 0 will be returned.
+ */
+APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree);
+
+/**
+ * Remove all elements from the skip list.
+ * @param sl The skip list
+ * @param myfree A function to be called for each removed element
+ */
+APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefunc myfree);
+
+/**
+ * Remove each element from the skip list.
+ * @param sl The skip list
+ * @param myfree A function to be called for each removed element
+ */
+APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree);
+
+/**
+ * Return the first element in the skip list, removing the element from the skip list.
+ * @param sl The skip list
+ * @param myfree A function to be called for the removed element
+ * @remark NULL will be returned if there are no elements
+ */
+APR_DECLARE(void *) apr_skiplist_pop(apr_skiplist *sl, apr_skiplist_freefunc myfree);
+
+/**
+ * Return the first element in the skip list, leaving the element in the skip list.
+ * @param sl The skip list
+ * @remark NULL will be returned if there are no elements
+ */
+APR_DECLARE(void *) apr_skiplist_peek(apr_skiplist *sl);
+
+/**
+ * Return the size of the list (number of elements), in O(1).
+ * @param sl The skip list
+ */
+APR_DECLARE(size_t) apr_skiplist_size(const apr_skiplist *sl);
+
+/**
+ * Return the height of the list (number of skip paths), in O(1).
+ * @param sl The skip list
+ */
+APR_DECLARE(int) apr_skiplist_height(const apr_skiplist *sl);
+
+/**
+ * Return the predefined maximum height of the skip list.
+ * @param sl The skip list
+ */
+APR_DECLARE(int) apr_skiplist_preheight(const apr_skiplist *sl);
+
+/**
+ * Set a predefined maximum height for the skip list.
+ * @param sl The skip list
+ * @param to The preheight to set, or a nul/negative value to disable.
+ * @remark When a preheight is used, the height of each inserted element is
+ * computed randomly up to this preheight instead of the current skip list's
+ * height plus one used by the default implementation. Using a preheight can
+ * probably ensure more fairness with long living elements (since with an
+ * adaptative height, former elements may have been created with a low height,
+ * hence a longest path to reach them while the skip list grows). On the other
+ * hand, the default behaviour (preheight <= 0) with a growing and decreasing
+ * maximum height is more adaptative/suitable for short living values.
+ * @note Should be called before any insertion/add.
+ */
+APR_DECLARE(void) apr_skiplist_set_preheight(apr_skiplist *sl, int to);
+
+/**
+ * Merge two skip lists. XXX SEMANTICS
+ * @param sl1 One of two skip lists to be merged
+ * @param sl2 The other of two skip lists to be merged
+ */
+APR_DECLARE(apr_skiplist *) apr_skiplist_merge(apr_skiplist *sl1, apr_skiplist *sl2);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_SKIPLIST_H */
diff --git a/include/apr_strings.h b/include/apr_strings.h
new file mode 100644
index 0000000..d5f8719
--- /dev/null
+++ b/include/apr_strings.h
@@ -0,0 +1,380 @@
+/* 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.
+ */
+
+/* Portions of this file are covered by */
+/* -*- mode: c; c-file-style: "k&r" -*-
+
+ strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
+ Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef APR_STRINGS_H
+#define APR_STRINGS_H
+
+/**
+ * @file apr_strings.h
+ * @brief APR Strings library
+ */
+
+#include "apr.h"
+#include "apr_errno.h"
+#include "apr_pools.h"
+#define APR_WANT_IOVEC
+#include "apr_want.h"
+
+#if APR_HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_strings String routines
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * Do a natural order comparison of two strings.
+ * @param a The first string to compare
+ * @param b The second string to compare
+ * @return Either <0, 0, or >0. If the first string is less than the second
+ * this returns <0, if they are equivalent it returns 0, and if the
+ * first string is greater than second string it retuns >0.
+ */
+APR_DECLARE(int) apr_strnatcmp(char const *a, char const *b);
+
+/**
+ * Do a natural order comparison of two strings ignoring the case of the
+ * strings.
+ * @param a The first string to compare
+ * @param b The second string to compare
+ * @return Either <0, 0, or >0. If the first string is less than the second
+ * this returns <0, if they are equivalent it returns 0, and if the
+ * first string is greater than second string it retuns >0.
+ */
+APR_DECLARE(int) apr_strnatcasecmp(char const *a, char const *b);
+
+/**
+ * duplicate a string into memory allocated out of a pool
+ * @param p The pool to allocate out of
+ * @param s The string to duplicate
+ * @return The new string or NULL if s == NULL
+ */
+APR_DECLARE(char *) apr_pstrdup(apr_pool_t *p, const char *s);
+
+/**
+ * Create a null-terminated string by making a copy of a sequence
+ * of characters and appending a null byte
+ * @param p The pool to allocate out of
+ * @param s The block of characters to duplicate
+ * @param n The number of characters to duplicate
+ * @return The new string or NULL if s == NULL
+ * @remark This is a faster alternative to apr_pstrndup(), for use
+ * when you know that the string being duplicated really
+ * has 'n' or more characters. If the string might contain
+ * fewer characters, use apr_pstrndup().
+ */
+APR_DECLARE(char *) apr_pstrmemdup(apr_pool_t *p, const char *s, apr_size_t n)
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+ __attribute__((alloc_size(3)))
+#endif
+ ;
+
+/**
+ * Duplicate at most n characters of a string into memory allocated
+ * out of a pool; the new string will be NUL-terminated
+ * @param p The pool to allocate out of
+ * @param s The string to duplicate
+ * @param n The maximum number of characters to duplicate
+ * @return The new string or NULL if s == NULL
+ * @remark The amount of memory allocated from the pool is the length
+ * of the returned string including the NUL terminator
+ */
+APR_DECLARE(char *) apr_pstrndup(apr_pool_t *p, const char *s, apr_size_t n);
+
+/**
+ * Duplicate a block of memory.
+ *
+ * @param p The pool to allocate from
+ * @param m The memory to duplicate
+ * @param n The number of bytes to duplicate
+ * @return The new block of memory or NULL if m == NULL
+ */
+APR_DECLARE(void *) apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n)
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+ __attribute__((alloc_size(3)))
+#endif
+ ;
+
+/**
+ * Concatenate multiple strings, allocating memory out a pool
+ * @param p The pool to allocate out of
+ * @param ... The strings to concatenate. The final string must be NULL
+ * @return The new string
+ */
+APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *p, ...)
+#if defined(__GNUC__) && __GNUC__ >= 4
+ __attribute__((sentinel))
+#endif
+ ;
+
+/**
+ * Concatenate multiple strings specified in a writev-style vector
+ * @param p The pool from which to allocate
+ * @param vec The strings to concatenate
+ * @param nvec The number of strings to concatenate
+ * @param nbytes (output) strlen of new string (pass in NULL to omit)
+ * @return The new string
+ */
+APR_DECLARE(char *) apr_pstrcatv(apr_pool_t *p, const struct iovec *vec,
+ apr_size_t nvec, apr_size_t *nbytes);
+
+/**
+ * printf-style style printing routine. The data is output to a string
+ * allocated from a pool
+ * @param p The pool to allocate out of
+ * @param fmt The format of the string
+ * @param ap The arguments to use while printing the data
+ * @return The new string
+ */
+APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *p, const char *fmt, va_list ap);
+
+/**
+ * printf-style style printing routine. The data is output to a string
+ * allocated from a pool
+ * @param p The pool to allocate out of
+ * @param fmt The format of the string
+ * @param ... The arguments to use while printing the data
+ * @return The new string
+ */
+APR_DECLARE_NONSTD(char *) apr_psprintf(apr_pool_t *p, const char *fmt, ...)
+ __attribute__((format(printf,2,3)));
+
+/**
+ * Copy up to dst_size characters from src to dst; does not copy
+ * past a NUL terminator in src, but always terminates dst with a NUL
+ * regardless.
+ * @param dst The destination string
+ * @param src The source string
+ * @param dst_size The space available in dst; dst always receives
+ * NUL termination, so if src is longer than
+ * dst_size, the actual number of characters copied is
+ * dst_size - 1.
+ * @return Pointer to the NUL terminator of the destination string, dst
+ * @remark
+ * <PRE>
+ * Note the differences between this function and strncpy():
+ * 1) strncpy() doesn't always NUL terminate; apr_cpystrn() does.
+ * 2) strncpy() pads the destination string with NULs, which is often
+ * unnecessary; apr_cpystrn() does not.
+ * 3) strncpy() returns a pointer to the beginning of the dst string;
+ * apr_cpystrn() returns a pointer to the NUL terminator of dst,
+ * to allow a check for truncation.
+ * </PRE>
+ */
+APR_DECLARE(char *) apr_cpystrn(char *dst, const char *src,
+ apr_size_t dst_size);
+
+/**
+ * Remove all whitespace from a string
+ * @param dest The destination string. It is okay to modify the string
+ * in place. Namely dest == src
+ * @param src The string to rid the spaces from.
+ * @return A pointer to the destination string's null terminator.
+ */
+APR_DECLARE(char *) apr_collapse_spaces(char *dest, const char *src);
+
+/**
+ * Convert the arguments to a program from one string to an array of
+ * strings terminated by a NULL pointer
+ * @param arg_str The arguments to convert
+ * @param argv_out Output location. This is a pointer to an array of strings.
+ * @param token_context Pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_tokenize_to_argv(const char *arg_str,
+ char ***argv_out,
+ apr_pool_t *token_context);
+
+/**
+ * Split a string into separate null-terminated tokens. The tokens are
+ * delimited in the string by one or more characters from the sep
+ * argument.
+ * @param str The string to separate; this should be specified on the
+ * first call to apr_strtok() for a given string, and NULL
+ * on subsequent calls.
+ * @param sep The set of delimiters
+ * @param last State saved by apr_strtok() between calls.
+ * @return The next token from the string
+ * @note the 'last' state points to the trailing NUL char of the final
+ * token, otherwise it points to the character following the current
+ * token (all successive or empty occurances of sep are skiped on the
+ * subsequent call to apr_strtok). Therefore it is possible to avoid
+ * a strlen() determination, with the following logic;
+ * toklen = last - retval; if (*last) --toklen;
+ */
+APR_DECLARE(char *) apr_strtok(char *str, const char *sep, char **last);
+
+/**
+ * @defgroup APR_Strings_Snprintf snprintf implementations
+ * @warning
+ * These are snprintf implementations based on apr_vformatter().
+ *
+ * Note that various standards and implementations disagree on the return
+ * value of snprintf, and side-effects due to %n in the formatting string.
+ * apr_snprintf (and apr_vsnprintf) behaves as follows:
+ *
+ * Process the format string until the entire string is exhausted, or
+ * the buffer fills. If the buffer fills then stop processing immediately
+ * (so no further %n arguments are processed), and return the buffer
+ * length. In all cases the buffer is NUL terminated. It will return the
+ * number of characters inserted into the buffer, not including the
+ * terminating NUL. As a special case, if len is 0, apr_snprintf will
+ * return the number of characters that would have been inserted if
+ * the buffer had been infinite (in this case, *buffer can be NULL)
+ *
+ * In no event does apr_snprintf return a negative number.
+ * @{
+ */
+
+/**
+ * snprintf routine based on apr_vformatter. This means it understands the
+ * same extensions.
+ * @param buf The buffer to write to
+ * @param len The size of the buffer
+ * @param format The format string
+ * @param ... The arguments to use to fill out the format string.
+ */
+APR_DECLARE_NONSTD(int) apr_snprintf(char *buf, apr_size_t len,
+ const char *format, ...)
+ __attribute__((format(printf,3,4)));
+
+/**
+ * vsnprintf routine based on apr_vformatter. This means it understands the
+ * same extensions.
+ * @param buf The buffer to write to
+ * @param len The size of the buffer
+ * @param format The format string
+ * @param ap The arguments to use to fill out the format string.
+ */
+APR_DECLARE(int) apr_vsnprintf(char *buf, apr_size_t len, const char *format,
+ va_list ap);
+/** @} */
+
+/**
+ * create a string representation of an int, allocated from a pool
+ * @param p The pool from which to allocate
+ * @param n The number to format
+ * @return The string representation of the number
+ */
+APR_DECLARE(char *) apr_itoa(apr_pool_t *p, int n);
+
+/**
+ * create a string representation of a long, allocated from a pool
+ * @param p The pool from which to allocate
+ * @param n The number to format
+ * @return The string representation of the number
+ */
+APR_DECLARE(char *) apr_ltoa(apr_pool_t *p, long n);
+
+/**
+ * create a string representation of an apr_off_t, allocated from a pool
+ * @param p The pool from which to allocate
+ * @param n The number to format
+ * @return The string representation of the number
+ */
+APR_DECLARE(char *) apr_off_t_toa(apr_pool_t *p, apr_off_t n);
+
+/**
+ * Convert a numeric string into an apr_off_t numeric value.
+ * @param offset The value of the parsed string.
+ * @param buf The string to parse. It may contain optional whitespace,
+ * followed by an optional '+' (positive, default) or '-' (negative)
+ * character, followed by an optional '0x' prefix if base is 0 or 16,
+ * followed by numeric digits appropriate for base.
+ * @param end A pointer to the end of the valid character in buf. If
+ * not NULL, it is set to the first invalid character in buf.
+ * @param base A numeric base in the range between 2 and 36 inclusive,
+ * or 0. If base is zero, buf will be treated as base ten unless its
+ * digits are prefixed with '0x', in which case it will be treated as
+ * base 16.
+ * @bug *end breaks type safety; where *buf is const, *end needs to be
+ * declared as const in APR 2.0
+ */
+APR_DECLARE(apr_status_t) apr_strtoff(apr_off_t *offset, const char *buf,
+ char **end, int base);
+
+/**
+ * parse a numeric string into a 64-bit numeric value
+ * @param buf The string to parse. It may contain optional whitespace,
+ * followed by an optional '+' (positive, default) or '-' (negative)
+ * character, followed by an optional '0x' prefix if base is 0 or 16,
+ * followed by numeric digits appropriate for base.
+ * @param end A pointer to the end of the valid character in buf. If
+ * not NULL, it is set to the first invalid character in buf.
+ * @param base A numeric base in the range between 2 and 36 inclusive,
+ * or 0. If base is zero, buf will be treated as base ten unless its
+ * digits are prefixed with '0x', in which case it will be treated as
+ * base 16.
+ * @return The numeric value of the string. On overflow, errno is set
+ * to ERANGE. On success, errno is set to 0.
+ */
+APR_DECLARE(apr_int64_t) apr_strtoi64(const char *buf, char **end, int base);
+
+/**
+ * parse a base-10 numeric string into a 64-bit numeric value.
+ * Equivalent to apr_strtoi64(buf, (char**)NULL, 10).
+ * @param buf The string to parse
+ * @return The numeric value of the string. On overflow, errno is set
+ * to ERANGE. On success, errno is set to 0.
+ */
+APR_DECLARE(apr_int64_t) apr_atoi64(const char *buf);
+
+/**
+ * Format a binary size (magnitiudes are 2^10 rather than 10^3) from an apr_off_t,
+ * as bytes, K, M, T, etc, to a four character compacted human readable string.
+ * @param size The size to format
+ * @param buf The 5 byte text buffer (counting the trailing null)
+ * @return The buf passed to apr_strfsize()
+ * @remark All negative sizes report ' - ', apr_strfsize only formats positive values.
+ */
+APR_DECLARE(char *) apr_strfsize(apr_off_t size, char *buf);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_STRINGS_H */
diff --git a/include/apr_support.h b/include/apr_support.h
new file mode 100644
index 0000000..79c8cb4
--- /dev/null
+++ b/include/apr_support.h
@@ -0,0 +1,57 @@
+/* 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 APR_SUPPORT_H
+#define APR_SUPPORT_H
+
+/**
+ * @file apr_support.h
+ * @brief APR Support functions
+ */
+
+#include "apr.h"
+#include "apr_network_io.h"
+#include "apr_file_io.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_support Internal APR support functions
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * Wait for IO to occur or timeout.
+ *
+ * @param f The file to wait on.
+ * @param s The socket to wait on if @a f is @c NULL.
+ * @param for_read If non-zero wait for data to be available to read,
+ * otherwise wait for data to be able to be written.
+ * @return APR_TIMEUP if we run out of time.
+ */
+apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
+ int for_read);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_SUPPORT_H */
diff --git a/include/apr_tables.h b/include/apr_tables.h
new file mode 100644
index 0000000..7ce2ada
--- /dev/null
+++ b/include/apr_tables.h
@@ -0,0 +1,507 @@
+/* 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 APR_TABLES_H
+#define APR_TABLES_H
+
+/**
+ * @file apr_tables.h
+ * @brief APR Table library
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+
+#if APR_HAVE_STDARG_H
+#include <stdarg.h> /* for va_list */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_tables Table and Array Functions
+ * @ingroup APR
+ * Arrays are used to store data which is referenced sequentially or
+ * as a stack. Functions are provided to push and pop individual
+ * elements as well as to operate on the entire array.
+ *
+ * Tables are used to store data which can be referenced by key.
+ * Limited capabilities are provided for tables with multiple elements
+ * which share a key; while key lookup will return only a single
+ * element, iteration is available. Additionally, a table can be
+ * compressed to resolve duplicates.
+ *
+ * Both arrays and tables may store string or binary data; some features,
+ * such as concatenation or merging of elements, work only for string
+ * data.
+ * @{
+ */
+
+/** the table abstract data type */
+typedef struct apr_table_t apr_table_t;
+
+/** @see apr_array_header_t */
+typedef struct apr_array_header_t apr_array_header_t;
+
+/** An opaque array type */
+struct apr_array_header_t {
+ /** The pool the array is allocated out of */
+ apr_pool_t *pool;
+ /** The amount of memory allocated for each element of the array */
+ int elt_size;
+ /** The number of active elements in the array */
+ int nelts;
+ /** The number of elements allocated in the array */
+ int nalloc;
+ /** The elements in the array */
+ char *elts;
+};
+
+/**
+ * The (opaque) structure for string-content tables.
+ */
+typedef struct apr_table_entry_t apr_table_entry_t;
+
+/** The type for each entry in a string-content table */
+struct apr_table_entry_t {
+ /** The key for the current table entry */
+ char *key; /* maybe NULL in future;
+ * check when iterating thru table_elts
+ */
+ /** The value for the current table entry */
+ char *val;
+
+ /** A checksum for the key, for use by the apr_table internals */
+ apr_uint32_t key_checksum;
+};
+
+/**
+ * Get the elements from a table.
+ * @param t The table
+ * @return An array containing the contents of the table
+ */
+APR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t);
+
+/**
+ * Determine if the table is empty (either NULL or having no elements).
+ * @param t The table to check
+ * @return True if empty, False otherwise
+ */
+APR_DECLARE(int) apr_is_empty_table(const apr_table_t *t);
+
+/**
+ * Determine if the array is empty (either NULL or having no elements).
+ * @param a The array to check
+ * @return True if empty, False otherwise
+ */
+APR_DECLARE(int) apr_is_empty_array(const apr_array_header_t *a);
+
+/**
+ * Create an array.
+ * @param p The pool to allocate the memory out of
+ * @param nelts the number of elements in the initial array
+ * @param elt_size The size of each element in the array.
+ * @return The new array
+ */
+APR_DECLARE(apr_array_header_t *) apr_array_make(apr_pool_t *p,
+ int nelts, int elt_size);
+
+/**
+ * Add a new element to an array (as a first-in, last-out stack).
+ * @param arr The array to add an element to.
+ * @return Location for the new element in the array.
+ * @remark If there are no free spots in the array, then this function will
+ * allocate new space for the new element.
+ */
+APR_DECLARE(void *) apr_array_push(apr_array_header_t *arr);
+
+/** A helper macro for accessing a member of an APR array.
+ *
+ * @param ary the array
+ * @param i the index into the array to return
+ * @param type the type of the objects stored in the array
+ *
+ * @return the item at index i
+ */
+#define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i])
+
+/** A helper macro for pushing elements into an APR array.
+ *
+ * @param ary the array
+ * @param type the type of the objects stored in the array
+ *
+ * @return the location where the new object should be placed
+ */
+#define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
+
+/**
+ * Remove an element from an array (as a first-in, last-out stack).
+ * @param arr The array to remove an element from.
+ * @return Location of the element in the array.
+ * @remark If there are no elements in the array, NULL is returned.
+ */
+APR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr);
+
+/**
+ * Remove all elements from an array.
+ * @param arr The array to remove all elements from.
+ * @remark As the underlying storage is allocated from a pool, no
+ * memory is freed by this operation, but is available for reuse.
+ */
+APR_DECLARE(void) apr_array_clear(apr_array_header_t *arr);
+
+/**
+ * Concatenate two arrays together.
+ * @param dst The destination array, and the one to go first in the combined
+ * array
+ * @param src The source array to add to the destination array
+ */
+APR_DECLARE(void) apr_array_cat(apr_array_header_t *dst,
+ const apr_array_header_t *src);
+
+/**
+ * Copy the entire array.
+ * @param p The pool to allocate the copy of the array out of
+ * @param arr The array to copy
+ * @return An exact copy of the array passed in
+ * @remark The alternate apr_array_copy_hdr() copies only the header, and arranges
+ * for the elements to be copied if (and only if) the code subsequently
+ * does a push or arraycat.
+ */
+APR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p,
+ const apr_array_header_t *arr);
+/**
+ * Copy the headers of the array, and arrange for the elements to be copied if
+ * and only if the code subsequently does a push or arraycat.
+ * @param p The pool to allocate the copy of the array out of
+ * @param arr The array to copy
+ * @return An exact copy of the array passed in
+ * @remark The alternate apr_array_copy() copies the *entire* array.
+ */
+APR_DECLARE(apr_array_header_t *) apr_array_copy_hdr(apr_pool_t *p,
+ const apr_array_header_t *arr);
+
+/**
+ * Append one array to the end of another, creating a new array in the process.
+ * @param p The pool to allocate the new array out of
+ * @param first The array to put first in the new array.
+ * @param second The array to put second in the new array.
+ * @return A new array containing the data from the two arrays passed in.
+*/
+APR_DECLARE(apr_array_header_t *) apr_array_append(apr_pool_t *p,
+ const apr_array_header_t *first,
+ const apr_array_header_t *second);
+
+/**
+ * Generate a new string from the apr_pool_t containing the concatenated
+ * sequence of substrings referenced as elements within the array. The string
+ * will be empty if all substrings are empty or null, or if there are no
+ * elements in the array. If sep is non-NUL, it will be inserted between
+ * elements as a separator.
+ * @param p The pool to allocate the string out of
+ * @param arr The array to generate the string from
+ * @param sep The separator to use
+ * @return A string containing all of the data in the array.
+ */
+APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p,
+ const apr_array_header_t *arr,
+ const char sep);
+
+/**
+ * Make a new table.
+ * @param p The pool to allocate the pool out of
+ * @param nelts The number of elements in the initial table.
+ * @return The new table.
+ * @warning This table can only store text data
+ */
+APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts);
+
+/**
+ * Create a new table and copy another table into it.
+ * @param p The pool to allocate the new table out of
+ * @param t The table to copy
+ * @return A copy of the table passed in
+ * @warning The table keys and respective values are not copied
+ */
+APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p,
+ const apr_table_t *t);
+
+/**
+ * Create a new table whose contents are deep copied from the given
+ * table. A deep copy operation copies all fields, and makes copies
+ * of dynamically allocated memory pointed to by the fields.
+ * @param p The pool to allocate the new table out of
+ * @param t The table to clone
+ * @return A deep copy of the table passed in
+ */
+APR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p,
+ const apr_table_t *t);
+
+/**
+ * Delete all of the elements from a table.
+ * @param t The table to clear
+ */
+APR_DECLARE(void) apr_table_clear(apr_table_t *t);
+
+/**
+ * Get the value associated with a given key from the table. After this call,
+ * the data is still in the table.
+ * @param t The table to search for the key
+ * @param key The key to search for (case does not matter)
+ * @return The value associated with the key, or NULL if the key does not exist.
+ */
+APR_DECLARE(const char *) apr_table_get(const apr_table_t *t, const char *key);
+
+/**
+ * Get values associated with a given key from the table. If more than one
+ * value exists, return a comma separated list of values. After this call, the
+ * data is still in the table.
+ * @param p The pool to allocate the combined value from, if necessary
+ * @param t The table to search for the key
+ * @param key The key to search for (case does not matter)
+ * @return The value associated with the key, or NULL if the key does not exist.
+ */
+APR_DECLARE(const char *) apr_table_getm(apr_pool_t *p, const apr_table_t *t,
+ const char *key);
+
+/**
+ * Add a key/value pair to a table. If another element already exists with the
+ * same key, this will overwrite the old data.
+ * @param t The table to add the data to.
+ * @param key The key to use (case does not matter)
+ * @param val The value to add
+ * @remark When adding data, this function makes a copy of both the key and the
+ * value.
+ */
+APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key,
+ const char *val);
+
+/**
+ * Add a key/value pair to a table. If another element already exists with the
+ * same key, this will overwrite the old data.
+ * @param t The table to add the data to.
+ * @param key The key to use (case does not matter)
+ * @param val The value to add
+ * @warning When adding data, this function does not make a copy of the key or
+ * the value, so care should be taken to ensure that the values will
+ * not change after they have been added..
+ */
+APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key,
+ const char *val);
+
+/**
+ * Remove data from the table.
+ * @param t The table to remove data from
+ * @param key The key of the data being removed (case does not matter)
+ */
+APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key);
+
+/**
+ * Add data to a table by merging the value with data that has already been
+ * stored. The merging is done by concatenating the two values, separated
+ * by the string ", ".
+ * @param t The table to search for the data
+ * @param key The key to merge data for (case does not matter)
+ * @param val The data to add
+ * @remark If the key is not found, then this function acts like apr_table_add()
+ */
+APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key,
+ const char *val);
+
+/**
+ * Add data to a table by merging the value with data that has already been
+ * stored. The merging is done by concatenating the two values, separated
+ * by the string ", ".
+ * @param t The table to search for the data
+ * @param key The key to merge data for (case does not matter)
+ * @param val The data to add
+ * @remark If the key is not found, then this function acts like apr_table_addn()
+ */
+APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key,
+ const char *val);
+
+/**
+ * Add data to a table, regardless of whether there is another element with the
+ * same key.
+ * @param t The table to add to
+ * @param key The key to use
+ * @param val The value to add.
+ * @remark When adding data, this function makes a copy of both the key and the
+ * value.
+ */
+APR_DECLARE(void) apr_table_add(apr_table_t *t, const char *key,
+ const char *val);
+
+/**
+ * Add data to a table, regardless of whether there is another element with the
+ * same key.
+ * @param t The table to add to
+ * @param key The key to use
+ * @param val The value to add.
+ * @remark When adding data, this function does not make a copy of the key or the
+ * value, so care should be taken to ensure that the values will not
+ * change after they have been added.
+ */
+APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key,
+ const char *val);
+
+/**
+ * Merge two tables into one new table.
+ * @param p The pool to use for the new table
+ * @param overlay The first table to put in the new table
+ * @param base The table to add at the end of the new table
+ * @return A new table containing all of the data from the two passed in
+ */
+APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p,
+ const apr_table_t *overlay,
+ const apr_table_t *base);
+
+/**
+ * Declaration prototype for the iterator callback function of apr_table_do()
+ * and apr_table_vdo().
+ * @param rec The data passed as the first argument to apr_table_[v]do()
+ * @param key The key from this iteration of the table
+ * @param value The value from this iteration of the table
+ * @remark Iteration continues while this callback function returns non-zero.
+ * To export the callback function for apr_table_[v]do() it must be declared
+ * in the _NONSTD convention.
+ * @see apr_table_do @see apr_table_vdo
+ */
+typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key,
+ const char *value);
+
+/**
+ * Iterate over a table running the provided function once for every
+ * element in the table. The varargs array must be a list of zero or
+ * more (char *) keys followed by a NULL pointer. If zero keys are
+ * given, the @p comp function will be invoked for every element
+ * in the table. Otherwise, the function is invoked only for those
+ * elements matching the keys specified.
+ *
+ * If an invocation of the @p comp function returns zero,
+ * iteration will continue using the next specified key, if any.
+ *
+ * @param comp The function to run
+ * @param rec The data to pass as the first argument to the function
+ * @param t The table to iterate over
+ * @param ... A varargs array of zero or more (char *) keys followed by NULL
+ * @return FALSE if one of the comp() iterations returned zero; TRUE if all
+ * iterations returned non-zero
+ * @see apr_table_do_callback_fn_t @see apr_table_vdo
+ */
+APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp,
+ void *rec, const apr_table_t *t, ...)
+#if defined(__GNUC__) && __GNUC__ >= 4
+ __attribute__((sentinel))
+#endif
+ ;
+
+/**
+ * Iterate over a table running the provided function once for every
+ * element in the table. The @p vp varargs parameter must be a
+ * list of zero or more (char *) keys followed by a NULL pointer. If
+ * zero keys are given, the @p comp function will be invoked for
+ * every element in the table. Otherwise, the function is invoked
+ * only for those elements matching the keys specified.
+ *
+ * If an invocation of the @p comp function returns zero,
+ * iteration will continue using the next specified key, if any.
+ *
+ * @param comp The function to run
+ * @param rec The data to pass as the first argument to the function
+ * @param t The table to iterate over
+ * @param vp List of zero or more (char *) keys followed by NULL
+ * @return FALSE if one of the comp() iterations returned zero; TRUE if all
+ * iterations returned non-zero
+ * @see apr_table_do_callback_fn_t @see apr_table_do
+ */
+APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp,
+ void *rec, const apr_table_t *t, va_list vp);
+
+/** flag for overlap to use apr_table_setn */
+#define APR_OVERLAP_TABLES_SET (0)
+/** flag for overlap to use apr_table_mergen */
+#define APR_OVERLAP_TABLES_MERGE (1)
+/** flag for overlap to use apr_table_addn */
+#define APR_OVERLAP_TABLES_ADD (2)
+/**
+ * For each element in table b, either use setn or mergen to add the data
+ * to table a. Which method is used is determined by the flags passed in.
+ * @param a The table to add the data to.
+ * @param b The table to iterate over, adding its data to table a
+ * @param flags How to add the table to table a. One of:
+ * APR_OVERLAP_TABLES_SET Use apr_table_setn
+ * APR_OVERLAP_TABLES_MERGE Use apr_table_mergen
+ * APR_OVERLAP_TABLES_ADD Use apr_table_addn
+ * @remark When merging duplicates, the two values are concatenated,
+ * separated by the string ", ".
+ * @remark This function is highly optimized, and uses less memory and CPU cycles
+ * than a function that just loops through table b calling other functions.
+ */
+/**
+ * Conceptually, apr_table_overlap does this:
+ *
+ * <pre>
+ * apr_array_header_t *barr = apr_table_elts(b);
+ * apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts;
+ * int i;
+ *
+ * for (i = 0; i < barr->nelts; ++i) {
+ * if (flags & APR_OVERLAP_TABLES_MERGE) {
+ * apr_table_mergen(a, belt[i].key, belt[i].val);
+ * }
+ * else if (flags & APR_OVERLAP_TABLES_ADD) {
+ * apr_table_addn(a, belt[i].key, belt[i].val);
+ * }
+ * else {
+ * apr_table_setn(a, belt[i].key, belt[i].val);
+ * }
+ * }
+ * </pre>
+ *
+ * Except that it is more efficient (less space and cpu-time) especially
+ * when b has many elements.
+ *
+ * Notice the assumptions on the keys and values in b -- they must be
+ * in an ancestor of a's pool. In practice b and a are usually from
+ * the same pool.
+ */
+
+APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b,
+ unsigned flags);
+
+/**
+ * Eliminate redundant entries in a table by either overwriting
+ * or merging duplicates.
+ *
+ * @param t Table.
+ * @param flags APR_OVERLAP_TABLES_MERGE to merge, or
+ * APR_OVERLAP_TABLES_SET to overwrite, or
+ * APR_OVERLAP_TABLES_ADD to add
+ * @remark When merging duplicates, the two values are concatenated,
+ * separated by the string ", ".
+ */
+APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_TABLES_H */
diff --git a/include/apr_thread_cond.h b/include/apr_thread_cond.h
new file mode 100644
index 0000000..199f1de
--- /dev/null
+++ b/include/apr_thread_cond.h
@@ -0,0 +1,139 @@
+/* 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 APR_THREAD_COND_H
+#define APR_THREAD_COND_H
+
+/**
+ * @file apr_thread_cond.h
+ * @brief APR Condition Variable Routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_time.h"
+#include "apr_thread_mutex.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if APR_HAS_THREADS || defined(DOXYGEN)
+
+/**
+ * @defgroup apr_thread_cond Condition Variable Routines
+ * @ingroup APR
+ * @{
+ */
+
+/** Opaque structure for thread condition variables */
+typedef struct apr_thread_cond_t apr_thread_cond_t;
+
+/**
+ * Note: destroying a condition variable (or likewise, destroying or
+ * clearing the pool from which a condition variable was allocated) if
+ * any threads are blocked waiting on it gives undefined results.
+ */
+
+/**
+ * Create and initialize a condition variable that can be used to signal
+ * and schedule threads in a single process.
+ * @param cond the memory address where the newly created condition variable
+ * will be stored.
+ * @param pool the pool from which to allocate the condition.
+ */
+APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
+ apr_pool_t *pool);
+
+/**
+ * Put the active calling thread to sleep until signaled to wake up. Each
+ * condition variable must be associated with a mutex, and that mutex must
+ * be locked before calling this function, or the behavior will be
+ * undefined. As the calling thread is put to sleep, the given mutex
+ * will be simultaneously released; and as this thread wakes up the lock
+ * is again simultaneously acquired.
+ * @param cond the condition variable on which to block.
+ * @param mutex the mutex that must be locked upon entering this function,
+ * is released while the thread is asleep, and is again acquired before
+ * returning from this function.
+ * @remark Spurious wakeups may occur. Before and after every call to wait on
+ * a condition variable, the caller should test whether the condition is already
+ * met.
+ */
+APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
+ apr_thread_mutex_t *mutex);
+
+/**
+ * Put the active calling thread to sleep until signaled to wake up or
+ * the timeout is reached. Each condition variable must be associated
+ * with a mutex, and that mutex must be locked before calling this
+ * function, or the behavior will be undefined. As the calling thread
+ * is put to sleep, the given mutex will be simultaneously released;
+ * and as this thread wakes up the lock is again simultaneously acquired.
+ * @param cond the condition variable on which to block.
+ * @param mutex the mutex that must be locked upon entering this function,
+ * is released while the thread is asleep, and is again acquired before
+ * returning from this function.
+ * @param timeout The amount of time in microseconds to wait. This is
+ * a maximum, not a minimum. If the condition is signaled, we
+ * will wake up before this time, otherwise the error APR_TIMEUP
+ * is returned.
+ */
+APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond,
+ apr_thread_mutex_t *mutex,
+ apr_interval_time_t timeout);
+
+/**
+ * Signals a single thread, if one exists, that is blocking on the given
+ * condition variable. That thread is then scheduled to wake up and acquire
+ * the associated mutex. Although it is not required, if predictable scheduling
+ * is desired, that mutex must be locked while calling this function.
+ * @param cond the condition variable on which to produce the signal.
+ * @remark If no threads are waiting on the condition variable, nothing happens.
+ */
+APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond);
+
+/**
+ * Signals all threads blocking on the given condition variable.
+ * Each thread that was signaled is then scheduled to wake up and acquire
+ * the associated mutex. This will happen in a serialized manner.
+ * @param cond the condition variable on which to produce the broadcast.
+ * @remark If no threads are waiting on the condition variable, nothing happens.
+ */
+APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond);
+
+/**
+ * Destroy the condition variable and free the associated memory.
+ * @param cond the condition variable to destroy.
+ */
+APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond);
+
+/**
+ * Get the pool used by this thread_cond.
+ * @return apr_pool_t the pool
+ */
+APR_POOL_DECLARE_ACCESSOR(thread_cond);
+
+#endif /* APR_HAS_THREADS */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_THREAD_COND_H */
diff --git a/include/apr_thread_mutex.h b/include/apr_thread_mutex.h
new file mode 100644
index 0000000..8eb6172
--- /dev/null
+++ b/include/apr_thread_mutex.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 APR_THREAD_MUTEX_H
+#define APR_THREAD_MUTEX_H
+
+/**
+ * @file apr_thread_mutex.h
+ * @brief APR Thread Mutex Routines
+ */
+
+#include "apr.h"
+#include "apr_errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if APR_HAS_THREADS || defined(DOXYGEN)
+
+/**
+ * @defgroup apr_thread_mutex Thread Mutex Routines
+ * @ingroup APR
+ * @{
+ */
+
+/** Opaque thread-local mutex structure */
+typedef struct apr_thread_mutex_t apr_thread_mutex_t;
+
+#define APR_THREAD_MUTEX_DEFAULT 0x0 /**< platform-optimal lock behavior */
+#define APR_THREAD_MUTEX_NESTED 0x1 /**< enable nested (recursive) locks */
+#define APR_THREAD_MUTEX_UNNESTED 0x2 /**< disable nested locks */
+#define APR_THREAD_MUTEX_TIMED 0x4 /**< enable timed locks */
+
+/* Delayed the include to avoid a circular reference */
+#include "apr_pools.h"
+#include "apr_time.h"
+
+/**
+ * Create and initialize a mutex that can be used to synchronize threads.
+ * @param mutex the memory address where the newly created mutex will be
+ * stored.
+ * @param flags Or'ed value of:
+ * <PRE>
+ * APR_THREAD_MUTEX_DEFAULT platform-optimal lock behavior.
+ * APR_THREAD_MUTEX_NESTED enable nested (recursive) locks.
+ * APR_THREAD_MUTEX_UNNESTED disable nested locks (non-recursive).
+ * </PRE>
+ * @param pool the pool from which to allocate the mutex.
+ * @warning Be cautious in using APR_THREAD_MUTEX_DEFAULT. While this is the
+ * most optimal mutex based on a given platform's performance characteristics,
+ * it will behave as either a nested or an unnested lock.
+ */
+APR_DECLARE(apr_status_t) apr_thread_mutex_create(apr_thread_mutex_t **mutex,
+ unsigned int flags,
+ apr_pool_t *pool);
+/**
+ * Acquire the lock for the given mutex. If the mutex is already locked,
+ * the current thread will be put to sleep until the lock becomes available.
+ * @param mutex the mutex on which to acquire the lock.
+ */
+APR_DECLARE(apr_status_t) apr_thread_mutex_lock(apr_thread_mutex_t *mutex);
+
+/**
+ * Attempt to acquire the lock for the given mutex. If the mutex has already
+ * been acquired, the call returns immediately with APR_EBUSY. Note: it
+ * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
+ * if the return value was APR_EBUSY, for portability reasons.
+ * @param mutex the mutex on which to attempt the lock acquiring.
+ */
+APR_DECLARE(apr_status_t) apr_thread_mutex_trylock(apr_thread_mutex_t *mutex);
+
+/**
+ * Attempt to acquire the lock for the given mutex until timeout expires.
+ * If the acquisition time outs, the call returns with APR_TIMEUP.
+ * @param mutex the mutex on which to attempt the lock acquiring.
+ * @param timeout the relative timeout (microseconds).
+ * @note A timeout negative or nul means immediate attempt, returning
+ * APR_TIMEUP without blocking if it the lock is already acquired.
+ */
+APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex,
+ apr_interval_time_t timeout);
+
+/**
+ * Release the lock for the given mutex.
+ * @param mutex the mutex from which to release the lock.
+ */
+APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex);
+
+/**
+ * Destroy the mutex and free the memory associated with the lock.
+ * @param mutex the mutex to destroy.
+ */
+APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex);
+
+/**
+ * Get the pool used by this thread_mutex.
+ * @return apr_pool_t the pool
+ */
+APR_POOL_DECLARE_ACCESSOR(thread_mutex);
+
+#endif /* APR_HAS_THREADS */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_THREAD_MUTEX_H */
diff --git a/include/apr_thread_proc.h b/include/apr_thread_proc.h
new file mode 100644
index 0000000..ea3c43f
--- /dev/null
+++ b/include/apr_thread_proc.h
@@ -0,0 +1,846 @@
+/* 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 APR_THREAD_PROC_H
+#define APR_THREAD_PROC_H
+
+/**
+ * @file apr_thread_proc.h
+ * @brief APR Thread and Process Library
+ */
+
+#include "apr.h"
+#include "apr_file_io.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_perms_set.h"
+
+#if APR_HAVE_STRUCT_RLIMIT
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_thread_proc Threads and Process Functions
+ * @ingroup APR
+ * @{
+ */
+
+typedef enum {
+ APR_SHELLCMD, /**< use the shell to invoke the program */
+ APR_PROGRAM, /**< invoke the program directly, no copied env */
+ APR_PROGRAM_ENV, /**< invoke the program, replicating our environment */
+ APR_PROGRAM_PATH, /**< find program on PATH, use our environment */
+ APR_SHELLCMD_ENV /**< use the shell to invoke the program,
+ * replicating our environment
+ */
+} apr_cmdtype_e;
+
+typedef enum {
+ APR_WAIT, /**< wait for the specified process to finish */
+ APR_NOWAIT /**< do not wait -- just see if it has finished */
+} apr_wait_how_e;
+
+/* I am specifically calling out the values so that the macros below make
+ * more sense. Yes, I know I don't need to, but I am hoping this makes what
+ * I am doing more clear. If you want to add more reasons to exit, continue
+ * to use bitmasks.
+ */
+typedef enum {
+ APR_PROC_EXIT = 1, /**< process exited normally */
+ APR_PROC_SIGNAL = 2, /**< process exited due to a signal */
+ APR_PROC_SIGNAL_CORE = 4 /**< process exited and dumped a core file */
+} apr_exit_why_e;
+
+/** did we exit the process */
+#define APR_PROC_CHECK_EXIT(x) (x & APR_PROC_EXIT)
+/** did we get a signal */
+#define APR_PROC_CHECK_SIGNALED(x) (x & APR_PROC_SIGNAL)
+/** did we get core */
+#define APR_PROC_CHECK_CORE_DUMP(x) (x & APR_PROC_SIGNAL_CORE)
+
+/** @see apr_procattr_io_set */
+#define APR_NO_PIPE 0
+/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
+#define APR_FULL_BLOCK 1
+/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
+#define APR_FULL_NONBLOCK 2
+/** @see apr_procattr_io_set */
+#define APR_PARENT_BLOCK 3
+/** @see apr_procattr_io_set */
+#define APR_CHILD_BLOCK 4
+/** @see apr_procattr_io_set */
+#define APR_NO_FILE 8
+
+/** @see apr_file_pipe_create_ex */
+#define APR_READ_BLOCK 3
+/** @see apr_file_pipe_create_ex */
+#define APR_WRITE_BLOCK 4
+
+/** @see apr_procattr_io_set
+ * @note Win32 only effective with version 1.2.12, portably introduced in 1.3.0
+ */
+#define APR_NO_FILE 8
+
+/** @see apr_procattr_limit_set */
+#define APR_LIMIT_CPU 0
+/** @see apr_procattr_limit_set */
+#define APR_LIMIT_MEM 1
+/** @see apr_procattr_limit_set */
+#define APR_LIMIT_NPROC 2
+/** @see apr_procattr_limit_set */
+#define APR_LIMIT_NOFILE 3
+
+/**
+ * @defgroup APR_OC Other Child Flags
+ * @{
+ */
+#define APR_OC_REASON_DEATH 0 /**< child has died, caller must call
+ * unregister still */
+#define APR_OC_REASON_UNWRITABLE 1 /**< write_fd is unwritable */
+#define APR_OC_REASON_RESTART 2 /**< a restart is occurring, perform
+ * any necessary cleanup (including
+ * sending a special signal to child)
+ */
+#define APR_OC_REASON_UNREGISTER 3 /**< unregister has been called, do
+ * whatever is necessary (including
+ * kill the child) */
+#define APR_OC_REASON_LOST 4 /**< somehow the child exited without
+ * us knowing ... buggy os? */
+#define APR_OC_REASON_RUNNING 5 /**< a health check is occurring,
+ * for most maintainence functions
+ * this is a no-op.
+ */
+/** @} */
+
+/** The APR process type */
+typedef struct apr_proc_t {
+ /** The process ID */
+ pid_t pid;
+ /** Parent's side of pipe to child's stdin */
+ apr_file_t *in;
+ /** Parent's side of pipe to child's stdout */
+ apr_file_t *out;
+ /** Parent's side of pipe to child's stdouterr */
+ apr_file_t *err;
+#if APR_HAS_PROC_INVOKED || defined(DOXYGEN)
+ /** Diagnositics/debugging string of the command invoked for
+ * this process [only present if APR_HAS_PROC_INVOKED is true]
+ * @remark Only enabled on Win32 by default.
+ * @bug This should either always or never be present in release
+ * builds - since it breaks binary compatibility. We may enable
+ * it always in APR 1.0 yet leave it undefined in most cases.
+ */
+ char *invoked;
+#endif
+#if defined(WIN32) || defined(DOXYGEN)
+ /** (Win32 only) Creator's handle granting access to the process
+ * @remark This handle is closed and reset to NULL in every case
+ * corresponding to a waitpid() on Unix which returns the exit status.
+ * Therefore Win32 correspond's to Unix's zombie reaping characteristics
+ * and avoids potential handle leaks.
+ */
+ HANDLE hproc;
+#endif
+} apr_proc_t;
+
+/**
+ * The prototype for APR child errfn functions. (See the description
+ * of apr_procattr_child_errfn_set() for more information.)
+ * It is passed the following parameters:
+ * @param pool Pool associated with the apr_proc_t. If your child
+ * error function needs user data, associate it with this
+ * pool.
+ * @param err APR error code describing the error
+ * @param description Text description of type of processing which failed
+ */
+typedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err,
+ const char *description);
+
+/** Opaque Thread structure. */
+typedef struct apr_thread_t apr_thread_t;
+
+/** Opaque Thread attributes structure. */
+typedef struct apr_threadattr_t apr_threadattr_t;
+
+/** Opaque Process attributes structure. */
+typedef struct apr_procattr_t apr_procattr_t;
+
+/** Opaque control variable for one-time atomic variables. */
+typedef struct apr_thread_once_t apr_thread_once_t;
+
+/** Opaque thread private address space. */
+typedef struct apr_threadkey_t apr_threadkey_t;
+
+/** Opaque record of child process. */
+typedef struct apr_other_child_rec_t apr_other_child_rec_t;
+
+/**
+ * The prototype for any APR thread worker functions.
+ */
+typedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_t*, void*);
+
+typedef enum {
+ APR_KILL_NEVER, /**< process is never killed (i.e., never sent
+ * any signals), but it will be reaped if it exits
+ * before the pool is cleaned up */
+ APR_KILL_ALWAYS, /**< process is sent SIGKILL on apr_pool_t cleanup */
+ APR_KILL_AFTER_TIMEOUT, /**< SIGTERM, wait 3 seconds, SIGKILL */
+ APR_JUST_WAIT, /**< wait forever for the process to complete */
+ APR_KILL_ONLY_ONCE /**< send SIGTERM and then wait */
+} apr_kill_conditions_e;
+
+/* Thread Function definitions */
+
+#if APR_HAS_THREADS
+
+/**
+ * Create and initialize a new threadattr variable
+ * @param new_attr The newly created threadattr.
+ * @param cont The pool to use
+ */
+APR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new_attr,
+ apr_pool_t *cont);
+
+/**
+ * Set if newly created threads should be created in detached state.
+ * @param attr The threadattr to affect
+ * @param on Non-zero if detached threads should be created.
+ */
+APR_DECLARE(apr_status_t) apr_threadattr_detach_set(apr_threadattr_t *attr,
+ apr_int32_t on);
+
+/**
+ * Get the detach state for this threadattr.
+ * @param attr The threadattr to reference
+ * @return APR_DETACH if threads are to be detached, or APR_NOTDETACH
+ * if threads are to be joinable.
+ */
+APR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr);
+
+/**
+ * Set the stack size of newly created threads.
+ * @param attr The threadattr to affect
+ * @param stacksize The stack size in bytes
+ */
+APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
+ apr_size_t stacksize);
+
+/**
+ * Set the stack guard area size of newly created threads.
+ * @param attr The threadattr to affect
+ * @param guardsize The stack guard area size in bytes
+ * @note Thread library implementations commonly use a "guard area"
+ * after each thread's stack which is not readable or writable such that
+ * stack overflows cause a segfault; this consumes e.g. 4K of memory
+ * and increases memory management overhead. Setting the guard area
+ * size to zero hence trades off reliable behaviour on stack overflow
+ * for performance. */
+APR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr,
+ apr_size_t guardsize);
+
+/**
+ * Create a new thread of execution
+ * @param new_thread The newly created thread handle.
+ * @param attr The threadattr to use to determine how to create the thread
+ * @param func The function to start the new thread in
+ * @param data Any data to be passed to the starting function
+ * @param cont The pool to use
+ */
+APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new_thread,
+ apr_threadattr_t *attr,
+ apr_thread_start_t func,
+ void *data, apr_pool_t *cont);
+
+/**
+ * stop the current thread
+ * @param thd The thread to stop
+ * @param retval The return value to pass back to any thread that cares
+ */
+APR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd,
+ apr_status_t retval);
+
+/**
+ * block until the desired thread stops executing.
+ * @param retval The return value from the dead thread.
+ * @param thd The thread to join
+ */
+APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
+ apr_thread_t *thd);
+
+/**
+ * force the current thread to yield the processor
+ */
+APR_DECLARE(void) apr_thread_yield(void);
+
+/**
+ * Initialize the control variable for apr_thread_once. If this isn't
+ * called, apr_initialize won't work.
+ * @param control The control variable to initialize
+ * @param p The pool to allocate data from.
+ */
+APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
+ apr_pool_t *p);
+
+/**
+ * Run the specified function one time, regardless of how many threads
+ * call it.
+ * @param control The control variable. The same variable should
+ * be passed in each time the function is tried to be
+ * called. This is how the underlying functions determine
+ * if the function has ever been called before.
+ * @param func The function to call.
+ */
+APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
+ void (*func)(void));
+
+/**
+ * detach a thread
+ * @param thd The thread to detach
+ */
+APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd);
+
+/**
+ * Return user data associated with the current thread.
+ * @param data The user data associated with the thread.
+ * @param key The key to associate with the data
+ * @param thread The currently open thread.
+ */
+APR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key,
+ apr_thread_t *thread);
+
+/**
+ * Set user data associated with the current thread.
+ * @param data The user data to associate with the thread.
+ * @param key The key to use for associating the data with the thread
+ * @param cleanup The cleanup routine to use when the thread is destroyed.
+ * @param thread The currently open thread.
+ */
+APR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key,
+ apr_status_t (*cleanup) (void *),
+ apr_thread_t *thread);
+
+/**
+ * Create and initialize a new thread private address space
+ * @param key The thread private handle.
+ * @param dest The destructor to use when freeing the private memory.
+ * @param cont The pool to use
+ */
+APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key,
+ void (*dest)(void *),
+ apr_pool_t *cont);
+
+/**
+ * Get a pointer to the thread private memory
+ * @param new_mem The data stored in private memory
+ * @param key The handle for the desired thread private memory
+ */
+APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new_mem,
+ apr_threadkey_t *key);
+
+/**
+ * Set the data to be stored in thread private memory
+ * @param priv The data to be stored in private memory
+ * @param key The handle for the desired thread private memory
+ */
+APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv,
+ apr_threadkey_t *key);
+
+/**
+ * Free the thread private memory
+ * @param key The handle for the desired thread private memory
+ */
+APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key);
+
+/**
+ * Return the pool associated with the current threadkey.
+ * @param data The user data associated with the threadkey.
+ * @param key The key associated with the data
+ * @param threadkey The currently open threadkey.
+ */
+APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
+ apr_threadkey_t *threadkey);
+
+/**
+ * Return the pool associated with the current threadkey.
+ * @param data The data to set.
+ * @param key The key to associate with the data.
+ * @param cleanup The cleanup routine to use when the file is destroyed.
+ * @param threadkey The currently open threadkey.
+ */
+APR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key,
+ apr_status_t (*cleanup) (void *),
+ apr_threadkey_t *threadkey);
+
+#endif
+
+/**
+ * Create and initialize a new procattr variable
+ * @param new_attr The newly created procattr.
+ * @param cont The pool to use
+ */
+APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new_attr,
+ apr_pool_t *cont);
+
+/**
+ * Determine if any of stdin, stdout, or stderr should be linked to pipes
+ * when starting a child process.
+ * @param attr The procattr we care about.
+ * @param in Should stdin be a pipe back to the parent?
+ * @param out Should stdout be a pipe back to the parent?
+ * @param err Should stderr be a pipe back to the parent?
+ * @note If APR_NO_PIPE, there will be no special channel, the child
+ * inherits the parent's corresponding stdio stream. If APR_NO_FILE is
+ * specified, that corresponding stream is closed in the child (and will
+ * be INVALID_HANDLE_VALUE when inspected on Win32). This can have ugly
+ * side effects, as the next file opened in the child on Unix will fall
+ * into the stdio stream fd slot!
+ */
+APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
+ apr_int32_t in, apr_int32_t out,
+ apr_int32_t err);
+
+/**
+ * Set the child_in and/or parent_in values to existing apr_file_t values.
+ * @param attr The procattr we care about.
+ * @param child_in apr_file_t value to use as child_in. Must be a valid file.
+ * @param parent_in apr_file_t value to use as parent_in. Must be a valid file.
+ * @remark This is NOT a required initializer function. This is
+ * useful if you have already opened a pipe (or multiple files)
+ * that you wish to use, perhaps persistently across multiple
+ * process invocations - such as a log file. You can save some
+ * extra function calls by not creating your own pipe since this
+ * creates one in the process space for you.
+ * @bug Note that calling this function with two NULL files on some platforms
+ * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
+ * is it supported. @see apr_procattr_io_set instead for simple pipes.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_child_in_set(struct apr_procattr_t *attr,
+ apr_file_t *child_in,
+ apr_file_t *parent_in);
+
+/**
+ * Set the child_out and parent_out values to existing apr_file_t values.
+ * @param attr The procattr we care about.
+ * @param child_out apr_file_t value to use as child_out. Must be a valid file.
+ * @param parent_out apr_file_t value to use as parent_out. Must be a valid file.
+ * @remark This is NOT a required initializer function. This is
+ * useful if you have already opened a pipe (or multiple files)
+ * that you wish to use, perhaps persistently across multiple
+ * process invocations - such as a log file.
+ * @bug Note that calling this function with two NULL files on some platforms
+ * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
+ * is it supported. @see apr_procattr_io_set instead for simple pipes.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_child_out_set(struct apr_procattr_t *attr,
+ apr_file_t *child_out,
+ apr_file_t *parent_out);
+
+/**
+ * Set the child_err and parent_err values to existing apr_file_t values.
+ * @param attr The procattr we care about.
+ * @param child_err apr_file_t value to use as child_err. Must be a valid file.
+ * @param parent_err apr_file_t value to use as parent_err. Must be a valid file.
+ * @remark This is NOT a required initializer function. This is
+ * useful if you have already opened a pipe (or multiple files)
+ * that you wish to use, perhaps persistently across multiple
+ * process invocations - such as a log file.
+ * @bug Note that calling this function with two NULL files on some platforms
+ * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
+ * is it supported. @see apr_procattr_io_set instead for simple pipes.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_child_err_set(struct apr_procattr_t *attr,
+ apr_file_t *child_err,
+ apr_file_t *parent_err);
+
+/**
+ * Set which directory the child process should start executing in.
+ * @param attr The procattr we care about.
+ * @param dir Which dir to start in. By default, this is the same dir as
+ * the parent currently resides in, when the createprocess call
+ * is made.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr,
+ const char *dir);
+
+/**
+ * Set what type of command the child process will call.
+ * @param attr The procattr we care about.
+ * @param cmd The type of command. One of:
+ * <PRE>
+ * APR_SHELLCMD -- Anything that the shell can handle
+ * APR_PROGRAM -- Executable program (default)
+ * APR_PROGRAM_ENV -- Executable program, copy environment
+ * APR_PROGRAM_PATH -- Executable program on PATH, copy env
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr,
+ apr_cmdtype_e cmd);
+
+/**
+ * Determine if the child should start in detached state.
+ * @param attr The procattr we care about.
+ * @param detach Should the child start in detached state? Default is no.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr,
+ apr_int32_t detach);
+
+#if APR_HAVE_STRUCT_RLIMIT
+/**
+ * Set the Resource Utilization limits when starting a new process.
+ * @param attr The procattr we care about.
+ * @param what Which limit to set, one of:
+ * <PRE>
+ * APR_LIMIT_CPU
+ * APR_LIMIT_MEM
+ * APR_LIMIT_NPROC
+ * APR_LIMIT_NOFILE
+ * </PRE>
+ * @param limit Value to set the limit to.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr,
+ apr_int32_t what,
+ struct rlimit *limit);
+#endif
+
+/**
+ * Specify an error function to be called in the child process if APR
+ * encounters an error in the child prior to running the specified program.
+ * @param attr The procattr describing the child process to be created.
+ * @param errfn The function to call in the child process.
+ * @remark At the present time, it will only be called from apr_proc_create()
+ * on platforms where fork() is used. It will never be called on other
+ * platforms, on those platforms apr_proc_create() will return the error
+ * in the parent process rather than invoke the callback in the now-forked
+ * child process.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
+ apr_child_errfn_t *errfn);
+
+/**
+ * Specify that apr_proc_create() should do whatever it can to report
+ * failures to the caller of apr_proc_create(), rather than find out in
+ * the child.
+ * @param attr The procattr describing the child process to be created.
+ * @param chk Flag to indicate whether or not extra work should be done
+ * to try to report failures to the caller.
+ * @remark This flag only affects apr_proc_create() on platforms where
+ * fork() is used. This leads to extra overhead in the calling
+ * process, but that may help the application handle such
+ * errors more gracefully.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
+ apr_int32_t chk);
+
+/**
+ * Determine if the child should start in its own address space or using the
+ * current one from its parent
+ * @param attr The procattr we care about.
+ * @param addrspace Should the child start in its own address space? Default
+ * is no on NetWare and yes on other platforms.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_addrspace_set(apr_procattr_t *attr,
+ apr_int32_t addrspace);
+
+/**
+ * Set the username used for running process
+ * @param attr The procattr we care about.
+ * @param username The username used
+ * @param password User password if needed. Password is needed on WIN32
+ * or any other platform having
+ * APR_PROCATTR_USER_SET_REQUIRES_PASSWORD set.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
+ const char *username,
+ const char *password);
+
+/**
+ * Set the group used for running process
+ * @param attr The procattr we care about.
+ * @param groupname The group name used
+ */
+APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
+ const char *groupname);
+
+
+/**
+ * Register permission set function
+ * @param attr The procattr we care about.
+ * @param perms_set_fn Permission set callback
+ * @param data Data to pass to permission callback function
+ * @param perms Permissions to set
+ */
+APR_DECLARE(apr_status_t) apr_procattr_perms_set_register(apr_procattr_t *attr,
+ apr_perms_setfn_t *perms_set_fn,
+ void *data,
+ apr_fileperms_t perms);
+
+#if APR_HAS_FORK
+/**
+ * This is currently the only non-portable call in APR. This executes
+ * a standard unix fork.
+ * @param proc The resulting process handle.
+ * @param cont The pool to use.
+ * @remark returns APR_INCHILD for the child, and APR_INPARENT for the parent
+ * or an error.
+ */
+APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont);
+#endif
+
+/**
+ * Create a new process and execute a new program within that process.
+ * @param new_proc The resulting process handle.
+ * @param progname The program to run
+ * @param args the arguments to pass to the new program. The first
+ * one should be the program name.
+ * @param env The new environment table for the new process. This
+ * should be a list of NULL-terminated strings. This argument
+ * is ignored for APR_PROGRAM_ENV, APR_PROGRAM_PATH, and
+ * APR_SHELLCMD_ENV types of commands.
+ * @param attr the procattr we should use to determine how to create the new
+ * process
+ * @param pool The pool to use.
+ * @note This function returns without waiting for the new process to terminate;
+ * use apr_proc_wait for that.
+ */
+APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new_proc,
+ const char *progname,
+ const char * const *args,
+ const char * const *env,
+ apr_procattr_t *attr,
+ apr_pool_t *pool);
+
+/**
+ * Wait for a child process to die
+ * @param proc The process handle that corresponds to the desired child process
+ * @param exitcode The returned exit status of the child, if a child process
+ * dies, or the signal that caused the child to die.
+ * On platforms that don't support obtaining this information,
+ * the status parameter will be returned as APR_ENOTIMPL.
+ * @param exitwhy Why the child died, the bitwise or of:
+ * <PRE>
+ * APR_PROC_EXIT -- process terminated normally
+ * APR_PROC_SIGNAL -- process was killed by a signal
+ * APR_PROC_SIGNAL_CORE -- process was killed by a signal, and
+ * generated a core dump.
+ * </PRE>
+ * @param waithow How should we wait. One of:
+ * <PRE>
+ * APR_WAIT -- block until the child process dies.
+ * APR_NOWAIT -- return immediately regardless of if the
+ * child is dead or not.
+ * </PRE>
+ * @remark The child's status is in the return code to this process. It is one of:
+ * <PRE>
+ * APR_CHILD_DONE -- child is no longer running.
+ * APR_CHILD_NOTDONE -- child is still running.
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
+ int *exitcode, apr_exit_why_e *exitwhy,
+ apr_wait_how_e waithow);
+
+/**
+ * Wait for any current child process to die and return information
+ * about that child.
+ * @param proc Pointer to NULL on entry, will be filled out with child's
+ * information
+ * @param exitcode The returned exit status of the child, if a child process
+ * dies, or the signal that caused the child to die.
+ * On platforms that don't support obtaining this information,
+ * the status parameter will be returned as APR_ENOTIMPL.
+ * @param exitwhy Why the child died, the bitwise or of:
+ * <PRE>
+ * APR_PROC_EXIT -- process terminated normally
+ * APR_PROC_SIGNAL -- process was killed by a signal
+ * APR_PROC_SIGNAL_CORE -- process was killed by a signal, and
+ * generated a core dump.
+ * </PRE>
+ * @param waithow How should we wait. One of:
+ * <PRE>
+ * APR_WAIT -- block until the child process dies.
+ * APR_NOWAIT -- return immediately regardless of if the
+ * child is dead or not.
+ * </PRE>
+ * @param p Pool to allocate child information out of.
+ * @bug Passing proc as a *proc rather than **proc was an odd choice
+ * for some platforms... this should be revisited in 1.0
+ */
+APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
+ int *exitcode,
+ apr_exit_why_e *exitwhy,
+ apr_wait_how_e waithow,
+ apr_pool_t *p);
+
+#define APR_PROC_DETACH_FOREGROUND 0 /**< Do not detach */
+#define APR_PROC_DETACH_DAEMONIZE 1 /**< Detach */
+
+/**
+ * Detach the process from the controlling terminal.
+ * @param daemonize set to non-zero if the process should daemonize
+ * and become a background process, else it will
+ * stay in the foreground.
+ */
+APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize);
+
+/**
+ * Register an other_child -- a child associated to its registered
+ * maintence callback. This callback is invoked when the process
+ * dies, is disconnected or disappears.
+ * @param proc The child process to register.
+ * @param maintenance maintenance is a function that is invoked with a
+ * reason and the data pointer passed here.
+ * @param data Opaque context data passed to the maintenance function.
+ * @param write_fd An fd that is probed for writing. If it is ever unwritable
+ * then the maintenance is invoked with reason
+ * OC_REASON_UNWRITABLE.
+ * @param p The pool to use for allocating memory.
+ * @bug write_fd duplicates the proc->out stream, it's really redundant
+ * and should be replaced in the APR 1.0 API with a bitflag of which
+ * proc->in/out/err handles should be health checked.
+ * @bug no platform currently tests the pipes health.
+ */
+APR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc,
+ void (*maintenance) (int reason,
+ void *,
+ int status),
+ void *data, apr_file_t *write_fd,
+ apr_pool_t *p);
+
+/**
+ * Stop watching the specified other child.
+ * @param data The data to pass to the maintenance function. This is
+ * used to find the process to unregister.
+ * @warning Since this can be called by a maintenance function while we're
+ * scanning the other_children list, all scanners should protect
+ * themself by loading ocr->next before calling any maintenance
+ * function.
+ */
+APR_DECLARE(void) apr_proc_other_child_unregister(void *data);
+
+/**
+ * Notify the maintenance callback of a registered other child process
+ * that application has detected an event, such as death.
+ * @param proc The process to check
+ * @param reason The reason code to pass to the maintenance function
+ * @param status The status to pass to the maintenance function
+ * @remark An example of code using this behavior;
+ * <pre>
+ * rv = apr_proc_wait_all_procs(&proc, &exitcode, &status, APR_WAIT, p);
+ * if (APR_STATUS_IS_CHILD_DONE(rv)) {
+ * \#if APR_HAS_OTHER_CHILD
+ * if (apr_proc_other_child_alert(&proc, APR_OC_REASON_DEATH, status)
+ * == APR_SUCCESS) {
+ * ; (already handled)
+ * }
+ * else
+ * \#endif
+ * [... handling non-otherchild processes death ...]
+ * </pre>
+ */
+APR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc,
+ int reason,
+ int status);
+
+/**
+ * Test one specific other child processes and invoke the maintenance callback
+ * with the appropriate reason code, if still running, or the appropriate reason
+ * code if the process is no longer healthy.
+ * @param ocr The registered other child
+ * @param reason The reason code (e.g. APR_OC_REASON_RESTART) if still running
+ */
+APR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
+ int reason);
+
+/**
+ * Test all registered other child processes and invoke the maintenance callback
+ * with the appropriate reason code, if still running, or the appropriate reason
+ * code if the process is no longer healthy.
+ * @param reason The reason code (e.g. APR_OC_REASON_RESTART) to running processes
+ */
+APR_DECLARE(void) apr_proc_other_child_refresh_all(int reason);
+
+/**
+ * Terminate a process.
+ * @param proc The process to terminate.
+ * @param sig How to kill the process.
+ */
+APR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int sig);
+
+/**
+ * Register a process to be killed when a pool dies.
+ * @param a The pool to use to define the processes lifetime
+ * @param proc The process to register
+ * @param how How to kill the process, one of:
+ * <PRE>
+ * APR_KILL_NEVER -- process is never sent any signals
+ * APR_KILL_ALWAYS -- process is sent SIGKILL on apr_pool_t cleanup
+ * APR_KILL_AFTER_TIMEOUT -- SIGTERM, wait 3 seconds, SIGKILL
+ * APR_JUST_WAIT -- wait forever for the process to complete
+ * APR_KILL_ONLY_ONCE -- send SIGTERM and then wait
+ * </PRE>
+ */
+APR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *a, apr_proc_t *proc,
+ apr_kill_conditions_e how);
+
+#if APR_HAS_THREADS
+
+#if (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2)
+
+/**
+ * Setup the process for a single thread to be used for all signal handling.
+ * @warning This must be called before any threads are created
+ */
+APR_DECLARE(apr_status_t) apr_setup_signal_thread(void);
+
+/**
+ * Make the current thread listen for signals. This thread will loop
+ * forever, calling a provided function whenever it receives a signal. That
+ * functions should return 1 if the signal has been handled, 0 otherwise.
+ * @param signal_handler The function to call when a signal is received
+ * apr_status_t apr_signal_thread((int)(*signal_handler)(int signum))
+ * @note Synchronous signals like SIGABRT/SIGSEGV/SIGBUS/... are ignored by
+ * apr_signal_thread() and thus can't be waited by this function (they remain
+ * handled by the operating system or its native signals interface).
+ * @remark In APR version 1.6 and ealier, SIGUSR2 was part of these ignored
+ * signals and thus was never passed in to the signal_handler. From APR 1.7
+ * this is no more the case so SIGUSR2 can be handled in signal_handler and
+ * acted upon like the other asynchronous signals.
+ */
+APR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum));
+
+#endif /* (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) */
+
+/**
+ * Get the child-pool used by the thread from the thread info.
+ * @return apr_pool_t the pool
+ */
+APR_POOL_DECLARE_ACCESSOR(thread);
+
+#endif /* APR_HAS_THREADS */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_THREAD_PROC_H */
+
diff --git a/include/apr_thread_rwlock.h b/include/apr_thread_rwlock.h
new file mode 100644
index 0000000..0bd958f
--- /dev/null
+++ b/include/apr_thread_rwlock.h
@@ -0,0 +1,129 @@
+/* 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 APR_THREAD_RWLOCK_H
+#define APR_THREAD_RWLOCK_H
+
+/**
+ * @file apr_thread_rwlock.h
+ * @brief APR Reader/Writer Lock Routines
+ */
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if APR_HAS_THREADS
+
+/**
+ * @defgroup apr_thread_rwlock Reader/Writer Lock Routines
+ * @ingroup APR
+ * @{
+ */
+
+/** Opaque read-write thread-safe lock. */
+typedef struct apr_thread_rwlock_t apr_thread_rwlock_t;
+
+/**
+ * Note: The following operations have undefined results: unlocking a
+ * read-write lock which is not locked in the calling thread; write
+ * locking a read-write lock which is already locked by the calling
+ * thread; destroying a read-write lock more than once; clearing or
+ * destroying the pool from which a <b>locked</b> read-write lock is
+ * allocated.
+ */
+
+/**
+ * Create and initialize a read-write lock that can be used to synchronize
+ * threads.
+ * @param rwlock the memory address where the newly created readwrite lock
+ * will be stored.
+ * @param pool the pool from which to allocate the mutex.
+ */
+APR_DECLARE(apr_status_t) apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock,
+ apr_pool_t *pool);
+/**
+ * Acquire a shared-read lock on the given read-write lock. This will allow
+ * multiple threads to enter the same critical section while they have acquired
+ * the read lock.
+ * @param rwlock the read-write lock on which to acquire the shared read.
+ */
+APR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock);
+
+/**
+ * Attempt to acquire the shared-read lock on the given read-write lock. This
+ * is the same as apr_thread_rwlock_rdlock(), only that the function fails
+ * if there is another thread holding the write lock, or if there are any
+ * write threads blocking on the lock. If the function fails for this case,
+ * APR_EBUSY will be returned. Note: it is important that the
+ * APR_STATUS_IS_EBUSY(s) macro be used to determine if the return value was
+ * APR_EBUSY, for portability reasons.
+ * @param rwlock the rwlock on which to attempt the shared read.
+ */
+APR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock);
+
+/**
+ * Acquire an exclusive-write lock on the given read-write lock. This will
+ * allow only one single thread to enter the critical sections. If there
+ * are any threads currently holding the read-lock, this thread is put to
+ * sleep until it can have exclusive access to the lock.
+ * @param rwlock the read-write lock on which to acquire the exclusive write.
+ */
+APR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock);
+
+/**
+ * Attempt to acquire the exclusive-write lock on the given read-write lock.
+ * This is the same as apr_thread_rwlock_wrlock(), only that the function fails
+ * if there is any other thread holding the lock (for reading or writing),
+ * in which case the function will return APR_EBUSY. Note: it is important
+ * that the APR_STATUS_IS_EBUSY(s) macro be used to determine if the return
+ * value was APR_EBUSY, for portability reasons.
+ * @param rwlock the rwlock on which to attempt the exclusive write.
+ */
+APR_DECLARE(apr_status_t) apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock);
+
+/**
+ * Release either the read or write lock currently held by the calling thread
+ * associated with the given read-write lock.
+ * @param rwlock the read-write lock to be released (unlocked).
+ */
+APR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock);
+
+/**
+ * Destroy the read-write lock and free the associated memory.
+ * @param rwlock the rwlock to destroy.
+ */
+APR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock);
+
+/**
+ * Get the pool used by this thread_rwlock.
+ * @return apr_pool_t the pool
+ */
+APR_POOL_DECLARE_ACCESSOR(thread_rwlock);
+
+#endif /* APR_HAS_THREADS */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_THREAD_RWLOCK_H */
diff --git a/include/apr_time.h b/include/apr_time.h
new file mode 100644
index 0000000..b0efd79
--- /dev/null
+++ b/include/apr_time.h
@@ -0,0 +1,237 @@
+/* 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 APR_TIME_H
+#define APR_TIME_H
+
+/**
+ * @file apr_time.h
+ * @brief APR Time Library
+ */
+
+#include "apr.h"
+#include "apr_errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_time Time Routines
+ * @ingroup APR
+ * @{
+ */
+
+/** month names */
+APR_DECLARE_DATA extern const char apr_month_snames[12][4];
+/** day names */
+APR_DECLARE_DATA extern const char apr_day_snames[7][4];
+
+
+/** number of microseconds since 00:00:00 January 1, 1970 UTC */
+typedef apr_int64_t apr_time_t;
+
+
+/** mechanism to properly type apr_time_t literals */
+#define APR_TIME_C(val) APR_INT64_C(val)
+
+/** mechanism to properly print apr_time_t values */
+#define APR_TIME_T_FMT APR_INT64_T_FMT
+
+/** intervals for I/O timeouts, in microseconds */
+typedef apr_int64_t apr_interval_time_t;
+/** short interval for I/O timeouts, in microseconds */
+typedef apr_int32_t apr_short_interval_time_t;
+
+/** number of microseconds per second */
+#define APR_USEC_PER_SEC APR_TIME_C(1000000)
+
+/** @return apr_time_t as a second */
+#define apr_time_sec(time) ((time) / APR_USEC_PER_SEC)
+
+/** @return apr_time_t as a usec */
+#define apr_time_usec(time) ((time) % APR_USEC_PER_SEC)
+
+/** @return apr_time_t as a msec */
+#define apr_time_msec(time) (((time) / 1000) % 1000)
+
+/** @return apr_time_t as a msec */
+#define apr_time_as_msec(time) ((time) / 1000)
+
+/** @return milliseconds as an apr_time_t */
+#define apr_time_from_msec(msec) ((apr_time_t)(msec) * 1000)
+
+/** @return seconds as an apr_time_t */
+#define apr_time_from_sec(sec) ((apr_time_t)(sec) * APR_USEC_PER_SEC)
+
+/** @return a second and usec combination as an apr_time_t */
+#define apr_time_make(sec, usec) ((apr_time_t)(sec) * APR_USEC_PER_SEC \
+ + (apr_time_t)(usec))
+
+/**
+ * @return the current time
+ */
+APR_DECLARE(apr_time_t) apr_time_now(void);
+
+/** @see apr_time_exp_t */
+typedef struct apr_time_exp_t apr_time_exp_t;
+
+/**
+ * a structure similar to ANSI struct tm with the following differences:
+ * - tm_usec isn't an ANSI field
+ * - tm_gmtoff isn't an ANSI field (it's a BSDism)
+ */
+struct apr_time_exp_t {
+ /** microseconds past tm_sec */
+ apr_int32_t tm_usec;
+ /** (0-61) seconds past tm_min */
+ apr_int32_t tm_sec;
+ /** (0-59) minutes past tm_hour */
+ apr_int32_t tm_min;
+ /** (0-23) hours past midnight */
+ apr_int32_t tm_hour;
+ /** (1-31) day of the month */
+ apr_int32_t tm_mday;
+ /** (0-11) month of the year */
+ apr_int32_t tm_mon;
+ /** year since 1900 */
+ apr_int32_t tm_year;
+ /** (0-6) days since Sunday */
+ apr_int32_t tm_wday;
+ /** (0-365) days since January 1 */
+ apr_int32_t tm_yday;
+ /** daylight saving time */
+ apr_int32_t tm_isdst;
+ /** seconds east of UTC */
+ apr_int32_t tm_gmtoff;
+};
+
+/* Delayed the include to avoid a circular reference */
+#include "apr_pools.h"
+
+/**
+ * Convert an ansi time_t to an apr_time_t
+ * @param result the resulting apr_time_t
+ * @param input the time_t to convert
+ */
+APR_DECLARE(apr_status_t) apr_time_ansi_put(apr_time_t *result,
+ time_t input);
+
+/**
+ * Convert a time to its human readable components using an offset
+ * from GMT.
+ * @param result the exploded time
+ * @param input the time to explode
+ * @param offs the number of seconds offset to apply
+ */
+APR_DECLARE(apr_status_t) apr_time_exp_tz(apr_time_exp_t *result,
+ apr_time_t input,
+ apr_int32_t offs);
+
+/**
+ * Convert a time to its human readable components (GMT).
+ * @param result the exploded time
+ * @param input the time to explode
+ */
+APR_DECLARE(apr_status_t) apr_time_exp_gmt(apr_time_exp_t *result,
+ apr_time_t input);
+
+/**
+ * Convert a time to its human readable components in the local timezone.
+ * @param result the exploded time
+ * @param input the time to explode
+ */
+APR_DECLARE(apr_status_t) apr_time_exp_lt(apr_time_exp_t *result,
+ apr_time_t input);
+
+/**
+ * Convert time value from human readable format to a numeric apr_time_t
+ * (elapsed microseconds since the epoch).
+ * @param result the resulting imploded time
+ * @param input the input exploded time
+ */
+APR_DECLARE(apr_status_t) apr_time_exp_get(apr_time_t *result,
+ apr_time_exp_t *input);
+
+/**
+ * Convert time value from human readable format to a numeric apr_time_t that
+ * always represents GMT.
+ * @param result the resulting imploded time
+ * @param input the input exploded time
+ */
+APR_DECLARE(apr_status_t) apr_time_exp_gmt_get(apr_time_t *result,
+ apr_time_exp_t *input);
+
+/**
+ * Sleep for the specified number of micro-seconds.
+ * @param t desired amount of time to sleep.
+ * @warning May sleep for longer than the specified time.
+ */
+APR_DECLARE(void) apr_sleep(apr_interval_time_t t);
+
+/** length of a RFC822 Date */
+#define APR_RFC822_DATE_LEN (30)
+/**
+ * apr_rfc822_date formats dates in the RFC822
+ * format in an efficient manner. It is a fixed length
+ * format which requires APR_RFC822_DATA_LEN bytes of storage,
+ * including the trailing NUL terminator.
+ * @param date_str String to write to.
+ * @param t the time to convert
+ */
+APR_DECLARE(apr_status_t) apr_rfc822_date(char *date_str, apr_time_t t);
+
+/** length of a CTIME date */
+#define APR_CTIME_LEN (25)
+/**
+ * apr_ctime formats dates in the ctime() format
+ * in an efficient manner. It is a fixed length format
+ * and requires APR_CTIME_LEN bytes of storage including
+ * the trailing NUL terminator.
+ * Unlike ANSI/ISO C ctime(), apr_ctime() does not include
+ * a \\n at the end of the string.
+ * @param date_str String to write to.
+ * @param t the time to convert
+ */
+APR_DECLARE(apr_status_t) apr_ctime(char *date_str, apr_time_t t);
+
+/**
+ * Formats the exploded time according to the format specified
+ * @param s string to write to
+ * @param retsize The length of the returned string
+ * @param max The maximum length of the string
+ * @param format The format for the time string
+ * @param tm The time to convert
+ */
+APR_DECLARE(apr_status_t) apr_strftime(char *s, apr_size_t *retsize,
+ apr_size_t max, const char *format,
+ apr_time_exp_t *tm);
+
+/**
+ * Improve the clock resolution for the lifetime of the given pool.
+ * Generally this is only desirable on benchmarking and other very
+ * time-sensitive applications, and has no impact on most platforms.
+ * @param p The pool to associate the finer clock resolution
+ */
+APR_DECLARE(void) apr_time_clock_hires(apr_pool_t *p);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_TIME_H */
diff --git a/include/apr_user.h b/include/apr_user.h
new file mode 100644
index 0000000..0e0a3ac
--- /dev/null
+++ b/include/apr_user.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 APR_USER_H
+#define APR_USER_H
+
+/**
+ * @file apr_user.h
+ * @brief APR User ID Services
+ */
+
+#include "apr.h"
+#include "apr_errno.h"
+#include "apr_pools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup apr_user User and Group ID Services
+ * @ingroup APR
+ * @{
+ */
+
+/**
+ * Structure for determining user ownership.
+ */
+#ifdef WIN32
+typedef PSID apr_uid_t;
+#else
+typedef uid_t apr_uid_t;
+#endif
+
+/**
+ * Structure for determining group ownership.
+ */
+#ifdef WIN32
+typedef PSID apr_gid_t;
+#else
+typedef gid_t apr_gid_t;
+#endif
+
+#if APR_HAS_USER
+
+/**
+ * Get the userid (and groupid) of the calling process
+ * @param userid Returns the user id
+ * @param groupid Returns the user's group id
+ * @param p The pool from which to allocate working space
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+APR_DECLARE(apr_status_t) apr_uid_current(apr_uid_t *userid,
+ apr_gid_t *groupid,
+ apr_pool_t *p);
+
+/**
+ * Get the user name for a specified userid
+ * @param username Pointer to new string containing user name (on output)
+ * @param userid The userid
+ * @param p The pool from which to allocate the string
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+APR_DECLARE(apr_status_t) apr_uid_name_get(char **username, apr_uid_t userid,
+ apr_pool_t *p);
+
+/**
+ * Get the userid (and groupid) for the specified username
+ * @param userid Returns the user id
+ * @param groupid Returns the user's group id
+ * @param username The username to look up
+ * @param p The pool from which to allocate working space
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+APR_DECLARE(apr_status_t) apr_uid_get(apr_uid_t *userid, apr_gid_t *groupid,
+ const char *username, apr_pool_t *p);
+
+/**
+ * Get the home directory for the named user
+ * @param dirname Pointer to new string containing directory name (on output)
+ * @param username The named user
+ * @param p The pool from which to allocate the string
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+APR_DECLARE(apr_status_t) apr_uid_homepath_get(char **dirname,
+ const char *username,
+ apr_pool_t *p);
+
+/**
+ * Compare two user identifiers for equality.
+ * @param left One uid to test
+ * @param right Another uid to test
+ * @return APR_SUCCESS if the apr_uid_t structures identify the same user,
+ * APR_EMISMATCH if not, APR_BADARG if an apr_uid_t is invalid.
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+#if defined(WIN32)
+APR_DECLARE(apr_status_t) apr_uid_compare(apr_uid_t left, apr_uid_t right);
+#else
+#define apr_uid_compare(left,right) (((left) == (right)) ? APR_SUCCESS : APR_EMISMATCH)
+#endif
+
+/**
+ * Get the group name for a specified groupid
+ * @param groupname Pointer to new string containing group name (on output)
+ * @param groupid The groupid
+ * @param p The pool from which to allocate the string
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+APR_DECLARE(apr_status_t) apr_gid_name_get(char **groupname,
+ apr_gid_t groupid, apr_pool_t *p);
+
+/**
+ * Get the groupid for a specified group name
+ * @param groupid Pointer to the group id (on output)
+ * @param groupname The group name to look up
+ * @param p The pool from which to allocate the string
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+APR_DECLARE(apr_status_t) apr_gid_get(apr_gid_t *groupid,
+ const char *groupname, apr_pool_t *p);
+
+/**
+ * Compare two group identifiers for equality.
+ * @param left One gid to test
+ * @param right Another gid to test
+ * @return APR_SUCCESS if the apr_gid_t structures identify the same group,
+ * APR_EMISMATCH if not, APR_BADARG if an apr_gid_t is invalid.
+ * @remark This function is available only if APR_HAS_USER is defined.
+ */
+#if defined(WIN32)
+APR_DECLARE(apr_status_t) apr_gid_compare(apr_gid_t left, apr_gid_t right);
+#else
+#define apr_gid_compare(left,right) (((left) == (right)) ? APR_SUCCESS : APR_EMISMATCH)
+#endif
+
+#endif /* ! APR_HAS_USER */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! APR_USER_H */
diff --git a/include/apr_version.h b/include/apr_version.h
new file mode 100644
index 0000000..cfa1cab
--- /dev/null
+++ b/include/apr_version.h
@@ -0,0 +1,164 @@
+/* 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 APR_VERSION_H
+#define APR_VERSION_H
+
+/**
+ * @file apr_version.h
+ * @brief APR Versioning Interface
+ *
+ * APR's Version
+ *
+ * There are several different mechanisms for accessing the version. There
+ * is a string form, and a set of numbers; in addition, there are constants
+ * which can be compiled into your application, and you can query the library
+ * being used for its actual version.
+ *
+ * Note that it is possible for an application to detect that it has been
+ * compiled against a different version of APR by use of the compile-time
+ * constants and the use of the run-time query function.
+ *
+ * APR version numbering follows the guidelines specified in:
+ *
+ * http://apr.apache.org/versioning.html
+ */
+
+
+#define APR_COPYRIGHT "Copyright (c) 2000-2023 The Apache Software " \
+ "Foundation or its licensors, as applicable."
+
+/* The numeric compile-time version constants. These constants are the
+ * authoritative version numbers for APR.
+ */
+
+/** major version
+ * Major API changes that could cause compatibility problems for older
+ * programs such as structure size changes. No binary compatibility is
+ * possible across a change in the major version.
+ */
+#define APR_MAJOR_VERSION 1
+
+/** minor version
+ * Minor API changes that do not cause binary compatibility problems.
+ * Reset to 0 when upgrading APR_MAJOR_VERSION
+ */
+#define APR_MINOR_VERSION 7
+
+/** patch level
+ * The Patch Level never includes API changes, simply bug fixes.
+ * Reset to 0 when upgrading APR_MINOR_VERSION
+ */
+#define APR_PATCH_VERSION 2
+
+/**
+ * The symbol APR_IS_DEV_VERSION is only defined for internal,
+ * "development" copies of APR. It is undefined for released versions
+ * of APR.
+ */
+/* #undef APR_IS_DEV_VERSION */
+
+/**
+ * Check at compile time if the APR version is at least a certain
+ * level.
+ * @param major The major version component of the version checked
+ * for (e.g., the "1" of "1.3.0").
+ * @param minor The minor version component of the version checked
+ * for (e.g., the "3" of "1.3.0").
+ * @param patch The patch level component of the version checked
+ * for (e.g., the "0" of "1.3.0").
+ * @remark This macro is available with APR versions starting with
+ * 1.3.0.
+ */
+#define APR_VERSION_AT_LEAST(major,minor,patch) \
+(((major) < APR_MAJOR_VERSION) \
+ || ((major) == APR_MAJOR_VERSION && (minor) < APR_MINOR_VERSION) \
+ || ((major) == APR_MAJOR_VERSION && (minor) == APR_MINOR_VERSION && (patch) <= APR_PATCH_VERSION))
+
+#if defined(APR_IS_DEV_VERSION) || defined(DOXYGEN)
+/** Internal: string form of the "is dev" flag */
+#ifndef APR_IS_DEV_STRING
+#define APR_IS_DEV_STRING "-dev"
+#endif
+#else
+#define APR_IS_DEV_STRING ""
+#endif
+
+/* APR_STRINGIFY is defined here, and also in apr_general.h, so wrap it */
+#ifndef APR_STRINGIFY
+/** Properly quote a value as a string in the C preprocessor */
+#define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
+/** Helper macro for APR_STRINGIFY */
+#define APR_STRINGIFY_HELPER(n) #n
+#endif
+
+/** The formatted string of APR's version */
+#define APR_VERSION_STRING \
+ APR_STRINGIFY(APR_MAJOR_VERSION) "." \
+ APR_STRINGIFY(APR_MINOR_VERSION) "." \
+ APR_STRINGIFY(APR_PATCH_VERSION) \
+ APR_IS_DEV_STRING
+
+/** An alternative formatted string of APR's version */
+/* macro for Win32 .rc files using numeric csv representation */
+#define APR_VERSION_STRING_CSV APR_MAJOR_VERSION ##, \
+ ##APR_MINOR_VERSION ##, \
+ ##APR_PATCH_VERSION
+
+
+#ifndef APR_VERSION_ONLY
+
+/* The C language API to access the version at run time,
+ * as opposed to compile time. APR_VERSION_ONLY may be defined
+ * externally when preprocessing apr_version.h to obtain strictly
+ * the C Preprocessor macro declarations.
+ */
+
+#include "apr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The numeric version information is broken out into fields within this
+ * structure.
+ */
+typedef struct {
+ int major; /**< major number */
+ int minor; /**< minor number */
+ int patch; /**< patch number */
+ int is_dev; /**< is development (1 or 0) */
+} apr_version_t;
+
+/**
+ * Return APR's version information information in a numeric form.
+ *
+ * @param pvsn Pointer to a version structure for returning the version
+ * information.
+ */
+APR_DECLARE(void) apr_version(apr_version_t *pvsn);
+
+/** Return APR's version information as a string. */
+APR_DECLARE(const char *) apr_version_string(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef APR_VERSION_ONLY */
+
+#endif /* ndef APR_VERSION_H */
diff --git a/include/apr_want.h b/include/apr_want.h
new file mode 100644
index 0000000..2863b00
--- /dev/null
+++ b/include/apr_want.h
@@ -0,0 +1,124 @@
+/* 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.h" /* configuration data */
+/**
+ * @file apr_want.h
+ * @brief APR Standard Headers Support
+ *
+ * <PRE>
+ * Features:
+ *
+ * APR_WANT_STRFUNC: strcmp, strcat, strcpy, etc
+ * APR_WANT_MEMFUNC: memcmp, memcpy, etc
+ * APR_WANT_STDIO: <stdio.h> and related bits
+ * APR_WANT_IOVEC: struct iovec
+ * APR_WANT_BYTEFUNC: htons, htonl, ntohl, ntohs
+ *
+ * Typical usage:
+ *
+ * \#define APR_WANT_STRFUNC
+ * \#define APR_WANT_MEMFUNC
+ * \#include "apr_want.h"
+ *
+ * The appropriate headers will be included.
+ *
+ * Note: it is safe to use this in a header (it won't interfere with other
+ * headers' or source files' use of apr_want.h)
+ * </PRE>
+ */
+
+/* --------------------------------------------------------------------- */
+
+#ifdef APR_WANT_STRFUNC
+
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#if APR_HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#undef APR_WANT_STRFUNC
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#ifdef APR_WANT_MEMFUNC
+
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+
+#undef APR_WANT_MEMFUNC
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#ifdef APR_WANT_STDIO
+
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#undef APR_WANT_STDIO
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#ifdef APR_WANT_IOVEC
+
+#if APR_HAVE_IOVEC
+
+#if APR_HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
+#else
+
+#ifndef APR_IOVEC_DEFINED
+#define APR_IOVEC_DEFINED
+struct iovec
+{
+ void *iov_base;
+ size_t iov_len;
+};
+#endif /* !APR_IOVEC_DEFINED */
+
+#endif /* APR_HAVE_IOVEC */
+
+#undef APR_WANT_IOVEC
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#ifdef APR_WANT_BYTEFUNC
+
+/* Single Unix says they are in arpa/inet.h. Linux has them in
+ * netinet/in.h. FreeBSD has them in arpa/inet.h but requires that
+ * netinet/in.h be included first.
+ */
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if APR_HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#undef APR_WANT_BYTEFUNC
+#endif
+
+/* --------------------------------------------------------------------- */
diff --git a/include/arch/aix/apr_arch_dso.h b/include/arch/aix/apr_arch_dso.h
new file mode 100644
index 0000000..d1cac68
--- /dev/null
+++ b/include/arch/aix/apr_arch_dso.h
@@ -0,0 +1,41 @@
+/* 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 DSO_H
+#define DSO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_dso.h"
+#include "apr.h"
+
+#if APR_HAS_DSO
+
+void *dlopen(const char *path, int mode);
+void *dlsym(void *handle, const char *symbol);
+const char *dlerror(void);
+int dlclose(void *handle);
+
+struct apr_dso_handle_t {
+ apr_pool_t *pool;
+ void *handle;
+ const char *errormsg;
+};
+
+#endif
+
+#endif
diff --git a/include/arch/apr_private_common.h b/include/arch/apr_private_common.h
new file mode 100644
index 0000000..ec850c6
--- /dev/null
+++ b/include/arch/apr_private_common.h
@@ -0,0 +1,41 @@
+/* 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 contains private declarations common to all architectures.
+ */
+
+#ifndef APR_PRIVATE_COMMON_H
+#define APR_PRIVATE_COMMON_H
+
+#include "apr_pools.h"
+#include "apr_tables.h"
+
+apr_status_t apr_filepath_list_split_impl(apr_array_header_t **pathelts,
+ const char *liststr,
+ char separator,
+ apr_pool_t *p);
+
+apr_status_t apr_filepath_list_merge_impl(char **liststr,
+ apr_array_header_t *pathelts,
+ char separator,
+ apr_pool_t *p);
+
+/* temporary defines to handle 64bit compile mismatches */
+#define APR_INT_TRUNC_CAST int
+#define APR_UINT32_TRUNC_CAST apr_uint32_t
+
+#endif /*APR_PRIVATE_COMMON_H*/
diff --git a/include/arch/beos/apr_arch_dso.h b/include/arch/beos/apr_arch_dso.h
new file mode 100644
index 0000000..fbc5c2f
--- /dev/null
+++ b/include/arch/beos/apr_arch_dso.h
@@ -0,0 +1,41 @@
+/* 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 DSO_H
+#define DSO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_errno.h"
+#include "apr_dso.h"
+#include "apr.h"
+#include <kernel/image.h>
+#include <string.h>
+
+#if APR_HAS_DSO
+
+struct apr_dso_handle_t {
+ image_id handle; /* Handle to the DSO loaded */
+ apr_pool_t *pool;
+ const char *errormsg; /* if the load fails, we have an error
+ * message here :)
+ */
+};
+
+#endif
+
+#endif
diff --git a/include/arch/beos/apr_arch_proc_mutex.h b/include/arch/beos/apr_arch_proc_mutex.h
new file mode 100644
index 0000000..c60d8c6
--- /dev/null
+++ b/include/arch/beos/apr_arch_proc_mutex.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 PROC_MUTEX_H
+#define PROC_MUTEX_H
+
+#include "apr_pools.h"
+#include "apr_proc_mutex.h"
+#include "apr_file_io.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_portable.h"
+
+struct apr_proc_mutex_t {
+ apr_pool_t *pool;
+
+ /* Our lock :) */
+ sem_id Lock;
+ int32 LockCount;
+};
+
+#endif /* PROC_MUTEX_H */
+
diff --git a/include/arch/beos/apr_arch_thread_cond.h b/include/arch/beos/apr_arch_thread_cond.h
new file mode 100644
index 0000000..c9420b5
--- /dev/null
+++ b/include/arch/beos/apr_arch_thread_cond.h
@@ -0,0 +1,46 @@
+/* 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 THREAD_COND_H
+#define THREAD_COND_H
+
+#include <kernel/OS.h>
+#include "apr_pools.h"
+#include "apr_thread_cond.h"
+#include "apr_file_io.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_portable.h"
+#include "apr_ring.h"
+
+struct waiter_t {
+ APR_RING_ENTRY(waiter_t) link;
+ sem_id sem;
+};
+
+struct apr_thread_cond_t {
+ apr_pool_t *pool;
+ sem_id lock;
+ apr_thread_mutex_t *condlock;
+ thread_id owner;
+ /* active list */
+ APR_RING_HEAD(active_list, waiter_t) alist;
+ /* free list */
+ APR_RING_HEAD(free_list, waiter_t) flist;
+};
+
+#endif /* THREAD_COND_H */
+
diff --git a/include/arch/beos/apr_arch_thread_mutex.h b/include/arch/beos/apr_arch_thread_mutex.h
new file mode 100644
index 0000000..bb7d4ae
--- /dev/null
+++ b/include/arch/beos/apr_arch_thread_mutex.h
@@ -0,0 +1,42 @@
+/* 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 THREAD_MUTEX_H
+#define THREAD_MUTEX_H
+
+#include <kernel/OS.h>
+#include "apr_pools.h"
+#include "apr_thread_mutex.h"
+#include "apr_file_io.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_portable.h"
+
+struct apr_thread_mutex_t {
+ apr_pool_t *pool;
+
+ /* Our lock :) */
+ sem_id Lock;
+ int32 LockCount;
+
+ /* If we nest locks we need these... */
+ int nested;
+ apr_os_thread_t owner;
+ int owner_ref;
+};
+
+#endif /* THREAD_MUTEX_H */
+
diff --git a/include/arch/beos/apr_arch_thread_rwlock.h b/include/arch/beos/apr_arch_thread_rwlock.h
new file mode 100644
index 0000000..694b0d5
--- /dev/null
+++ b/include/arch/beos/apr_arch_thread_rwlock.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 THREAD_RWLOCK_H
+#define THREAD_RWLOCK_H
+
+#include <kernel/OS.h>
+#include "apr_pools.h"
+#include "apr_thread_rwlock.h"
+#include "apr_file_io.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_portable.h"
+
+struct apr_thread_rwlock_t {
+ apr_pool_t *pool;
+
+ /* Our lock :) */
+ sem_id Lock;
+ int32 LockCount;
+ /* Read/Write lock stuff */
+ sem_id Read;
+ int32 ReadCount;
+ sem_id Write;
+ int32 WriteCount;
+ int32 Nested;
+
+ thread_id writer;
+};
+
+#endif /* THREAD_RWLOCK_H */
+
diff --git a/include/arch/beos/apr_arch_threadproc.h b/include/arch/beos/apr_arch_threadproc.h
new file mode 100644
index 0000000..13de053
--- /dev/null
+++ b/include/arch/beos/apr_arch_threadproc.h
@@ -0,0 +1,95 @@
+/* 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_thread_proc.h"
+#include "apr_arch_file_io.h"
+#include "apr_file_io.h"
+#include "apr_thread_proc.h"
+#include "apr_general.h"
+#include "apr_portable.h"
+#include <kernel/OS.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <image.h>
+
+#ifndef THREAD_PROC_H
+#define THREAD_PROC_H
+
+#define SHELL_PATH "/bin/sh"
+
+#define PTHREAD_CANCEL_AYNCHRONOUS CANCEL_ASYNCH;
+#define PTHREAD_CANCEL_DEFERRED CANCEL_DEFER;
+
+#define PTHREAD_CANCEL_ENABLE CANCEL_ENABLE;
+#define PTHREAD_CANCEL_DISABLE CANCEL_DISABLE;
+
+#define BEOS_MAX_DATAKEYS 128
+
+struct apr_thread_t {
+ apr_pool_t *pool;
+ thread_id td;
+ void *data;
+ apr_thread_start_t func;
+ apr_status_t exitval;
+};
+
+struct apr_threadattr_t {
+ apr_pool_t *pool;
+ int32 attr;
+ int detached;
+ int joinable;
+};
+
+struct apr_threadkey_t {
+ apr_pool_t *pool;
+ int32 key;
+};
+
+struct beos_private_data {
+ const void ** data;
+ int count;
+ volatile thread_id td;
+};
+
+struct beos_key {
+ int assigned;
+ int count;
+ sem_id lock;
+ int32 ben_lock;
+ void (* destructor) (void *);
+};
+
+struct apr_procattr_t {
+ apr_pool_t *pool;
+ apr_file_t *parent_in;
+ apr_file_t *child_in;
+ apr_file_t *parent_out;
+ apr_file_t *child_out;
+ apr_file_t *parent_err;
+ apr_file_t *child_err;
+ char *currdir;
+ apr_int32_t cmdtype;
+ apr_int32_t detached;
+};
+
+struct apr_thread_once_t {
+ sem_id sem;
+ int hit;
+};
+
+#endif /* ! THREAD_PROC_H */
+
diff --git a/include/arch/netware/apr_arch_dso.h b/include/arch/netware/apr_arch_dso.h
new file mode 100644
index 0000000..ea0fe8c
--- /dev/null
+++ b/include/arch/netware/apr_arch_dso.h
@@ -0,0 +1,43 @@
+/* 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 DSO_H
+#define DSO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_dso.h"
+#include "apr.h"
+
+#include <dlfcn.h>
+
+typedef struct sym_list sym_list;
+
+struct sym_list {
+ sym_list *next;
+ char *symbol;
+};
+
+struct apr_dso_handle_t {
+ apr_pool_t *pool;
+ void *handle;
+ const char *errormsg;
+ sym_list *symbols;
+ char *path;
+};
+
+#endif
diff --git a/include/arch/netware/apr_arch_file_io.h b/include/arch/netware/apr_arch_file_io.h
new file mode 100644
index 0000000..8bd2a72
--- /dev/null
+++ b/include/arch/netware/apr_arch_file_io.h
@@ -0,0 +1,176 @@
+/* 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 FILE_IO_H
+#define FILE_IO_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_tables.h"
+#include "apr_file_io.h"
+#include "apr_file_info.h"
+#include "apr_errno.h"
+#include "apr_lib.h"
+#include "apr_poll.h"
+
+/* System headers the file I/O library needs */
+#if APR_HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if APR_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#if APR_HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#if APR_HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if APR_HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#if APR_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include <fsio.h>
+
+/* End System headers */
+
+#define APR_FILE_DEFAULT_BUFSIZE 4096
+/* For backwards compat */
+#define APR_FILE_BUFSIZE APR_FILE_DEFAULT_BUFSIZE
+
+#if APR_HAS_THREADS
+#define file_lock(f) do { \
+ if ((f)->thlock) \
+ apr_thread_mutex_lock((f)->thlock); \
+ } while (0)
+#define file_unlock(f) do { \
+ if ((f)->thlock) \
+ apr_thread_mutex_unlock((f)->thlock); \
+ } while (0)
+#else
+#define file_lock(f) do {} while (0)
+#define file_unlock(f) do {} while (0)
+#endif
+
+#if APR_HAS_LARGE_FILES
+#define lseek(f,o,w) lseek64(f,o,w)
+#define ftruncate(f,l) ftruncate64(f,l)
+#endif
+
+typedef struct stat struct_stat;
+
+struct apr_file_t {
+ apr_pool_t *pool;
+ int filedes;
+ char *fname;
+ apr_int32_t flags;
+ int eof_hit;
+ int is_pipe;
+ apr_interval_time_t timeout;
+ int buffered;
+ enum {BLK_UNKNOWN, BLK_OFF, BLK_ON } blocking;
+ int ungetchar; /* Last char provided by an unget op. (-1 = no char)*/
+
+ /* if there is a timeout set, then this pollset is used */
+ apr_pollset_t *pollset;
+
+ /* Stuff for buffered mode */
+ char *buffer;
+ apr_size_t bufpos; /* Read/Write position in buffer */
+ apr_size_t bufsize; /* The buffer size */
+ apr_off_t dataRead; /* amount of valid data read into buffer */
+ int direction; /* buffer being used for 0 = read, 1 = write */
+ apr_off_t filePtr; /* position in file of handle */
+#if APR_HAS_THREADS
+ struct apr_thread_mutex_t *thlock;
+#endif
+};
+
+struct apr_dir_t {
+ apr_pool_t *pool;
+ char *dirname;
+ DIR *dirstruct;
+ struct dirent *entry;
+};
+
+typedef struct apr_stat_entry_t apr_stat_entry_t;
+
+struct apr_stat_entry_t {
+ struct stat info;
+ char *casedName;
+ apr_time_t expire;
+ NXPathCtx_t pathCtx;
+};
+
+#define MAX_SERVER_NAME 64
+#define MAX_VOLUME_NAME 64
+#define MAX_PATH_NAME 256
+#define MAX_FILE_NAME 256
+
+#define DRIVE_ONLY 1
+
+/* If the user passes d: vs. D: (or //mach/share vs. //MACH/SHARE),
+ * we need to fold the case to canonical form. This function is
+ * supposed to do so.
+ */
+apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
+
+/* This function check to see of the given path includes a drive/volume
+ * specifier. If the _only_ parameter is set to DRIVE_ONLY then it
+ * check to see of the path only contains a drive/volume specifier and
+ * nothing else.
+ */
+apr_status_t filepath_has_drive(const char *rootpath, int only, apr_pool_t *p);
+
+/* This function compares the drive/volume specifiers for each given path.
+ * It returns zero if they match or non-zero if not.
+ */
+apr_status_t filepath_compare_drive(const char *path1, const char *path2, apr_pool_t *p);
+
+apr_status_t apr_unix_file_cleanup(void *);
+apr_status_t apr_unix_child_file_cleanup(void *);
+
+mode_t apr_unix_perms2mode(apr_fileperms_t perms);
+apr_fileperms_t apr_unix_mode2perms(mode_t mode);
+
+apr_status_t apr_file_flush_locked(apr_file_t *thefile);
+apr_status_t apr_file_info_get_locked(apr_finfo_t *finfo, apr_int32_t wanted,
+ apr_file_t *thefile);
+
+#endif /* ! FILE_IO_H */
+
diff --git a/include/arch/netware/apr_arch_global_mutex.h b/include/arch/netware/apr_arch_global_mutex.h
new file mode 100644
index 0000000..4167d37
--- /dev/null
+++ b/include/arch/netware/apr_arch_global_mutex.h
@@ -0,0 +1,29 @@
+/* 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 GLOBAL_MUTEX_H
+#define GLOBAL_MUTEX_H
+
+#include "apr_global_mutex.h"
+#include "apr_thread_mutex.h"
+
+struct apr_global_mutex_t {
+ apr_pool_t *pool;
+ apr_thread_mutex_t *mutex;
+};
+
+#endif /* GLOBAL_MUTEX_H */
+
diff --git a/include/arch/netware/apr_arch_internal_time.h b/include/arch/netware/apr_arch_internal_time.h
new file mode 100644
index 0000000..59f1067
--- /dev/null
+++ b/include/arch/netware/apr_arch_internal_time.h
@@ -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.
+ */
+
+#ifndef TIME_INTERNAL_H
+#define TIME_INTERNAL_H
+
+#include "apr.h"
+
+#define TZONE (*___timezone())
+
+void apr_netware_setup_time(void);
+
+#endif /* TIME_INTERNAL_H */
diff --git a/include/arch/netware/apr_arch_networkio.h b/include/arch/netware/apr_arch_networkio.h
new file mode 100644
index 0000000..63f17ab
--- /dev/null
+++ b/include/arch/netware/apr_arch_networkio.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.
+ */
+
+#ifndef NETWORK_IO_H
+
+#ifdef USE_WINSOCK
+/* Making sure that we include the correct networkio.h since the
+ the project file is configured to first look for headers in
+ arch/netware and then arch/unix. But in this specific case we
+ want arch/win32.
+*/
+#include <../win32/apr_arch_networkio.h>
+#else
+#include <../unix/apr_arch_networkio.h>
+#endif
+
+#endif /* ! NETWORK_IO_H */
+
diff --git a/include/arch/netware/apr_arch_pre_nw.h b/include/arch/netware/apr_arch_pre_nw.h
new file mode 100644
index 0000000..7380e11
--- /dev/null
+++ b/include/arch/netware/apr_arch_pre_nw.h
@@ -0,0 +1,57 @@
+/* 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 __pre_nw__
+#define __pre_nw__
+
+#include <stdint.h>
+
+#ifndef __GNUC__
+#pragma precompile_target "precomp.mch"
+#endif
+
+#define NETWARE
+
+#define N_PLAT_NLM
+
+#define FAR
+#define far
+
+/* no-op for Codewarrior C compiler; a functions are cdecl
+ by default */
+#define cdecl
+
+/* if we have wchar_t enabled in C++, predefine this type to avoid
+ a conflict in Novell's header files */
+#ifndef __GNUC__
+#ifndef DOXYGEN
+#if (__option(cplusplus) && __option(wchar_type))
+#define _WCHAR_T
+#endif
+#endif
+#endif
+
+/* C9X defintion used by MSL C++ library */
+#define DECIMAL_DIG 17
+
+/* some code may want to use the MS convention for long long */
+#ifndef __int64
+#define __int64 long long
+#endif
+
+#endif
+
+
+
diff --git a/include/arch/netware/apr_arch_proc_mutex.h b/include/arch/netware/apr_arch_proc_mutex.h
new file mode 100644
index 0000000..7a634c2
--- /dev/null
+++ b/include/arch/netware/apr_arch_proc_mutex.h
@@ -0,0 +1,29 @@
+/* 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 PROC_MUTEX_H
+#define PROC_MUTEX_H
+
+#include "apr_proc_mutex.h"
+#include "apr_thread_mutex.h"
+
+struct apr_proc_mutex_t {
+ apr_pool_t *pool;
+ apr_thread_mutex_t *mutex;
+};
+
+#endif /* PROC_MUTEX_H */
+
diff --git a/include/arch/netware/apr_arch_thread_cond.h b/include/arch/netware/apr_arch_thread_cond.h
new file mode 100644
index 0000000..b11a5f8
--- /dev/null
+++ b/include/arch/netware/apr_arch_thread_cond.h
@@ -0,0 +1,29 @@
+/* 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 THREAD_COND_H
+#define THREAD_COND_H
+
+#include "apr_thread_cond.h"
+#include <nks/synch.h>
+
+struct apr_thread_cond_t {
+ apr_pool_t *pool;
+ NXCond_t *cond;
+};
+
+#endif /* THREAD_COND_H */
+
diff --git a/include/arch/netware/apr_arch_thread_mutex.h b/include/arch/netware/apr_arch_thread_mutex.h
new file mode 100644
index 0000000..18702fc
--- /dev/null
+++ b/include/arch/netware/apr_arch_thread_mutex.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.
+ */
+
+#ifndef THREAD_MUTEX_H
+#define THREAD_MUTEX_H
+
+#include "apr_thread_mutex.h"
+#include "apr_thread_cond.h"
+#include <nks/synch.h>
+
+struct apr_thread_mutex_t {
+ apr_pool_t *pool;
+ NXMutex_t *mutex;
+ apr_thread_cond_t *cond;
+ int locked, num_waiters;
+};
+
+#endif /* THREAD_MUTEX_H */
+
diff --git a/include/arch/netware/apr_arch_thread_rwlock.h b/include/arch/netware/apr_arch_thread_rwlock.h
new file mode 100644
index 0000000..d2dbd42
--- /dev/null
+++ b/include/arch/netware/apr_arch_thread_rwlock.h
@@ -0,0 +1,29 @@
+/* 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 THREAD_RWLOCK_H
+#define THREAD_RWLOCK_H
+
+#include "apr_thread_rwlock.h"
+#include <nks/synch.h>
+
+struct apr_thread_rwlock_t {
+ apr_pool_t *pool;
+ NXRwLock_t *rwlock;
+};
+
+#endif /* THREAD_RWLOCK_H */
+
diff --git a/include/arch/netware/apr_arch_threadproc.h b/include/arch/netware/apr_arch_threadproc.h
new file mode 100644
index 0000000..2fee2c0
--- /dev/null
+++ b/include/arch/netware/apr_arch_threadproc.h
@@ -0,0 +1,80 @@
+/* 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.h"
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+
+#include <sys/wait.h>
+
+#ifndef THREAD_PROC_H
+#define THREAD_PROC_H
+
+#define SHELL_PATH ""
+#define APR_DEFAULT_STACK_SIZE 65536
+
+struct apr_thread_t {
+ apr_pool_t *pool;
+ NXContext_t ctx;
+ NXThreadId_t td;
+ char *thread_name;
+ apr_int32_t cancel;
+ apr_int32_t cancel_how;
+ void *data;
+ apr_thread_start_t func;
+ apr_status_t exitval;
+};
+
+struct apr_threadattr_t {
+ apr_pool_t *pool;
+ apr_size_t stack_size;
+ apr_int32_t detach;
+ char *thread_name;
+};
+
+struct apr_threadkey_t {
+ apr_pool_t *pool;
+ NXKey_t key;
+};
+
+struct apr_procattr_t {
+ apr_pool_t *pool;
+ apr_file_t *parent_in;
+ apr_file_t *child_in;
+ apr_file_t *parent_out;
+ apr_file_t *child_out;
+ apr_file_t *parent_err;
+ apr_file_t *child_err;
+ char *currdir;
+ apr_int32_t cmdtype;
+ apr_int32_t detached;
+ apr_int32_t addrspace;
+};
+
+struct apr_thread_once_t {
+ unsigned long value;
+};
+
+/*
+struct apr_proc_t {
+ apr_pool_t *pool;
+ pid_t pid;
+ apr_procattr_t *attr;
+};
+*/
+
+#endif /* ! THREAD_PROC_H */
+
diff --git a/include/arch/netware/apr_private.h b/include/arch/netware/apr_private.h
new file mode 100644
index 0000000..04f336d
--- /dev/null
+++ b/include/arch/netware/apr_private.h
@@ -0,0 +1,205 @@
+/* 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.
+ */
+
+/*
+ * Note:
+ * This is the netware-specific autoconf-like config file
+ * which unix creates at ./configure time.
+ */
+
+#ifdef NETWARE
+
+#ifndef APR_PRIVATE_H
+#define APR_PRIVATE_H
+
+/* Pick up publicly advertised headers and symbols before the
+ * APR internal private headers and symbols
+ */
+#include <apr.h>
+
+/* Pick up privately consumed headers */
+#include <ndkvers.h>
+
+/* Include alloca.h to get compiler-dependent defines */
+#include <alloca.h>
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <library.h>
+#include <netware.h>
+
+/* Use this section to define all of the HAVE_FOO_H
+ * that are required to build properly.
+ */
+#define HAVE_DLFCN_H 1
+#define HAVE_LIMITS_H 1
+#define HAVE_SIGNAL_H 1
+#define HAVE_STDDEF_H 1
+#define HAVE_STDLIB_H 1
+#ifndef USE_WINSOCK
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_WRITEV 1
+#endif
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_MMAN_H 1
+#define HAVE_FCNTL_H 1
+#define HAVE_ICONV_H 1
+#define HAVE_UTIME_H 1
+
+#define HAVE_STRICMP 1
+#define HAVE_STRNICMP 1
+#define HAVE_STRDUP 1
+#define HAVE_STRSTR 1
+#define HAVE_MEMCHR 1
+#define HAVE_CALLOC 1
+#define HAVE_UTIME 1
+
+#define HAVE_GETENV 1
+#define HAVE_SETENV 1
+#define HAVE_UNSETENV 1
+
+#define HAVE_WRITEV 1
+
+#define HAVE_GETPASS_R 1
+/*
+ * Hack around older NDKs which have only the getpassword() function,
+ * a threadsafe, API-equivalent of getpass_r().
+ */
+#if (CURRENT_NDK_THRESHOLD < 709060000)
+#define getpass_r getpassword
+#endif
+
+/*#define DSO_USE_DLFCN */
+
+#ifdef NW_BUILD_IPV6
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETNAMEINFO 1
+#endif
+
+/* 1 is used for SIGABRT on netware */
+/* 2 is used for SIGFPE on netware */
+/* 3 is used for SIGILL on netware */
+/* 4 is used for SIGINT on netware */
+/* 5 is used for SIGSEGV on netware */
+/* 6 is used for SIGTERM on netware */
+/* 7 is used for SIGPOLL on netware */
+
+#if (CURRENT_NDK_THRESHOLD < 306030000)
+#define SIGKILL 11
+#define SIGALRM 13
+#define SIGCHLD 14
+#define SIGCONT 15
+#define SIGHUP 16
+#define SIGPIPE 17
+#define SIGQUIT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGUSR1 23
+#define SIGUSR2 24
+#endif
+
+#define SIGTRAP 25
+#define SIGIOT 26
+#define SIGSTKFLT 28
+#define SIGURG 29
+#define SIGXCPU 30
+#define SIGXFSZ 31
+#define SIGVTALRM 32
+#define SIGPROF 33
+#define SIGWINCH 34
+#define SIGIO 35
+
+#if (CURRENT_NDK_THRESHOLD < 406230000)
+#undef SA_NOCLDSTOP
+#define SA_NOCLDSTOP 0x00000001
+#endif
+#ifndef SIGBUS
+#define SIGBUS SIGSEGV
+#endif
+
+#define _getch getcharacter
+
+#define SIZEOF_SHORT 2
+#define SIZEOF_INT 4
+#define SIZEOF_LONGLONG 8
+#define SIZEOF_CHAR 1
+#define SIZEOF_SSIZE_T SIZEOF_INT
+
+void netware_pool_proc_cleanup();
+
+/* NLM registration routines for managing which NLMs
+ are using the library. */
+int register_NLM(void *NLMHandle);
+int unregister_NLM(void *NLMHandle);
+
+/* Application global data management */
+extern int gLibId;
+extern void *gLibHandle;
+
+typedef struct app_data {
+ int initialized;
+ void* gPool;
+ void* gs_aHooksToSort;
+ void* gs_phOptionalHooks;
+ void* gs_phOptionalFunctions;
+ void* gs_nlmhandle;
+ rtag_t gs_startup_rtag;
+ rtag_t gs_socket_rtag;
+ rtag_t gs_lookup_rtag;
+ rtag_t gs_event_rtag;
+ rtag_t gs_pcp_rtag;
+ void* gs_ldap_xref_lock;
+ void* gs_xref_head;
+} APP_DATA;
+
+int setGlobalPool(void *data);
+void* getGlobalPool();
+int setStatCache(void *data);
+void* getStatCache();
+
+/* Redefine malloc to use the library malloc call so
+ that all of the memory resources will be owned
+ and can be shared by the library. */
+#undef malloc
+#define malloc(x) library_malloc(gLibHandle,x)
+#ifndef __MWERKS__
+#define _alloca alloca
+#endif
+
+/* 64-bit integer conversion function */
+#define APR_INT64_STRFN strtoll
+
+#if APR_HAS_LARGE_FILES
+#define APR_OFF_T_STRFN strtoll
+#else
+#define APR_OFF_T_STRFN strtol
+#endif
+
+/* used to check DWORD overflow for 64bit compiles */
+#define APR_DWORD_MAX 0xFFFFFFFFUL
+
+/*
+ * Include common private declarations.
+ */
+#include "../apr_private_common.h"
+
+#endif /*APR_PRIVATE_H*/
+#endif /*NETWARE*/
diff --git a/include/arch/os2/apr_arch_dso.h b/include/arch/os2/apr_arch_dso.h
new file mode 100644
index 0000000..2bda6b7
--- /dev/null
+++ b/include/arch/os2/apr_arch_dso.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 DSO_H
+#define DSO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_dso.h"
+#include "apr.h"
+
+#if APR_HAS_DSO
+
+struct apr_dso_handle_t {
+ apr_pool_t *cont; /* Context for returning error strings */
+ HMODULE handle; /* Handle to the DSO loaded */
+ apr_status_t load_error;
+ char *failed_module;
+};
+
+#endif
+
+#endif
diff --git a/include/arch/os2/apr_arch_file_io.h b/include/arch/os2/apr_arch_file_io.h
new file mode 100644
index 0000000..79a5796
--- /dev/null
+++ b/include/arch/os2/apr_arch_file_io.h
@@ -0,0 +1,86 @@
+/* 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 FILE_IO_H
+#define FILE_IO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_thread_mutex.h"
+#include "apr_file_io.h"
+#include "apr_file_info.h"
+#include "apr_errno.h"
+#include "apr_poll.h"
+
+/* We have an implementation of mkstemp but it's not very multi-threading
+ * friendly & is part of the POSIX emulation rather than native so don't
+ * use it.
+ */
+#undef HAVE_MKSTEMP
+
+#define APR_FILE_DEFAULT_BUFSIZE 4096
+#define APR_FILE_BUFSIZE APR_FILE_DEFAULT_BUFSIZE
+
+struct apr_file_t {
+ apr_pool_t *pool;
+ HFILE filedes;
+ char * fname;
+ int isopen;
+ int buffered;
+ int eof_hit;
+ apr_int32_t flags;
+ int timeout;
+ int pipe;
+ HEV pipeSem;
+ enum { BLK_UNKNOWN, BLK_OFF, BLK_ON } blocking;
+
+ /* Stuff for buffered mode */
+ char *buffer;
+ apr_size_t bufsize; /* Read/Write position in buffer */
+ apr_size_t bufpos; /* Read/Write position in buffer */
+ unsigned long dataRead; /* amount of valid data read into buffer */
+ int direction; /* buffer being used for 0 = read, 1 = write */
+ unsigned long filePtr; /* position in file of handle */
+ apr_thread_mutex_t *mutex; /* mutex semaphore, must be owned to access
+ the above fields */
+};
+
+struct apr_dir_t {
+ apr_pool_t *pool;
+ char *dirname;
+ ULONG handle;
+ FILEFINDBUF3 entry;
+ int validentry;
+};
+
+apr_status_t apr_file_cleanup(void *);
+apr_status_t apr_os2_time_to_apr_time(apr_time_t *result, FDATE os2date,
+ FTIME os2time);
+apr_status_t apr_apr_time_to_os2_time(FDATE *os2date, FTIME *os2time,
+ apr_time_t aprtime);
+
+/* see win32/fileio.h for description of these */
+extern const char c_is_fnchar[256];
+
+#define IS_FNCHAR(c) c_is_fnchar[(unsigned char)c]
+
+apr_status_t filepath_root_test(char *path, apr_pool_t *p);
+apr_status_t filepath_drive_get(char **rootpath, char drive,
+ apr_int32_t flags, apr_pool_t *p);
+apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
+
+#endif /* ! FILE_IO_H */
+
diff --git a/include/arch/os2/apr_arch_inherit.h b/include/arch/os2/apr_arch_inherit.h
new file mode 100644
index 0000000..494772a
--- /dev/null
+++ b/include/arch/os2/apr_arch_inherit.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 INHERIT_H
+#define INHERIT_H
+
+#include "apr_inherit.h"
+
+#define APR_INHERIT (1 << 24) /* Must not conflict with other bits */
+
+#define APR_IMPLEMENT_INHERIT_SET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_set(apr_##name##_t *the##name) \
+{ \
+ int rv; \
+ ULONG state; \
+ if (((rv = DosQueryFHState(attr->parent_err->filedes, &state)) \
+ != 0) || \
+ ((rv = DosSetFHState(attr->parent_err->filedes, \
+ state & ~OPEN_FLAGS_NOINHERIT)) != 0)) \
+ return APR_FROM_OS_ERROR(rv); \
+ return APR_SUCCESS; \
+}
+
+#define APR_IMPLEMENT_INHERIT_UNSET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_unset(apr_##name##_t *the##name)\
+{ \
+ int rv; \
+ ULONG state; \
+ if (((rv = DosQueryFHState(attr->parent_err->filedes, &state)) \
+ != 0) || \
+ ((rv = DosSetFHState(attr->parent_err->filedes, \
+ state | OPEN_FLAGS_NOINHERIT)) != 0)) \
+ return APR_FROM_OS_ERROR(rv); \
+ return APR_SUCCESS; \
+}
+
+#endif /* ! INHERIT_H */
diff --git a/include/arch/os2/apr_arch_networkio.h b/include/arch/os2/apr_arch_networkio.h
new file mode 100644
index 0000000..10c6de8
--- /dev/null
+++ b/include/arch/os2/apr_arch_networkio.h
@@ -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.
+ */
+
+#ifndef NETWORK_IO_H
+#define NETWORK_IO_H
+
+#include "apr_private.h"
+#include "apr_network_io.h"
+#include "apr_general.h"
+#include "apr_arch_os2calls.h"
+#include "apr_poll.h"
+
+#if APR_HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+typedef struct sock_userdata_t sock_userdata_t;
+struct sock_userdata_t {
+ sock_userdata_t *next;
+ const char *key;
+ void *data;
+};
+
+struct apr_socket_t {
+ apr_pool_t *pool;
+ int socketdes;
+ int type;
+ int protocol;
+ apr_sockaddr_t *local_addr;
+ apr_sockaddr_t *remote_addr;
+ apr_interval_time_t timeout;
+ int nonblock;
+ int local_port_unknown;
+ int local_interface_unknown;
+ int remote_addr_unknown;
+ apr_int32_t options;
+ apr_int32_t inherit;
+ sock_userdata_t *userdata;
+
+ /* if there is a timeout set, then this pollset is used */
+ apr_pollset_t *pollset;
+};
+
+/* Error codes returned from sock_errno() */
+#define SOCBASEERR 10000
+#define SOCEPERM (SOCBASEERR+1) /* Not owner */
+#define SOCESRCH (SOCBASEERR+3) /* No such process */
+#define SOCEINTR (SOCBASEERR+4) /* Interrupted system call */
+#define SOCENXIO (SOCBASEERR+6) /* No such device or address */
+#define SOCEBADF (SOCBASEERR+9) /* Bad file number */
+#define SOCEACCES (SOCBASEERR+13) /* Permission denied */
+#define SOCEFAULT (SOCBASEERR+14) /* Bad address */
+#define SOCEINVAL (SOCBASEERR+22) /* Invalid argument */
+#define SOCEMFILE (SOCBASEERR+24) /* Too many open files */
+#define SOCEPIPE (SOCBASEERR+32) /* Broken pipe */
+#define SOCEOS2ERR (SOCBASEERR+100) /* OS/2 Error */
+
+const char *apr_inet_ntop(int af, const void *src, char *dst, apr_size_t size);
+int apr_inet_pton(int af, const char *src, void *dst);
+void apr_sockaddr_vars_set(apr_sockaddr_t *, int, apr_port_t);
+
+#endif /* ! NETWORK_IO_H */
+
diff --git a/include/arch/os2/apr_arch_os2calls.h b/include/arch/os2/apr_arch_os2calls.h
new file mode 100644
index 0000000..3c739bf
--- /dev/null
+++ b/include/arch/os2/apr_arch_os2calls.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.
+ */
+
+#include "apr_errno.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+
+extern int (*apr_os2_socket)(int, int, int);
+extern int (*apr_os2_select)(int *, int, int, int, long);
+extern int (*apr_os2_sock_errno)();
+extern int (*apr_os2_accept)(int, struct sockaddr *, int *);
+extern int (*apr_os2_bind)(int, struct sockaddr *, int);
+extern int (*apr_os2_connect)(int, struct sockaddr *, int);
+extern int (*apr_os2_getpeername)(int, struct sockaddr *, int *);
+extern int (*apr_os2_getsockname)(int, struct sockaddr *, int *);
+extern int (*apr_os2_getsockopt)(int, int, int, char *, int *);
+extern int (*apr_os2_ioctl)(int, int, caddr_t, int);
+extern int (*apr_os2_listen)(int, int);
+extern int (*apr_os2_recv)(int, char *, int, int);
+extern int (*apr_os2_send)(int, const char *, int, int);
+extern int (*apr_os2_setsockopt)(int, int, int, char *, int);
+extern int (*apr_os2_shutdown)(int, int);
+extern int (*apr_os2_soclose)(int);
+extern int (*apr_os2_writev)(int, struct iovec *, int);
+extern int (*apr_os2_sendto)(int, const char *, int, int, const struct sockaddr *, int);
+extern int (*apr_os2_recvfrom)(int, char *, int, int, struct sockaddr *, int *);
+
+#define socket apr_os2_socket
+#define select apr_os2_select
+#define sock_errno apr_os2_sock_errno
+#define accept apr_os2_accept
+#define bind apr_os2_bind
+#define connect apr_os2_connect
+#define getpeername apr_os2_getpeername
+#define getsockname apr_os2_getsockname
+#define getsockopt apr_os2_getsockopt
+#define ioctl apr_os2_ioctl
+#define listen apr_os2_listen
+#define recv apr_os2_recv
+#define send apr_os2_send
+#define setsockopt apr_os2_setsockopt
+#define shutdown apr_os2_shutdown
+#define soclose apr_os2_soclose
+#define writev apr_os2_writev
+#define sendto apr_os2_sendto
+#define recvfrom apr_os2_recvfrom
diff --git a/include/arch/os2/apr_arch_proc_mutex.h b/include/arch/os2/apr_arch_proc_mutex.h
new file mode 100644
index 0000000..8caf336
--- /dev/null
+++ b/include/arch/os2/apr_arch_proc_mutex.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.
+ */
+
+#ifndef PROC_MUTEX_H
+#define PROC_MUTEX_H
+
+#include "apr_proc_mutex.h"
+#include "apr_file_io.h"
+
+struct apr_proc_mutex_t {
+ apr_pool_t *pool;
+ HMTX hMutex;
+ TID owner;
+ int lock_count;
+};
+
+#endif /* PROC_MUTEX_H */
+
diff --git a/include/arch/os2/apr_arch_thread_cond.h b/include/arch/os2/apr_arch_thread_cond.h
new file mode 100644
index 0000000..aa0a7ca
--- /dev/null
+++ b/include/arch/os2/apr_arch_thread_cond.h
@@ -0,0 +1,33 @@
+/* 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 THREAD_COND_H
+#define THREAD_COND_H
+
+#include "apr_thread_cond.h"
+#include "apr_file_io.h"
+
+struct apr_thread_cond_t {
+ apr_pool_t *pool;
+ HEV semaphore;
+ HMTX mutex;
+ unsigned long num_waiting;
+ unsigned long num_wake;
+ unsigned long generation;
+};
+
+#endif /* THREAD_COND_H */
+
diff --git a/include/arch/os2/apr_arch_thread_mutex.h b/include/arch/os2/apr_arch_thread_mutex.h
new file mode 100644
index 0000000..3ae2a41
--- /dev/null
+++ b/include/arch/os2/apr_arch_thread_mutex.h
@@ -0,0 +1,29 @@
+/* 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 THREAD_MUTEX_H
+#define THREAD_MUTEX_H
+
+#include "apr_thread_mutex.h"
+#include "apr_file_io.h"
+
+struct apr_thread_mutex_t {
+ apr_pool_t *pool;
+ HMTX hMutex;
+};
+
+#endif /* THREAD_MUTEX_H */
+
diff --git a/include/arch/os2/apr_arch_thread_rwlock.h b/include/arch/os2/apr_arch_thread_rwlock.h
new file mode 100644
index 0000000..7187d5c
--- /dev/null
+++ b/include/arch/os2/apr_arch_thread_rwlock.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.
+ */
+
+#ifndef THREAD_RWLOCK_H
+#define THREAD_RWLOCK_H
+
+#include "apr_thread_rwlock.h"
+#include "apr_file_io.h"
+
+struct apr_thread_rwlock_t {
+ apr_pool_t *pool;
+ int readers;
+ HMTX write_lock;
+ HEV read_done;
+};
+
+#endif /* THREAD_RWLOCK_H */
+
diff --git a/include/arch/os2/apr_arch_threadproc.h b/include/arch/os2/apr_arch_threadproc.h
new file mode 100644
index 0000000..c8017ad
--- /dev/null
+++ b/include/arch/os2/apr_arch_threadproc.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.
+ */
+
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+
+#ifndef THREAD_PROC_H
+#define THREAD_PROC_H
+
+#define APR_THREADATTR_DETACHED 1
+
+#define SHELL_PATH "cmd.exe"
+#define APR_THREAD_STACKSIZE 65536
+
+struct apr_threadattr_t {
+ apr_pool_t *pool;
+ unsigned long attr;
+ apr_size_t stacksize;
+};
+
+struct apr_thread_t {
+ apr_pool_t *pool;
+ struct apr_threadattr_t *attr;
+ unsigned long tid;
+ apr_thread_start_t func;
+ void *data;
+ apr_status_t exitval;
+};
+
+struct apr_threadkey_t {
+ apr_pool_t *pool;
+ unsigned long *key;
+};
+
+struct apr_procattr_t {
+ apr_pool_t *pool;
+ apr_file_t *parent_in;
+ apr_file_t *child_in;
+ apr_file_t *parent_out;
+ apr_file_t *child_out;
+ apr_file_t *parent_err;
+ apr_file_t *child_err;
+ char *currdir;
+ apr_int32_t cmdtype;
+ apr_int32_t detached;
+};
+
+struct apr_thread_once_t {
+ unsigned long sem;
+ char hit;
+};
+
+#endif /* ! THREAD_PROC_H */
+
diff --git a/include/arch/os390/apr_arch_dso.h b/include/arch/os390/apr_arch_dso.h
new file mode 100644
index 0000000..4263297
--- /dev/null
+++ b/include/arch/os390/apr_arch_dso.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.
+ */
+
+#ifndef DSO_H
+#define DSO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_dso.h"
+#include "apr.h"
+
+#if APR_HAS_DSO
+
+#include <dll.h>
+
+struct apr_dso_handle_t {
+ dllhandle *handle; /* Handle to the DSO loaded */
+ int failing_errno; /* Don't save the buffer returned by
+ strerror(); it gets reused */
+ apr_pool_t *pool;
+};
+
+#endif
+
+#endif
diff --git a/include/arch/unix/apr_arch_atomic.h b/include/arch/unix/apr_arch_atomic.h
new file mode 100644
index 0000000..ce771ad
--- /dev/null
+++ b/include/arch/unix/apr_arch_atomic.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 ATOMIC_H
+#define ATOMIC_H
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_private.h"
+#include "apr_atomic.h"
+
+#if defined(USE_ATOMICS_GENERIC)
+/* noop */
+#elif HAVE_ATOMIC_BUILTINS
+# define USE_ATOMICS_BUILTINS
+# if HAVE_ATOMIC_BUILTINS64
+# define USE_ATOMICS_BUILTINS64
+# else
+# define NEED_ATOMICS_GENERIC64
+# endif
+#elif defined(SOLARIS2) && SOLARIS2 >= 10
+# define USE_ATOMICS_SOLARIS
+# define NEED_ATOMICS_GENERIC64
+#elif defined(__GNUC__) && defined(__STRICT_ANSI__)
+/* force use of generic atomics if building e.g. with -std=c89, which
+ * doesn't allow inline asm */
+# define USE_ATOMICS_GENERIC
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# define USE_ATOMICS_IA32
+# define NEED_ATOMICS_GENERIC64
+#elif defined(__GNUC__) && (defined(__powerpc__) \
+ || defined(__PPC__) \
+ || defined(__ppc__))
+# define USE_ATOMICS_PPC
+# define NEED_ATOMICS_GENERIC64
+#elif defined(__GNUC__) && (defined(__s390__) || defined(__s390x__))
+# define USE_ATOMICS_S390
+# define NEED_ATOMICS_GENERIC64
+#else
+# define USE_ATOMICS_GENERIC
+#endif
+
+#if defined(USE_ATOMICS_GENERIC) || defined (NEED_ATOMICS_GENERIC64)
+apr_status_t apr__atomic_generic64_init(apr_pool_t *p);
+#endif
+
+#endif /* ATOMIC_H */
diff --git a/include/arch/unix/apr_arch_dso.h b/include/arch/unix/apr_arch_dso.h
new file mode 100644
index 0000000..d82182d
--- /dev/null
+++ b/include/arch/unix/apr_arch_dso.h
@@ -0,0 +1,63 @@
+/* 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 DSO_H
+#define DSO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_dso.h"
+#include "apr.h"
+
+#if APR_HAS_DSO
+
+#ifdef HAVE_MACH_O_DYLD_H
+#include <mach-o/dyld.h>
+#endif
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#ifdef HAVE_DL_H
+#include <dl.h>
+#endif
+
+#ifndef RTLD_NOW
+#define RTLD_NOW 1
+#endif
+
+#ifndef RTLD_GLOBAL
+#define RTLD_GLOBAL 0
+#endif
+
+#if (defined(__DragonFly__) ||\
+ defined(__FreeBSD__) ||\
+ defined(__OpenBSD__) ||\
+ defined(__NetBSD__) ) && !defined(__ELF__)
+#define DLSYM_NEEDS_UNDERSCORE
+#endif
+
+struct apr_dso_handle_t {
+ apr_pool_t *pool;
+ void *handle;
+ const char *errormsg;
+};
+
+#endif
+
+#endif
diff --git a/include/arch/unix/apr_arch_file_io.h b/include/arch/unix/apr_arch_file_io.h
new file mode 100644
index 0000000..77a9091
--- /dev/null
+++ b/include/arch/unix/apr_arch_file_io.h
@@ -0,0 +1,174 @@
+/* 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 FILE_IO_H
+#define FILE_IO_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_tables.h"
+#include "apr_file_io.h"
+#include "apr_file_info.h"
+#include "apr_errno.h"
+#include "apr_lib.h"
+#include "apr_thread_mutex.h"
+#ifndef WAITIO_USES_POLL
+#include "apr_poll.h"
+#endif
+
+/* System headers the file I/O library needs */
+#if APR_HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if APR_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#if APR_HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#if APR_HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if APR_HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#if APR_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef BEOS
+#include <kernel/OS.h>
+#endif
+/* Hunting down DEV_BSIZE if not from dirent.h, sys/stat.h etc */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#if BEOS_BONE
+# ifndef BONE7
+ /* prior to BONE/7 fd_set & select were defined in sys/socket.h */
+# include <sys/socket.h>
+# else
+ /* Be moved the fd_set stuff and also the FIONBIO definition... */
+# include <sys/ioctl.h>
+# endif
+#endif
+/* End System headers */
+
+#define APR_FILE_DEFAULT_BUFSIZE 4096
+/* For backwards-compat */
+#define APR_FILE_BUFSIZE APR_FILE_DEFAULT_BUFSIZE
+
+struct apr_file_t {
+ apr_pool_t *pool;
+ int filedes;
+ char *fname;
+ apr_int32_t flags;
+ int eof_hit;
+ int is_pipe;
+ apr_interval_time_t timeout;
+ int buffered;
+ enum {BLK_UNKNOWN, BLK_OFF, BLK_ON } blocking;
+ int ungetchar; /* Last char provided by an unget op. (-1 = no char)*/
+#ifndef WAITIO_USES_POLL
+ /* if there is a timeout set, then this pollset is used */
+ apr_pollset_t *pollset;
+#endif
+ /* Stuff for buffered mode */
+ char *buffer;
+ apr_size_t bufpos; /* Read/Write position in buffer */
+ apr_size_t bufsize; /* The size of the buffer */
+ unsigned long dataRead; /* amount of valid data read into buffer */
+ int direction; /* buffer being used for 0 = read, 1 = write */
+ apr_off_t filePtr; /* position in file of handle */
+#if APR_HAS_THREADS
+ struct apr_thread_mutex_t *thlock;
+#endif
+};
+
+#if APR_HAS_THREADS
+#define file_lock(f) do { \
+ if ((f)->thlock) \
+ apr_thread_mutex_lock((f)->thlock); \
+ } while (0)
+#define file_unlock(f) do { \
+ if ((f)->thlock) \
+ apr_thread_mutex_unlock((f)->thlock); \
+ } while (0)
+#else
+#define file_lock(f) do {} while (0)
+#define file_unlock(f) do {} while (0)
+#endif
+
+#if APR_HAS_LARGE_FILES && defined(_LARGEFILE64_SOURCE)
+#define stat(f,b) stat64(f,b)
+#define lstat(f,b) lstat64(f,b)
+#define fstat(f,b) fstat64(f,b)
+#define lseek(f,o,w) lseek64(f,o,w)
+#define ftruncate(f,l) ftruncate64(f,l)
+typedef struct stat64 struct_stat;
+#else
+typedef struct stat struct_stat;
+#endif
+
+/* readdir64_r is only used in specific cases: */
+#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) \
+ && !defined(READDIR_IS_THREAD_SAFE) && defined(HAVE_READDIR64_R)
+#define APR_USE_READDIR64_R
+#endif
+
+struct apr_dir_t {
+ apr_pool_t *pool;
+ char *dirname;
+ DIR *dirstruct;
+#ifdef APR_USE_READDIR64_R
+ struct dirent64 *entry;
+#else
+ struct dirent *entry;
+#endif
+};
+
+apr_status_t apr_unix_file_cleanup(void *);
+apr_status_t apr_unix_child_file_cleanup(void *);
+
+mode_t apr_unix_perms2mode(apr_fileperms_t perms);
+apr_fileperms_t apr_unix_mode2perms(mode_t mode);
+
+apr_status_t apr_file_flush_locked(apr_file_t *thefile);
+apr_status_t apr_file_info_get_locked(apr_finfo_t *finfo, apr_int32_t wanted,
+ apr_file_t *thefile);
+
+
+#endif /* ! FILE_IO_H */
+
diff --git a/include/arch/unix/apr_arch_global_mutex.h b/include/arch/unix/apr_arch_global_mutex.h
new file mode 100644
index 0000000..3add9ec
--- /dev/null
+++ b/include/arch/unix/apr_arch_global_mutex.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 GLOBAL_MUTEX_H
+#define GLOBAL_MUTEX_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_global_mutex.h"
+#include "apr_arch_proc_mutex.h"
+#include "apr_arch_thread_mutex.h"
+
+struct apr_global_mutex_t {
+ apr_pool_t *pool;
+ apr_proc_mutex_t *proc_mutex;
+#if APR_HAS_THREADS
+ apr_thread_mutex_t *thread_mutex;
+#endif /* APR_HAS_THREADS */
+};
+
+#endif /* GLOBAL_MUTEX_H */
+
diff --git a/include/arch/unix/apr_arch_inherit.h b/include/arch/unix/apr_arch_inherit.h
new file mode 100644
index 0000000..21543c1
--- /dev/null
+++ b/include/arch/unix/apr_arch_inherit.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 INHERIT_H
+#define INHERIT_H
+
+#include "apr_inherit.h"
+
+#define APR_INHERIT (1 << 24) /* Must not conflict with other bits */
+
+#define APR_IMPLEMENT_INHERIT_SET(name, flag, pool, cleanup) \
+apr_status_t apr_##name##_inherit_set(apr_##name##_t *the##name) \
+{ \
+ if (the##name->flag & APR_FOPEN_NOCLEANUP) \
+ return APR_EINVAL; \
+ if (!(the##name->flag & APR_INHERIT)) { \
+ int flags = fcntl(the##name->name##des, F_GETFD); \
+ if (flags == -1) \
+ return errno; \
+ flags &= ~(FD_CLOEXEC); \
+ if (fcntl(the##name->name##des, F_SETFD, flags) == -1) \
+ return errno; \
+ the##name->flag |= APR_INHERIT; \
+ apr_pool_child_cleanup_set(the##name->pool, \
+ (void *)the##name, \
+ cleanup, apr_pool_cleanup_null); \
+ } \
+ return APR_SUCCESS; \
+}
+
+#define APR_IMPLEMENT_INHERIT_UNSET(name, flag, pool, cleanup) \
+apr_status_t apr_##name##_inherit_unset(apr_##name##_t *the##name) \
+{ \
+ if (the##name->flag & APR_FOPEN_NOCLEANUP) \
+ return APR_EINVAL; \
+ if (the##name->flag & APR_INHERIT) { \
+ int flags; \
+ if ((flags = fcntl(the##name->name##des, F_GETFD)) == -1) \
+ return errno; \
+ flags |= FD_CLOEXEC; \
+ if (fcntl(the##name->name##des, F_SETFD, flags) == -1) \
+ return errno; \
+ the##name->flag &= ~APR_INHERIT; \
+ apr_pool_child_cleanup_set(the##name->pool, \
+ (void *)the##name, \
+ cleanup, cleanup); \
+ } \
+ return APR_SUCCESS; \
+}
+
+#endif /* ! INHERIT_H */
diff --git a/include/arch/unix/apr_arch_internal_time.h b/include/arch/unix/apr_arch_internal_time.h
new file mode 100644
index 0000000..6e12c67
--- /dev/null
+++ b/include/arch/unix/apr_arch_internal_time.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.
+ */
+
+#ifndef TIME_INTERNAL_H
+#define TIME_INTERNAL_H
+
+#include "apr.h"
+
+void apr_unix_setup_time(void);
+
+#endif /* TIME_INTERNAL_H */
diff --git a/include/arch/unix/apr_arch_misc.h b/include/arch/unix/apr_arch_misc.h
new file mode 100644
index 0000000..8235125
--- /dev/null
+++ b/include/arch/unix/apr_arch_misc.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 MISC_H
+#define MISC_H
+
+#include "apr.h"
+#include "apr_portable.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_getopt.h"
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+#include "apr_errno.h"
+#include "apr_getopt.h"
+
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if APR_HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if APR_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef BEOS
+#include <kernel/OS.h>
+#endif
+
+struct apr_other_child_rec_t {
+ apr_pool_t *p;
+ struct apr_other_child_rec_t *next;
+ apr_proc_t *proc;
+ void (*maintenance) (int, void *, int);
+ void *data;
+ apr_os_file_t write_fd;
+};
+
+#if defined(WIN32) || defined(NETWARE)
+#define WSAHighByte 2
+#define WSALowByte 0
+#endif
+
+#endif /* ! MISC_H */
+
diff --git a/include/arch/unix/apr_arch_networkio.h b/include/arch/unix/apr_arch_networkio.h
new file mode 100644
index 0000000..5f3189d
--- /dev/null
+++ b/include/arch/unix/apr_arch_networkio.h
@@ -0,0 +1,145 @@
+/* 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 NETWORK_IO_H
+#define NETWORK_IO_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_network_io.h"
+#include "apr_errno.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#ifndef WAITIO_USES_POLL
+#include "apr_poll.h"
+#endif
+
+/* System headers the network I/O library needs */
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if APR_HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if APR_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if APR_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#if APR_HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+#if APR_HAVE_NETINET_SCTP_UIO_H
+#include <netinet/sctp_uio.h>
+#endif
+#if APR_HAVE_NETINET_SCTP_H
+#include <netinet/sctp.h>
+#endif
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if APR_HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if APR_HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if APR_HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#if APR_HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if APR_HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if APR_HAVE_SYS_SENDFILE_H
+#include <sys/sendfile.h>
+#endif
+#if APR_HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+/* End System Headers */
+
+#ifndef HAVE_POLLIN
+#define POLLIN 1
+#define POLLPRI 2
+#define POLLOUT 4
+#define POLLERR 8
+#define POLLHUP 16
+#define POLLNVAL 32
+#endif
+
+typedef struct sock_userdata_t sock_userdata_t;
+struct sock_userdata_t {
+ sock_userdata_t *next;
+ const char *key;
+ void *data;
+};
+
+struct apr_socket_t {
+ apr_pool_t *pool;
+ int socketdes;
+ int type;
+ int protocol;
+ apr_sockaddr_t *local_addr;
+ apr_sockaddr_t *remote_addr;
+ apr_interval_time_t timeout;
+#ifndef HAVE_POLL
+ int connected;
+#endif
+#if APR_HAVE_SOCKADDR_UN
+ int bound;
+#endif
+ int local_port_unknown;
+ int local_interface_unknown;
+ int remote_addr_unknown;
+ apr_int32_t options;
+ apr_int32_t inherit;
+ sock_userdata_t *userdata;
+#ifndef WAITIO_USES_POLL
+ /* if there is a timeout set, then this pollset is used */
+ apr_pollset_t *pollset;
+#endif
+};
+
+const char *apr_inet_ntop(int af, const void *src, char *dst, apr_size_t size);
+int apr_inet_pton(int af, const char *src, void *dst);
+void apr_sockaddr_vars_set(apr_sockaddr_t *, int, apr_port_t);
+
+#define apr_is_option_set(skt, option) \
+ (((skt)->options & (option)) == (option))
+
+#define apr_set_option(skt, option, on) \
+ do { \
+ if (on) \
+ (skt)->options |= (option); \
+ else \
+ (skt)->options &= ~(option); \
+ } while (0)
+
+#endif /* ! NETWORK_IO_H */
+
diff --git a/include/arch/unix/apr_arch_poll_private.h b/include/arch/unix/apr_arch_poll_private.h
new file mode 100644
index 0000000..4c2aaa7
--- /dev/null
+++ b/include/arch/unix/apr_arch_poll_private.h
@@ -0,0 +1,187 @@
+/* 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 APR_ARCH_POLL_PRIVATE_H
+#define APR_ARCH_POLL_PRIVATE_H
+
+#if HAVE_POLL_H
+#include <poll.h>
+#elif HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#endif
+
+#ifdef HAVE_PORT_CREATE
+#include <port.h>
+#include <sys/port_impl.h>
+#endif
+
+#ifdef HAVE_KQUEUE
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_EPOLL
+#include <sys/epoll.h>
+#endif
+
+#ifdef NETWARE
+#define HAS_SOCKETS(dt) (dt == APR_POLL_SOCKET) ? 1 : 0
+#define HAS_PIPES(dt) (dt == APR_POLL_FILE) ? 1 : 0
+#endif
+
+#if defined(HAVE_AIO_H) && defined(HAVE_AIO_MSGQ)
+#define _AIO_OS390 /* enable a bunch of z/OS aio.h definitions */
+#include <aio.h> /* aiocb */
+#endif
+
+/* Choose the best method platform specific to use in apr_pollset */
+#ifdef HAVE_KQUEUE
+#define POLLSET_USES_KQUEUE
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_KQUEUE
+#elif defined(HAVE_PORT_CREATE)
+#define POLLSET_USES_PORT
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_PORT
+#elif defined(HAVE_EPOLL)
+#define POLLSET_USES_EPOLL
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_EPOLL
+#elif defined(HAVE_AIO_MSGQ)
+#define POLLSET_USES_AIO_MSGQ
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_AIO_MSGQ
+#elif defined(HAVE_POLL)
+#define POLLSET_USES_POLL
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_POLL
+#else
+#define POLLSET_USES_SELECT
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_SELECT
+#endif
+
+#ifdef WIN32
+#define POLL_USES_SELECT
+#undef POLLSET_DEFAULT_METHOD
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_SELECT
+#else
+#ifdef HAVE_POLL
+#define POLL_USES_POLL
+#else
+#define POLL_USES_SELECT
+#endif
+#endif
+
+#if defined(POLLSET_USES_KQUEUE) || defined(POLLSET_USES_EPOLL) || defined(POLLSET_USES_PORT) || defined(POLLSET_USES_AIO_MSGQ)
+
+#include "apr_ring.h"
+
+#if APR_HAS_THREADS
+#include "apr_thread_mutex.h"
+#define pollset_lock_rings() \
+ if (pollset->flags & APR_POLLSET_THREADSAFE) \
+ apr_thread_mutex_lock(pollset->p->ring_lock);
+#define pollset_unlock_rings() \
+ if (pollset->flags & APR_POLLSET_THREADSAFE) \
+ apr_thread_mutex_unlock(pollset->p->ring_lock);
+#else
+#define pollset_lock_rings()
+#define pollset_unlock_rings()
+#endif
+
+typedef struct pfd_elem_t pfd_elem_t;
+
+struct pfd_elem_t {
+ APR_RING_ENTRY(pfd_elem_t) link;
+ apr_pollfd_t pfd;
+#ifdef HAVE_PORT_CREATE
+ int on_query_ring;
+#endif
+};
+
+#endif
+
+typedef struct apr_pollset_private_t apr_pollset_private_t;
+typedef struct apr_pollset_provider_t apr_pollset_provider_t;
+typedef struct apr_pollcb_provider_t apr_pollcb_provider_t;
+
+struct apr_pollset_t
+{
+ apr_pool_t *pool;
+ apr_uint32_t nelts;
+ apr_uint32_t nalloc;
+ apr_uint32_t flags;
+ /* Pipe descriptors used for wakeup */
+ apr_file_t *wakeup_pipe[2];
+ apr_pollfd_t wakeup_pfd;
+ apr_pollset_private_t *p;
+ const apr_pollset_provider_t *provider;
+};
+
+typedef union {
+#if defined(HAVE_EPOLL)
+ struct epoll_event *epoll;
+#endif
+#if defined(HAVE_PORT_CREATE)
+ port_event_t *port;
+#endif
+#if defined(HAVE_KQUEUE)
+ struct kevent *ke;
+#endif
+#if defined(HAVE_POLL)
+ struct pollfd *ps;
+#endif
+ void *undef;
+} apr_pollcb_pset;
+
+struct apr_pollcb_t {
+ apr_pool_t *pool;
+ apr_uint32_t nelts;
+ apr_uint32_t nalloc;
+ apr_uint32_t flags;
+ /* Pipe descriptors used for wakeup */
+ apr_file_t *wakeup_pipe[2];
+ apr_pollfd_t wakeup_pfd;
+ int fd;
+ apr_pollcb_pset pollset;
+ apr_pollfd_t **copyset;
+ const apr_pollcb_provider_t *provider;
+};
+
+struct apr_pollset_provider_t {
+ apr_status_t (*create)(apr_pollset_t *, apr_uint32_t, apr_pool_t *, apr_uint32_t);
+ apr_status_t (*add)(apr_pollset_t *, const apr_pollfd_t *);
+ apr_status_t (*remove)(apr_pollset_t *, const apr_pollfd_t *);
+ apr_status_t (*poll)(apr_pollset_t *, apr_interval_time_t, apr_int32_t *, const apr_pollfd_t **);
+ apr_status_t (*cleanup)(apr_pollset_t *);
+ const char *name;
+};
+
+struct apr_pollcb_provider_t {
+ apr_status_t (*create)(apr_pollcb_t *, apr_uint32_t, apr_pool_t *, apr_uint32_t);
+ apr_status_t (*add)(apr_pollcb_t *, apr_pollfd_t *);
+ apr_status_t (*remove)(apr_pollcb_t *, apr_pollfd_t *);
+ apr_status_t (*poll)(apr_pollcb_t *, apr_interval_time_t, apr_pollcb_cb_t, void *);
+ apr_status_t (*cleanup)(apr_pollcb_t *);
+ const char *name;
+};
+
+/*
+ * Private functions used for the implementation of both apr_pollcb_* and
+ * apr_pollset_*
+ */
+apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd,
+ apr_file_t **wakeup_pipe);
+apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe);
+void apr_poll_drain_wakeup_pipe(apr_file_t **wakeup_pipe);
+
+#endif /* APR_ARCH_POLL_PRIVATE_H */
diff --git a/include/arch/unix/apr_arch_proc_mutex.h b/include/arch/unix/apr_arch_proc_mutex.h
new file mode 100644
index 0000000..cfa0049
--- /dev/null
+++ b/include/arch/unix/apr_arch_proc_mutex.h
@@ -0,0 +1,121 @@
+/* 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 PROC_MUTEX_H
+#define PROC_MUTEX_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_proc_mutex.h"
+#include "apr_pools.h"
+#include "apr_portable.h"
+#include "apr_file_io.h"
+#include "apr_arch_file_io.h"
+#include "apr_time.h"
+
+/* System headers required by Locks library */
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if APR_HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_IPC_H
+#include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SEM_H
+#include <sys/sem.h>
+#endif
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#if APR_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+/* End System Headers */
+
+struct apr_proc_mutex_unix_lock_methods_t {
+ unsigned int flags;
+ apr_status_t (*create)(apr_proc_mutex_t *, const char *);
+ apr_status_t (*acquire)(apr_proc_mutex_t *);
+ apr_status_t (*tryacquire)(apr_proc_mutex_t *);
+ apr_status_t (*timedacquire)(apr_proc_mutex_t *, apr_interval_time_t);
+ apr_status_t (*release)(apr_proc_mutex_t *);
+ apr_status_t (*cleanup)(void *);
+ apr_status_t (*child_init)(apr_proc_mutex_t **, apr_pool_t *, const char *);
+ apr_status_t (*perms_set)(apr_proc_mutex_t *, apr_fileperms_t, apr_uid_t, apr_gid_t);
+ apr_lockmech_e mech;
+ const char *name;
+};
+typedef struct apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_lock_methods_t;
+
+/* bit values for flags field in apr_unix_lock_methods_t */
+#define APR_PROCESS_LOCK_MECH_IS_GLOBAL 1
+
+#if !APR_HAVE_UNION_SEMUN && defined(APR_HAS_SYSVSEM_SERIALIZE)
+union semun {
+ int val;
+ struct semid_ds *buf;
+ unsigned short *array;
+};
+#endif
+
+struct apr_proc_mutex_t {
+ apr_pool_t *pool;
+ const apr_proc_mutex_unix_lock_methods_t *meth;
+ int curr_locked;
+ char *fname;
+
+ apr_os_proc_mutex_t os; /* Native mutex holder. */
+
+#if APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
+ apr_file_t *interproc; /* For apr_file_ calls on native fd. */
+ int interproc_closing; /* whether the native fd is opened/closed with
+ * 'interproc' or apr_os_file_put()ed (hence
+ * needing an an explicit close for consistency
+ * with other methods).
+ */
+#endif
+#if APR_HAS_PROC_PTHREAD_SERIALIZE
+ int pthread_refcounting; /* Whether the native mutex is refcounted or
+ * apr_os_proc_mutex_put()ed, which makes
+ * refcounting impossible/undesirable.
+ */
+#endif
+};
+
+void apr_proc_mutex_unix_setup_lock(void);
+
+#endif /* PROC_MUTEX_H */
+
diff --git a/include/arch/unix/apr_arch_shm.h b/include/arch/unix/apr_arch_shm.h
new file mode 100644
index 0000000..e9d25ca
--- /dev/null
+++ b/include/arch/unix/apr_arch_shm.h
@@ -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.
+ */
+
+#ifndef SHM_H
+#define SHM_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_shm.h"
+#include "apr_pools.h"
+#include "apr_file_io.h"
+#include "apr_network_io.h"
+#include "apr_portable.h"
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_SYS_IPC_H
+#include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_MUTEX_H
+#include <sys/mutex.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif
+#if !defined(SHM_R)
+#define SHM_R 0400
+#endif
+#if !defined(SHM_W)
+#define SHM_W 0200
+#endif
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+
+/* Not all systems seem to have MAP_FAILED defined, but it should always
+ * just be (void *)-1. */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+struct apr_shm_t {
+ apr_pool_t *pool;
+ void *base; /* base real address */
+ void *usable; /* base usable address */
+ apr_size_t reqsize; /* requested segment size */
+ apr_size_t realsize; /* actual segment size */
+ const char *filename; /* NULL if anonymous */
+#if APR_USE_SHMEM_SHMGET || APR_USE_SHMEM_SHMGET_ANON
+ int shmid; /* shmem ID returned from shmget() */
+ key_t shmkey; /* shmem key IPC_ANON or returned from ftok() */
+#endif
+};
+
+#endif /* SHM_H */
diff --git a/include/arch/unix/apr_arch_thread_cond.h b/include/arch/unix/apr_arch_thread_cond.h
new file mode 100644
index 0000000..5c2b51d
--- /dev/null
+++ b/include/arch/unix/apr_arch_thread_cond.h
@@ -0,0 +1,42 @@
+/* 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 THREAD_COND_H
+#define THREAD_COND_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_thread_mutex.h"
+#include "apr_thread_cond.h"
+#include "apr_pools.h"
+
+#if APR_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+/* XXX: Should we have a better autoconf search, something like
+ * APR_HAS_PTHREAD_COND? -aaron */
+#if APR_HAS_THREADS
+struct apr_thread_cond_t {
+ apr_pool_t *pool;
+ pthread_cond_t cond;
+};
+#endif
+
+#endif /* THREAD_COND_H */
+
diff --git a/include/arch/unix/apr_arch_thread_mutex.h b/include/arch/unix/apr_arch_thread_mutex.h
new file mode 100644
index 0000000..0844bed
--- /dev/null
+++ b/include/arch/unix/apr_arch_thread_mutex.h
@@ -0,0 +1,44 @@
+/* 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 THREAD_MUTEX_H
+#define THREAD_MUTEX_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_thread_mutex.h"
+#include "apr_thread_cond.h"
+#include "apr_portable.h"
+#include "apr_atomic.h"
+
+#if APR_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#if APR_HAS_THREADS
+struct apr_thread_mutex_t {
+ apr_pool_t *pool;
+ pthread_mutex_t mutex;
+#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+ apr_thread_cond_t *cond;
+ int locked, num_waiters;
+#endif
+};
+#endif
+
+#endif /* THREAD_MUTEX_H */
+
diff --git a/include/arch/unix/apr_arch_thread_rwlock.h b/include/arch/unix/apr_arch_thread_rwlock.h
new file mode 100644
index 0000000..2cb43af
--- /dev/null
+++ b/include/arch/unix/apr_arch_thread_rwlock.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 THREAD_RWLOCK_H
+#define THREAD_RWLOCK_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_thread_rwlock.h"
+#include "apr_pools.h"
+
+#if APR_HAVE_PTHREAD_H
+/* this gives us pthread_rwlock_t */
+#include <pthread.h>
+#endif
+
+#if APR_HAS_THREADS
+#ifdef HAVE_PTHREAD_RWLOCKS
+
+struct apr_thread_rwlock_t {
+ apr_pool_t *pool;
+ pthread_rwlock_t rwlock;
+};
+
+#else
+
+struct apr_thread_rwlock_t {
+ apr_pool_t *pool;
+};
+#endif
+
+#endif
+
+#endif /* THREAD_RWLOCK_H */
+
diff --git a/include/arch/unix/apr_arch_threadproc.h b/include/arch/unix/apr_arch_threadproc.h
new file mode 100644
index 0000000..7a3b3c0
--- /dev/null
+++ b/include/arch/unix/apr_arch_threadproc.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 "apr.h"
+#include "apr_private.h"
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+#include "apr_arch_file_io.h"
+#include "apr_perms_set.h"
+
+/* System headers required for thread/process library */
+#if APR_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#if APR_HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#if APR_HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+/* End System Headers */
+
+
+#ifndef THREAD_PROC_H
+#define THREAD_PROC_H
+
+#define SHELL_PATH "/bin/sh"
+
+#if APR_HAS_THREADS
+
+struct apr_thread_t {
+ apr_pool_t *pool;
+ pthread_t *td;
+ void *data;
+ apr_thread_start_t func;
+ apr_status_t exitval;
+};
+
+struct apr_threadattr_t {
+ apr_pool_t *pool;
+ pthread_attr_t attr;
+};
+
+struct apr_threadkey_t {
+ apr_pool_t *pool;
+ pthread_key_t key;
+};
+
+struct apr_thread_once_t {
+ pthread_once_t once;
+};
+
+#endif
+
+typedef struct apr_procattr_pscb_t apr_procattr_pscb_t;
+struct apr_procattr_pscb_t {
+ struct apr_procattr_pscb_t *next;
+ apr_perms_setfn_t *perms_set_fn;
+ apr_fileperms_t perms;
+ const void *data;
+};
+
+struct apr_procattr_t {
+ apr_pool_t *pool;
+ apr_file_t *parent_in;
+ apr_file_t *child_in;
+ apr_file_t *parent_out;
+ apr_file_t *child_out;
+ apr_file_t *parent_err;
+ apr_file_t *child_err;
+ char *currdir;
+ apr_int32_t cmdtype;
+ apr_int32_t detached;
+#ifdef RLIMIT_CPU
+ struct rlimit *limit_cpu;
+#endif
+#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
+ struct rlimit *limit_mem;
+#endif
+#ifdef RLIMIT_NPROC
+ struct rlimit *limit_nproc;
+#endif
+#ifdef RLIMIT_NOFILE
+ struct rlimit *limit_nofile;
+#endif
+ apr_child_errfn_t *errfn;
+ apr_int32_t errchk;
+ apr_uid_t uid;
+ apr_gid_t gid;
+ apr_procattr_pscb_t *perms_set_callbacks;
+};
+
+#endif /* ! THREAD_PROC_H */
+
diff --git a/include/arch/unix/apr_private.h.in b/include/arch/unix/apr_private.h.in
new file mode 100644
index 0000000..8f2aa3f
--- /dev/null
+++ b/include/arch/unix/apr_private.h.in
@@ -0,0 +1,1142 @@
+/* include/arch/unix/apr_private.h.in. Generated from configure.in by autoheader. */
+
+
+#ifndef APR_PRIVATE_H
+#define APR_PRIVATE_H
+
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define if apr_allocator should use guard pages */
+#undef APR_ALLOCATOR_GUARD_PAGES
+
+/* Define if apr_allocator should use mmap */
+#undef APR_ALLOCATOR_USES_MMAP
+
+/* Define as function which can be used for conversion of strings to
+ apr_int64_t */
+#undef APR_INT64_STRFN
+
+/* Define as function used for conversion of strings to apr_off_t */
+#undef APR_OFF_T_STRFN
+
+/* Define if pool functions should abort if concurrent usage is detected */
+#undef APR_POOL_CONCURRENCY_CHECK
+
+/* Define to 1 if using 'alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to path of random device */
+#undef DEV_RANDOM
+
+/* Define if struct dirent has an inode member */
+#undef DIRENT_INODE
+
+/* Define if struct dirent has a d_type member */
+#undef DIRENT_TYPE
+
+/* Define if DSO support uses dlfcn.h */
+#undef DSO_USE_DLFCN
+
+/* Define if DSO support uses dyld.h */
+#undef DSO_USE_DYLD
+
+/* Define if DSO support uses shl_load */
+#undef DSO_USE_SHL
+
+/* Define to list of paths to EGD sockets */
+#undef EGD_DEFAULT_SOCKET
+
+/* Define if fcntl locks affect threads within the process */
+#undef FCNTL_IS_GLOBAL
+
+/* Define if fcntl returns EACCES when F_SETLK is already held */
+#undef FCNTL_TRYACQUIRE_EACCES
+
+/* Define if flock locks affect threads within the process */
+#undef FLOCK_IS_GLOBAL
+
+/* Define if gethostbyaddr is thread safe */
+#undef GETHOSTBYADDR_IS_THREAD_SAFE
+
+/* Define if gethostbyname is thread safe */
+#undef GETHOSTBYNAME_IS_THREAD_SAFE
+
+/* Define if gethostbyname_r has the glibc style */
+#undef GETHOSTBYNAME_R_GLIBC2
+
+/* Define if gethostbyname_r has the hostent_data for the third argument */
+#undef GETHOSTBYNAME_R_HOSTENT_DATA
+
+/* Define if getservbyname is thread safe */
+#undef GETSERVBYNAME_IS_THREAD_SAFE
+
+/* Define if getservbyname_r has the glibc style */
+#undef GETSERVBYNAME_R_GLIBC2
+
+/* Define if getservbyname_r has the OSF/1 style */
+#undef GETSERVBYNAME_R_OSF1
+
+/* Define if getservbyname_r has the Solaris style */
+#undef GETSERVBYNAME_R_SOLARIS
+
+/* Define if accept4 function is supported */
+#undef HAVE_ACCEPT4
+
+/* Define to 1 if you have the `acquire_sem' function. */
+#undef HAVE_ACQUIRE_SEM
+
+/* Define to 1 if you have the `acquire_sem_etc' function. */
+#undef HAVE_ACQUIRE_SEM_ETC
+
+/* Define if async i/o supports message q's */
+#undef HAVE_AIO_MSGQ
+
+/* Define to 1 if you have 'alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if <alloca.h> works. */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the `arc4random_buf' function. */
+#undef HAVE_ARC4RANDOM_BUF
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define if compiler provides 32bit atomic builtins */
+#undef HAVE_ATOMIC_BUILTINS
+
+/* Define if compiler provides 64bit atomic builtins */
+#undef HAVE_ATOMIC_BUILTINS64
+
+/* Define if BONE_VERSION is defined in sys/socket.h */
+#undef HAVE_BONE_VERSION
+
+/* Define to 1 if you have the <ByteOrder.h> header file. */
+#undef HAVE_BYTEORDER_H
+
+/* Define to 1 if you have the `calloc' function. */
+#undef HAVE_CALLOC
+
+/* Define to 1 if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define to 1 if you have the `create_area' function. */
+#undef HAVE_CREATE_AREA
+
+/* Define to 1 if you have the `create_sem' function. */
+#undef HAVE_CREATE_SEM
+
+/* Define to 1 if you have the <crypt.h> header file. */
+#undef HAVE_CRYPT_H
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define to 1 if you have the declaration of `SYS_getrandom', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_GETRANDOM
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_SIGLIST
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dir.h> header file. */
+#undef HAVE_DIR_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <dl.h> header file. */
+#undef HAVE_DL_H
+
+/* Define if dup3 function is supported */
+#undef HAVE_DUP3
+
+/* Define if EGD is supported */
+#undef HAVE_EGD
+
+/* Define if the epoll interface is supported */
+#undef HAVE_EPOLL
+
+/* Define if epoll_create1 function is supported */
+#undef HAVE_EPOLL_CREATE1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have the `flock' function. */
+#undef HAVE_FLOCK
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define if F_SETLK is defined in fcntl.h */
+#undef HAVE_F_SETLK
+
+/* Define if getaddrinfo accepts the AI_ADDRCONFIG flag */
+#undef HAVE_GAI_ADDRCONFIG
+
+/* Define to 1 if you have the `gai_strerror' function. */
+#undef HAVE_GAI_STRERROR
+
+/* Define if getaddrinfo exists and works well enough for APR */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the `getenv' function. */
+#undef HAVE_GETENV
+
+/* Define to 1 if you have the `getgrgid_r' function. */
+#undef HAVE_GETGRGID_R
+
+/* Define to 1 if you have the `getgrnam_r' function. */
+#undef HAVE_GETGRNAM_R
+
+/* Define to 1 if you have the `gethostbyaddr_r' function. */
+#undef HAVE_GETHOSTBYADDR_R
+
+/* Define to 1 if you have the `gethostbyname_r' function. */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define to 1 if you have the `getifaddrs' function. */
+#undef HAVE_GETIFADDRS
+
+/* Define if getnameinfo exists */
+#undef HAVE_GETNAMEINFO
+
+/* Define to 1 if you have the `getpass' function. */
+#undef HAVE_GETPASS
+
+/* Define to 1 if you have the `getpassphrase' function. */
+#undef HAVE_GETPASSPHRASE
+
+/* Define to 1 if you have the `getpwnam_r' function. */
+#undef HAVE_GETPWNAM_R
+
+/* Define to 1 if you have the `getpwuid_r' function. */
+#undef HAVE_GETPWUID_R
+
+/* Define to 1 if you have the `getrandom' function. */
+#undef HAVE_GETRANDOM
+
+/* Define to 1 if you have the `getrlimit' function. */
+#undef HAVE_GETRLIMIT
+
+/* Define to 1 if you have the `getservbyname_r' function. */
+#undef HAVE_GETSERVBYNAME_R
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#undef HAVE_GMTIME_R
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if hstrerror is present */
+#undef HAVE_HSTRERROR
+
+/* Define to 1 if you have the `if_indextoname' function. */
+#undef HAVE_IF_INDEXTONAME
+
+/* Define to 1 if you have the `if_nametoindex' function. */
+#undef HAVE_IF_NAMETOINDEX
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define to 1 if you have the `isinf' function. */
+#undef HAVE_ISINF
+
+/* Define to 1 if you have the `isnan' function. */
+#undef HAVE_ISNAN
+
+/* Define to 1 if you have the <kernel/OS.h> header file. */
+#undef HAVE_KERNEL_OS_H
+
+/* Define to 1 if you have the `kqueue' function. */
+#undef HAVE_KQUEUE
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H
+
+/* Define to 1 if you have the `bsd' library (-lbsd). */
+#undef HAVE_LIBBSD
+
+/* Define to 1 if you have the `sendfile' library (-lsendfile). */
+#undef HAVE_LIBSENDFILE
+
+/* Define to 1 if you have the `truerand' library (-ltruerand). */
+#undef HAVE_LIBTRUERAND
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <linux/random.h> header file. */
+#undef HAVE_LINUX_RANDOM_H
+
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define if LOCK_EX is defined in sys/file.h */
+#undef HAVE_LOCK_EX
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+#undef HAVE_MACH_O_DYLD_H
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if MAP_ANON is defined in sys/mman.h */
+#undef HAVE_MAP_ANON
+
+/* Define to 1 if you have the <memcheck.h> header file. */
+#undef HAVE_MEMCHECK_H
+
+/* Define to 1 if you have the `memchr' function. */
+#undef HAVE_MEMCHR
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <minix/config.h> header file. */
+#undef HAVE_MINIX_CONFIG_H
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define to 1 if you have the `mkstemp64' function. */
+#undef HAVE_MKSTEMP64
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `mmap64' function. */
+#undef HAVE_MMAP64
+
+/* Define to 1 if you have the `mprotect' function. */
+#undef HAVE_MPROTECT
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <netinet/sctp.h> header file. */
+#undef HAVE_NETINET_SCTP_H
+
+/* Define to 1 if you have the <netinet/sctp_uio.h> header file. */
+#undef HAVE_NETINET_SCTP_UIO_H
+
+/* Defined if netinet/tcp.h is present */
+#undef HAVE_NETINET_TCP_H
+
+/* Define to 1 if you have the <net/errno.h> header file. */
+#undef HAVE_NET_ERRNO_H
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#undef HAVE_NET_IF_H
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#undef HAVE_NL_LANGINFO
+
+/* Define to 1 if you have the <os2.h> header file. */
+#undef HAVE_OS2_H
+
+/* Define to 1 if you have the <osreldate.h> header file. */
+#undef HAVE_OSRELDATE_H
+
+/* Define to 1 if you have the <OS.h> header file. */
+#undef HAVE_OS_H
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define if POLLIN is defined */
+#undef HAVE_POLLIN
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the `port_create' function. */
+#undef HAVE_PORT_CREATE
+
+/* Define to 1 if you have the <process.h> header file. */
+#undef HAVE_PROCESS_H
+
+/* Define to 1 if you have the `pthread_attr_setguardsize' function. */
+#undef HAVE_PTHREAD_ATTR_SETGUARDSIZE
+
+/* Define to 1 if you have the `pthread_condattr_setpshared' function. */
+#undef HAVE_PTHREAD_CONDATTR_SETPSHARED
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the `pthread_key_delete' function. */
+#undef HAVE_PTHREAD_KEY_DELETE
+
+/* Define to 1 if you have the `pthread_mutexattr_setpshared' function. */
+#undef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
+
+/* Define if recursive pthread mutexes are available */
+#undef HAVE_PTHREAD_MUTEX_RECURSIVE
+
+/* Define if cross-process robust mutexes are available */
+#undef HAVE_PTHREAD_MUTEX_ROBUST
+
+/* Define if non-posix/portable cross-process robust mutexes are available */
+#undef HAVE_PTHREAD_MUTEX_ROBUST_NP
+
+/* Define to 1 if you have the `pthread_mutex_timedlock' function. */
+#undef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+
+/* Define if PTHREAD_PROCESS_SHARED is defined in pthread.h */
+#undef HAVE_PTHREAD_PROCESS_SHARED
+
+/* Define if pthread rwlocks are available */
+#undef HAVE_PTHREAD_RWLOCKS
+
+/* Define to 1 if you have the `pthread_rwlock_init' function. */
+#undef HAVE_PTHREAD_RWLOCK_INIT
+
+/* Define to 1 if you have the `pthread_yield' function. */
+#undef HAVE_PTHREAD_YIELD
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define to 1 if you have the `readdir64_r' function. */
+#undef HAVE_READDIR64_R
+
+/* Define to 1 if you have the <sched.h> header file. */
+#undef HAVE_SCHED_H
+
+/* Define to 1 if you have the `sched_yield' function. */
+#undef HAVE_SCHED_YIELD
+
+/* Define to 1 if you have the <semaphore.h> header file. */
+#undef HAVE_SEMAPHORE_H
+
+/* Define to 1 if you have the `semctl' function. */
+#undef HAVE_SEMCTL
+
+/* Define to 1 if you have the `semget' function. */
+#undef HAVE_SEMGET
+
+/* Define to 1 if you have the `semop' function. */
+#undef HAVE_SEMOP
+
+/* Define to 1 if you have the `semtimedop' function. */
+#undef HAVE_SEMTIMEDOP
+
+/* Define to 1 if you have the `sem_close' function. */
+#undef HAVE_SEM_CLOSE
+
+/* Define to 1 if you have the `sem_post' function. */
+#undef HAVE_SEM_POST
+
+/* Define to 1 if you have the `sem_timedwait' function. */
+#undef HAVE_SEM_TIMEDWAIT
+
+/* Define if SEM_UNDO is defined in sys/sem.h */
+#undef HAVE_SEM_UNDO
+
+/* Define to 1 if you have the `sem_unlink' function. */
+#undef HAVE_SEM_UNLINK
+
+/* Define to 1 if you have the `sem_wait' function. */
+#undef HAVE_SEM_WAIT
+
+/* Define to 1 if you have the `sendfile' function. */
+#undef HAVE_SENDFILE
+
+/* Define to 1 if you have the `sendfile64' function. */
+#undef HAVE_SENDFILE64
+
+/* Define to 1 if you have the `sendfilev' function. */
+#undef HAVE_SENDFILEV
+
+/* Define to 1 if you have the `sendfilev64' function. */
+#undef HAVE_SENDFILEV64
+
+/* Define to 1 if you have the `send_file' function. */
+#undef HAVE_SEND_FILE
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
+
+/* Define to 1 if you have the `setsid' function. */
+#undef HAVE_SETSID
+
+/* Define to 1 if you have the `set_h_errno' function. */
+#undef HAVE_SET_H_ERRNO
+
+/* Define to 1 if you have the `shmat' function. */
+#undef HAVE_SHMAT
+
+/* Define to 1 if you have the `shmctl' function. */
+#undef HAVE_SHMCTL
+
+/* Define to 1 if you have the `shmdt' function. */
+#undef HAVE_SHMDT
+
+/* Define to 1 if you have the `shmget' function. */
+#undef HAVE_SHMGET
+
+/* Define to 1 if you have the `shm_open' function. */
+#undef HAVE_SHM_OPEN
+
+/* Define to 1 if you have the `shm_unlink' function. */
+#undef HAVE_SHM_UNLINK
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `sigsuspend' function. */
+#undef HAVE_SIGSUSPEND
+
+/* Define to 1 if you have the `sigwait' function. */
+#undef HAVE_SIGWAIT
+
+/* Whether you have socklen_t */
+#undef HAVE_SOCKLEN_T
+
+/* Define if the SOCK_CLOEXEC flag is supported */
+#undef HAVE_SOCK_CLOEXEC
+
+/* Define if SO_ACCEPTFILTER is defined in sys/socket.h */
+#undef HAVE_SO_ACCEPTFILTER
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror_r' function. */
+#undef HAVE_STRERROR_R
+
+/* Define to 1 if you have the `stricmp' function. */
+#undef HAVE_STRICMP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strnicmp' function. */
+#undef HAVE_STRNICMP
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define if struct impreq was found */
+#undef HAVE_STRUCT_IPMREQ
+
+/* Define to 1 if `st_atimensec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_ATIMENSEC
+
+/* Define to 1 if `st_atime_n' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_ATIME_N
+
+/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+
+/* Define to 1 if `st_blocks' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLOCKS
+
+/* Define to 1 if `st_ctimensec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_CTIMENSEC
+
+/* Define to 1 if `st_ctime_n' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_CTIME_N
+
+/* Define to 1 if `st_ctim.tv_nsec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
+
+/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
+
+/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_MTIME_N
+
+/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+
+/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_GMTOFF
+
+/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
+#undef HAVE_STRUCT_TM___TM_GMTOFF
+
+/* Define to 1 if you have the <sysapi.h> header file. */
+#undef HAVE_SYSAPI_H
+
+/* Define to 1 if you have the <sysgtime.h> header file. */
+#undef HAVE_SYSGTIME_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+#undef HAVE_SYS_IPC_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/mutex.h> header file. */
+#undef HAVE_SYS_MUTEX_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#undef HAVE_SYS_POLL_H
+
+/* Define to 1 if you have the <sys/random.h> header file. */
+#undef HAVE_SYS_RANDOM_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/sem.h> header file. */
+#undef HAVE_SYS_SEM_H
+
+/* Define to 1 if you have the <sys/sendfile.h> header file. */
+#undef HAVE_SYS_SENDFILE_H
+
+/* Define to 1 if you have the <sys/shm.h> header file. */
+#undef HAVE_SYS_SHM_H
+
+/* Define to 1 if you have the <sys/signal.h> header file. */
+#undef HAVE_SYS_SIGNAL_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#undef HAVE_SYS_SYSCALL_H
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#undef HAVE_SYS_SYSCTL_H
+
+/* Define to 1 if you have the <sys/syslimits.h> header file. */
+#undef HAVE_SYS_SYSLIMITS_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define to 1 if you have the <sys/uuid.h> header file. */
+#undef HAVE_SYS_UUID_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if TCP_CORK is defined in netinet/tcp.h */
+#undef HAVE_TCP_CORK
+
+/* Define if TCP_NODELAY and TCP_CORK can be enabled at the same time */
+#undef HAVE_TCP_NODELAY_WITH_CORK
+
+/* Define if TCP_NOPUSH is defined in netinet/tcp.h */
+#undef HAVE_TCP_NOPUSH
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define to 1 if you have the <tpfeq.h> header file. */
+#undef HAVE_TPFEQ_H
+
+/* Define to 1 if you have the <tpfio.h> header file. */
+#undef HAVE_TPFIO_H
+
+/* Define if truerand is supported */
+#undef HAVE_TRUERAND
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <unix.h> header file. */
+#undef HAVE_UNIX_H
+
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define to 1 if you have the `utime' function. */
+#undef HAVE_UTIME
+
+/* Define to 1 if you have the `utimes' function. */
+#undef HAVE_UTIMES
+
+/* Define to 1 if you have the `uuid_create' function. */
+#undef HAVE_UUID_CREATE
+
+/* Define to 1 if you have the `uuid_generate' function. */
+#undef HAVE_UUID_GENERATE
+
+/* Define to 1 if you have the <uuid.h> header file. */
+#undef HAVE_UUID_H
+
+/* Define to 1 if you have the <uuid/uuid.h> header file. */
+#undef HAVE_UUID_UUID_H
+
+/* Compile in valgrind support */
+#undef HAVE_VALGRIND
+
+/* Define to 1 if you have the <valgrind.h> header file. */
+#undef HAVE_VALGRIND_H
+
+/* Define if C compiler supports VLA */
+#undef HAVE_VLA
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+#undef HAVE_WINSOCK2_H
+
+/* Define to 1 if you have the `writev' function. */
+#undef HAVE_WRITEV
+
+/* Define for z/OS pthread API nuances */
+#undef HAVE_ZOS_PTHREADS
+
+/* Define if compiler provides 32bit __atomic builtins */
+#undef HAVE__ATOMIC_BUILTINS
+
+/* Define if compiler provides 64bit __atomic builtins */
+#undef HAVE__ATOMIC_BUILTINS64
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Define if EAI_ error codes from getaddrinfo are negative */
+#undef NEGATIVE_EAI
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define if POSIX semaphores affect threads within the process */
+#undef POSIXSEM_IS_GLOBAL
+
+/* Define on PowerPC 405 where errata 77 applies */
+#undef PPC405_ERRATA
+
+/* Define if pthread_attr_getdetachstate() has one arg */
+#undef PTHREAD_ATTR_GETDETACHSTATE_TAKES_ONE_ARG
+
+/* Define if pthread_getspecific() has two args */
+#undef PTHREAD_GETSPECIFIC_TAKES_TWO_ARGS
+
+/* Modern readdir is thread safe */
+#undef READDIR_IS_THREAD_SAFE
+
+/* Define to 1 if the `setpgrp' function requires zero arguments. */
+#undef SETPGRP_VOID
+
+/* */
+#undef SIGWAIT_TAKES_ONE_ARG
+
+/* The size of `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of `ino_t', as computed by sizeof. */
+#undef SIZEOF_INO_T
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `off_t', as computed by sizeof. */
+#undef SIZEOF_OFF_T
+
+/* The size of `pid_t', as computed by sizeof. */
+#undef SIZEOF_PID_T
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of `ssize_t', as computed by sizeof. */
+#undef SIZEOF_SSIZE_T
+
+/* The size of `struct iovec', as computed by sizeof. */
+#undef SIZEOF_STRUCT_IOVEC
+
+/* The size of `void*', as computed by sizeof. */
+#undef SIZEOF_VOIDP
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+ required in a freestanding environment). This macro is provided for
+ backward compatibility; new code need not use it. */
+#undef STDC_HEADERS
+
+/* Define if strerror returns int */
+#undef STRERROR_R_RC_INT
+
+/* Define if SysV semaphores affect threads within the process */
+#undef SYSVSEM_IS_GLOBAL
+
+/* Define system call of random */
+#undef SYS_RANDOM
+
+/* Define if use of generic atomics is requested */
+#undef USE_ATOMICS_GENERIC
+
+/* Define if BeOS Semaphores will be used */
+#undef USE_BEOSSEM
+
+/* Define if SVR4-style fcntl() will be used */
+#undef USE_FCNTL_SERIALIZE
+
+/* Define if 4.2BSD-style flock() will be used */
+#undef USE_FLOCK_SERIALIZE
+
+/* Define if pthread pshared mutex will be used */
+#undef USE_PROC_PTHREAD_SERIALIZE
+
+/* Define if BeOS areas will be used */
+#undef USE_SHMEM_BEOS
+
+/* Define if BeOS areas will be used */
+#undef USE_SHMEM_BEOS_ANON
+
+/* Define if 4.4BSD-style mmap() via MAP_ANON will be used */
+#undef USE_SHMEM_MMAP_ANON
+
+/* Define if mmap() via POSIX.1 shm_open() on temporary file will be used */
+#undef USE_SHMEM_MMAP_SHM
+
+/* Define if Classical mmap() on temporary file will be used */
+#undef USE_SHMEM_MMAP_TMP
+
+/* Define if SVR4-style mmap() on /dev/zero will be used */
+#undef USE_SHMEM_MMAP_ZERO
+
+/* Define if OS/2 DosAllocSharedMem() will be used */
+#undef USE_SHMEM_OS2
+
+/* Define if OS/2 DosAllocSharedMem() will be used */
+#undef USE_SHMEM_OS2_ANON
+
+/* Define if SysV IPC shmget() will be used */
+#undef USE_SHMEM_SHMGET
+
+/* Define if SysV IPC shmget() will be used */
+#undef USE_SHMEM_SHMGET_ANON
+
+/* Define if Windows shared memory will be used */
+#undef USE_SHMEM_WIN32
+
+/* Define if Windows CreateFileMapping() will be used */
+#undef USE_SHMEM_WIN32_ANON
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable general extensions on macOS. */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable X/Open compliant socket functions that do not require linking
+ with -lxnet on HP-UX 11.11. */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# undef _HPUX_ALT_XOPEN_SOCKET_API
+#endif
+/* Identify the host operating system as Minix.
+ This macro does not affect the system headers' behavior.
+ A future release of Autoconf may stop defining this macro. */
+#ifndef _MINIX
+# undef _MINIX
+#endif
+/* Enable general extensions on NetBSD.
+ Enable NetBSD compatibility extensions on Minix. */
+#ifndef _NETBSD_SOURCE
+# undef _NETBSD_SOURCE
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+ Oddly enough, this does nothing on OpenBSD. */
+#ifndef _OPENBSD_SOURCE
+# undef _OPENBSD_SOURCE
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_SOURCE
+# undef _POSIX_SOURCE
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_1_SOURCE
+# undef _POSIX_1_SOURCE
+#endif
+/* Enable POSIX-compatible threading on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# undef __STDC_WANT_IEC_60559_BFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# undef __STDC_WANT_IEC_60559_DFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# undef __STDC_WANT_IEC_60559_TYPES_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
+#ifndef __STDC_WANT_LIB_EXT2__
+# undef __STDC_WANT_LIB_EXT2__
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009. */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# undef __STDC_WANT_MATH_SPEC_FUNCS__
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable X/Open extensions. Define to 500 only if necessary
+ to make mbstate_t available. */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
+#endif
+
+
+/* Define if SysV IPC semget() will be used */
+#undef USE_SYSVSEM_SERIALIZE
+
+/* Define if apr_wait_for_io_or_timeout() uses poll(2) */
+#undef WAITIO_USES_POLL
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `long int' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define as a signed integer type capable of holding a process identifier. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+
+/* switch this on if we have a BeOS version below BONE */
+#if defined(BEOS) && !defined(HAVE_BONE_VERSION)
+#define BEOS_R5 1
+#else
+#define BEOS_BONE 1
+#endif
+
+/*
+ * Darwin 10's default compiler (gcc42) builds for both 64 and
+ * 32 bit architectures unless specifically told not to.
+ * In those cases, we need to override types depending on how
+ * we're being built at compile time.
+ * NOTE: This is an ugly work-around for Darwin's
+ * concept of universal binaries, a single package
+ * (executable, lib, etc...) which contains both 32
+ * and 64 bit versions. The issue is that if APR is
+ * built universally, if something else is compiled
+ * against it, some bit sizes will depend on whether
+ * it is 32 or 64 bit. This is determined by the __LP64__
+ * flag. Since we need to support both, we have to
+ * handle OS X unqiuely.
+ */
+#ifdef DARWIN_10
+
+#undef APR_OFF_T_STRFN
+#undef APR_INT64_STRFN
+#undef SIZEOF_LONG
+#undef SIZEOF_SIZE_T
+#undef SIZEOF_SSIZE_T
+#undef SIZEOF_VOIDP
+#undef SIZEOF_STRUCT_IOVEC
+
+#ifdef __LP64__
+ #define APR_INT64_STRFN strtol
+ #define SIZEOF_LONG 8
+ #define SIZEOF_SIZE_T 8
+ #define SIZEOF_SSIZE_T 8
+ #define SIZEOF_VOIDP 8
+ #define SIZEOF_STRUCT_IOVEC 16
+#else
+ #define APR_INT64_STRFN strtoll
+ #define SIZEOF_LONG 4
+ #define SIZEOF_SIZE_T 4
+ #define SIZEOF_SSIZE_T 4
+ #define SIZEOF_VOIDP 4
+ #define SIZEOF_STRUCT_IOVEC 8
+#endif
+
+#undef APR_OFF_T_STRFN
+#define APR_OFF_T_STRFN APR_INT64_STRFN
+
+
+#undef SETPGRP_VOID
+#ifdef __DARWIN_UNIX03
+ #define SETPGRP_VOID 1
+#else
+/* #undef SETPGRP_VOID */
+#endif
+
+#endif /* DARWIN_10 */
+
+/*
+ * Include common private declarations.
+ */
+#include "../apr_private_common.h"
+#endif /* APR_PRIVATE_H */
+
diff --git a/include/arch/win32/apr_arch_atime.h b/include/arch/win32/apr_arch_atime.h
new file mode 100644
index 0000000..35f2041
--- /dev/null
+++ b/include/arch/win32/apr_arch_atime.h
@@ -0,0 +1,63 @@
+/* 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 ATIME_H
+#define ATIME_H
+
+#include "apr_private.h"
+#include "apr_time.h"
+#if APR_HAVE_TIME_H
+#include <time.h>
+#endif
+
+struct atime_t {
+ apr_pool_t *cntxt;
+ apr_time_t currtime;
+ SYSTEMTIME *explodedtime;
+};
+
+
+/* Number of micro-seconds between the beginning of the Windows epoch
+ * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970)
+ */
+#define APR_DELTA_EPOCH_IN_USEC APR_TIME_C(11644473600000000);
+
+
+static APR_INLINE void FileTimeToAprTime(apr_time_t *result, FILETIME *input)
+{
+ /* Convert FILETIME one 64 bit number so we can work with it. */
+ *result = input->dwHighDateTime;
+ *result = (*result) << 32;
+ *result |= input->dwLowDateTime;
+ *result /= 10; /* Convert from 100 nano-sec periods to micro-seconds. */
+ *result -= APR_DELTA_EPOCH_IN_USEC; /* Convert from Windows epoch to Unix epoch */
+ return;
+}
+
+
+static APR_INLINE void AprTimeToFileTime(LPFILETIME pft, apr_time_t t)
+{
+ LONGLONG ll;
+ t += APR_DELTA_EPOCH_IN_USEC;
+ ll = t * 10;
+ pft->dwLowDateTime = (DWORD)ll;
+ pft->dwHighDateTime = (DWORD) (ll >> 32);
+ return;
+}
+
+
+#endif /* ! ATIME_H */
+
diff --git a/include/arch/win32/apr_arch_dso.h b/include/arch/win32/apr_arch_dso.h
new file mode 100644
index 0000000..e2e4e40
--- /dev/null
+++ b/include/arch/win32/apr_arch_dso.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 DSO_H
+#define DSO_H
+
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_dso.h"
+#include "apr.h"
+
+#if APR_HAS_DSO
+
+struct apr_dso_handle_t {
+ apr_pool_t *cont;
+ void *handle;
+ apr_status_t load_error;
+};
+
+#endif
+
+#endif
diff --git a/include/arch/win32/apr_arch_file_io.h b/include/arch/win32/apr_arch_file_io.h
new file mode 100644
index 0000000..9fb8df1
--- /dev/null
+++ b/include/arch/win32/apr_arch_file_io.h
@@ -0,0 +1,266 @@
+/* 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 FILE_IO_H
+#define FILE_IO_H
+
+#include "apr.h"
+#include "apr_private.h"
+#include "apr_pools.h"
+#include "apr_general.h"
+#include "apr_tables.h"
+#include "apr_thread_mutex.h"
+#include "apr_file_io.h"
+#include "apr_file_info.h"
+#include "apr_errno.h"
+#include "apr_arch_misc.h"
+#include "apr_poll.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#if APR_HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#if APR_HAS_UNICODE_FS
+#include "arch/win32/apr_arch_utf8.h"
+#include <wchar.h>
+
+/* Helper functions for the WinNT ApiW() functions. APR treats all
+ * resource identifiers (files, etc) by their UTF-8 name, to provide
+ * access to all named identifiers. [UTF-8 completely maps Unicode
+ * into char type strings.]
+ *
+ * The _path flavors below provide us fast mappings of the
+ * Unicode filename //?/D:/path and //?/UNC/mach/share/path mappings,
+ * which allow unlimited (well, 32000 wide character) length names.
+ * These prefixes may appear in Unicode, but must not appear in the
+ * Ascii API calls. So we tack them on in utf8_to_unicode_path, and
+ * strip them right back off in unicode_to_utf8_path.
+ */
+apr_status_t utf8_to_unicode_path(apr_wchar_t* dststr, apr_size_t dstchars,
+ const char* srcstr);
+apr_status_t unicode_to_utf8_path(char* dststr, apr_size_t dstchars,
+ const apr_wchar_t* srcstr);
+
+#endif /* APR_HAS_UNICODE_FS */
+
+/* Another Helper functions for the WinNT ApiW() functions. We need to
+ * derive some 'resource' names (max length 255 characters, prefixed with
+ * Global/ or Local/ on WinNT) from something that looks like a filename.
+ * Since 'resource' names never contain slashes, convert these to '_'s
+ * and return the appropriate char* or wchar* for ApiA or ApiW calls.
+ */
+
+void *res_name_from_filename(const char *file, int global, apr_pool_t *pool);
+
+#define APR_FILE_MAX MAX_PATH
+
+#define APR_FILE_DEFAULT_BUFSIZE 4096
+/* For backwards-compat */
+#define APR_FILE_BUFSIZE APR_FILE_DEFAULT_BUFSIZE
+
+/* obscure ommissions from msvc's sys/stat.h */
+#ifdef _MSC_VER
+#define S_IFIFO _S_IFIFO /* pipe */
+#define S_IFBLK 0060000 /* Block Special */
+#define S_IFLNK 0120000 /* Symbolic Link */
+#define S_IFSOCK 0140000 /* Socket */
+#define S_IFWHT 0160000 /* Whiteout */
+#endif
+
+/* Internal Flags for apr_file_open */
+#define APR_OPENINFO 0x00100000 /* Open without READ or WRITE access */
+#define APR_OPENLINK 0x00200000 /* Open a link itself, if supported */
+#define APR_READCONTROL 0x00400000 /* Read the file's owner/perms */
+#define APR_WRITECONTROL 0x00800000 /* Modify the file's owner/perms */
+/* #define APR_INHERIT 0x01000000 -- Defined in apr_arch_inherit.h! */
+#define APR_STDIN_FLAG 0x02000000 /* Obtained via apr_file_open_stdin() */
+#define APR_STDOUT_FLAG 0x04000000 /* Obtained via apr_file_open_stdout() */
+#define APR_STDERR_FLAG 0x06000000 /* Obtained via apr_file_open_stderr() */
+#define APR_STD_FLAGS (APR_STDIN_FLAG | APR_STDOUT_FLAG | APR_STDERR_FLAG)
+#define APR_WRITEATTRS 0x08000000 /* Modify the file's attributes */
+
+/* Entries missing from the MSVC 5.0 Win32 SDK:
+ */
+#ifndef FILE_ATTRIBUTE_DEVICE
+#define FILE_ATTRIBUTE_DEVICE 0x00000040
+#endif
+#ifndef FILE_ATTRIBUTE_REPARSE_POINT
+#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+#endif
+#ifndef FILE_FLAG_OPEN_NO_RECALL
+#define FILE_FLAG_OPEN_NO_RECALL 0x00100000
+#endif
+#ifndef FILE_FLAG_OPEN_REPARSE_POINT
+#define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000
+#endif
+#ifndef TRUSTEE_IS_WELL_KNOWN_GROUP
+#define TRUSTEE_IS_WELL_KNOWN_GROUP 5
+#endif
+
+/* Information bits available from the WIN32 FindFirstFile function */
+#define APR_FINFO_WIN32_DIR (APR_FINFO_NAME | APR_FINFO_TYPE \
+ | APR_FINFO_CTIME | APR_FINFO_ATIME \
+ | APR_FINFO_MTIME | APR_FINFO_SIZE)
+
+/* Sneak the Readonly bit through finfo->protection for internal use _only_ */
+#define APR_FREADONLY 0x10000000
+
+/* Private function for apr_stat/lstat/getfileinfo/dir_read */
+int fillin_fileinfo(apr_finfo_t *finfo, WIN32_FILE_ATTRIBUTE_DATA *wininfo,
+ int byhandle, int finddata, const char *fname,
+ apr_int32_t wanted);
+
+/* Private function that extends apr_stat/lstat/getfileinfo/dir_read */
+apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile,
+ apr_int32_t wanted, int whatfile);
+
+/* whatfile types for the ufile arg */
+#define MORE_OF_HANDLE 0
+#define MORE_OF_FSPEC 1
+#define MORE_OF_WFSPEC 2
+
+/* quick run-down of fields in windows' apr_file_t structure that may have
+ * obvious uses.
+ * fname -- the filename as passed to the open call.
+ * dwFileAttricutes -- Attributes used to open the file.
+ * append -- Windows doesn't support the append concept when opening files.
+ * APR needs to keep track of this, and always make sure we append
+ * correctly when writing to a file with this flag set TRUE.
+ */
+
+/* for apr_poll.c */
+#define filedes filehand
+
+struct apr_file_t {
+ apr_pool_t *pool;
+ HANDLE filehand;
+ BOOLEAN pipe; /* Is this a pipe of a file? */
+ OVERLAPPED *pOverlapped;
+ apr_interval_time_t timeout;
+ apr_int32_t flags;
+
+ /* File specific info */
+ apr_finfo_t *finfo;
+ char *fname;
+ DWORD dwFileAttributes;
+ int eof_hit;
+ BOOLEAN buffered; /* Use buffered I/O? */
+ int ungetchar; /* Last char provided by an unget op. (-1 = no char) */
+ int append;
+
+ /* Stuff for buffered mode */
+ char *buffer;
+ apr_size_t bufpos; /* Read/Write position in buffer */
+ apr_size_t bufsize; /* The size of the buffer */
+ apr_size_t dataRead; /* amount of valid data read into buffer */
+ int direction; /* buffer being used for 0 = read, 1 = write */
+ apr_off_t filePtr; /* position in file of handle */
+ apr_thread_mutex_t *mutex; /* mutex semaphore, must be owned to access
+ * the above fields */
+
+#if APR_FILES_AS_SOCKETS
+ /* if there is a timeout set, then this pollset is used */
+ apr_pollset_t *pollset;
+#endif
+ /* Pipe specific info */
+};
+
+struct apr_dir_t {
+ apr_pool_t *pool;
+ HANDLE dirhand;
+ apr_size_t rootlen;
+ char *dirname;
+ char *name;
+ union {
+#if APR_HAS_UNICODE_FS
+ struct {
+ WIN32_FIND_DATAW *entry;
+ } w;
+#endif
+#if APR_HAS_ANSI_FS
+ struct {
+ WIN32_FIND_DATAA *entry;
+ } n;
+#endif
+ };
+ int bof;
+};
+
+/* There are many goofy characters the filesystem can't accept
+ * or can confound the cmd.exe shell. Here's the list
+ * [declared in filesys.c]
+ */
+extern const char apr_c_is_fnchar[256];
+
+#define IS_FNCHAR(c) (apr_c_is_fnchar[(unsigned char)(c)] & 1)
+#define IS_SHCHAR(c) ((apr_c_is_fnchar[(unsigned char)(c)] & 2) == 2)
+
+
+/* If the user passes APR_FILEPATH_TRUENAME to either
+ * apr_filepath_root or apr_filepath_merge, this fn determines
+ * that the root really exists. It's expensive, wouldn't want
+ * to do this too frequenly.
+ */
+apr_status_t filepath_root_test(char *path, apr_pool_t *p);
+
+
+/* The apr_filepath_merge wants to canonicalize the cwd to the
+ * addpath if the user passes NULL as the old root path (this
+ * isn't true of an empty string "", which won't be concatenated.
+ *
+ * But we need to figure out what the cwd of a given volume is,
+ * when the user passes D:foo. This fn will determine D:'s cwd.
+ *
+ * If flags includes the bit APR_FILEPATH_NATIVE, the path returned
+ * is in the os-native format.
+ */
+apr_status_t filepath_drive_get(char **rootpath, char drive,
+ apr_int32_t flags, apr_pool_t *p);
+
+
+/* If the user passes d: vs. D: (or //mach/share vs. //MACH/SHARE),
+ * we need to fold the case to canonical form. This function is
+ * supposed to do so.
+ */
+apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
+
+
+apr_status_t file_cleanup(void *);
+
+extern apr_status_t
+apr_file_socket_pipe_create(apr_file_t **in,
+ apr_file_t **out,
+ apr_pool_t *p);
+
+extern apr_status_t
+apr_file_socket_pipe_close(apr_file_t *file);
+
+#endif /* ! FILE_IO_H */
diff --git a/include/arch/win32/apr_arch_inherit.h b/include/arch/win32/apr_arch_inherit.h
new file mode 100644
index 0000000..8969af6
--- /dev/null
+++ b/include/arch/win32/apr_arch_inherit.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 INHERIT_H
+#define INHERIT_H
+
+#include "apr_inherit.h"
+
+#define APR_INHERIT (1 << 24) /* Must not conflict with other bits */
+
+#if APR_HAS_UNICODE_FS && APR_HAS_ANSI_FS
+/* !defined(_WIN32_WCE) is implicit here */
+
+#define APR_IMPLEMENT_INHERIT_SET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_set(apr_##name##_t *the##name) \
+{ \
+ IF_WIN_OS_IS_UNICODE \
+ { \
+/* if (!SetHandleInformation(the##name->filehand, \
+ * HANDLE_FLAG_INHERIT, \
+ * HANDLE_FLAG_INHERIT)) \
+ * return apr_get_os_error(); \
+ */ } \
+ ELSE_WIN_OS_IS_ANSI \
+ { \
+ HANDLE temp, hproc = GetCurrentProcess(); \
+ if (!DuplicateHandle(hproc, the##name->filehand, \
+ hproc, &temp, 0, TRUE, \
+ DUPLICATE_SAME_ACCESS)) \
+ return apr_get_os_error(); \
+ CloseHandle(the##name->filehand); \
+ the##name->filehand = temp; \
+ } \
+ return APR_SUCCESS; \
+}
+
+#define APR_IMPLEMENT_INHERIT_UNSET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_unset(apr_##name##_t *the##name)\
+{ \
+ IF_WIN_OS_IS_UNICODE \
+ { \
+/* if (!SetHandleInformation(the##name->filehand, \
+ * HANDLE_FLAG_INHERIT, 0)) \
+ * return apr_get_os_error(); \
+ */ } \
+ ELSE_WIN_OS_IS_ANSI \
+ { \
+ HANDLE temp, hproc = GetCurrentProcess(); \
+ if (!DuplicateHandle(hproc, the##name->filehand, \
+ hproc, &temp, 0, FALSE, \
+ DUPLICATE_SAME_ACCESS)) \
+ return apr_get_os_error(); \
+ CloseHandle(the##name->filehand); \
+ the##name->filehand = temp; \
+ } \
+ return APR_SUCCESS; \
+}
+
+#elif APR_HAS_ANSI_FS || defined(_WIN32_WCE)
+
+#define APR_IMPLEMENT_INHERIT_SET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_set(apr_##name##_t *the##name) \
+{ \
+ HANDLE temp, hproc = GetCurrentProcess(); \
+ if (!DuplicateHandle(hproc, the##name->filehand, \
+ hproc, &temp, 0, TRUE, \
+ DUPLICATE_SAME_ACCESS)) \
+ return apr_get_os_error(); \
+ CloseHandle(the##name->filehand); \
+ the##name->filehand = temp; \
+ return APR_SUCCESS; \
+}
+
+#define APR_IMPLEMENT_INHERIT_UNSET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_unset(apr_##name##_t *the##name)\
+{ \
+ HANDLE temp, hproc = GetCurrentProcess(); \
+ if (!DuplicateHandle(hproc, the##name->filehand, \
+ hproc, &temp, 0, FALSE, \
+ DUPLICATE_SAME_ACCESS)) \
+ return apr_get_os_error(); \
+ CloseHandle(the##name->filehand); \
+ the##name->filehand = temp; \
+ return APR_SUCCESS; \
+}
+
+#else /* APR_HAS_UNICODE_FS && !APR_HAS_ANSI_FS && !defined(_WIN32_WCE) */
+
+#define APR_IMPLEMENT_INHERIT_SET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_set(apr_##name##_t *the##name) \
+{ \
+/* if (!SetHandleInformation(the##name->filehand, \
+ * HANDLE_FLAG_INHERIT, \
+ * HANDLE_FLAG_INHERIT)) \
+ * return apr_get_os_error(); \
+ */ return APR_SUCCESS; \
+}
+
+#define APR_IMPLEMENT_INHERIT_UNSET(name, flag, pool, cleanup) \
+APR_DECLARE(apr_status_t) apr_##name##_inherit_unset(apr_##name##_t *the##name)\
+{ \
+/* if (!SetHandleInformation(the##name->filehand, \
+ * HANDLE_FLAG_INHERIT, 0)) \
+ * return apr_get_os_error(); \
+ */ return APR_SUCCESS; \
+}
+
+#endif /* defined(APR_HAS_UNICODE_FS) */
+
+#endif /* ! INHERIT_H */
diff --git a/include/arch/win32/apr_arch_misc.h b/include/arch/win32/apr_arch_misc.h
new file mode 100644
index 0000000..4dbe899
--- /dev/null
+++ b/include/arch/win32/apr_arch_misc.h
@@ -0,0 +1,517 @@
+/* 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 MISC_H
+#define MISC_H
+
+#include "apr.h"
+#include "apr_portable.h"
+#include "apr_private.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_getopt.h"
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+#include "apr_errno.h"
+#include "apr_getopt.h"
+
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if APR_HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if APR_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#ifndef _WIN32_WCE
+#include <tlhelp32.h>
+#endif
+
+#if defined(HAVE_IF_INDEXTONAME) && defined(_MSC_VER)
+#include <Iphlpapi.h>
+#endif
+
+struct apr_other_child_rec_t {
+ apr_pool_t *p;
+ struct apr_other_child_rec_t *next;
+ apr_proc_t *proc;
+ void (*maintenance) (int, void *, int);
+ void *data;
+ apr_os_file_t write_fd;
+};
+
+#define WSAHighByte 2
+#define WSALowByte 0
+
+/* start.c and apr_app.c helpers and communication within misc.c
+ *
+ * They are not for public consumption, although apr_app_init_complete
+ * must be an exported symbol to avoid reinitialization.
+ */
+extern int APR_DECLARE_DATA apr_app_init_complete;
+
+int apr_wastrtoastr(char const * const * *retarr,
+ wchar_t const * const *arr, int args);
+
+/* Platform specific designation of run time os version.
+ * Gaps allow for specific service pack levels that
+ * export new kernel or winsock functions or behavior.
+ */
+typedef enum {
+ APR_WIN_UNK = 0,
+ APR_WIN_UNSUP = 1,
+ APR_WIN_95 = 10,
+ APR_WIN_95_B = 11,
+ APR_WIN_95_OSR2 = 12,
+ APR_WIN_98 = 14,
+ APR_WIN_98_SE = 16,
+ APR_WIN_ME = 18,
+
+ APR_WIN_UNICODE = 20, /* Prior versions support only narrow chars */
+
+ APR_WIN_CE_3 = 23, /* CE is an odd beast, not supporting */
+ /* some pre-NT features, such as the */
+ APR_WIN_NT = 30, /* narrow charset APIs (fooA fns), while */
+ APR_WIN_NT_3_5 = 35, /* not supporting some NT-family features. */
+ APR_WIN_NT_3_51 = 36,
+
+ APR_WIN_NT_4 = 40,
+ APR_WIN_NT_4_SP2 = 42,
+ APR_WIN_NT_4_SP3 = 43,
+ APR_WIN_NT_4_SP4 = 44,
+ APR_WIN_NT_4_SP5 = 45,
+ APR_WIN_NT_4_SP6 = 46,
+
+ APR_WIN_2000 = 50,
+ APR_WIN_2000_SP1 = 51,
+ APR_WIN_2000_SP2 = 52,
+ APR_WIN_XP = 60,
+ APR_WIN_XP_SP1 = 61,
+ APR_WIN_XP_SP2 = 62,
+ APR_WIN_2003 = 70,
+ APR_WIN_VISTA = 80,
+ APR_WIN_7 = 90,
+ APR_WIN_7_SP1 = 91,
+ APR_WIN_8 = 100,
+ APR_WIN_8_1 = 110,
+ APR_WIN_10 = 120
+} apr_oslevel_e;
+
+extern APR_DECLARE_DATA apr_oslevel_e apr_os_level;
+
+apr_status_t apr_get_oslevel(apr_oslevel_e *);
+
+/* The APR_HAS_ANSI_FS symbol is PRIVATE, and internal to APR.
+ * APR only supports char data for filenames. Like most applications,
+ * characters >127 are essentially undefined. APR_HAS_UNICODE_FS lets
+ * the application know that utf-8 is the encoding method of APR, and
+ * only incidently hints that we have Wide OS calls.
+ *
+ * APR_HAS_ANSI_FS is simply an OS flag to tell us all calls must be
+ * the unicode eqivilant.
+ */
+
+#if defined(_WIN32_WCE) || defined(WINNT)
+#define APR_HAS_ANSI_FS 0
+#else
+#define APR_HAS_ANSI_FS 1
+#endif
+
+/* IF_WIN_OS_IS_UNICODE / ELSE_WIN_OS_IS_ANSI help us keep the code trivial
+ * where have runtime tests for unicode-ness, that aren't needed in any
+ * build which supports only WINNT or WCE.
+ */
+#if APR_HAS_ANSI_FS && APR_HAS_UNICODE_FS
+#define IF_WIN_OS_IS_UNICODE if (apr_os_level >= APR_WIN_UNICODE)
+#define ELSE_WIN_OS_IS_ANSI else
+#else /* APR_HAS_UNICODE_FS */
+#define IF_WIN_OS_IS_UNICODE
+#define ELSE_WIN_OS_IS_ANSI
+#endif /* WINNT */
+
+#if defined(_MSC_VER) && !defined(_WIN32_WCE)
+#include "crtdbg.h"
+
+static APR_INLINE void* apr_malloc_dbg(size_t size, const char* filename,
+ int linenumber)
+{
+ return _malloc_dbg(size, _CRT_BLOCK, filename, linenumber);
+}
+
+static APR_INLINE void* apr_realloc_dbg(void* userData, size_t newSize,
+ const char* filename, int linenumber)
+{
+ return _realloc_dbg(userData, newSize, _CRT_BLOCK, filename, linenumber);
+}
+
+#else
+
+static APR_INLINE void* apr_malloc_dbg(size_t size, const char* filename,
+ int linenumber)
+{
+ return malloc(size);
+}
+
+static APR_INLINE void* apr_realloc_dbg(void* userData, size_t newSize,
+ const char* filename, int linenumber)
+{
+ return realloc(userData, newSize);
+}
+
+#endif /* ! _MSC_VER */
+
+typedef enum {
+ DLL_WINBASEAPI = 0, /* kernel32 From WinBase.h */
+ DLL_WINADVAPI = 1, /* advapi32 From WinBase.h */
+ DLL_WINSOCKAPI = 2, /* mswsock From WinSock.h */
+ DLL_WINSOCK2API = 3, /* ws2_32 From WinSock2.h */
+ DLL_SHSTDAPI = 4, /* shell32 From ShellAPI.h */
+ DLL_NTDLL = 5, /* ntdll From our real kernel */
+ DLL_IPHLPAPI = 6, /* Iphlpapi From Iphlpapi.h */
+ DLL_defined = 7 /* must define as last idx_ + 1 */
+} apr_dlltoken_e;
+
+FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char *fnName, int ordinal);
+
+/* The apr_load_dll_func call WILL return 0 set error to
+ * ERROR_INVALID_FUNCTION if the function cannot be loaded
+ */
+#define APR_DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args, names) \
+ typedef rettype (calltype *apr_winapi_fpt_##fn) args; \
+ static apr_winapi_fpt_##fn apr_winapi_pfn_##fn = NULL; \
+ static int apr_winapi_chk_##fn = 0; \
+ static APR_INLINE int apr_winapi_ld_##fn(void) \
+ { if (apr_winapi_pfn_##fn) return 1; \
+ if (apr_winapi_chk_##fn ++) return 0; \
+ if (!apr_winapi_pfn_##fn) \
+ apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \
+ apr_load_dll_func(lib, #fn, ord); \
+ if (apr_winapi_pfn_##fn) return 1; else return 0; }; \
+ static APR_INLINE rettype apr_winapi_##fn args \
+ { if (apr_winapi_ld_##fn()) \
+ return (*(apr_winapi_pfn_##fn)) names; \
+ else { SetLastError(ERROR_INVALID_FUNCTION); return 0;} }; \
+
+#define APR_HAVE_LATE_DLL_FUNC(fn) apr_winapi_ld_##fn()
+
+/* Provide late bound declarations of every API function missing from
+ * one or more supported releases of the Win32 API
+ *
+ * lib is the enumerated token from apr_dlltoken_e, and must correspond
+ * to the string table entry in start.c used by the apr_load_dll_func().
+ * Token names (attempt to) follow Windows.h declarations prefixed by DLL_
+ * in order to facilitate comparison. Use the exact declaration syntax
+ * and names from Windows.h to prevent ambigutity and bugs.
+ *
+ * rettype and calltype follow the original declaration in Windows.h
+ * fn is the true function name - beware Ansi/Unicode #defined macros
+ * ord is the ordinal within the library, use 0 if it varies between versions
+ * args is the parameter list following the original declaration, in parens
+ * names is the parameter list sans data types, enclosed in parens
+ *
+ * #undef/re#define the Ansi/Unicode generic name to abate confusion
+ * In the case of non-text functions, simply #define the original name
+ */
+
+#if !defined(_WIN32_WCE) && !defined(WINNT)
+/* This group is available to all versions of WINNT 4.0 SP6 and later */
+
+#ifdef GetFileAttributesExA
+#undef GetFileAttributesExA
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, GetFileAttributesExA, 0, (
+ IN LPCSTR lpFileName,
+ IN GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ OUT LPVOID lpFileInformation),
+ (lpFileName, fInfoLevelId, lpFileInformation));
+#define GetFileAttributesExA apr_winapi_GetFileAttributesExA
+#undef GetFileAttributesEx
+#define GetFileAttributesEx apr_winapi_GetFileAttributesExA
+
+#ifdef GetFileAttributesExW
+#undef GetFileAttributesExW
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, GetFileAttributesExW, 0, (
+ IN LPCWSTR lpFileName,
+ IN GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ OUT LPVOID lpFileInformation),
+ (lpFileName, fInfoLevelId, lpFileInformation));
+#define GetFileAttributesExW apr_winapi_GetFileAttributesExW
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, CancelIo, 0, (
+ IN HANDLE hFile),
+ (hFile));
+#define CancelIo apr_winapi_CancelIo
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, TryEnterCriticalSection, 0, (
+ LPCRITICAL_SECTION lpCriticalSection),
+ (lpCriticalSection));
+#define TryEnterCriticalSection apr_winapi_TryEnterCriticalSection
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, SwitchToThread, 0, (
+ void),
+ ());
+#define SwitchToThread apr_winapi_SwitchToThread
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetEffectiveRightsFromAclW, 0, (
+ IN PACL pacl,
+ IN PTRUSTEE_W pTrustee,
+ OUT PACCESS_MASK pAccessRights),
+ (pacl, pTrustee, pAccessRights));
+#define GetEffectiveRightsFromAclW apr_winapi_GetEffectiveRightsFromAclW
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetNamedSecurityInfoW, 0, (
+ IN LPWSTR pObjectName,
+ IN SE_OBJECT_TYPE ObjectType,
+ IN SECURITY_INFORMATION SecurityInfo,
+ OUT PSID *ppsidOwner,
+ OUT PSID *ppsidGroup,
+ OUT PACL *ppDacl,
+ OUT PACL *ppSacl,
+ OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor),
+ (pObjectName, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup,
+ ppDacl, ppSacl, ppSecurityDescriptor));
+#define GetNamedSecurityInfoW apr_winapi_GetNamedSecurityInfoW
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetNamedSecurityInfoA, 0, (
+ IN LPSTR pObjectName,
+ IN SE_OBJECT_TYPE ObjectType,
+ IN SECURITY_INFORMATION SecurityInfo,
+ OUT PSID *ppsidOwner,
+ OUT PSID *ppsidGroup,
+ OUT PACL *ppDacl,
+ OUT PACL *ppSacl,
+ OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor),
+ (pObjectName, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup,
+ ppDacl, ppSacl, ppSecurityDescriptor));
+#define GetNamedSecurityInfoA apr_winapi_GetNamedSecurityInfoA
+#undef GetNamedSecurityInfo
+#define GetNamedSecurityInfo apr_winapi_GetNamedSecurityInfoA
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI, GetSecurityInfo, 0, (
+ IN HANDLE handle,
+ IN SE_OBJECT_TYPE ObjectType,
+ IN SECURITY_INFORMATION SecurityInfo,
+ OUT PSID *ppsidOwner,
+ OUT PSID *ppsidGroup,
+ OUT PACL *ppDacl,
+ OUT PACL *ppSacl,
+ OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor),
+ (handle, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup,
+ ppDacl, ppSacl, ppSecurityDescriptor));
+#define GetSecurityInfo apr_winapi_GetSecurityInfo
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_SHSTDAPI, LPWSTR *, WINAPI, CommandLineToArgvW, 0, (
+ LPCWSTR lpCmdLine,
+ int *pNumArgs),
+ (lpCmdLine, pNumArgs));
+#define CommandLineToArgvW apr_winapi_CommandLineToArgvW
+
+#endif /* !defined(_WIN32_WCE) && !defined(WINNT) */
+
+#if !defined(_WIN32_WCE)
+/* This group is NOT available to all versions of WinNT,
+ * these we must always look up
+ */
+
+#ifdef GetCompressedFileSizeA
+#undef GetCompressedFileSizeA
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, DWORD, WINAPI, GetCompressedFileSizeA, 0, (
+ IN LPCSTR lpFileName,
+ OUT LPDWORD lpFileSizeHigh),
+ (lpFileName, lpFileSizeHigh));
+#define GetCompressedFileSizeA apr_winapi_GetCompressedFileSizeA
+#undef GetCompressedFileSize
+#define GetCompressedFileSize apr_winapi_GetCompressedFileSizeA
+
+#ifdef GetCompressedFileSizeW
+#undef GetCompressedFileSizeW
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, DWORD, WINAPI, GetCompressedFileSizeW, 0, (
+ IN LPCWSTR lpFileName,
+ OUT LPDWORD lpFileSizeHigh),
+ (lpFileName, lpFileSizeHigh));
+#define GetCompressedFileSizeW apr_winapi_GetCompressedFileSizeW
+
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtQueryTimerResolution, 0, (
+ ULONG *pMaxRes, /* Minimum NS Resolution */
+ ULONG *pMinRes, /* Maximum NS Resolution */
+ ULONG *pCurRes), /* Current NS Resolution */
+ (pMaxRes, pMinRes, pCurRes));
+#define QueryTimerResolution apr_winapi_NtQueryTimerResolution
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtSetTimerResolution, 0, (
+ ULONG ReqRes, /* Requested NS Clock Resolution */
+ BOOL Acquire, /* Aquire (1) or Release (0) our interest */
+ ULONG *pNewRes), /* The NS Clock Resolution granted */
+ (ReqRes, Acquire, pNewRes));
+#define SetTimerResolution apr_winapi_NtSetTimerResolution
+
+typedef struct PBI {
+ LONG ExitStatus;
+ PVOID PebBaseAddress;
+ apr_uintptr_t AffinityMask;
+ LONG BasePriority;
+ apr_uintptr_t UniqueProcessId;
+ apr_uintptr_t InheritedFromUniqueProcessId;
+} PBI, *PPBI;
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtQueryInformationProcess, 0, (
+ HANDLE hProcess, /* Obvious */
+ INT info, /* Use 0 for PBI documented above */
+ PVOID pPI, /* The PIB buffer */
+ ULONG LenPI, /* Use sizeof(PBI) */
+ ULONG *pSizePI), /* returns pPI buffer used (may pass NULL) */
+ (hProcess, info, pPI, LenPI, pSizePI));
+#define QueryInformationProcess apr_winapi_NtQueryInformationProcess
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, NtQueryObject, 0, (
+ HANDLE hObject, /* Obvious */
+ INT info, /* Use 0 for PBI documented above */
+ PVOID pOI, /* The PIB buffer */
+ ULONG LenOI, /* Use sizeof(PBI) */
+ ULONG *pSizeOI), /* returns pPI buffer used (may pass NULL) */
+ (hObject, info, pOI, LenOI, pSizeOI));
+#define QueryObject apr_winapi_NtQueryObject
+
+typedef struct IOSB {
+ union {
+ UINT Status;
+ PVOID reserved;
+ };
+ apr_uintptr_t Information; /* Varies by op, consumed buffer size for FSI below */
+} IOSB, *PIOSB;
+
+typedef struct FSI {
+ LONGLONG AllocationSize;
+ LONGLONG EndOfFile;
+ ULONG NumberOfLinks;
+ BOOL DeletePending;
+ BOOL Directory;
+} FSI, *PFSI;
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_NTDLL, LONG, WINAPI, ZwQueryInformationFile, 0, (
+ HANDLE hObject, /* Obvious */
+ PVOID pIOSB, /* Point to the IOSB buffer for detailed return results */
+ PVOID pFI, /* The buffer, using FIB above */
+ ULONG LenFI, /* Use sizeof(FI) */
+ ULONG info), /* Use 5 for FSI documented above*/
+ (hObject, pIOSB, pFI, LenFI, info));
+#define ZwQueryInformationFile apr_winapi_ZwQueryInformationFile
+
+#ifdef CreateToolhelp32Snapshot
+#undef CreateToolhelp32Snapshot
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, HANDLE, WINAPI, CreateToolhelp32Snapshot, 0, (
+ DWORD dwFlags,
+ DWORD th32ProcessID),
+ (dwFlags, th32ProcessID));
+#define CreateToolhelp32Snapshot apr_winapi_CreateToolhelp32Snapshot
+
+#ifdef Process32FirstW
+#undef Process32FirstW
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, Process32FirstW, 0, (
+ HANDLE hSnapshot,
+ LPPROCESSENTRY32W lppe),
+ (hSnapshot, lppe));
+#define Process32FirstW apr_winapi_Process32FirstW
+
+#ifdef Process32NextW
+#undef Process32NextW
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, Process32NextW, 0, (
+ HANDLE hSnapshot,
+ LPPROCESSENTRY32W lppe),
+ (hSnapshot, lppe));
+#define Process32NextW apr_winapi_Process32NextW
+
+#if !defined(POLLERR)
+/* Event flag definitions for WSAPoll(). */
+#define POLLRDNORM 0x0100
+#define POLLRDBAND 0x0200
+#define POLLIN (POLLRDNORM | POLLRDBAND)
+#define POLLPRI 0x0400
+
+#define POLLWRNORM 0x0010
+#define POLLOUT (POLLWRNORM)
+#define POLLWRBAND 0x0020
+
+#define POLLERR 0x0001
+#define POLLHUP 0x0002
+#define POLLNVAL 0x0004
+
+typedef struct pollfd {
+ SOCKET fd;
+ SHORT events;
+ SHORT revents;
+
+} WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD;
+
+#endif /* !defined(POLLERR) */
+#ifdef WSAPoll
+#undef WSAPoll
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINSOCK2API, int, WSAAPI, WSAPoll, 0, (
+ IN OUT LPWSAPOLLFD fdArray,
+ IN ULONG fds,
+ IN INT timeout),
+ (fdArray, fds, timeout));
+#define WSAPoll apr_winapi_WSAPoll
+#define HAVE_POLL 1
+
+#ifdef SetDllDirectoryW
+#undef SetDllDirectoryW
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, SetDllDirectoryW, 0, (
+ IN LPCWSTR lpPathName),
+ (lpPathName));
+#define SetDllDirectoryW apr_winapi_SetDllDirectoryW
+
+#if HAVE_IF_NAMETOINDEX
+#ifdef if_nametoindex
+#undef if_nametoindex
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_IPHLPAPI, NET_IFINDEX, WINAPI, if_nametoindex, 0, (
+ IN PCSTR InterfaceName),
+ (InterfaceName));
+#define if_nametoindex apr_winapi_if_nametoindex
+#endif
+
+#if HAVE_IF_INDEXTONAME
+#ifdef if_indextoname
+#undef if_indextoname
+#endif
+APR_DECLARE_LATE_DLL_FUNC(DLL_IPHLPAPI, PCHAR, NETIOAPI_API_, if_indextoname, 0, (
+ NET_IFINDEX InterfaceIndex,
+ PCHAR InterfaceName),
+ (InterfaceIndex, InterfaceName));
+#define if_indextoname apr_winapi_if_indextoname
+#endif
+
+#endif /* !defined(_WIN32_WCE) */
+
+#endif /* ! MISC_H */
+
diff --git a/include/arch/win32/apr_arch_networkio.h b/include/arch/win32/apr_arch_networkio.h
new file mode 100644
index 0000000..04be555
--- /dev/null
+++ b/include/arch/win32/apr_arch_networkio.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 NETWORK_IO_H
+#define NETWORK_IO_H
+
+#include "apr_network_io.h"
+#include "apr_general.h"
+#include "apr_poll.h"
+
+typedef struct sock_userdata_t sock_userdata_t;
+struct sock_userdata_t {
+ sock_userdata_t *next;
+ const char *key;
+ void *data;
+};
+
+struct apr_socket_t {
+ apr_pool_t *pool;
+ SOCKET socketdes;
+ int type; /* SOCK_STREAM, SOCK_DGRAM */
+ int protocol;
+ apr_sockaddr_t *local_addr;
+ apr_sockaddr_t *remote_addr;
+ int timeout_ms; /* MUST MATCH if timeout > 0 */
+ apr_interval_time_t timeout;
+ apr_int32_t disconnected;
+ int local_port_unknown;
+ int local_interface_unknown;
+ int remote_addr_unknown;
+ apr_int32_t options;
+ apr_int32_t inherit;
+#if APR_HAS_SENDFILE
+ /* As of 07.20.04, the overlapped structure is only used by
+ * apr_socket_sendfile and that's where it will be allocated
+ * and initialized.
+ */
+ OVERLAPPED *overlapped;
+#endif
+ sock_userdata_t *userdata;
+
+ /* if there is a timeout set, then this pollset is used */
+ apr_pollset_t *pollset;
+};
+
+#ifdef _WIN32_WCE
+#ifndef WSABUF
+typedef struct _WSABUF {
+ u_long len; /* the length of the buffer */
+ char FAR * buf; /* the pointer to the buffer */
+} WSABUF, FAR * LPWSABUF;
+#endif
+#else
+#ifdef _MSC_VER
+#define HAVE_STRUCT_IPMREQ
+#endif
+#endif
+
+apr_status_t status_from_res_error(int);
+
+const char *apr_inet_ntop(int af, const void *src, char *dst, apr_size_t size);
+int apr_inet_pton(int af, const char *src, void *dst);
+void apr_sockaddr_vars_set(apr_sockaddr_t *, int, apr_port_t);
+
+#define apr_is_option_set(skt, option) \
+ (((skt)->options & (option)) == (option))
+
+#define apr_set_option(skt, option, on) \
+ do { \
+ if (on) \
+ (skt)->options |= (option); \
+ else \
+ (skt)->options &= ~(option); \
+ } while (0)
+
+#endif /* ! NETWORK_IO_H */
+
diff --git a/include/arch/win32/apr_arch_proc_mutex.h b/include/arch/win32/apr_arch_proc_mutex.h
new file mode 100644
index 0000000..4e3e399
--- /dev/null
+++ b/include/arch/win32/apr_arch_proc_mutex.h
@@ -0,0 +1,29 @@
+/* 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 PROC_MUTEX_H
+#define PROC_MUTEX_H
+
+#include "apr_proc_mutex.h"
+
+struct apr_proc_mutex_t {
+ apr_pool_t *pool;
+ HANDLE handle;
+ const char *fname;
+};
+
+#endif /* PROC_MUTEX_H */
+
diff --git a/include/arch/win32/apr_arch_thread_cond.h b/include/arch/win32/apr_arch_thread_cond.h
new file mode 100644
index 0000000..c7f69f8
--- /dev/null
+++ b/include/arch/win32/apr_arch_thread_cond.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.
+ */
+
+#ifndef THREAD_COND_H
+#define THREAD_COND_H
+
+#include "apr_thread_cond.h"
+
+struct apr_thread_cond_t {
+ apr_pool_t *pool;
+ HANDLE semaphore;
+ CRITICAL_SECTION csection;
+ unsigned long num_waiting;
+ unsigned long num_wake;
+ unsigned long generation;
+};
+
+#endif /* THREAD_COND_H */
+
diff --git a/include/arch/win32/apr_arch_thread_mutex.h b/include/arch/win32/apr_arch_thread_mutex.h
new file mode 100644
index 0000000..13d3c1c
--- /dev/null
+++ b/include/arch/win32/apr_arch_thread_mutex.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 THREAD_MUTEX_H
+#define THREAD_MUTEX_H
+
+#include "apr_pools.h"
+
+typedef enum thread_mutex_type {
+ thread_mutex_critical_section,
+ thread_mutex_unnested_event,
+ thread_mutex_nested_mutex
+} thread_mutex_type;
+
+/* handle applies only to unnested_event on all platforms
+ * and nested_mutex on Win9x only. Otherwise critical_section
+ * is used for NT nexted mutexes providing optimal performance.
+ */
+struct apr_thread_mutex_t {
+ apr_pool_t *pool;
+ thread_mutex_type type;
+ HANDLE handle;
+ CRITICAL_SECTION section;
+};
+
+#endif /* THREAD_MUTEX_H */
+
diff --git a/include/arch/win32/apr_arch_thread_rwlock.h b/include/arch/win32/apr_arch_thread_rwlock.h
new file mode 100644
index 0000000..1177e52
--- /dev/null
+++ b/include/arch/win32/apr_arch_thread_rwlock.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 THREAD_RWLOCK_H
+#define THREAD_RWLOCK_H
+
+#include "apr_thread_rwlock.h"
+
+struct apr_thread_rwlock_t {
+ apr_pool_t *pool;
+ HANDLE write_mutex;
+ HANDLE read_event;
+ LONG readers;
+};
+
+#endif /* THREAD_RWLOCK_H */
+
diff --git a/include/arch/win32/apr_arch_threadproc.h b/include/arch/win32/apr_arch_threadproc.h
new file mode 100644
index 0000000..d3ce9c5
--- /dev/null
+++ b/include/arch/win32/apr_arch_threadproc.h
@@ -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 "apr_private.h"
+#include "apr_thread_proc.h"
+#include "apr_file_io.h"
+
+#ifndef THREAD_PROC_H
+#define THREAD_PROC_H
+
+#define SHELL_PATH "cmd.exe"
+
+struct apr_thread_t {
+ apr_pool_t *pool;
+ HANDLE td;
+ apr_int32_t cancel;
+ apr_int32_t cancel_how;
+ void *data;
+ apr_thread_start_t func;
+ apr_status_t exitval;
+};
+
+struct apr_threadattr_t {
+ apr_pool_t *pool;
+ apr_int32_t detach;
+ apr_size_t stacksize;
+};
+
+struct apr_threadkey_t {
+ apr_pool_t *pool;
+ DWORD key;
+};
+
+struct apr_procattr_t {
+ apr_pool_t *pool;
+ apr_file_t *parent_in;
+ apr_file_t *child_in;
+ apr_file_t *parent_out;
+ apr_file_t *child_out;
+ apr_file_t *parent_err;
+ apr_file_t *child_err;
+ char *currdir;
+ apr_int32_t cmdtype;
+ apr_int32_t detached;
+ apr_child_errfn_t *errfn;
+ apr_int32_t errchk;
+#ifndef _WIN32_WCE
+ HANDLE user_token;
+ LPSECURITY_ATTRIBUTES sa;
+ LPVOID sd;
+#endif
+};
+
+struct apr_thread_once_t {
+ long value;
+};
+
+extern apr_status_t apr_threadproc_init(apr_pool_t *pool);
+
+#endif /* ! THREAD_PROC_H */
+
diff --git a/include/arch/win32/apr_arch_utf8.h b/include/arch/win32/apr_arch_utf8.h
new file mode 100644
index 0000000..84f8bf7
--- /dev/null
+++ b/include/arch/win32/apr_arch_utf8.h
@@ -0,0 +1,56 @@
+/* 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 UTF8_H
+#define UTF8_H
+
+#include "apr.h"
+#include "apr_lib.h"
+#include "apr_errno.h"
+
+/* If we ever support anything more exciting than char... this could move.
+ */
+typedef apr_uint16_t apr_wchar_t;
+
+/**
+ * An APR internal function for fast utf-8 octet-encoded Unicode conversion
+ * to the ucs-2 wide Unicode format. This function is used for filename and
+ * other resource conversions for platforms providing native Unicode support.
+ *
+ * @tip Only the errors APR_EINVAL and APR_INCOMPLETE may occur, the former
+ * when the character code is invalid (in or out of context) and the later
+ * when more characters were expected, but insufficient characters remain.
+ */
+APR_DECLARE(apr_status_t) apr_conv_utf8_to_ucs2(const char *in,
+ apr_size_t *inbytes,
+ apr_wchar_t *out,
+ apr_size_t *outwords);
+
+/**
+ * An APR internal function for fast ucs-2 wide Unicode format conversion to
+ * the utf-8 octet-encoded Unicode. This function is used for filename and
+ * other resource conversions for platforms providing native Unicode support.
+ *
+ * @tip Only the errors APR_EINVAL and APR_INCOMPLETE may occur, the former
+ * when the character code is invalid (in or out of context) and the later
+ * when more words were expected, but insufficient words remain.
+ */
+APR_DECLARE(apr_status_t) apr_conv_ucs2_to_utf8(const apr_wchar_t *in,
+ apr_size_t *inwords,
+ char *out,
+ apr_size_t *outbytes);
+
+#endif /* def UTF8_H */
diff --git a/include/arch/win32/apr_dbg_win32_handles.h b/include/arch/win32/apr_dbg_win32_handles.h
new file mode 100644
index 0000000..471cd66
--- /dev/null
+++ b/include/arch/win32/apr_dbg_win32_handles.h
@@ -0,0 +1,217 @@
+/* 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 APR_DBG_WIN32_HANDLES_H
+#define APR_DBG_WIN32_HANDLES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* USAGE:
+ *
+ * Add the following include to apr_private.h for internal debugging,
+ * or copy this header into apr/include add the include below to apr.h
+ * for really global debugging;
+ *
+ * #include "apr_dbg_win32_handles.h"
+ *
+ * apr_dbg_log is the crux of this function ... it uses Win32 API and
+ * no apr calls itself to log all activity to a file named for the
+ * executing application with a .pid suffix. Ergo several instances
+ * may be executing and logged at once.
+ *
+ * HANDLE apr_dbg_log(char* fn, HANDLE ha, char* fl, int ln, int nh
+ * [, HANDLE *hv, char *dsc...])
+ *
+ * returns: the handle passed in ha, which is cast back to the real return type.
+ *
+ * formats one line into the debug log file if nh is zero;
+ * ha (hex) seq(hex) tid(hex) fn fl ln
+ * xxxxxxxx xxxxxxxx xxxxxxxx func() sourcefile:lineno
+ * The macro apr_dbg_rv makes this simple to implement for many APIs
+ * that simply take args that don't interest us, and return a handle.
+ *
+ * formats multiple lines (nh) into the debug log file for each hv/dsc pair
+ * (nh must correspond to the number of pairs);
+ * hv (hex) seq(hex) tid(hex) fn dsc fl ln
+ * xxxxxxxx xxxxxxxx xxxxxxxx func(arg) sourcefile:lineno
+ * In this later usage, hv is the still the return value but is not
+ * treated as a handle.
+ */
+
+APR_DECLARE_NONSTD(HANDLE) apr_dbg_log(char* fn, HANDLE ha, char* fl, int ln,
+ int nh,/* HANDLE *hv, char *dsc */...);
+
+#define apr_dbg_rv(fn, args) (apr_dbg_log(#fn,(fn) args,__FILE__,__LINE__,0))
+
+#define CloseHandle(h) \
+ ((BOOL)apr_dbg_log("CloseHandle", \
+ (HANDLE)(CloseHandle)(h), \
+ __FILE__,__LINE__,1, \
+ &(h),""))
+
+#define CreateEventA(sd,b1,b2,nm) apr_dbg_rv(CreateEventA,(sd,b1,b2,nm))
+#define CreateEventW(sd,b1,b2,nm) apr_dbg_rv(CreateEventW,(sd,b1,b2,nm))
+
+#define CreateFileA(nm,d1,d2,sd,d3,d4,h) apr_dbg_rv(CreateFileA,(nm,d1,d2,sd,d3,d4,h))
+#define CreateFileW(nm,d1,d2,sd,d3,d4,h) apr_dbg_rv(CreateFileW,(nm,d1,d2,sd,d3,d4,h))
+
+#define CreateFileMappingA(fh,sd,d1,d2,d3,nm) apr_dbg_rv(CreateFileMappingA,(fh,sd,d1,d2,d3,nm))
+#define CreateFileMappingW(fh,sd,d1,d2,d3,nm) apr_dbg_rv(CreateFileMappingW,(fh,sd,d1,d2,d3,nm))
+
+#define CreateMutexA(sd,b,nm) apr_dbg_rv(CreateMutexA,(sd,b,nm))
+#define CreateMutexW(sd,b,nm) apr_dbg_rv(CreateMutexW,(sd,b,nm))
+
+#define CreateIoCompletionPort(h1,h2,pd1,d2) apr_dbg_rv(CreateIoCompletionPort,(h1,h2,pd1,d2))
+
+#define CreateNamedPipeA(nm,d1,d2,d3,d4,d5,d6,sd) apr_dbg_rv(CreateNamedPipeA,(nm,d1,d2,d3,d4,d5,d6,sd))
+#define CreateNamedPipeW(nm,d1,d2,d3,d4,d5,d6,sd) apr_dbg_rv(CreateNamedPipeW,(nm,d1,d2,d3,d4,d5,d6,sd))
+
+#define CreatePipe(ph1,ph2,sd,d) \
+ ((BOOL)apr_dbg_log("CreatePipe", \
+ (HANDLE)(CreatePipe)(ph1,ph2,sd,d), \
+ __FILE__,__LINE__,2, \
+ (ph1),"hRead", \
+ (ph2),"hWrite"))
+
+#define CreateProcessA(s1,s2,sd1,sd2,b,d1,s3,s4,pd2,hr) \
+ ((BOOL)apr_dbg_log("CreateProcessA", \
+ (HANDLE)(CreateProcessA)(s1,s2,sd1,sd2,b,d1,s3,s4,pd2,hr), \
+ __FILE__,__LINE__,2, \
+ &((hr)->hProcess),"hProcess", \
+ &((hr)->hThread),"hThread"))
+#define CreateProcessW(s1,s2,sd1,sd2,b,d1,s3,s4,pd2,hr) \
+ ((BOOL)apr_dbg_log("CreateProcessW", \
+ (HANDLE)(CreateProcessW)(s1,s2,sd1,sd2,b,d1,s3,s4,pd2,hr), \
+ __FILE__,__LINE__,2, \
+ &((hr)->hProcess),"hProcess", \
+ &((hr)->hThread),"hThread"))
+
+#define CreateSemaphoreA(sd,d1,d2,nm) apr_dbg_rv(CreateSemaphoreA,(sd,d1,d2,nm))
+#define CreateSemaphoreW(sd,d1,d2,nm) apr_dbg_rv(CreateSemaphoreW,(sd,d1,d2,nm))
+
+#define CreateThread(sd,d1,fn,pv,d2,pd3) apr_dbg_rv(CreateThread,(sd,d1,fn,pv,d2,pd3))
+
+#define DeregisterEventSource(h) \
+ ((BOOL)apr_dbg_log("DeregisterEventSource", \
+ (HANDLE)(DeregisterEventSource)(h), \
+ __FILE__,__LINE__,1, \
+ &(h),""))
+
+#define DuplicateHandle(h1,h2,h3,ph4,d1,b,d2) \
+ ((BOOL)apr_dbg_log("DuplicateHandle", \
+ (HANDLE)(DuplicateHandle)(h1,h2,h3,ph4,d1,b,d2), \
+ __FILE__,__LINE__,2, \
+ (ph4),((h3)==GetCurrentProcess()) \
+ ? "Target" : "EXTERN Target", \
+ &(h2),((h1)==GetCurrentProcess()) \
+ ? "Source" : "EXTERN Source"))
+
+#define GetCurrentProcess() \
+ (apr_dbg_log("GetCurrentProcess", \
+ (GetCurrentProcess)(),__FILE__,__LINE__,0))
+
+#define GetCurrentThread() \
+ (apr_dbg_log("GetCurrentThread", \
+ (GetCurrentThread)(),__FILE__,__LINE__,0))
+
+#define GetModuleHandleA(nm) apr_dbg_rv(GetModuleHandleA,(nm))
+#define GetModuleHandleW(nm) apr_dbg_rv(GetModuleHandleW,(nm))
+
+#define GetStdHandle(d) apr_dbg_rv(GetStdHandle,(d))
+
+#define LoadLibraryA(nm) apr_dbg_rv(LoadLibraryA,(nm))
+#define LoadLibraryW(nm) apr_dbg_rv(LoadLibraryW,(nm))
+
+#define LoadLibraryExA(nm,h,d) apr_dbg_rv(LoadLibraryExA,(nm,h,d))
+#define LoadLibraryExW(nm,h,d) apr_dbg_rv(LoadLibraryExW,(nm,h,d))
+
+#define OpenEventA(d,b,nm) apr_dbg_rv(OpenEventA,(d,b,nm))
+#define OpenEventW(d,b,nm) apr_dbg_rv(OpenEventW,(d,b,nm))
+
+#define OpenFileMappingA(d,b,nm) apr_dbg_rv(OpenFileMappingA,(d,b,nm))
+#define OpenFileMappingW(d,b,nm) apr_dbg_rv(OpenFileMappingW,(d,b,nm))
+
+#define RegisterEventSourceA(s1,s2) apr_dbg_rv(RegisterEventSourceA,(s1,s2))
+#define RegisterEventSourceW(s1,s2) apr_dbg_rv(RegisterEventSourceW,(s1,s2))
+
+#define SetEvent(h) \
+ ((BOOL)apr_dbg_log("SetEvent", \
+ (HANDLE)(SetEvent)(h), \
+ __FILE__,__LINE__,1, \
+ &(h),""))
+
+#define SetStdHandle(d,h) \
+ ((BOOL)apr_dbg_log("SetStdHandle", \
+ (HANDLE)(SetStdHandle)(d,h), \
+ __FILE__,__LINE__,1,&(h),""))
+
+#define socket(i1,i2,i3) \
+ ((SOCKET)apr_dbg_log("socket", \
+ (HANDLE)(socket)(i1,i2,i3), \
+ __FILE__,__LINE__,0))
+
+#define WaitForSingleObject(h,d) \
+ ((DWORD)apr_dbg_log("WaitForSingleObject", \
+ (HANDLE)(WaitForSingleObject)(h,d), \
+ __FILE__,__LINE__,1,&(h),"Signaled"))
+
+#define WaitForSingleObjectEx(h,d,b) \
+ ((DWORD)apr_dbg_log("WaitForSingleObjectEx", \
+ (HANDLE)(WaitForSingleObjectEx)(h,d,b), \
+ __FILE__,__LINE__,1,&(h),"Signaled"))
+
+#define WaitForMultipleObjects(d1,ah,b,d2) \
+ ((DWORD)apr_dbg_log("WaitForMultipleObjects", \
+ (HANDLE)(WaitForMultipleObjects)(d1,ah,b,d2), \
+ __FILE__,__LINE__,1,ah,"Signaled"))
+
+#define WaitForMultipleObjectsEx(d1,ah,b1,d2,b2) \
+ ((DWORD)apr_dbg_log("WaitForMultipleObjectsEx", \
+ (HANDLE)(WaitForMultipleObjectsEx)(d1,ah,b1,d2,b2), \
+ __FILE__,__LINE__,1,ah,"Signaled"))
+
+#define WSASocketA(i1,i2,i3,pi,g,dw) \
+ ((SOCKET)apr_dbg_log("WSASocketA", \
+ (HANDLE)(WSASocketA)(i1,i2,i3,pi,g,dw), \
+ __FILE__,__LINE__,0))
+
+#define WSASocketW(i1,i2,i3,pi,g,dw) \
+ ((SOCKET)apr_dbg_log("WSASocketW", \
+ (HANDLE)(WSASocketW)(i1,i2,i3,pi,g,dw), \
+ __FILE__,__LINE__,0))
+
+#define closesocket(sh) \
+ ((int)apr_dbg_log("closesocket", \
+ (HANDLE)(closesocket)(sh), \
+ __FILE__,__LINE__,1,&(sh),""))
+
+#define _beginthread(fn,d,pv) \
+ ((unsigned long)apr_dbg_log("_beginthread", \
+ (HANDLE)(_beginthread)(fn,d,pv), \
+ __FILE__,__LINE__,0))
+
+#define _beginthreadex(sd,d1,fn,pv,d2,pd3) \
+ ((unsigned long)apr_dbg_log("_beginthreadex", \
+ (HANDLE)(_beginthreadex)(sd,d1,fn,pv,d2,pd3), \
+ __FILE__,__LINE__,0))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(APR_DBG_WIN32_HANDLES_H) */
diff --git a/include/arch/win32/apr_private.h b/include/arch/win32/apr_private.h
new file mode 100644
index 0000000..c631ad4
--- /dev/null
+++ b/include/arch/win32/apr_private.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.
+ */
+
+/*
+ * Note:
+ * This is the windows specific autoconf-like config file
+ * which unix would create at build time.
+ */
+
+#ifdef WIN32
+
+#ifndef APR_PRIVATE_H
+#define APR_PRIVATE_H
+
+/* Include the public APR symbols, include our idea of the 'right'
+ * subset of the Windows.h header. This saves us repetition.
+ */
+#include "apr.h"
+
+/*
+ * Add a _very_few_ declarations missing from the restricted set of headers
+ * (If this list becomes extensive, re-enable the required headers above!)
+ * winsock headers were excluded by WIN32_LEAN_AND_MEAN, so include them now
+ */
+#ifndef SW_HIDE
+#define SW_HIDE 0
+#endif
+
+/* For the misc.h late-loaded dynamic symbols, we need some obscure types
+ * Avoid dragging in wtypes.h unless it's absolutely necessary [generally
+ * not with APR itself, until some GUI-related security is introduced.]
+ */
+#ifndef _WIN32_WCE
+#define HAVE_ACLAPI 1
+#ifdef __wtypes_h__
+#include <accctrl.h>
+#else
+#define __wtypes_h__
+#include <accctrl.h>
+#undef __wtypes_h__
+#endif
+#else
+#define HAVE_ACLAPI 0
+#endif
+
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if APR_HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+#include <stdio.h>
+#if APR_HAVE_TIME_H
+#include <time.h>
+#endif
+
+/* Use this section to define all of the HAVE_FOO_H
+ * that are required to build properly.
+ */
+#define HAVE_LIMITS_H 1
+#define HAVE_MALLOC_H 1
+#define HAVE_SIGNAL_H 1
+/* #define HAVE_STDDEF_H 1 why not? */
+#define HAVE_STDLIB_H 1
+
+#define HAVE_STRICMP 1
+#define HAVE_STRNICMP 1
+#define HAVE_STRDUP 1
+#define HAVE_STRSTR 1
+#define HAVE_MEMCHR 1
+
+#define SIGHUP 1
+/* 2 is used for SIGINT on windows */
+#define SIGQUIT 3
+/* 4 is used for SIGILL on windows */
+#define SIGTRAP 5
+#define SIGIOT 6
+#define SIGBUS 7
+/* 8 is used for SIGFPE on windows */
+#define SIGKILL 9
+#define SIGUSR1 10
+/* 11 is used for SIGSEGV on windows */
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+/* 15 is used for SIGTERM on windows */
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+/* 21 is used for SIGBREAK on windows */
+/* 22 is used for SIGABRT on windows */
+#define SIGTTIN 23
+#define SIGTTOU 24
+#define SIGURG 25
+#define SIGXCPU 26
+#define SIGXFSZ 27
+#define SIGVTALRM 28
+#define SIGPROF 29
+#define SIGWINCH 30
+#define SIGIO 31
+
+/* APR COMPATABILITY FUNCTIONS
+ * This section should be used to define functions and
+ * macros which are need to make Windows features look
+ * like POSIX features.
+ */
+typedef void (Sigfunc)(int);
+
+#define sleep(t) Sleep((t) * 1000)
+
+#define SIZEOF_SHORT 2
+#define SIZEOF_INT 4
+#define SIZEOF_LONGLONG 8
+#define SIZEOF_CHAR 1
+#define SIZEOF_SSIZE_T SIZEOF_INT
+
+unsigned __stdcall SignalHandling(void *);
+int thread_ready(void);
+
+#if !APR_HAVE_ERRNO_H
+APR_DECLARE_DATA int errno;
+#define ENOSPC 1
+#endif
+
+#if APR_HAVE_IPV6
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETNAMEINFO 1
+#define HAVE_IF_INDEXTONAME 1
+#define HAVE_IF_NAMETOINDEX 1
+#endif
+
+/* MSVC 7.0 introduced _strtoi64 */
+#if _MSC_VER >= 1300 && _INTEGRAL_MAX_BITS >= 64 && !defined(_WIN32_WCE)
+#define APR_INT64_STRFN _strtoi64
+#endif
+
+#if APR_HAS_LARGE_FILES
+#ifdef APR_INT64_STRFN
+#define APR_OFF_T_STRFN APR_INT64_STRFN
+#else
+#define APR_OFF_T_STRFN apr_strtoi64
+#endif
+#else
+#if defined(_WIN32_WCE)
+#define APR_OFF_T_STRFN strtol
+#else
+#define APR_OFF_T_STRFN strtoi
+#endif
+#endif
+
+/* used to check for DWORD overflow in 64bit compiles */
+#define APR_DWORD_MAX 0xFFFFFFFFUL
+
+/*
+ * Include common private declarations.
+ */
+#include "../apr_private_common.h"
+
+#endif /*APR_PRIVATE_H*/
+#endif /*WIN32*/
diff --git a/include/private/apr_encode_private.h b/include/private/apr_encode_private.h
new file mode 100644
index 0000000..93ce0a0
--- /dev/null
+++ b/include/private/apr_encode_private.h
@@ -0,0 +1,89 @@
+/* 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.
+ */
+
+/**
+ * @file apr_encode_private.h
+ * @brief APR-UTIL Encoding Private
+ */
+#ifndef APR_ENCODE_PRIVATE_H
+#define APR_ENCODE_PRIVATE_H
+
+#include "apr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup APR_Util_Encode_Private
+ * @ingroup APR_Util
+ * @{
+ */
+
+#if APR_CHARSET_EBCDIC
+
+static unsigned char convert_a2e[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B,
+ 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF,
+ 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, 0xBB, 0xB4, 0x9A, 0x8A, 0xB0, 0xCA, 0xAF, 0xBC,
+ 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB,
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
+ 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xBA, 0xAE, 0x59,
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
+ 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF};
+
+static unsigned char convert_e2a[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07,
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A,
+ 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
+ 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
+ 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+ 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+ 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1,
+ 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4,
+ 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE,
+ 0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, 0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7,
+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5,
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF,
+ 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F};
+
+#define TO_ASCII(ch) (convert_e2a[(unsigned char)(ch)])
+#define TO_NATIVE(ch) (convert_a2e[(unsigned char)(ch)])
+
+#else /* APR_CHARSET_EBCDIC */
+
+#define TO_ASCII(ch) ((unsigned char)(ch))
+#define TO_NATIVE(ch) ((unsigned char)(ch))
+
+#endif /* !APR_CHARSET_EBCDIC */
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APR_ENCODE_PRIVATE_H */