diff options
author | (no author) <(no author)@13f79535-47bb-0310-9956-ffa450edef68> | 1999-08-24 05:50:38 +0000 |
---|---|---|
committer | (no author) <(no author)@13f79535-47bb-0310-9956-ffa450edef68> | 1999-08-24 05:50:38 +0000 |
commit | 091b42897a381794c8283ee53d643995ff514e65 (patch) | |
tree | 9600a7a8672c30de1b898febf0383af458593f20 /lib | |
parent | 400bc1c2b333ad45e6ad452dbfd4754aea04aba3 (diff) | |
download | libapr-091b42897a381794c8283ee53d643995ff514e65.tar.gz |
This commit was manufactured by cvs2svn to create tag 'APACHE_1_3_9'.APACHE_1_3_9
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/tags/APACHE_1_3_9@59168 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.in | 89 | ||||
-rw-r--r-- | lib/apr_cpystrn.c | 101 | ||||
-rw-r--r-- | lib/apr_execve.c | 390 | ||||
-rw-r--r-- | lib/apr_fnmatch.c | 240 | ||||
-rw-r--r-- | lib/apr_getpass.c | 173 | ||||
-rw-r--r-- | lib/apr_md5.c | 609 | ||||
-rw-r--r-- | lib/apr_pools.c | 2113 | ||||
-rw-r--r-- | lib/apr_signal.c | 84 | ||||
-rw-r--r-- | lib/apr_slack.c | 126 | ||||
-rw-r--r-- | lib/apr_snprintf.c | 1026 | ||||
-rw-r--r-- | lib/apr_tables.c | 775 | ||||
-rw-r--r-- | lib/lib.def | 60 | ||||
-rw-r--r-- | lib/lib.dsp | 129 |
13 files changed, 0 insertions, 5915 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in deleted file mode 100644 index 36570237b..000000000 --- a/lib/Makefile.in +++ /dev/null @@ -1,89 +0,0 @@ -#CFLAGS=$(OPTIM) $(CFLAGS1) $(EXTRA_CFLAGS) -#LIBS=$(EXTRA_LIBS) $(LIBS1) -#INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES) -#LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS) - -CC=@CC@ -RANLIB=@RANLIB@ -AR=@AR@ -RM=@RM@ -CFLAGS=@CFLAGS@ @OPTIM@ -LIBS=@LIBS@ -LDFLAGS=@LDFLAGS@ $(LIBS) -INCDIR=../inc -INCDIR1=../include -INCDIR2=../misc/@OSDIR@ -INCLUDES=-I$(INCDIR) -I$(INCDIR1) -I$(INCDIR2) - -LIB=@LIBPREFIX@apr.a - -OBJS=apr_cpystrn.o \ - apr_fnmatch.o \ - apr_execve.o \ - apr_md5.o \ - apr_pools.o \ - apr_signal.o \ - apr_slack.o \ - apr_snprintf.o \ - apr_tables.o \ - apr_getpass.o - -.c.o: - $(CC) $(CFLAGS) -c $(INCLUDES) $< - -all: $(LIB) - -clean: - $(RM) -f *.o *.a *.so - -distclean: clean - -$(RM) -f Makefile - -$(OBJS): Makefile - -$(LIB): $(OBJS) - $(RM) -f $@ - $(AR) cr $@ $(OBJS) - $(RANLIB) $@ - -# -# We really don't expect end users to use this rule. It works only with -# gcc, and rebuilds Makefile.tmpl. You have to re-run Configure after -# using it. -# -depend: - cp Makefile.in Makefile.in.bak \ - && sed -ne '1,/^# DO NOT REMOVE/p' Makefile.in > Makefile.new \ - && gcc -MM $(INCLUDES) $(CFLAGS) *.c >> Makefile.new \ - && sed -e '1,$$s: $(INCDIR)/: $$(INCDIR)/:g' \ - -e '1,$$s: $(OSDIR)/: $$(OSDIR)/:g' Makefile.new \ - > Makefile.in \ - && rm Makefile.new - -# DO NOT REMOVE -apr_cpystrn.o: apr_cpystrn.c ../include/apr_config.h -apr_execve.o: apr_execve.c ../include/apr_config.h -apr_fnmatch.o: apr_fnmatch.c ../include/apr_config.h \ - $(INCDIR)/apr_fnmatch.h ../include/apr_lib.h ../include/apr_general.h \ - ../include/apr_errno.h ../include/apr_file_io.h ../include/hsregex.h -apr_getpass.o: apr_getpass.c ../include/apr_config.h \ - ../include/apr_errno.h ../include/apr_lib.h ../include/apr_general.h \ - ../include/apr_file_io.h ../include/hsregex.h -apr_md5.o: apr_md5.c ../include/apr_config.h ../include/apr_md5.h \ - ../include/apr_lib.h ../include/apr_general.h ../include/apr_errno.h \ - ../include/apr_file_io.h ../include/hsregex.h -apr_pools.o: apr_pools.c ../include/apr_config.h \ - ../include/apr_general.h ../include/apr_errno.h $(INCDIR)/apr_pools.h \ - ../include/apr_lib.h ../include/apr_file_io.h ../include/hsregex.h \ - ../misc/unix/misc.h -apr_signal.o: apr_signal.c ../include/apr_config.h \ - ../include/apr_lib.h ../include/apr_general.h ../include/apr_errno.h \ - ../include/apr_file_io.h ../include/hsregex.h -apr_slack.o: apr_slack.c ../include/apr_config.h -apr_snprintf.o: apr_snprintf.c ../include/apr_config.h \ - ../include/apr_lib.h ../include/apr_general.h ../include/apr_errno.h \ - ../include/apr_file_io.h ../include/hsregex.h -apr_tables.o: apr_tables.c ../include/apr_config.h \ - ../include/apr_general.h ../include/apr_errno.h $(INCDIR)/apr_pools.h \ - ../include/apr_lib.h ../include/apr_file_io.h ../include/hsregex.h \ - ../misc/unix/misc.h diff --git a/lib/apr_cpystrn.c b/lib/apr_cpystrn.c deleted file mode 100644 index ed24b600a..000000000 --- a/lib/apr_cpystrn.c +++ /dev/null @@ -1,101 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ -#ifndef WIN32 -#include "apr_config.h" -#else -#include "apr_win.h" -#endif - -#if HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -/* - * Apache's "replacement" for the strncpy() function. We roll our - * own to implement these specific changes: - * (1) strncpy() doesn't always null terminate and we want it to. - * (2) strncpy() null fills, which is bogus, esp. when copy 8byte - * strings into 8k blocks. - * (3) Instead of returning the pointer to the beginning of - * the destination string, we return a pointer to the - * terminating '\0' to allow us to "check" for truncation - * - * apr_cpystrn() follows the same call structure as strncpy(). - */ - -API_EXPORT(char *) apr_cpystrn(char *dst, const char *src, size_t dst_size) -{ - - char *d, *end; - - if (dst_size == 0) { - return (dst); - } - - d = dst; - end = dst + dst_size - 1; - - for (; d < end; ++d, ++src) { - if (!(*d = *src)) { - return (d); - } - } - - *d = '\0'; /* always null terminate */ - - return (d); -} diff --git a/lib/apr_execve.c b/lib/apr_execve.c deleted file mode 100644 index d584a8551..000000000 --- a/lib/apr_execve.c +++ /dev/null @@ -1,390 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1998-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ - -/* - * Portions of this code are under this license: - * - * Copyright (c) 1980, 1991 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. - */ -#ifndef WIN32 -#include "apr_config.h" -#endif -/*---------------------------------------------------------------*/ - -#ifdef NEED_HASHBANG_EMUL - -#undef execle -#undef execve - -static const char **hashbang(const char *filename, char **argv); - - -/* Historically, a list of arguments on the stack was often treated as - * being equivalent to an array (since they already were "contiguous" - * on the stack, and the arguments were pushed in the correct order). - * On today's processors, this is not necessarily equivalent, because - * often arguments are padded or passed partially in registers, - * or the stack direction is backwards. - * To be on the safe side, we copy the argument list to our own - * local argv[] array. The va_arg logic makes sure we do the right thing. - * XXX: malloc() is used because we expect to be overlaid soon. - */ -int apr_execle(const char *filename, const char *argv0, ...) -{ - va_list adummy; - char **envp; - char **argv; - int argc, ret; - - /* First pass: Count arguments on stack */ - va_start(adummy, argv0); - for (argc = 1; va_arg(adummy, char *) != NULL; ++argc) { - continue; - } - va_end(adummy); - - if ((argv = (char **) malloc((argc + 2) * sizeof(*argv))) == NULL) { - fprintf(stderr, "Ouch! Out of memory in apr_execle()!\n"); - return -1; - } - - /* Pass two --- copy the argument strings into the result space */ - va_start(adummy, argv0); - argv[0] = argv0; - for (argc = 1; (argv[argc] = va_arg(adummy, char *)) != NULL; ++argc) { - continue; - } - envp = va_arg(adummy, char **); - va_end(adummy); - - ret = apr_execve(filename, argv, envp); - free(argv); - - return ret; -} - -/* Count number of entries in vector "args", including the trailing NULL entry - */ -static int -count_args(const char **args) -{ - int i; - for (i = 0; args[i] != NULL; ++i) { - continue; - } - return i+1; -} - -/* Emulate the execve call, respecting a #!/interpreter line if present. - * On "real" unixes, the kernel does this. - * We have to fiddle with the argv array to make it work on platforms - * which don't support the "hashbang" interpreter line by default. - */ -int apr_execve(const char *filename, const char *argv[], - const char *envp[]) -{ - const char **script_argv; - extern char **environ; - - if (envp == NULL) { - envp = (const char **) environ; - } - - /* Try to execute the file directly first: */ - execve(filename, argv, envp); - - /* Still with us? Then something went seriously wrong. - * From the (linux) man page: - * EACCES The file is not a regular file. - * EACCES Execute permission is denied for the file. - * EACCES Search permission is denied on a component of the path prefix. - * EPERM The file system is mounted noexec. - * EPERM The file system is mounted nosuid and the file has an SUID - * or SGID bit set. - * E2BIG The argument list is too big. - * ENOEXEC The magic number in the file is incorrect. - * EFAULT filename points outside your accessible address space. - * ENAMETOOLONG filename is too long. - * ENOENT The file does not exist. - * ENOMEM Insufficient kernel memory was available. - * ENOTDIR A component of the path prefix is not a directory. - * ELOOP filename contains a circular reference (i.e., via a symbolic link) - */ - - if (errno == ENOEXEC) { - /* Probably a script. - * Have a look; if there's a "#!" header then try to emulate - * the feature found in all modern OS's: - * Interpret the line following the #! as a command line - * in shell style. - */ - if ((script_argv = hashbang(filename, argv)) != NULL) { - - /* new filename is the interpreter to call */ - filename = script_argv[0]; - - /* Restore argv[0] as on entry */ - if (argv[0] != NULL) { - script_argv[0] = argv[0]; - } - - execve(filename, script_argv, envp); - - free(script_argv); - } - /* - * Script doesn't start with a hashbang line! - * So, try to have the default shell execute it. - * For this, the size of argv must be increased by one - * entry: the shell's name. The remaining args are appended. - */ - else { - int i = count_args(argv) + 1; /* +1 for leading SHELL_PATH */ - - if ((script_argv = malloc(sizeof(*script_argv) * i)) == NULL) { - fprintf(stderr, "Ouch! Out of memory in apr_execve()!\n"); - return -1; - } - - script_argv[0] = SHELL_PATH; - - while (i > 0) { - script_argv[i] = argv[i-1]; - --i; - } - - execve(SHELL_PATH, script_argv, envp); - - free(script_argv); - } - } - return -1; -} - -/*---------------------------------------------------------------*/ - -/* - * From: peter@zeus.dialix.oz.au (Peter Wemm) - * (taken from tcsh) - * If exec() fails look first for a #! [word] [word] .... - * If it is, splice the header into the argument list and retry. - * Return value: the original argv array (sans argv[0]), with the - * script's argument list prepended. - * XXX: malloc() is used so that everything can be free()ed after a failure. - */ -#define HACKBUFSZ 1024 /* Max chars in #! vector */ -#define HACKVECSZ 128 /* Max words in #! vector */ -static const char **hashbang(const char *filename, char **argv) -{ - char lbuf[HACKBUFSZ]; - char *sargv[HACKVECSZ]; - const char **newargv; - char *p, *ws; - int fd; - int sargc = 0; - int i, j; -#ifdef WIN32 - int fw = 0; /* found at least one word */ - int first_word = 0; -#endif /* WIN32 */ - - if ((fd = open(filename, O_RDONLY)) == -1) { - return NULL; - } - - if (read(fd, (char *) lbuf, 2) != 2 - || lbuf[0] != '#' || lbuf[1] != '!' - || read(fd, (char *) lbuf, HACKBUFSZ) <= 0) { - close(fd); - return NULL; - } - - close(fd); - - ws = NULL; /* word started = 0 */ - - for (p = lbuf; p < &lbuf[HACKBUFSZ];) { - switch (*p) { - case ' ': - case '\t': -#ifdef NEW_CRLF - case '\r': -#endif /*NEW_CRLF */ - if (ws) { /* a blank after a word.. save it */ - *p = '\0'; -#ifndef WIN32 - if (sargc < HACKVECSZ - 1) { - sargv[sargc++] = ws; - } - ws = NULL; -#else /* WIN32 */ - if (sargc < HACKVECSZ - 1) { - sargv[sargc] = first_word ? NULL : hb_subst(ws); - if (sargv[sargc] == NULL) { - sargv[sargc] = ws; - } - sargc++; - } - ws = NULL; - fw = 1; - first_word = 1; -#endif /* WIN32 */ - } - p++; - continue; - - case '\0': /* Whoa!! what the hell happened */ - return NULL; - - case '\n': /* The end of the line. */ - if ( -#ifdef WIN32 - fw || -#endif /* WIN32 */ - ws) { /* terminate the last word */ - *p = '\0'; -#ifndef WIN32 - if (sargc < HACKVECSZ - 1) { - sargv[sargc++] = ws; - } -#else /* WIN32 */ - if (sargc < HACKVECSZ - 1) { /* deal with the 1-word case */ - sargv[sargc] = first_word ? NULL : hb_subst(ws); - if (sargv[sargc] == NULL) { - sargv[sargc] = ws; - } - sargc++; - } -#endif /* !WIN32 */ - sargv[sargc] = NULL; - } - /* Count number of entries in the old argv vector */ - for (i = 0; argv[i] != NULL; ++i) { - continue; - } - ++i; - - newargv = (char **) malloc((p - lbuf + 1) - + (i + sargc + 1) * sizeof(*newargv)); - if (newargv == NULL) { - fprintf(stderr, "Ouch! Out of memory in hashbang()!\n"); - return NULL; - } - ws = &((char *) newargv)[(i + sargc + 1) * sizeof(*newargv)]; - - /* Copy entries to allocated memory */ - for (j = 0; j < sargc; ++j) { - newargv[j] = strcpy(ws, sargv[j]); - ws += strlen(ws) + 1; /* skip trailing '\0' */ - } - newargv[sargc] = filename; - - /* Append the old array. The old argv[0] is skipped. */ - if (i > 1) { - memcpy(&newargv[sargc + 1], &argv[1], - (i - 1) * sizeof(*newargv)); - } - - newargv[sargc + i] = NULL; - - ws = NULL; - - return newargv; - - default: - if (!ws) { /* Start a new word? */ - ws = p; - } - p++; - break; - } - } - return NULL; -} -#else -extern void apr_execve_is_not_here(void); -void apr_execve_is_not_here(void) {} -#endif /* NEED_HASHBANG_EMUL */ diff --git a/lib/apr_fnmatch.c b/lib/apr_fnmatch.c deleted file mode 100644 index c06b08142..000000000 --- a/lib/apr_fnmatch.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; -#endif /* LIBC_SCCS and not lint */ - -/* - * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. - * Compares a filename or pathname to a pattern. - */ -#ifndef WIN32 -#include "apr_config.h" -#endif -#include "apr_fnmatch.h" -#include "apr_lib.h" -#include <string.h> - -#define EOS '\0' - -static const char *rangematch(const char *, int, int); - -API_EXPORT(int) apr_fnmatch(const char *pattern, const char *string, int flags) -{ - const char *stringstart; - char c, test; - - for (stringstart = string;;) { - switch (c = *pattern++) { - case EOS: - return (*string == EOS ? 0 : FNM_NOMATCH); - case '?': - if (*string == EOS) { - return (FNM_NOMATCH); - } - if (*string == '/' && (flags & FNM_PATHNAME)) { - return (FNM_NOMATCH); - } - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) { - return (FNM_NOMATCH); - } - ++string; - break; - case '*': - c = *pattern; - /* Collapse multiple stars. */ - while (c == '*') { - c = *++pattern; - } - - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) { - return (FNM_NOMATCH); - } - - /* Optimize for pattern with * at end or before /. */ - if (c == EOS) { - if (flags & FNM_PATHNAME) { - return (strchr(string, '/') == NULL ? 0 : FNM_NOMATCH); - } - else { - return (0); - } - } - else if (c == '/' && flags & FNM_PATHNAME) { - if ((string = strchr(string, '/')) == NULL) { - return (FNM_NOMATCH); - } - break; - } - - /* General case, use recursion. */ - while ((test = *string) != EOS) { - if (!apr_fnmatch(pattern, string, flags & ~FNM_PERIOD)) { - return (0); - } - if (test == '/' && flags & FNM_PATHNAME) { - break; - } - ++string; - } - return (FNM_NOMATCH); - case '[': - if (*string == EOS) { - return (FNM_NOMATCH); - } - if (*string == '/' && flags & FNM_PATHNAME) { - return (FNM_NOMATCH); - } - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) { - return (FNM_NOMATCH); - } - if ((pattern = rangematch(pattern, *string, flags)) == NULL) { - return (FNM_NOMATCH); - } - ++string; - break; - case '\\': - if (!(flags & FNM_NOESCAPE)) { - if ((c = *pattern++) == EOS) { - c = '\\'; - --pattern; - } - } - /* FALLTHROUGH */ - default: - if (flags & FNM_CASE_BLIND) { - if (apr_tolower(c) != apr_tolower(*string)) { - return (FNM_NOMATCH); - } - } - else if (c != *string) { - return (FNM_NOMATCH); - } - string++; - break; - } - /* NOTREACHED */ - } -} - -static const char *rangematch(const char *pattern, int test, int flags) -{ - int negate, ok; - char c, c2; - - /* - * A bracket expression starting with an unquoted circumflex - * character produces unspecified results (IEEE 1003.2-1992, - * 3.13.2). This implementation treats it like '!', for - * consistency with the regular expression syntax. - * J.T. Conklin (conklin@ngai.kaleida.com) - */ - if ((negate = (*pattern == '!' || *pattern == '^'))) { - ++pattern; - } - - for (ok = 0; (c = *pattern++) != ']';) { - if (c == '\\' && !(flags & FNM_NOESCAPE)) { - c = *pattern++; - } - if (c == EOS) { - return (NULL); - } - if (*pattern == '-' && (c2 = *(pattern + 1)) != EOS && c2 != ']') { - pattern += 2; - if (c2 == '\\' && !(flags & FNM_NOESCAPE)) { - c2 = *pattern++; - } - if (c2 == EOS) { - return (NULL); - } - if ((c <= test && test <= c2) - || ((flags & FNM_CASE_BLIND) - && ((apr_tolower(c) <= apr_tolower(test)) - && (apr_tolower(test) <= apr_tolower(c2))))) { - ok = 1; - } - } - else if ((c == test) - || ((flags & FNM_CASE_BLIND) - && (apr_tolower(c) == apr_tolower(test)))) { - ok = 1; - } - } - return (ok == negate ? NULL : pattern); -} - - -/* This function is an Apache addition */ -/* return non-zero if pattern has any glob chars in it */ -API_EXPORT(int) apr_is_fnmatch(const char *pattern) -{ - int nesting; - - nesting = 0; - while (*pattern) { - switch (*pattern) { - case '?': - case '*': - return 1; - - case '\\': - if (*pattern++ == '\0') { - return 0; - } - break; - - case '[': /* '[' is only a glob if it has a matching ']' */ - ++nesting; - break; - - case ']': - if (nesting) { - return 1; - } - break; - } - ++pattern; - } - return 0; -} diff --git a/lib/apr_getpass.c b/lib/apr_getpass.c deleted file mode 100644 index 036c8c1ee..000000000 --- a/lib/apr_getpass.c +++ /dev/null @@ -1,173 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ -/* - * ap_getpass.c: abstraction to provide for obtaining a password from the - * command line in whatever way the OS supports. In the best case, it's a - * wrapper for the system library's getpass() routine; otherwise, we - * use one we define ourselves. - */ -#ifndef WIN32 -#include "apr_config.h" -#else -#include "apr_win.h" -#endif -#include "apr_errno.h" -#include <sys/types.h> -#include <errno.h> -#include "apr_lib.h" - -#ifdef WIN32 -#include <conio.h> -#endif - -#ifndef CHARSET_EBCDIC -#define LF 10 -#define CR 13 -#else /* CHARSET_EBCDIC */ -#define LF '\n' -#define CR '\r' -#endif /* CHARSET_EBCDIC */ - -#define MAX_STRING_LEN 256 - -#define ERR_OVERFLOW 5 - -#ifdef MPE -/* - * MPE lacks getpass() and a way to suppress stdin echo. So for now, just - * issue the prompt and read the results with echo. (Ugh). - */ - -static char *getpass(const char *prompt) -{ - static char password[MAX_STRING_LEN]; - - fputs(prompt, stderr); - gets((char *) &password); - - if (strlen((char *) &password) > (MAX_STRING_LEN - 1)) { - password[MAX_STRING_LEN - 1] = '\0'; - } - - return (char *) &password; -} - -#endif - -#ifdef WIN32 -/* - * Windows lacks getpass(). So we'll re-implement it here. - */ - -static char *getpass(const char *prompt) -{ - static char password[MAX_STRING_LEN]; - int n = 0; - - fputs(prompt, stderr); - - while ((password[n] = _getch()) != '\r') { - if (password[n] >= ' ' && password[n] <= '~') { - n++; - printf("*"); - } - else { - printf("\n"); - fputs(prompt, stderr); - n = 0; - } - } - - password[n] = '\0'; - printf("\n"); - - if (n > (MAX_STRING_LEN - 1)) { - password[MAX_STRING_LEN - 1] = '\0'; - } - - return (char *) &password; -} -#endif - -/* - * Use the OS getpass() routine (or our own) to obtain a password from - * the input stream. - * - * Exit values: - * 0: Success - * 5: Partial success; entered text truncated to the size of the - * destination buffer - * - * Restrictions: Truncation also occurs according to the host system's - * getpass() semantics, or at position 255 if our own version is used, - * but the caller is *not* made aware of it. - */ - -API_EXPORT(ap_status_t) ap_getpass(const char *prompt, char *pwbuf, size_t *bufsiz) -{ - char *pw_got; - int result = 0; - - pw_got = getpass(prompt); - if (strlen(pw_got) > (*bufsiz - 1)) { - *bufsiz = ERR_OVERFLOW; - return APR_ENAMETOOLONG; - } - apr_cpystrn(pwbuf, pw_got, *bufsiz); - *bufsiz = result; - return APR_SUCCESS; -} diff --git a/lib/apr_md5.c b/lib/apr_md5.c deleted file mode 100644 index e41cfde2a..000000000 --- a/lib/apr_md5.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * This is work is derived from material Copyright RSA Data Security, Inc. - * - * The RSA copyright statement and Licence for that original material is - * included below. This is followed by the Apache copyright statement and - * licence for the modifications made to that material. - */ - -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - rights reserved. - - License to copy and use this software is granted provided that it - is identified as the "RSA Data Security, Inc. MD5 Message-Digest - Algorithm" in all material mentioning or referencing this software - or this function. - - License is also granted to make and use derivative works provided - that such works are identified as "derived from the RSA Data - Security, Inc. MD5 Message-Digest Algorithm" in all material - mentioning or referencing the derived work. - - RSA Data Security, Inc. makes no representations concerning either - the merchantability of this software or the suitability of this - software for any particular purpose. It is provided "as is" - without express or implied warranty of any kind. - - These notices must be retained in any copies of any part of this - documentation and/or software. - */ - -/* ==================================================================== - * Copyright (c) 1996-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ - -/* - * The apr_MD5Encode() routine uses much code obtained from the FreeBSD 3.0 - * MD5 crypt() function, which is licenced as follows: - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - */ -#ifndef WIN32 -#include "apr_config.h" -#endif -#include "apr_md5.h" -#include "apr_lib.h" - -#ifdef HAVE_CRYPT_H -#include <crypt.h> -#endif - -/* Constants for MD5Transform routine. - */ - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform(UINT4 state[4], const unsigned char block[64]); -static void Encode(unsigned char *output, const UINT4 *input, - unsigned int len); -static void Decode(UINT4 *output, const unsigned char *input, - unsigned int len); - -static unsigned char PADDING[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. - Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -API_EXPORT(void) apr_MD5Init(APR_MD5_CTX * context) -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. */ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ -API_EXPORT(void) apr_MD5Update(APR_MD5_CTX * context, const unsigned char *input, - unsigned int inputLen) -{ - unsigned int i, idx, partLen; - - /* Compute number of bytes mod 64 */ - idx = (unsigned int) ((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((UINT4) inputLen << 3)) < ((UINT4) inputLen << 3)) - context->count[1]++; - context->count[1] += (UINT4) inputLen >> 29; - - partLen = 64 - idx; - - /* Transform as many times as possible. */ -#ifndef CHARSET_EBCDIC - if (inputLen >= partLen) { - memcpy(&context->buffer[idx], input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform(context->state, &input[i]); - - idx = 0; - } - else - i = 0; - - /* Buffer remaining input */ - memcpy(&context->buffer[idx], &input[i], inputLen - i); -#else /*CHARSET_EBCDIC*/ - if (inputLen >= partLen) { - ebcdic2ascii_strictly(&context->buffer[idx], input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) { - unsigned char inp_tmp[64]; - ebcdic2ascii_strictly(inp_tmp, &input[i], 64); - MD5Transform(context->state, inp_tmp); - } - - idx = 0; - } - else - i = 0; - - /* Buffer remaining input */ - ebcdic2ascii_strictly(&context->buffer[idx], &input[i], inputLen - i); -#endif /*CHARSET_EBCDIC*/ -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ -API_EXPORT(void) apr_MD5Final(unsigned char digest[16], APR_MD5_CTX * context) -{ - unsigned char bits[8]; - unsigned int idx, padLen; - - - /* Save number of bits */ - Encode(bits, context->count, 8); - -#ifdef CHARSET_EBCDIC - /* XXX: @@@: In order to make this no more complex than necessary, - * this kludge converts the bits[] array using the ascii-to-ebcdic - * table, because the following apr_MD5Update() re-translates - * its input (ebcdic-to-ascii). - * Otherwise, we would have to pass a "conversion" flag to apr_MD5Update() - */ - ascii2ebcdic(bits,bits,8); - - /* Since everything is converted to ascii within apr_MD5Update(), - * the initial 0x80 (PADDING[0]) must be stored as 0x20 - */ - PADDING[0] = os_toebcdic[0x80]; -#endif /*CHARSET_EBCDIC*/ - - /* Pad out to 56 mod 64. */ - idx = (unsigned int) ((context->count[0] >> 3) & 0x3f); - padLen = (idx < 56) ? (56 - idx) : (120 - idx); - apr_MD5Update(context, PADDING, padLen); - - /* Append length (before padding) */ - apr_MD5Update(context, bits, 8); - - /* Store state in digest */ - Encode(digest, context->state, 16); - - /* Zeroize sensitive information. */ - memset(context, 0, sizeof(*context)); -} - -/* MD5 basic transformation. Transforms state based on block. */ -static void MD5Transform(UINT4 state[4], const unsigned char block[64]) -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode(x, block, 64); - - /* Round 1 */ - FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ - FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ - FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ - FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ - FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ - FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ - FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ - FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ - FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ - FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ - FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ - GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ - GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ - GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ - GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ - GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ - GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ - GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ - GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ - GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ - GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ - HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ - HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ - HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ - HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ - HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ - HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ - HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ - HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ - HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ - II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ - II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ - II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ - II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ - II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ - II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ - II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ - II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ - II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. */ - memset(x, 0, sizeof(x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode(unsigned char *output, const UINT4 *input, unsigned int len) -{ - unsigned int i, j; - UINT4 k; - - for (i = 0, j = 0; j < len; i++, j += 4) { - k = input[i]; - output[j] = (unsigned char) (k & 0xff); - output[j + 1] = (unsigned char) ((k >> 8) & 0xff); - output[j + 2] = (unsigned char) ((k >> 16) & 0xff); - output[j + 3] = (unsigned char) ((k >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - * a multiple of 4. - */ -static void Decode(UINT4 *output, const unsigned char *input, unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) | - (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24); -} - -/* - * Define the Magic String prefix that identifies a password as being - * hashed using our algorithm. - */ -static const char *apr1_id = "$apr1$"; - -/* - * The following MD5 password encryption code was largely borrowed from - * the FreeBSD 3.0 /usr/src/lib/libcrypt/crypt.c file, which is - * licenced as stated at the top of this file. - */ - -static void to64(char *s, unsigned long v, int n) -{ - static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - while (--n >= 0) { - *s++ = itoa64[v&0x3f]; - v >>= 6; - } -} - -API_EXPORT(void) apr_MD5Encode(const char *pw, const char *salt, - char *result, size_t nbytes) -{ - /* - * Minimum size is 8 bytes for salt, plus 1 for the trailing NUL, - * plus 4 for the '$' separators, plus the password hash itself. - * Let's leave a goodly amount of leeway. - */ - - char passwd[120], *p; - const char *sp, *ep; - unsigned char final[16]; - int sl, pl, i; - APR_MD5_CTX ctx, ctx1; - unsigned long l; - - /* - * Refine the salt first. It's possible we were given an already-hashed - * string as the salt argument, so extract the actual salt value from it - * if so. Otherwise just use the string up to the first '$' as the salt. - */ - sp = salt; - - /* - * If it starts with the magic string, then skip that. - */ - if (!strncmp(sp, apr1_id, strlen(apr1_id))) { - sp += strlen(apr1_id); - } - - /* - * It stops at the first '$' or 8 chars, whichever comes first - */ - for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) { - continue; - } - - /* - * Get the length of the true salt - */ - sl = ep - sp; - - /* - * 'Time to make the doughnuts..' - */ - apr_MD5Init(&ctx); - - /* - * The password first, since that is what is most unknown - */ - apr_MD5Update(&ctx, pw, strlen(pw)); - - /* - * Then our magic string - */ - apr_MD5Update(&ctx, apr1_id, strlen(apr1_id)); - - /* - * Then the raw salt - */ - apr_MD5Update(&ctx, sp, sl); - - /* - * Then just as many characters of the MD5(pw, salt, pw) - */ - apr_MD5Init(&ctx1); - apr_MD5Update(&ctx1, pw, strlen(pw)); - apr_MD5Update(&ctx1, sp, sl); - apr_MD5Update(&ctx1, pw, strlen(pw)); - apr_MD5Final(final, &ctx1); - for(pl = strlen(pw); pl > 0; pl -= 16) { - apr_MD5Update(&ctx, final, (pl > 16) ? 16 : pl); - } - - /* - * Don't leave anything around in vm they could use. - */ - memset(final, 0, sizeof(final)); - - /* - * Then something really weird... - */ - for (i = strlen(pw); i != 0; i >>= 1) { - if (i & 1) { - apr_MD5Update(&ctx, final, 1); - } - else { - apr_MD5Update(&ctx, pw, 1); - } - } - - /* - * Now make the output string. We know our limitations, so we - * can use the string routines without bounds checking. - */ - strcpy(passwd, apr1_id); - strncat(passwd, sp, sl); - strcat(passwd, "$"); - - apr_MD5Final(final, &ctx); - - /* - * And now, just to make sure things don't run too fast.. - * On a 60 Mhz Pentium this takes 34 msec, so you would - * need 30 seconds to build a 1000 entry dictionary... - */ - for (i = 0; i < 1000; i++) { - apr_MD5Init(&ctx1); - if (i & 1) { - apr_MD5Update(&ctx1, pw, strlen(pw)); - } - else { - apr_MD5Update(&ctx1, final, 16); - } - if (i % 3) { - apr_MD5Update(&ctx1, sp, sl); - } - - if (i % 7) { - apr_MD5Update(&ctx1, pw, strlen(pw)); - } - - if (i & 1) { - apr_MD5Update(&ctx1, final, 16); - } - else { - apr_MD5Update(&ctx1, pw, strlen(pw)); - } - apr_MD5Final(final,&ctx1); - } - - p = passwd + strlen(passwd); - - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4; - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4; - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4; - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4; - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4; - l = final[11] ; to64(p, l, 2); p += 2; - *p = '\0'; - - /* - * Don't leave anything around in vm they could use. - */ - memset(final, 0, sizeof(final)); - - apr_cpystrn(result, passwd, nbytes - 1); -} - -/* - * Validate a plaintext password against a smashed one. Use either - * crypt() (if available) or apr_MD5Encode(), depending upon the format - * of the smashed input password. Return NULL if they match, or - * an explanatory text string if they don't. - */ - -API_EXPORT(char *) apr_validate_password(const char *passwd, const char *hash) -{ - char sample[120]; -#ifndef WIN32 - char *crypt_pw; -#endif - if (!strncmp(hash, apr1_id, strlen(apr1_id))) { - /* - * The hash was created using our custom algorithm. - */ - apr_MD5Encode(passwd, hash, sample, sizeof(sample)); - } - else { - /* - * It's not our algorithm, so feed it to crypt() if possible. - */ -#ifdef WIN32 - apr_cpystrn(sample, passwd, sizeof(sample) - 1); -#else - crypt_pw = crypt(passwd, hash); - apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1); -#endif - } - return (strcmp(sample, hash) == 0) ? NULL : "password mismatch"; -} diff --git a/lib/apr_pools.c b/lib/apr_pools.c deleted file mode 100644 index afe3b8d49..000000000 --- a/lib/apr_pools.c +++ /dev/null @@ -1,2113 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ - -/* - * Resource allocation code... the code here is responsible for making - * sure that nothing leaks. - * - * rst --- 4/95 --- 6/95 - */ - -#ifndef WIN32 -#include "apr_config.h" -#else -#include "apr_win.h" -#endif - -#include "apr_general.h" -#include "apr_pools.h" -#include "apr_lib.h" -#include "misc.h" -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif - -/* - * Debugging support: Define this to enable code which helps detect re-use - * of freed memory and other such nonsense. - * - * The theory is simple. The FILL_BYTE (0xa5) is written over all malloc'd - * memory as we receive it, and is written over everything that we free up - * during a clear_pool. We check that blocks on the free list always - * have the FILL_BYTE in them, and we check during palloc() that the bytes - * still have FILL_BYTE in them. If you ever see garbage URLs or whatnot - * containing lots of 0xa5s then you know something used data that's been - * freed or uninitialized. - */ -/* #define ALLOC_DEBUG */ - -/* - * Debugging support: If defined all allocations will be done with - * malloc and free()d appropriately at the end. This is intended to be - * used with something like Electric Fence or Purify to help detect - * memory problems. Note that if you're using efence then you should also - * add in ALLOC_DEBUG. But don't add in ALLOC_DEBUG if you're using Purify - * because ALLOC_DEBUG would hide all the uninitialized read errors that - * Purify can diagnose. - */ -/* #define ALLOC_USE_MALLOC */ - -/* - * Pool debugging support: This is intended to detect cases where the - * wrong pool is used when assigning data to an object in another pool. - * In particular, it causes the table_{set,add,merge}n routines to check - * that their arguments are safe for the table they're being placed in. - * It currently only works with the unix multiprocess model, but could - * be extended to others. - */ -/* #define POOL_DEBUG */ - -/* - * Provide diagnostic information about make_table() calls which are - * possibly too small. This requires a recent gcc which supports - * __builtin_return_address(). The error_log output will be a - * message such as: - * table_push: table created by 0x804d874 hit limit of 10 - * Use "l *0x804d874" to find the source that corresponds to. It - * indicates that a table allocated by a call at that address has - * possibly too small an initial table size guess. - */ -/* #define MAKE_TABLE_PROFILE */ - -/* - * Provide some statistics on the cost of allocations. It requires a - * bit of an understanding of how alloc.c works. - */ -/* #define ALLOC_STATS */ - -#ifdef POOL_DEBUG -#ifdef ALLOC_USE_MALLOC -#error "sorry, no support for ALLOC_USE_MALLOC and POOL_DEBUG at the same time" -#endif /* ALLOC_USE_MALLOC */ - -#ifdef MULTITHREAD -# error "sorry, no support for MULTITHREAD and POOL_DEBUG at the same time" -#endif /* MULTITHREAD */ - -#endif /* POOL_DEBUG */ - -#ifdef ALLOC_USE_MALLOC -#undef BLOCK_MINFREE -#undef BLOCK_MINALLOC -#define BLOCK_MINFREE 0 -#define BLOCK_MINALLOC 0 -#endif /* ALLOC_USE_MALLOC */ - -/***************************************************************** - * - * Managing free storage blocks... - */ - -union align { - /* - * Types which are likely to have the longest RELEVANT alignment - * restrictions... - */ - - char *cp; - void (*f) (void); - long l; - FILE *fp; - double d; -}; - -#define CLICK_SZ (sizeof(union align)) - -union block_hdr { - union align a; - - /* Actual header... */ - - struct { - char *endp; - union block_hdr *next; - char *first_avail; -#ifdef POOL_DEBUG - union block_hdr *global_next; - ap_pool_t *owning_pool; -#endif /* POOL_DEBUG */ - } h; -}; - -/* - * Static cells for managing our internal synchronisation. - */ -static union block_hdr *block_freelist = NULL; -static ap_mutex_t *alloc_mutex = NULL; -static ap_mutex_t *spawn_mutex = NULL; - -#ifdef POOL_DEBUG -static char *known_stack_point; -static int stack_direction; -static union block_hdr *global_block_list; -#define FREE_POOL ((ap_pool_t *)(-1)) -#endif /* POOL_DEBUG */ - -#ifdef ALLOC_STATS -static unsigned long long num_free_blocks_calls; -static unsigned long long num_blocks_freed; -static unsigned max_blocks_in_one_free; -static unsigned num_malloc_calls; -static unsigned num_malloc_bytes; -#endif /* ALLOC_STATS */ - -#ifdef ALLOC_DEBUG -#define FILL_BYTE ((char)(0xa5)) -#define debug_fill(ptr,size) ((void)memset((ptr), FILL_BYTE, (size))) - -static APR_INLINE void debug_verify_filled(const char *ptr, const char *endp, - const char *error_msg) -{ - for ( ; ptr < endp; ++ptr) { - if (*ptr != FILL_BYTE) { - fputs(error_msg, stderr); - abort(); - exit(1); - } - } -} - -#else /* ALLOC_DEBUG */ -#define debug_fill(a,b) -#define debug_verify_filled(a,b,c) -#endif /* ALLOC_DEBUG */ - -/* - * Get a completely new block from the system pool. Note that we rely on - * malloc() to provide aligned memory. - */ - -static union block_hdr *malloc_block(int size) -{ - union block_hdr *blok; - -#ifdef ALLOC_DEBUG - /* make some room at the end which we'll fill and expect to be - * always filled - */ - size += CLICK_SZ; -#endif /* ALLOC_DEBUG */ - -#ifdef ALLOC_STATS - ++num_malloc_calls; - num_malloc_bytes += size + sizeof(union block_hdr); -#endif /* ALLOC_STATS */ - - blok = (union block_hdr *) malloc(size + sizeof(union block_hdr)); - if (blok == NULL) { - fprintf(stderr, "Ouch! malloc failed in malloc_block()\n"); - exit(1); - } - debug_fill(blok, size + sizeof(union block_hdr)); - blok->h.next = NULL; - blok->h.first_avail = (char *) (blok + 1); - blok->h.endp = size + blok->h.first_avail; - -#ifdef ALLOC_DEBUG - blok->h.endp -= CLICK_SZ; -#endif /* ALLOC_DEBUG */ - -#ifdef POOL_DEBUG - blok->h.global_next = global_block_list; - global_block_list = blok; - blok->h.owning_pool = NULL; -#endif /* POOL_DEBUG */ - - return blok; -} - - - -#if defined(ALLOC_DEBUG) && !defined(ALLOC_USE_MALLOC) -static void chk_on_blk_list(union block_hdr *blok, union block_hdr *free_blk) -{ - debug_verify_filled(blok->h.endp, blok->h.endp + CLICK_SZ, - "Ouch! Someone trounced the padding " - "at the end of a block!\n"); - while (free_blk) { - if (free_blk == blok) { - fprintf(stderr, "Ouch! Freeing free block\n"); - abort(); - exit(1); - } - free_blk = free_blk->h.next; - } -} -#else /* defined(ALLOC_DEBUG) && !defined(ALLOC_USE_MALLOC) */ -#define chk_on_blk_list(_x, _y) -#endif /* defined(ALLOC_DEBUG) && !defined(ALLOC_USE_MALLOC) */ - -/* Free a chain of blocks --- must be called with alarms blocked. */ - -static void free_blocks(union block_hdr *blok) -{ -#ifdef ALLOC_USE_MALLOC - union block_hdr *next; - - for ( ; blok; blok = next) { - next = blok->h.next; - free(blok); - } -#else /* ALLOC_USE_MALLOC */ - -#ifdef ALLOC_STATS - unsigned num_blocks; -#endif /* ALLOC_STATS */ - - /* - * First, put new blocks at the head of the free list --- - * we'll eventually bash the 'next' pointer of the last block - * in the chain to point to the free blocks we already had. - */ - - union block_hdr *old_free_list; - - if (blok == NULL) { - return; /* Sanity check --- freeing empty pool? */ - } - - (void) ap_acquire_mutex(alloc_mutex); - old_free_list = block_freelist; - block_freelist = blok; - - /* - * Next, adjust first_avail pointers of each block --- have to do it - * sooner or later, and it simplifies the search in new_block to do it - * now. - */ - -#ifdef ALLOC_STATS - num_blocks = 1; -#endif /* ALLOC_STATS */ - - while (blok->h.next != NULL) { - -#ifdef ALLOC_STATS - ++num_blocks; -#endif /* ALLOC_STATS */ - - chk_on_blk_list(blok, old_free_list); - blok->h.first_avail = (char *) (blok + 1); - debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail); -#ifdef POOL_DEBUG - blok->h.owning_pool = FREE_POOL; -#endif /* POOL_DEBUG */ - blok = blok->h.next; - } - - chk_on_blk_list(blok, old_free_list); - blok->h.first_avail = (char *) (blok + 1); - debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail); -#ifdef POOL_DEBUG - blok->h.owning_pool = FREE_POOL; -#endif /* POOL_DEBUG */ - - /* Finally, reset next pointer to get the old free blocks back */ - - blok->h.next = old_free_list; - -#ifdef ALLOC_STATS - if (num_blocks > max_blocks_in_one_free) { - max_blocks_in_one_free = num_blocks; - } - ++num_free_blocks_calls; - num_blocks_freed += num_blocks; -#endif /* ALLOC_STATS */ - - (void) ap_release_mutex(alloc_mutex); -#endif /* ALLOC_USE_MALLOC */ -} - -/* - * Get a new block, from our own free list if possible, from the system - * if necessary. Must be called with alarms blocked. - */ - -static union block_hdr *new_block(int min_size) -{ - union block_hdr **lastptr = &block_freelist; - union block_hdr *blok = block_freelist; - - /* First, see if we have anything of the required size - * on the free list... - */ - - while (blok != NULL) { - if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) { - *lastptr = blok->h.next; - blok->h.next = NULL; - debug_verify_filled(blok->h.first_avail, blok->h.endp, - "Ouch! Someone trounced a block " - "on the free list!\n"); - return blok; - } - else { - lastptr = &blok->h.next; - blok = blok->h.next; - } - } - - /* Nope. */ - - min_size += BLOCK_MINFREE; - blok = malloc_block((min_size > BLOCK_MINALLOC) - ? min_size : BLOCK_MINALLOC); - return blok; -} - - -/* Accounting */ - -static long bytes_in_block_list(union block_hdr *blok) -{ - long size = 0; - - while (blok) { - size += blok->h.endp - (char *) (blok + 1); - blok = blok->h.next; - } - - return size; -} - - -/***************************************************************** - * - * Pool internals and management... - * NB that subprocesses are not handled by the generic cleanup code, - * basically because we don't want cleanups for multiple subprocesses - * to result in multiple three-second pauses. - */ - -struct process_chain; -struct cleanup; - -static void run_cleanups(struct cleanup *c); -static void free_proc_chain(struct process_chain *p); - -static ap_pool_t *permanent_pool; - -/* Each pool structure is allocated in the start of its own first block, - * so we need to know how many bytes that is (once properly aligned...). - * This also means that when a pool's sub-pool is destroyed, the storage - * associated with it is *completely* gone, so we have to make sure it - * gets taken off the parent's sub-pool list... - */ - -#define POOL_HDR_CLICKS (1 + ((sizeof(struct ap_pool_t) - 1) / CLICK_SZ)) -#define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ) - -API_EXPORT(ap_pool_t *) ap_make_sub_pool(ap_pool_t *p) -{ - union block_hdr *blok; - ap_pool_t *new_pool; - - ap_block_alarms(); - - (void) ap_acquire_mutex(alloc_mutex); - - blok = new_block(POOL_HDR_BYTES); - new_pool = (ap_pool_t *) blok->h.first_avail; - blok->h.first_avail += POOL_HDR_BYTES; -#ifdef POOL_DEBUG - blok->h.owning_pool = new_pool; -#endif - - memset((char *) new_pool, '\0', sizeof(struct ap_pool_t)); - new_pool->free_first_avail = blok->h.first_avail; - new_pool->first = new_pool->last = blok; - - if (p) { - new_pool->parent = p; - new_pool->sub_next = p->sub_pools; - if (new_pool->sub_next) { - new_pool->sub_next->sub_prev = new_pool; - } - p->sub_pools = new_pool; - } - - (void) ap_release_mutex(alloc_mutex); - ap_unblock_alarms(); - - return new_pool; -} - -#ifdef POOL_DEBUG -static void stack_var_init(char *s) -{ - char t; - - if (s < &t) { - stack_direction = 1; /* stack grows up */ - } - else { - stack_direction = -1; /* stack grows down */ - } -} -#endif - -#ifdef ALLOC_STATS -static void dump_stats(void) -{ - fprintf(stderr, - "alloc_stats: [%d] #free_blocks %llu #blocks %llu max " - "%u #malloc %u #bytes %u\n", - (int) getpid(), - num_free_blocks_calls, - num_blocks_freed, - max_blocks_in_one_free, - num_malloc_calls, - num_malloc_bytes); -} -#endif - -ap_pool_t *ap_init_alloc(void) -{ -#ifdef POOL_DEBUG - char s; - - known_stack_point = &s; - stack_var_init(&s); -#endif - alloc_mutex = ap_create_mutex(NULL); - spawn_mutex = ap_create_mutex(NULL); - permanent_pool = ap_make_sub_pool(NULL); -#ifdef ALLOC_STATS - atexit(dump_stats); -#endif - - return permanent_pool; -} - -API_EXPORT(void) ap_clear_pool(struct context_t *a) -{ - ap_block_alarms(); - - (void) ap_acquire_mutex(alloc_mutex); - while (a->pool->sub_pools) { - ap_destroy_pool(a); - } - (void) ap_release_mutex(alloc_mutex); - /* - * Don't hold the mutex during cleanups. - */ - run_cleanups(a->pool->cleanups); - a->pool->cleanups = NULL; - free_proc_chain(a->pool->subprocesses); - a->pool->subprocesses = NULL; - free_blocks(a->pool->first->h.next); - a->pool->first->h.next = NULL; - - a->pool->last = a->pool->first; - a->pool->first->h.first_avail = a->pool->free_first_avail; - debug_fill(a->pool->first->h.first_avail, - a->pool->first->h.endp - a->pool->first->h.first_avail); - -#ifdef ALLOC_USE_MALLOC - { - void *c, *n; - - for (c = a->pool->allocation_list; c; c = n) { - n = *(void **)c; - free(c); - } - a->pool->allocation_list = NULL; - } -#endif - - ap_unblock_alarms(); -} - -API_EXPORT(void) ap_destroy_pool(struct context_t *a) -{ - ap_block_alarms(); - ap_clear_pool(a); - - (void) ap_acquire_mutex(alloc_mutex); - if (a->pool->parent) { - if (a->pool->parent->sub_pools == a->pool) { - a->pool->parent->sub_pools = a->pool->sub_next; - } - if (a->pool->sub_prev) { - a->pool->sub_prev->sub_next = a->pool->sub_next; - } - if (a->pool->sub_next) { - a->pool->sub_next->sub_prev = a->pool->sub_prev; - } - } - (void) ap_release_mutex(alloc_mutex); - - free_blocks(a->pool->first); - ap_unblock_alarms(); -} - -API_EXPORT(long) ap_bytes_in_pool(ap_pool_t *p) -{ - return bytes_in_block_list(p->first); -} -API_EXPORT(long) ap_bytes_in_free_blocks(void) -{ - return bytes_in_block_list(block_freelist); -} - -/***************************************************************** - * POOL_DEBUG support - */ -#ifdef POOL_DEBUG - -/* the unix linker defines this symbol as the last byte + 1 of - * the executable... so it includes TEXT, BSS, and DATA - */ -extern char _end; - -/* is ptr in the range [lo,hi) */ -#define is_ptr_in_range(ptr, lo, hi) \ - (((unsigned long)(ptr) - (unsigned long)(lo)) \ - < (unsigned long)(hi) - (unsigned long)(lo)) - -/* Find the pool that ts belongs to, return NULL if it doesn't - * belong to any pool. - */ -API_EXPORT(ap_pool_t *) ap_find_pool(const void *ts) -{ - const char *s = ts; - union block_hdr **pb; - union block_hdr *b; - - /* short-circuit stuff which is in TEXT, BSS, or DATA */ - if (is_ptr_in_range(s, 0, &_end)) { - return NULL; - } - /* consider stuff on the stack to also be in the NULL pool... - * XXX: there's cases where we don't want to assume this - */ - if ((stack_direction == -1 && is_ptr_in_range(s, &ts, known_stack_point)) - || (stack_direction == 1 - && is_ptr_in_range(s, known_stack_point, &ts))) { - abort(); - return NULL; - } - ap_block_alarms(); - /* search the global_block_list */ - for (pb = &global_block_list; *pb; pb = &b->h.global_next) { - b = *pb; - if (is_ptr_in_range(s, b, b->h.endp)) { - if (b->h.owning_pool == FREE_POOL) { - fprintf(stderr, - "Ouch! find_pool() called on pointer " - "in a free block\n"); - abort(); - exit(1); - } - if (b != global_block_list) { - /* - * promote b to front of list, this is a hack to speed - * up the lookup - */ - *pb = b->h.global_next; - b->h.global_next = global_block_list; - global_block_list = b; - } - ap_unblock_alarms(); - return b->h.owning_pool; - } - } - ap_unblock_alarms(); - return NULL; -} - -/* return TRUE iff a is an ancestor of b - * NULL is considered an ancestor of all pools - */ -API_EXPORT(int) ap_pool_is_ancestor(ap_pool_t *a, ap_pool_t *b) -{ - if (a == NULL) { - return 1; - } - while (a->joined) { - a = a->joined; - } - while (b) { - if (a == b) { - return 1; - } - b = b->parent; - } - return 0; -} - -/* - * All blocks belonging to sub will be changed to point to p - * instead. This is a guarantee by the caller that sub will not - * be destroyed before p is. - */ -API_EXPORT(void) ap_pool_join(ap_pool_t *p, ap_pool_t *sub) -{ - union block_hdr *b; - - /* We could handle more general cases... but this is it for now. */ - if (sub->parent != p) { - fprintf(stderr, "pool_join: p is not parent of sub\n"); - abort(); - } - ap_block_alarms(); - while (p->joined) { - p = p->joined; - } - sub->joined = p; - for (b = global_block_list; b; b = b->h.global_next) { - if (b->h.owning_pool == sub) { - b->h.owning_pool = p; - } - } - ap_unblock_alarms(); -} -#endif - -/***************************************************************** - * - * Allocating stuff... - */ - - -API_EXPORT(void *) ap_palloc(struct context_t *c, int reqsize) -{ -#ifdef ALLOC_USE_MALLOC - ap_pool_t *a = c->pool; - int size = reqsize + CLICK_SZ; - void *ptr; - - ap_block_alarms(); - ptr = malloc(size); - if (ptr == NULL) { - fputs("Ouch! Out of memory!\n", stderr); - exit(1); - } - debug_fill(ptr, size); /* might as well get uninitialized protection */ - *(void **)ptr = a->allocation_list; - a->allocation_list = ptr; - ap_unblock_alarms(); - return (char *)ptr + CLICK_SZ; -#else - - /* - * Round up requested size to an even number of alignment units - * (core clicks) - */ - ap_pool_t *a = c->pool; - int nclicks = 1 + ((reqsize - 1) / CLICK_SZ); - int size = nclicks * CLICK_SZ; - - /* First, see if we have space in the block most recently - * allocated to this pool - */ - - union block_hdr *blok = a->last; - char *first_avail = blok->h.first_avail; - char *new_first_avail; - - if (reqsize <= 0) { - return NULL; - } - - new_first_avail = first_avail + size; - - if (new_first_avail <= blok->h.endp) { - debug_verify_filled(first_avail, blok->h.endp, - "Ouch! Someone trounced past the end " - "of their allocation!\n"); - blok->h.first_avail = new_first_avail; - return (void *) first_avail; - } - - /* Nope --- get a new one that's guaranteed to be big enough */ - - ap_block_alarms(); - - (void) ap_acquire_mutex(alloc_mutex); - - blok = new_block(size); - a->last->h.next = blok; - a->last = blok; -#ifdef POOL_DEBUG - blok->h.owning_pool = a; -#endif - - (void) ap_release_mutex(alloc_mutex); - - ap_unblock_alarms(); - - first_avail = blok->h.first_avail; - blok->h.first_avail += size; - - return (void *) first_avail; -#endif -} - -API_EXPORT(void *) ap_pcalloc(struct context_t *a, int size) -{ - void *res = ap_palloc(a, size); - memset(res, '\0', size); - return res; -} - -API_EXPORT(char *) ap_pstrdup(struct context_t *a, const char *s) -{ - char *res; - size_t len; - - if (s == NULL) { - return NULL; - } - len = strlen(s) + 1; - res = ap_palloc(a, len); - memcpy(res, s, len); - return res; -} - -API_EXPORT(char *) ap_pstrndup(struct context_t *a, const char *s, int n) -{ - char *res; - - if (s == NULL) { - return NULL; - } - res = ap_palloc(a, n + 1); - memcpy(res, s, n); - res[n] = '\0'; - return res; -} - -API_EXPORT_NONSTD(char *) ap_pstrcat(struct context_t *a, ...) -{ - char *cp, *argp, *res; - - /* Pass one --- find length of required string */ - - int len = 0; - va_list adummy; - - va_start(adummy, a); - - while ((cp = va_arg(adummy, char *)) != NULL) { - len += strlen(cp); - } - - va_end(adummy); - - /* Allocate the required string */ - - res = (char *) ap_palloc(a, len + 1); - cp = res; - *cp = '\0'; - - /* Pass two --- copy the argument strings into the result space */ - - va_start(adummy, a); - - while ((argp = va_arg(adummy, char *)) != NULL) { - strcpy(cp, argp); - cp += strlen(argp); - } - - va_end(adummy); - - /* Return the result string */ - - return res; -} - -/* - * ap_psprintf is implemented by writing directly into the current - * block of the pool, starting right at first_avail. If there's - * insufficient room, then a new block is allocated and the earlier - * output is copied over. The new block isn't linked into the pool - * until all the output is done. - * - * Note that this is completely safe because nothing else can - * allocate in this pool while ap_psprintf is running. alarms are - * blocked, and the only thing outside of alloc.c that's invoked - * is ap_vformatter -- which was purposefully written to be - * self-contained with no callouts. - */ - -struct psprintf_data { - ap_vformatter_buff_t vbuff; -#ifdef ALLOC_USE_MALLOC - char *base; -#else - union block_hdr *blok; - int got_a_new_block; -#endif -}; - -static int psprintf_flush(ap_vformatter_buff_t *vbuff) -{ - struct psprintf_data *ps = (struct psprintf_data *)vbuff; -#ifdef ALLOC_USE_MALLOC - int size; - char *ptr; - - size = (char *)ps->vbuff.curpos - ps->base; - ptr = realloc(ps->base, 2*size); - if (ptr == NULL) { - fputs("Ouch! Out of memory!\n", stderr); - exit(1); - } - ps->base = ptr; - ps->vbuff.curpos = ptr + size; - ps->vbuff.endpos = ptr + 2*size - 1; - return 0; -#else - union block_hdr *blok; - union block_hdr *nblok; - size_t cur_len; - char *strp; - - blok = ps->blok; - strp = ps->vbuff.curpos; - cur_len = strp - blok->h.first_avail; - - /* must try another blok */ - (void) ap_acquire_mutex(alloc_mutex); - nblok = new_block(2 * cur_len); - (void) ap_release_mutex(alloc_mutex); - memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len); - ps->vbuff.curpos = nblok->h.first_avail + cur_len; - /* save a byte for the NUL terminator */ - ps->vbuff.endpos = nblok->h.endp - 1; - - /* did we allocate the current blok? if so free it up */ - if (ps->got_a_new_block) { - debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail); - (void) ap_acquire_mutex(alloc_mutex); - blok->h.next = block_freelist; - block_freelist = blok; - (void) ap_release_mutex(alloc_mutex); - } - ps->blok = nblok; - ps->got_a_new_block = 1; - /* note that we've deliberately not linked the new block onto - * the pool yet... because we may need to flush again later, and - * we'd have to spend more effort trying to unlink the block. - */ - return 0; -#endif -} - -API_EXPORT(char *) ap_pvsprintf(struct context_t *c, const char *fmt, va_list ap) -{ -#ifdef ALLOC_USE_MALLOC - ap_pool_t *p = c->pool; - struct psprintf_data ps; - void *ptr; - - ap_block_alarms(); - ps.base = malloc(512); - if (ps.base == NULL) { - fputs("Ouch! Out of memory!\n", stderr); - exit(1); - } - /* need room at beginning for allocation_list */ - ps.vbuff.curpos = ps.base + CLICK_SZ; - ps.vbuff.endpos = ps.base + 511; - ap_vformatter(psprintf_flush, &ps.vbuff, fmt, ap); - *ps.vbuff.curpos++ = '\0'; - ptr = ps.base; - /* shrink */ - ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr); - if (ptr == NULL) { - fputs("Ouch! Out of memory!\n", stderr); - exit(1); - } - *(void **)ptr = p->allocation_list; - p->allocation_list = ptr; - ap_unblock_alarms(); - return (char *)ptr + CLICK_SZ; -#else - struct psprintf_data ps; - char *strp; - int size; - ap_pool_t *p = c->pool; - - ap_block_alarms(); - ps.blok = p->last; - ps.vbuff.curpos = ps.blok->h.first_avail; - ps.vbuff.endpos = ps.blok->h.endp - 1; /* save one for NUL */ - ps.got_a_new_block = 0; - - ap_vformatter(psprintf_flush, &ps.vbuff, fmt, ap); - - strp = ps.vbuff.curpos; - *strp++ = '\0'; - - size = strp - ps.blok->h.first_avail; - size = (1 + ((size - 1) / CLICK_SZ)) * CLICK_SZ; - strp = ps.blok->h.first_avail; /* save away result pointer */ - ps.blok->h.first_avail += size; - - /* have to link the block in if it's a new one */ - if (ps.got_a_new_block) { - p->last->h.next = ps.blok; - p->last = ps.blok; -#ifdef POOL_DEBUG - ps.blok->h.owning_pool = p; -#endif - } - ap_unblock_alarms(); - - return strp; -#endif -} - -API_EXPORT_NONSTD(char *) ap_psprintf(struct context_t *p, const char *fmt, ...) -{ - va_list ap; - char *res; - - va_start(ap, fmt); - res = ap_pvsprintf(p, fmt, ap); - va_end(ap); - return res; -} - -/***************************************************************** - * - * Managing generic cleanups. - */ - -struct cleanup { - void *data; - ap_status_t (*plain_cleanup) (void *); - ap_status_t (*child_cleanup) (void *); - struct cleanup *next; -}; - -API_EXPORT(void) ap_register_cleanup(struct context_t *p, void *data, - ap_status_t (*plain_cleanup) (void *), - ap_status_t (*child_cleanup) (void *)) -{ - struct cleanup *c; - c = (struct cleanup *) ap_palloc(p, sizeof(struct cleanup)); - c->data = data; - c->plain_cleanup = plain_cleanup; - c->child_cleanup = child_cleanup; - c->next = p->pool->cleanups; - p->pool->cleanups = c; -} - -API_EXPORT(void) ap_kill_cleanup(struct context_t *p, void *data, - ap_status_t (*cleanup) (void *)) -{ - struct cleanup *c = p->pool->cleanups; - struct cleanup **lastp = &p->pool->cleanups; - - while (c) { - if (c->data == data && c->plain_cleanup == cleanup) { - *lastp = c->next; - break; - } - - lastp = &c->next; - c = c->next; - } -} - -API_EXPORT(void) ap_run_cleanup(struct context_t *p, void *data, - ap_status_t (*cleanup) (void *)) -{ - ap_block_alarms(); /* Run cleanup only once! */ - (*cleanup) (data); - ap_kill_cleanup(p, data, cleanup); - ap_unblock_alarms(); -} - -static void run_cleanups(struct cleanup *c) -{ - while (c) { - (*c->plain_cleanup) (c->data); - c = c->next; - } -} - -static void run_child_cleanups(struct cleanup *c) -{ - while (c) { - (*c->child_cleanup) (c->data); - c = c->next; - } -} - -static void cleanup_pool_for_exec(ap_pool_t *p) -{ - run_child_cleanups(p->cleanups); - p->cleanups = NULL; - - for (p = p->sub_pools; p; p = p->sub_next) { - cleanup_pool_for_exec(p); - } -} - -API_EXPORT(void) ap_cleanup_for_exec(void) -{ -#if !defined(WIN32) && !defined(OS2) - /* - * Don't need to do anything on NT or OS/2, because I - * am actually going to spawn the new process - not - * exec it. All handles that are not inheritable, will - * be automajically closed. The only problem is with - * file handles that are open, but there isn't much - * I can do about that (except if the child decides - * to go out and close them - */ - ap_block_alarms(); - cleanup_pool_for_exec(permanent_pool); - ap_unblock_alarms(); -#endif /* ndef WIN32 */ -} - -API_EXPORT_NONSTD(void) ap_null_cleanup(void *data) -{ - /* do nothing cleanup routine */ -} - -/***************************************************************** - * - * Files and file descriptors; these are just an application of the - * generic cleanup interface. - */ -#if 0 /*not really needed any more, apr takes care of this stuff */ -static void fd_cleanup(void *fdv) -{ - close((int) (long) fdv); -} - -API_EXPORT(void) ap_note_cleanups_for_fd(ap_pool_t *p, int fd) -{ - ap_register_cleanup(p, (void *) (long) fd, fd_cleanup, fd_cleanup); -} - -API_EXPORT(void) ap_kill_cleanups_for_fd(ap_pool_t *p, int fd) -{ - ap_kill_cleanup(p, (void *) (long) fd, fd_cleanup); -} - -API_EXPORT(int) ap_popenf(ap_pool_t *a, const char *name, int flg, int mode) -{ - int fd; - int save_errno; - - ap_block_alarms(); - fd = open(name, flg, mode); - save_errno = errno; - if (fd >= 0) { - fd = ap_slack(fd, ap_SLACK_HIGH); - ap_note_cleanups_for_fd(a, fd); - } - ap_unblock_alarms(); - errno = save_errno; - return fd; -} - -API_EXPORT(int) ap_pclosef(ap_pool_t *a, int fd) -{ - int res; - int save_errno; - - ap_block_alarms(); - res = close(fd); - save_errno = errno; - ap_kill_cleanup(a, (void *) (long) fd, fd_cleanup); - ap_unblock_alarms(); - errno = save_errno; - return res; -} - -#ifdef WIN32 -static void h_cleanup(void *fdv) -{ - CloseHandle((HANDLE) fdv); -} - -API_EXPORT(void) ap_note_cleanups_for_h(ap_pool_t *p, HANDLE hDevice) -{ - ap_register_cleanup(p, (void *) hDevice, h_cleanup, h_cleanup); -} - -API_EXPORT(int) ap_pcloseh(ap_pool_t *a, HANDLE hDevice) -{ - int res=0; - int save_errno; - - ap_block_alarms(); - - if (!CloseHandle(hDevice)) { - res = GetLastError(); - } - - save_errno = errno; - ap_kill_cleanup(a, (void *) hDevice, h_cleanup); - ap_unblock_alarms(); - errno = save_errno; - return res; -} -#endif -*/ -/* Note that we have separate plain_ and child_ cleanups for FILE *s, - * since fclose() would flush I/O buffers, which is extremely undesirable; - * we just close the descriptor. - */ -static void file_cleanup(void *fpv) -{ - fclose((FILE *) fpv); -} -static void file_child_cleanup(void *fpv) -{ - close(fileno((FILE *) fpv)); -} - -API_EXPORT(void) ap_note_cleanups_for_file(ap_pool_t *p, FILE *fp) -{ - ap_register_cleanup(p, (void *) fp, file_cleanup, file_child_cleanup); -} - -API_EXPORT(FILE *) ap_pfopen(ap_pool_t *a, const char *name, - const char *mode) -{ - FILE *fd = NULL; - int baseFlag, desc; - int modeFlags = 0; - int saved_errno; - -#ifdef WIN32 - modeFlags = _S_IREAD | _S_IWRITE; -#else - modeFlags = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; -#endif - - ap_block_alarms(); - - if (*mode == 'a') { - /* Work around faulty implementations of fopen */ - baseFlag = (*(mode + 1) == '+') ? O_RDWR : O_WRONLY; - desc = open(name, baseFlag | O_APPEND | O_CREAT, - modeFlags); - if (desc >= 0) { - desc = ap_slack(desc, ap_SLACK_LOW); - fd = ap_fdopen(desc, mode); - } - } - else { - fd = fopen(name, mode); - } - saved_errno = errno; - if (fd != NULL) { - ap_note_cleanups_for_file(a, fd); - } - ap_unblock_alarms(); - errno = saved_errno; - return fd; -} - -API_EXPORT(FILE *) ap_pfdopen(ap_pool_t *a, int fd, const char *mode) -{ - FILE *f; - int saved_errno; - - ap_block_alarms(); - f = ap_fdopen(fd, mode); - saved_errno = errno; - if (f != NULL) { - ap_note_cleanups_for_file(a, f); - } - ap_unblock_alarms(); - errno = saved_errno; - return f; -} - - -API_EXPORT(int) ap_pfclose(ap_pool_t *a, FILE *fd) -{ - int res; - - ap_block_alarms(); - res = fclose(fd); - ap_kill_cleanup(a, (void *) fd, file_cleanup); - ap_unblock_alarms(); - return res; -} - -/* - * DIR * with cleanup - */ - -static void dir_cleanup(void *dv) -{ - closedir((DIR *) dv); -} - -API_EXPORT(DIR *) ap_popendir(ap_pool_t *p, const char *name) -{ - DIR *d; - int save_errno; - - ap_block_alarms(); - d = opendir(name); - if (d == NULL) { - save_errno = errno; - ap_unblock_alarms(); - errno = save_errno; - return NULL; - } - ap_register_cleanup(p, (void *) d, dir_cleanup, dir_cleanup); - ap_unblock_alarms(); - return d; -} - -API_EXPORT(void) ap_pclosedir(ap_pool_t *p, DIR * d) -{ - ap_block_alarms(); - ap_kill_cleanup(p, (void *) d, dir_cleanup); - closedir(d); - ap_unblock_alarms(); -} - -/***************************************************************** - * - * Files and file descriptors; these are just an application of the - * generic cleanup interface. - */ - -static void socket_cleanup(void *fdv) -{ - closesocket((int) (long) fdv); -} - -API_EXPORT(void) ap_note_cleanups_for_socket(ap_pool_t *p, int fd) -{ - ap_register_cleanup(p, (void *) (long) fd, socket_cleanup, - socket_cleanup); -} - -API_EXPORT(void) ap_kill_cleanups_for_socket(ap_pool_t *p, int sock) -{ - ap_kill_cleanup(p, (void *) (long) sock, socket_cleanup); -} - -API_EXPORT(int) ap_psocket(ap_pool_t *p, int domain, int type, int protocol) -{ - int fd; - - ap_block_alarms(); - fd = socket(domain, type, protocol); - if (fd == -1) { - int save_errno = errno; - ap_unblock_alarms(); - errno = save_errno; - return -1; - } - ap_note_cleanups_for_socket(p, fd); - ap_unblock_alarms(); - return fd; -} - -API_EXPORT(int) ap_pclosesocket(ap_pool_t *a, int sock) -{ - int res; - int save_errno; - - ap_block_alarms(); - res = closesocket(sock); -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - save_errno = errno; - ap_kill_cleanup(a, (void *) (long) sock, socket_cleanup); - ap_unblock_alarms(); - errno = save_errno; - return res; -} - - -/* - * Here's a pool-based interface to POSIX regex's regcomp(). - * Note that we return regex_t instead of being passed one. - * The reason is that if you use an already-used regex_t structure, - * the memory that you've already allocated gets forgotten, and - * regfree() doesn't clear it. So we don't allow it. - */ - -static void regex_cleanup(void *preg) -{ - regfree((regex_t *) preg); -} - -API_EXPORT(regex_t *) ap_pregcomp(ap_pool_t *p, const char *pattern, - int cflags) -{ - regex_t *preg = ap_palloc(p, sizeof(regex_t)); - - if (regcomp(preg, pattern, cflags)) { - return NULL; - } - - ap_register_cleanup(p, (void *) preg, regex_cleanup, regex_cleanup); - - return preg; -} - - -API_EXPORT(void) ap_pregfree(ap_pool_t *p, regex_t * reg) -{ - ap_block_alarms(); - regfree(reg); - ap_kill_cleanup(p, (void *) reg, regex_cleanup); - ap_unblock_alarms(); -} -#endif /* if 0 not really needed anymore. APR takes care of this. */ -/***************************************************************** - * - * More grotty system stuff... subprocesses. Frump. These don't use - * the generic cleanup interface because I don't want multiple - * subprocesses to result in multiple three-second pauses; the - * subprocesses have to be "freed" all at once. If someone comes - * along with another resource they want to allocate which has the - * same property, we might want to fold support for that into the - * generic interface, but for now, it's a special case - */ - -API_EXPORT(void) ap_note_subprocess(struct context_t *a, pid_t pid, - enum kill_conditions how) -{ - struct process_chain *new = - (struct process_chain *) ap_palloc(a, sizeof(struct process_chain)); - - new->pid = pid; - new->kill_how = how; - new->next = a->pool->subprocesses; - a->pool->subprocesses = new; -} - -#ifdef WIN32 -#define os_pipe(fds) _pipe(fds, 512, O_BINARY | O_NOINHERIT) -#else -#define os_pipe(fds) pipe(fds) -#endif /* WIN32 */ - -/* for ap_fdopen, to get binary mode */ -#if defined (OS2) || defined (WIN32) -#define BINMODE "b" -#else -#define BINMODE -#endif - -#if 0 -static pid_t spawn_child_core(ap_pool_t *p, - int (*func) (void *, ap_child_info_t *), - void *data,enum kill_conditions kill_how, - int *pipe_in, int *pipe_out, int *pipe_err) -{ - pid_t pid; - int in_fds[2]; - int out_fds[2]; - int err_fds[2]; - int save_errno; - - if (pipe_in && os_pipe(in_fds) < 0) { - return 0; - } - - if (pipe_out && os_pipe(out_fds) < 0) { - save_errno = errno; - if (pipe_in) { - close(in_fds[0]); - close(in_fds[1]); - } - errno = save_errno; - return 0; - } - - if (pipe_err && os_pipe(err_fds) < 0) { - save_errno = errno; - if (pipe_in) { - close(in_fds[0]); - close(in_fds[1]); - } - if (pipe_out) { - close(out_fds[0]); - close(out_fds[1]); - } - errno = save_errno; - return 0; - } - -#ifdef WIN32 - - { - HANDLE thread_handle; - int hStdIn, hStdOut, hStdErr; - int old_priority; - ap_child_info_t info; - - (void) ap_acquire_mutex(spawn_mutex); - thread_handle = GetCurrentThread(); /* doesn't need to be closed */ - old_priority = GetThreadPriority(thread_handle); - SetThreadPriority(thread_handle, THREAD_PRIORITY_HIGHEST); - /* Now do the right thing with your pipes */ - if (pipe_in) { - hStdIn = dup(fileno(stdin)); - if (dup2(in_fds[0], fileno(stdin))) { - ap_log_error(APLOG_MARK, APLOG_ERR, NULL, - "dup2(stdin) failed"); - } - close(in_fds[0]); - } - if (pipe_out) { - hStdOut = dup(fileno(stdout)); - close(fileno(stdout)); - if (dup2(out_fds[1], fileno(stdout))) { - ap_log_error(APLOG_MARK, APLOG_ERR, NULL, - "dup2(stdout) failed"); - } - close(out_fds[1]); - } - if (pipe_err) { - hStdErr = dup(fileno(stderr)); - if (dup2(err_fds[1], fileno(stderr))) { - ap_log_error(APLOG_MARK, APLOG_ERR, NULL, - "dup2(stdin) failed"); - } - close(err_fds[1]); - } - - info.hPipeInputRead = GetStdHandle(STD_INPUT_HANDLE); - info.hPipeOutputWrite = GetStdHandle(STD_OUTPUT_HANDLE); - info.hPipeErrorWrite = GetStdHandle(STD_ERROR_HANDLE); - - pid = (*func) (data, &info); - if (pid == -1) { - pid = 0; /* map Win32 error code onto Unix default */ - } - - if (!pid) { - save_errno = errno; - close(in_fds[1]); - close(out_fds[0]); - close(err_fds[0]); - } - - /* restore the original stdin, stdout and stderr */ - if (pipe_in) { - dup2(hStdIn, fileno(stdin)); - close(hStdIn); - } - if (pipe_out) { - dup2(hStdOut, fileno(stdout)); - close(hStdOut); - } - if (pipe_err) { - dup2(hStdErr, fileno(stderr)); - close(hStdErr); - } - - if (pid) { - ap_note_subprocess(p, pid, kill_how); - if (pipe_in) { - *pipe_in = in_fds[1]; - } - if (pipe_out) { - *pipe_out = out_fds[0]; - } - if (pipe_err) { - *pipe_err = err_fds[0]; - } - } - SetThreadPriority(thread_handle, old_priority); - (void) ap_release_mutex(spawn_mutex); - /* - * go on to the end of the function, where you can - * unblock alarms and return the pid - */ - - } -#elif defined(OS2) - { - int save_in=-1, save_out=-1, save_err=-1; - - if (pipe_out) { - save_out = dup(STDOUT_FILENO); - dup2(out_fds[1], STDOUT_FILENO); - close(out_fds[1]); - } - - if (pipe_in) { - save_in = dup(STDIN_FILENO); - dup2(in_fds[0], STDIN_FILENO); - close(in_fds[0]); - } - - if (pipe_err) { - save_err = dup(STDERR_FILENO); - dup2(err_fds[1], STDERR_FILENO); - close(err_fds[1]); - } - - pid = func(data, NULL); - - if (pid) { - ap_note_subprocess(p, pid, kill_how); - } - - if (pipe_out) { - close(STDOUT_FILENO); - dup2(save_out, STDOUT_FILENO); - close(save_out); - *pipe_out = out_fds[0]; - } - - if (pipe_in) { - close(STDIN_FILENO); - dup2(save_in, STDIN_FILENO); - close(save_in); - *pipe_in = in_fds[1]; - } - - if (pipe_err) { - close(STDERR_FILENO); - dup2(save_err, STDERR_FILENO); - close(save_err); - *pipe_err = err_fds[0]; - } - } -#elif defined(TPF) - return (pid = ap_tpf_spawn_child(p, func, data, kill_how, - pipe_in, pipe_out, pipe_err, out_fds, - in_fds, err_fds)); -#else - - if ((pid = fork()) < 0) { - save_errno = errno; - if (pipe_in) { - close(in_fds[0]); - close(in_fds[1]); - } - if (pipe_out) { - close(out_fds[0]); - close(out_fds[1]); - } - if (pipe_err) { - close(err_fds[0]); - close(err_fds[1]); - } - errno = save_errno; - return 0; - } - - if (!pid) { - /* Child process */ - RAISE_SIGSTOP(SPAWN_CHILD); - - if (pipe_out) { - close(out_fds[0]); - dup2(out_fds[1], STDOUT_FILENO); - close(out_fds[1]); - } - - if (pipe_in) { - close(in_fds[1]); - dup2(in_fds[0], STDIN_FILENO); - close(in_fds[0]); - } - - if (pipe_err) { - close(err_fds[0]); - dup2(err_fds[1], STDERR_FILENO); - close(err_fds[1]); - } - - /* - * HP-UX SIGCHLD fix goes here, if someone will remind me - * what it is... - */ - signal(SIGCHLD, SIG_DFL); /* Was that it? */ - - func(data, NULL); - exit(1); /* Should only get here if the exec in func() failed */ - } - - /* Parent process */ - - ap_note_subprocess(p, pid, kill_how); - - if (pipe_out) { - close(out_fds[1]); - *pipe_out = out_fds[0]; - } - - if (pipe_in) { - close(in_fds[0]); - *pipe_in = in_fds[1]; - } - - if (pipe_err) { - close(err_fds[1]); - *pipe_err = err_fds[0]; - } -#endif /* WIN32 */ - - return pid; -} - - -API_EXPORT(int) ap_spawn_child(ap_pool_t *p, - int (*func) (void *v, ap_child_info_t *c), - void *data, enum kill_conditions kill_how, - FILE **pipe_in, FILE **pipe_out, - FILE **pipe_err) -{ - int fd_in, fd_out, fd_err; - pid_t pid; - int save_errno; - - ap_block_alarms(); - - pid = spawn_child_core(p, func, data, kill_how, - pipe_in ? &fd_in : NULL, - pipe_out ? &fd_out : NULL, - pipe_err ? &fd_err : NULL); - - if (pid == 0) { - save_errno = errno; - ap_unblock_alarms(); - errno = save_errno; - return 0; - } - - if (pipe_out) { - *pipe_out = ap_fdopen(fd_out, "r" BINMODE); - if (*pipe_out) { - ap_note_cleanups_for_file(p, *pipe_out); - } - else { - close(fd_out); - } - } - - if (pipe_in) { - *pipe_in = ap_fdopen(fd_in, "w" BINMODE); - if (*pipe_in) { - ap_note_cleanups_for_file(p, *pipe_in); - } - else { - close(fd_in); - } - } - - if (pipe_err) { - *pipe_err = ap_fdopen(fd_err, "r" BINMODE); - if (*pipe_err) { - ap_note_cleanups_for_file(p, *pipe_err); - } - else { - close(fd_err); - } - } - - ap_unblock_alarms(); - return pid; -} - -API_EXPORT(int) ap_bspawn_child(ap_pool_t *p, - int (*func) (void *v, ap_child_info_t *c), - void *data, enum kill_conditions kill_how, - BUFF **pipe_in, BUFF **pipe_out, - BUFF **pipe_err) -{ -#ifdef WIN32 - SECURITY_ATTRIBUTES sa = {0}; - HANDLE hPipeOutputRead = NULL; - HANDLE hPipeOutputWrite = NULL; - HANDLE hPipeInputRead = NULL; - HANDLE hPipeInputWrite = NULL; - HANDLE hPipeErrorRead = NULL; - HANDLE hPipeErrorWrite = NULL; - HANDLE hPipeInputWriteDup = NULL; - HANDLE hPipeOutputReadDup = NULL; - HANDLE hPipeErrorReadDup = NULL; - HANDLE hCurrentProcess; - pid_t pid = 0; - ap_child_info_t info; - - ap_block_alarms(); - - /* - * First thing to do is to create the pipes that we will use - * for stdin, stdout, and stderr in the child process. - */ - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - sa.lpSecurityDescriptor = NULL; - - - /* Create pipes for standard input/output/error redirection. */ - if (pipe_in && !CreatePipe(&hPipeInputRead, &hPipeInputWrite, &sa, 0)) { - return 0; - } - - if (pipe_out && !CreatePipe(&hPipeOutputRead, &hPipeOutputWrite, &sa, 0)) { - if (pipe_in) { - CloseHandle(hPipeInputRead); - CloseHandle(hPipeInputWrite); - } - return 0; - } - - if (pipe_err && !CreatePipe(&hPipeErrorRead, &hPipeErrorWrite, &sa, 0)) { - if (pipe_in) { - CloseHandle(hPipeInputRead); - CloseHandle(hPipeInputWrite); - } - if (pipe_out) { - CloseHandle(hPipeOutputRead); - CloseHandle(hPipeOutputWrite); - } - return 0; - } - /* - * When the pipe handles are created, the security descriptor - * indicates that the handle can be inherited. However, we do not - * want the server side handles to the pipe to be inherited by the - * child CGI process. If the child CGI does inherit the server - * side handles, then the child may be left around if the server - * closes its handles (e.g. if the http connection is aborted), - * because the child will have a valid copy of handles to both - * sides of the pipes, and no I/O error will occur. Microsoft - * recommends using DuplicateHandle to turn off the inherit bit - * under NT and Win95. - */ - hCurrentProcess = GetCurrentProcess(); - if ((pipe_in && !DuplicateHandle(hCurrentProcess, hPipeInputWrite, - hCurrentProcess, - &hPipeInputWriteDup, 0, FALSE, - DUPLICATE_SAME_ACCESS)) - || (pipe_out && !DuplicateHandle(hCurrentProcess, hPipeOutputRead, - hCurrentProcess, &hPipeOutputReadDup, - 0, FALSE, DUPLICATE_SAME_ACCESS)) - || (pipe_err && !DuplicateHandle(hCurrentProcess, hPipeErrorRead, - hCurrentProcess, &hPipeErrorReadDup, - 0, FALSE, DUPLICATE_SAME_ACCESS))) { - if (pipe_in) { - CloseHandle(hPipeInputRead); - CloseHandle(hPipeInputWrite); - } - if (pipe_out) { - CloseHandle(hPipeOutputRead); - CloseHandle(hPipeOutputWrite); - } - if (pipe_err) { - CloseHandle(hPipeErrorRead); - CloseHandle(hPipeErrorWrite); - } - return 0; - } - else { - if (pipe_in) { - CloseHandle(hPipeInputWrite); - hPipeInputWrite = hPipeInputWriteDup; - } - if (pipe_out) { - CloseHandle(hPipeOutputRead); - hPipeOutputRead = hPipeOutputReadDup; - } - if (pipe_err) { - CloseHandle(hPipeErrorRead); - hPipeErrorRead = hPipeErrorReadDup; - } - } - - /* The script writes stdout to this pipe handle */ - info.hPipeOutputWrite = hPipeOutputWrite; - - /* The script reads stdin from this pipe handle */ - info.hPipeInputRead = hPipeInputRead; - - /* The script writes stderr to this pipe handle */ - info.hPipeErrorWrite = hPipeErrorWrite; - - /* - * Try to launch the CGI. Under the covers, this call - * will try to pick up the appropriate interpreter if - * one is needed. - */ - pid = func(data, &info); - if (pid == -1) { - /* Things didn't work, so cleanup */ - pid = 0; /* map Win32 error code onto Unix default */ - CloseHandle(hPipeOutputRead); - CloseHandle(hPipeInputWrite); - CloseHandle(hPipeErrorRead); - } - else { - if (pipe_out) { - /* - * This pipe represents stdout for the script, - * so we read from this pipe. - */ - /* Create a read buffer */ - *pipe_out = ap_bcreate(p, B_RD); - - /* Setup the cleanup routine for the handle */ - ap_note_cleanups_for_h(p, hPipeOutputRead); - - /* Associate the handle with the new buffer */ - ap_bpushh(*pipe_out, hPipeOutputRead); - } - - if (pipe_in) { - /* - * This pipe represents stdin for the script, so we - * write to this pipe. - */ - /* Create a write buffer */ - *pipe_in = ap_bcreate(p, B_WR); - - /* Setup the cleanup routine for the handle */ - ap_note_cleanups_for_h(p, hPipeInputWrite); - - /* Associate the handle with the new buffer */ - ap_bpushh(*pipe_in, hPipeInputWrite); - - } - - if (pipe_err) { - /* - * This pipe represents stderr for the script, so - * we read from this pipe. - */ - /* Create a read buffer */ - *pipe_err = ap_bcreate(p, B_RD); - - /* Setup the cleanup routine for the handle */ - ap_note_cleanups_for_h(p, hPipeErrorRead); - - /* Associate the handle with the new buffer */ - ap_bpushh(*pipe_err, hPipeErrorRead); - } - } - - - /* - * Now that handles have been inherited, close them to be safe. - * You don't want to read or write to them accidentally, and we - * sure don't want to have a handle leak. - */ - CloseHandle(hPipeOutputWrite); - CloseHandle(hPipeInputRead); - CloseHandle(hPipeErrorWrite); - -#else - int fd_in, fd_out, fd_err; - pid_t pid; - int save_errno; - - ap_block_alarms(); - - pid = spawn_child_core(p, func, data, kill_how, - pipe_in ? &fd_in : NULL, - pipe_out ? &fd_out : NULL, - pipe_err ? &fd_err : NULL); - - if (pid == 0) { - save_errno = errno; - ap_unblock_alarms(); - errno = save_errno; - return 0; - } - - if (pipe_out) { - *pipe_out = ap_bcreate(p, B_RD); - ap_note_cleanups_for_fd(p, fd_out); - ap_bpushfd(*pipe_out, fd_out, fd_out); - } - - if (pipe_in) { - *pipe_in = ap_bcreate(p, B_WR); - ap_note_cleanups_for_fd(p, fd_in); - ap_bpushfd(*pipe_in, fd_in, fd_in); - } - - if (pipe_err) { - *pipe_err = ap_bcreate(p, B_RD); - ap_note_cleanups_for_fd(p, fd_err); - ap_bpushfd(*pipe_err, fd_err, fd_err); - } -#endif - - ap_unblock_alarms(); - return pid; -} -#endif - -static void free_proc_chain(struct process_chain *procs) -{ - /* Dispose of the subprocesses we've spawned off in the course of - * whatever it was we're cleaning up now. This may involve killing - * some of them off... - */ - - struct process_chain *p; - int need_timeout = 0; - int status; - - if (procs == NULL) { - return; /* No work. Whew! */ - } - - /* First, check to see if we need to do the SIGTERM, sleep, SIGKILL - * dance with any of the processes we're cleaning up. If we've got - * any kill-on-sight subprocesses, ditch them now as well, so they - * don't waste any more cycles doing whatever it is that they shouldn't - * be doing anymore. - */ -#ifdef WIN32 - /* Pick up all defunct processes */ - for (p = procs; p; p = p->next) { - if (GetExitCodeProcess((HANDLE) p->pid, &status)) { - p->kill_how = kill_never; - } - } - - - for (p = procs; p; p = p->next) { - if (p->kill_how == kill_after_timeout) { - need_timeout = 1; - } - else if (p->kill_how == kill_always) { - TerminateProcess((HANDLE) p->pid, 1); - } - } - /* Sleep only if we have to... */ - - if (need_timeout) { - sleep(3); - } - - /* OK, the scripts we just timed out for have had a chance to clean up - * --- now, just get rid of them, and also clean up the system accounting - * goop... - */ - - for (p = procs; p; p = p->next) { - if (p->kill_how == kill_after_timeout) { - TerminateProcess((HANDLE) p->pid, 1); - } - } - - for (p = procs; p; p = p->next) { - CloseHandle((HANDLE) p->pid); - } -#else -#ifndef NEED_WAITPID - /* Pick up all defunct processes */ - for (p = procs; p; p = p->next) { - if (waitpid(p->pid, (int *) 0, WNOHANG) > 0) { - p->kill_how = kill_never; - } - } -#endif - - for (p = procs; p; p = p->next) { - if ((p->kill_how == kill_after_timeout) - || (p->kill_how == kill_only_once)) { - /* - * Subprocess may be dead already. Only need the timeout if not. - */ - if (kill(p->pid, SIGTERM) != -1) { - need_timeout = 1; - } - } - else if (p->kill_how == kill_always) { - kill(p->pid, SIGKILL); - } - } - - /* Sleep only if we have to... */ - - if (need_timeout) { - sleep(3); - } - - /* OK, the scripts we just timed out for have had a chance to clean up - * --- now, just get rid of them, and also clean up the system accounting - * goop... - */ - - for (p = procs; p; p = p->next) { - - if (p->kill_how == kill_after_timeout) { - kill(p->pid, SIGKILL); - } - - if (p->kill_how != kill_never) { - waitpid(p->pid, &status, 0); - } - } -#endif /* WIN32 */ -} diff --git a/lib/apr_signal.c b/lib/apr_signal.c deleted file mode 100644 index b4b361f02..000000000 --- a/lib/apr_signal.c +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ - -#include "apr_config.h" -#include "apr_lib.h" - -#ifndef NO_USE_SIGACTION -/* - * Replace standard signal() with the more reliable sigaction equivalent - * from W. Richard Stevens' "Advanced Programming in the UNIX Environment" - * (the version that does not automatically restart system calls). - */ -Sigfunc *signal(int signo, Sigfunc * func) -{ - struct sigaction act, oact; - - act.sa_handler = func; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; -#ifdef SA_INTERRUPT /* SunOS */ - act.sa_flags |= SA_INTERRUPT; -#endif - if (sigaction(signo, &act, &oact) < 0) - return SIG_ERR; - return oact.sa_handler; -} -#else -/* need some function in this file, otherwise the linker on NeXT bitches */ -void apr_signal_is_not_here(void) {} -#endif diff --git a/lib/apr_slack.c b/lib/apr_slack.c deleted file mode 100644 index 8df9c8847..000000000 --- a/lib/apr_slack.c +++ /dev/null @@ -1,126 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ - -/* - * apr_slack.c: File descriptor preallocation - * - * 3/21/93 Rob McCool - * 1995-96 Many changes by the Apache Group - * - */ - -#ifndef WIN32 -#include "apr_config.h" -#else -#include "apr_win.h" -#endif - -#ifdef APACHE -#include "http_log.h" -#endif - -#ifndef NO_SLACK -int apr_slack(int fd, int line) -{ -#if !defined(F_DUPFD) - return fd; -#else - static int low_warned; - int new_fd; - -#ifdef HIGH_SLACK_LINE - if (line == APR_SLACK_HIGH && fd < HIGH_SLACK_LINE) { - new_fd = fcntl(fd, F_DUPFD, HIGH_SLACK_LINE); - if (new_fd != -1) { - close(fd); - return new_fd; - } - } -#endif - /* otherwise just assume line == APR_SLACK_LOW */ - if (fd >= LOW_SLACK_LINE) { - return fd; - } - new_fd = fcntl(fd, F_DUPFD, LOW_SLACK_LINE); - if (new_fd == -1) { - if (!low_warned) { - -#ifdef APACHE - /* Give them a warning here, because we really can't predict - * how libraries and such are going to fail. If we can't - * do this F_DUPFD there's a good chance that apache has too - * few descriptors available to it. Note we don't warn on - * the high line, because if it fails we'll eventually try - * the low line... - */ - apr_log_error(APLOG_MARK, APLOG_WARNING, NULL, - "unable to open a file descriptor above %u, " - "you may need to increase the number of descriptors", - LOW_SLACK_LINE); -#endif /* APACHE */ - low_warned = 1; - } - return fd; - } - close(fd); - return new_fd; -#endif -} -#else -/* need at least one function in the file for some linkers */ -void apr_slack_is_not_here(void) {} -#endif /* NO_SLACK */ diff --git a/lib/apr_snprintf.c b/lib/apr_snprintf.c deleted file mode 100644 index bcba6ae45..000000000 --- a/lib/apr_snprintf.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - * This code is based on, and used with the permission of, the - * SIO stdiocntxteplacement strx_* functions by Panos Tsirigotis - * <panos@alumni.cs.colorado.edu> for xinetd. - */ - -#ifndef WIN32 -#include "apr_config.h" -#else -#include <winsock2.h> -#include "apr_win.h" -#endif - -#include "apr_lib.h" -#include <math.h> - -typedef enum { - NO = 0, YES = 1 -} boolean_e; - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#define NUL '\0' -#define INT_NULL ((int *)0) -#define WIDE_INT long - -typedef WIDE_INT wide_int; -typedef unsigned WIDE_INT u_wide_int; -typedef int bool_int; - -#define S_NULL "(null)" -#define S_NULL_LEN 6 - -#define FLOAT_DIGITS 6 -#define EXPONENT_LENGTH 10 - -/* - * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions - * - * XXX: this is a magic number; do not decrease it - */ -#define NUM_BUF_SIZE 512 - -/* - * cvt.c - IEEE floating point formatting routines for FreeBSD - * from GNU libc-4.6.27. Modified to be thread safe. - */ - -/* - * ap_ecvt converts to decimal - * the number of digits is specified by ndigit - * decpt is set to the position of the decimal point - * sign is set to 0 for positive, 1 for negative - */ - -#define NDIG 80 - -/* buf must have at least NDIG bytes */ -static char *ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf) -{ - register int r2; - double fi, fj; - register char *p, *p1; - - if (ndigits >= NDIG - 1) - ndigits = NDIG - 2; - r2 = 0; - *sign = 0; - p = &buf[0]; - if (arg < 0) { - *sign = 1; - arg = -arg; - } - arg = modf(arg, &fi); - p1 = &buf[NDIG]; - /* - * Do integer part - */ - if (fi != 0) { - p1 = &buf[NDIG]; - while (fi != 0) { - fj = modf(fi / 10, &fi); - *--p1 = (int) ((fj + .03) * 10) + '0'; - r2++; - } - while (p1 < &buf[NDIG]) - *p++ = *p1++; - } - else if (arg > 0) { - while ((fj = arg * 10) < 1) { - arg = fj; - r2--; - } - } - p1 = &buf[ndigits]; - if (eflag == 0) - p1 += r2; - *decpt = r2; - if (p1 < &buf[0]) { - buf[0] = '\0'; - return (buf); - } - while (p <= p1 && p < &buf[NDIG]) { - arg *= 10; - arg = modf(arg, &fj); - *p++ = (int) fj + '0'; - } - if (p1 >= &buf[NDIG]) { - buf[NDIG - 1] = '\0'; - return (buf); - } - p = p1; - *p1 += 5; - while (*p1 > '9') { - *p1 = '0'; - if (p1 > buf) - ++ * --p1; - else { - *p1 = '1'; - (*decpt)++; - if (eflag == 0) { - if (p > buf) - *p = '0'; - p++; - } - } - } - *p = '\0'; - return (buf); -} - -static char *ap_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf) -{ - return (ap_cvt(arg, ndigits, decpt, sign, 1, buf)); -} - -static char *ap_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf) -{ - return (ap_cvt(arg, ndigits, decpt, sign, 0, buf)); -} - -/* - * ap_gcvt - Floating output conversion to - * minimal length string - */ - -static char *ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) -{ - int sign, decpt; - register char *p1, *p2; - register int i; - char buf1[NDIG]; - - p1 = ap_ecvt(number, ndigit, &decpt, &sign, buf1); - p2 = buf; - if (sign) - *p2++ = '-'; - for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--) - ndigit--; - if ((decpt >= 0 && decpt - ndigit > 4) - || (decpt < 0 && decpt < -3)) { /* use E-style */ - decpt--; - *p2++ = *p1++; - *p2++ = '.'; - for (i = 1; i < ndigit; i++) - *p2++ = *p1++; - *p2++ = 'e'; - if (decpt < 0) { - decpt = -decpt; - *p2++ = '-'; - } - else - *p2++ = '+'; - if (decpt / 100 > 0) - *p2++ = decpt / 100 + '0'; - if (decpt / 10 > 0) - *p2++ = (decpt % 100) / 10 + '0'; - *p2++ = decpt % 10 + '0'; - } - else { - if (decpt <= 0) { - if (*p1 != '0') - *p2++ = '.'; - while (decpt < 0) { - decpt++; - *p2++ = '0'; - } - } - for (i = 1; i <= ndigit; i++) { - *p2++ = *p1++; - if (i == decpt) - *p2++ = '.'; - } - if (ndigit < decpt) { - while (ndigit++ < decpt) - *p2++ = '0'; - *p2++ = '.'; - } - } - if (p2[-1] == '.' && !altform) - p2--; - *p2 = '\0'; - return (buf); -} - -/* - * The INS_CHAR macro inserts a character in the buffer and writes - * the buffer back to disk if necessary - * It uses the char pointers sp and bep: - * sp points to the next available character in the buffer - * bep points to the end-of-buffer+1 - * While using this macro, note that the nextb pointer is NOT updated. - * - * NOTE: Evaluation of the c argument should not have any side-effects - */ -#define INS_CHAR(c, sp, bep, cc) \ - { \ - if (sp >= bep) { \ - vbuff->curpos = sp; \ - if (flush_func(vbuff)) \ - return -1; \ - sp = vbuff->curpos; \ - bep = vbuff->endpos; \ - } \ - *sp++ = (c); \ - cc++; \ - } - -#define NUM( c ) ( c - '0' ) - -#define STR_TO_DEC( str, num ) \ - num = NUM( *str++ ) ; \ - while ( ap_isdigit( *str ) ) \ - { \ - num *= 10 ; \ - num += NUM( *str++ ) ; \ - } - -/* - * This macro does zero padding so that the precision - * requirement is satisfied. The padding is done by - * adding '0's to the left of the string that is going - * to be printed. - */ -#define FIX_PRECISION( adjust, precision, s, s_len ) \ - if ( adjust ) \ - while ( s_len < precision ) \ - { \ - *--s = '0' ; \ - s_len++ ; \ - } - -/* - * Macro that does padding. The padding is done by printing - * the character ch. - */ -#define PAD( width, len, ch ) do \ - { \ - INS_CHAR( ch, sp, bep, cc ) ; \ - width-- ; \ - } \ - while ( width > len ) - -/* - * Prefix the character ch to the string str - * Increase length - * Set the has_prefix flag - */ -#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES - - -/* - * Convert num to its decimal format. - * Return value: - * - a pointer to a string containing the number (no sign) - * - len contains the length of the string - * - is_negative is set to TRUE or FALSE depending on the sign - * of the number (always set to FALSE if is_unsigned is TRUE) - * - * The caller provides a buffer for the string: that is the buf_end argument - * which is a pointer to the END of the buffer + 1 (i.e. if the buffer - * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) - */ -static char *conv_10(register wide_int num, register bool_int is_unsigned, - register bool_int *is_negative, char *buf_end, - register int *len) -{ - register char *p = buf_end; - register u_wide_int magnitude; - - if (is_unsigned) { - magnitude = (u_wide_int) num; - *is_negative = FALSE; - } - else { - *is_negative = (num < 0); - - /* - * On a 2's complement machine, negating the most negative integer - * results in a number that cannot be represented as a signed integer. - * Here is what we do to obtain the number's magnitude: - * a. add 1 to the number - * b. negate it (becomes positive) - * c. convert it to unsigned - * d. add 1 - */ - if (*is_negative) { - wide_int t = num + 1; - - magnitude = ((u_wide_int) -t) + 1; - } - else - magnitude = (u_wide_int) num; - } - - /* - * We use a do-while loop so that we write at least 1 digit - */ - do { - register u_wide_int new_magnitude = magnitude / 10; - - *--p = (char) (magnitude - new_magnitude * 10 + '0'); - magnitude = new_magnitude; - } - while (magnitude); - - *len = buf_end - p; - return (p); -} - - - -static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len) -{ - unsigned addr = ntohl(ia->s_addr); - char *p = buf_end; - bool_int is_negative; - int sub_len; - - p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len); - *--p = '.'; - p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len); - *--p = '.'; - p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len); - *--p = '.'; - p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len); - - *len = buf_end - p; - return (p); -} - - - -static char *conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, int *len) -{ - char *p = buf_end; - bool_int is_negative; - int sub_len; - - p = conv_10(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len); - *--p = ':'; - p = conv_in_addr(&si->sin_addr, p, &sub_len); - - *len = buf_end - p; - return (p); -} - - - -/* - * Convert a floating point number to a string formats 'f', 'e' or 'E'. - * The result is placed in buf, and len denotes the length of the string - * The sign is returned in the is_negative argument (and is not placed - * in buf). - */ -static char *conv_fp(register char format, register double num, - boolean_e add_dp, int precision, bool_int *is_negative, - char *buf, int *len) -{ - register char *s = buf; - register char *p; - int decimal_point; - char buf1[NDIG]; - - if (format == 'f') - p = ap_fcvt(num, precision, &decimal_point, is_negative, buf1); - else /* either e or E format */ - p = ap_ecvt(num, precision + 1, &decimal_point, is_negative, buf1); - - /* - * Check for Infinity and NaN - */ - if (ap_isalpha(*p)) { - *len = strlen(strcpy(buf, p)); - *is_negative = FALSE; - return (buf); - } - - if (format == 'f') { - if (decimal_point <= 0) { - *s++ = '0'; - if (precision > 0) { - *s++ = '.'; - while (decimal_point++ < 0) - *s++ = '0'; - } - else if (add_dp) - *s++ = '.'; - } - else { - while (decimal_point-- > 0) - *s++ = *p++; - if (precision > 0 || add_dp) - *s++ = '.'; - } - } - else { - *s++ = *p++; - if (precision > 0 || add_dp) - *s++ = '.'; - } - - /* - * copy the rest of p, the NUL is NOT copied - */ - while (*p) - *s++ = *p++; - - if (format != 'f') { - char temp[EXPONENT_LENGTH]; /* for exponent conversion */ - int t_len; - bool_int exponent_is_negative; - - *s++ = format; /* either e or E */ - decimal_point--; - if (decimal_point != 0) { - p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative, - &temp[EXPONENT_LENGTH], &t_len); - *s++ = exponent_is_negative ? '-' : '+'; - - /* - * Make sure the exponent has at least 2 digits - */ - if (t_len == 1) - *s++ = '0'; - while (t_len--) - *s++ = *p++; - } - else { - *s++ = '+'; - *s++ = '0'; - *s++ = '0'; - } - } - - *len = s - buf; - return (buf); -} - - -/* - * Convert num to a base X number where X is a power of 2. nbits determines X. - * For example, if nbits is 3, we do base 8 conversion - * Return value: - * a pointer to a string containing the number - * - * The caller provides a buffer for the string: that is the buf_end argument - * which is a pointer to the END of the buffer + 1 (i.e. if the buffer - * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) - */ -static char *conv_p2(register u_wide_int num, register int nbits, - char format, char *buf_end, register int *len) -{ - register int mask = (1 << nbits) - 1; - register char *p = buf_end; - static const char low_digits[] = "0123456789abcdef"; - static const char upper_digits[] = "0123456789ABCDEF"; - register const char *digits = (format == 'X') ? upper_digits : low_digits; - - do { - *--p = digits[num & mask]; - num >>= nbits; - } - while (num); - - *len = buf_end - p; - return (p); -} - - -/* - * Do format conversion placing the output in buffer - */ -API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff_t *), - ap_vformatter_buff_t *vbuff, const char *fmt, va_list ap) -{ - register char *sp; - register char *bep; - register int cc = 0; - register int i; - - register char *s = NULL; - char *q; - int s_len; - - register int min_width = 0; - int precision = 0; - enum { - LEFT, RIGHT - } adjust; - char pad_char; - char prefix_char; - - double fp_num; - wide_int i_num = (wide_int) 0; - u_wide_int ui_num; - - char num_buf[NUM_BUF_SIZE]; - char char_buf[2]; /* for printing %% and %<unknown> */ - - /* - * Flag variables - */ - boolean_e is_long; - boolean_e alternate_form; - boolean_e print_sign; - boolean_e print_blank; - boolean_e adjust_precision; - boolean_e adjust_width; - bool_int is_negative; - - sp = vbuff->curpos; - bep = vbuff->endpos; - - while (*fmt) { - if (*fmt != '%') { - INS_CHAR(*fmt, sp, bep, cc); - } - else { - /* - * Default variable settings - */ - adjust = RIGHT; - alternate_form = print_sign = print_blank = NO; - pad_char = ' '; - prefix_char = NUL; - - fmt++; - - /* - * Try to avoid checking for flags, width or precision - */ - if (!ap_islower(*fmt)) { - /* - * Recognize flags: -, #, BLANK, + - */ - for (;; fmt++) { - if (*fmt == '-') - adjust = LEFT; - else if (*fmt == '+') - print_sign = YES; - else if (*fmt == '#') - alternate_form = YES; - else if (*fmt == ' ') - print_blank = YES; - else if (*fmt == '0') - pad_char = '0'; - else - break; - } - - /* - * Check if a width was specified - */ - if (ap_isdigit(*fmt)) { - STR_TO_DEC(fmt, min_width); - adjust_width = YES; - } - else if (*fmt == '*') { - min_width = va_arg(ap, int); - fmt++; - adjust_width = YES; - if (min_width < 0) { - adjust = LEFT; - min_width = -min_width; - } - } - else - adjust_width = NO; - - /* - * Check if a precision was specified - * - * XXX: an unreasonable amount of precision may be specified - * resulting in overflow of num_buf. Currently we - * ignore this possibility. - */ - if (*fmt == '.') { - adjust_precision = YES; - fmt++; - if (ap_isdigit(*fmt)) { - STR_TO_DEC(fmt, precision); - } - else if (*fmt == '*') { - precision = va_arg(ap, int); - fmt++; - if (precision < 0) - precision = 0; - } - else - precision = 0; - } - else - adjust_precision = NO; - } - else - adjust_precision = adjust_width = NO; - - /* - * Modifier check - */ - if (*fmt == 'l') { - is_long = YES; - fmt++; - } - else { - if (*fmt == 'h') /* "short" backward compatibility */ - ++fmt; - is_long = NO; - } - - /* - * Argument extraction and printing. - * First we determine the argument type. - * Then, we convert the argument to a string. - * On exit from the switch, s points to the string that - * must be printed, s_len has the length of the string - * The precision requirements, if any, are reflected in s_len. - * - * NOTE: pad_char may be set to '0' because of the 0 flag. - * It is reset to ' ' by non-numeric formats - */ - switch (*fmt) { - case 'u': - if (is_long) - i_num = va_arg(ap, u_wide_int); - else - i_num = (wide_int) va_arg(ap, unsigned int); - s = conv_10(i_num, 1, &is_negative, - &num_buf[NUM_BUF_SIZE], &s_len); - FIX_PRECISION(adjust_precision, precision, s, s_len); - break; - - case 'd': - case 'i': - if (is_long) - i_num = va_arg(ap, wide_int); - else - i_num = (wide_int) va_arg(ap, int); - s = conv_10(i_num, 0, &is_negative, - &num_buf[NUM_BUF_SIZE], &s_len); - FIX_PRECISION(adjust_precision, precision, s, s_len); - - if (is_negative) - prefix_char = '-'; - else if (print_sign) - prefix_char = '+'; - else if (print_blank) - prefix_char = ' '; - break; - - - case 'o': - if (is_long) - ui_num = va_arg(ap, u_wide_int); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); - s = conv_p2(ui_num, 3, *fmt, - &num_buf[NUM_BUF_SIZE], &s_len); - FIX_PRECISION(adjust_precision, precision, s, s_len); - if (alternate_form && *s != '0') { - *--s = '0'; - s_len++; - } - break; - - - case 'x': - case 'X': - if (is_long) - ui_num = (u_wide_int) va_arg(ap, u_wide_int); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); - s = conv_p2(ui_num, 4, *fmt, - &num_buf[NUM_BUF_SIZE], &s_len); - FIX_PRECISION(adjust_precision, precision, s, s_len); - if (alternate_form && i_num != 0) { - *--s = *fmt; /* 'x' or 'X' */ - *--s = '0'; - s_len += 2; - } - break; - - - case 's': - s = va_arg(ap, char *); - if (s != NULL) { - s_len = strlen(s); - if (adjust_precision && precision < s_len) - s_len = precision; - } - else { - s = S_NULL; - s_len = S_NULL_LEN; - } - pad_char = ' '; - break; - - - case 'f': - case 'e': - case 'E': - fp_num = va_arg(ap, double); - /* - * * We use &num_buf[ 1 ], so that we have room for the sign - */ - s = conv_fp(*fmt, fp_num, alternate_form, - (adjust_precision == NO) ? FLOAT_DIGITS : precision, - &is_negative, &num_buf[1], &s_len); - if (is_negative) - prefix_char = '-'; - else if (print_sign) - prefix_char = '+'; - else if (print_blank) - prefix_char = ' '; - break; - - - case 'g': - case 'G': - if (adjust_precision == NO) - precision = FLOAT_DIGITS; - else if (precision == 0) - precision = 1; - /* - * * We use &num_buf[ 1 ], so that we have room for the sign - */ - s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1], - alternate_form); - if (*s == '-') - prefix_char = *s++; - else if (print_sign) - prefix_char = '+'; - else if (print_blank) - prefix_char = ' '; - - s_len = strlen(s); - - if (alternate_form && (q = strchr(s, '.')) == NULL) { - s[s_len++] = '.'; - s[s_len] = '\0'; /* delimit for following strchr() */ - } - if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL) - *q = 'E'; - break; - - - case 'c': - char_buf[0] = (char) (va_arg(ap, int)); - s = &char_buf[0]; - s_len = 1; - pad_char = ' '; - break; - - - case '%': - char_buf[0] = '%'; - s = &char_buf[0]; - s_len = 1; - pad_char = ' '; - break; - - - case 'n': - *(va_arg(ap, int *)) = cc; - break; - - /* - * This is where we extend the printf format, with a second - * type specifier - */ - case 'p': - switch(*++fmt) { - /* - * If the pointer size is equal to the size of an unsigned - * integer we convert the pointer to a hex number, otherwise - * we print "%p" to indicate that we don't handle "%p". - */ - case 'p': - ui_num = (u_wide_int) va_arg(ap, void *); - - if (sizeof(char *) <= sizeof(u_wide_int)) - s = conv_p2(ui_num, 4, 'x', - &num_buf[NUM_BUF_SIZE], &s_len); - else { - s = "%p"; - s_len = 2; - prefix_char = NUL; - } - pad_char = ' '; - break; - - /* print a struct sockaddr_in as a.b.c.d:port */ - case 'I': - { - struct sockaddr_in *si; - - si = va_arg(ap, struct sockaddr_in *); - if (si != NULL) { - s = conv_sockaddr_in(si, &num_buf[NUM_BUF_SIZE], &s_len); - if (adjust_precision && precision < s_len) - s_len = precision; - } - else { - s = S_NULL; - s_len = S_NULL_LEN; - } - pad_char = ' '; - } - break; - - /* print a struct in_addr as a.b.c.d */ - case 'A': - { - struct in_addr *ia; - - ia = va_arg(ap, struct in_addr *); - if (ia != NULL) { - s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len); - if (adjust_precision && precision < s_len) - s_len = precision; - } - else { - s = S_NULL; - s_len = S_NULL_LEN; - } - pad_char = ' '; - } - break; - - case NUL: - /* if %p ends the string, oh well ignore it */ - continue; - - default: - s = "bogus %p"; - s_len = 8; - prefix_char = NUL; - break; - } - break; - - case NUL: - /* - * The last character of the format string was %. - * We ignore it. - */ - continue; - - - /* - * The default case is for unrecognized %'s. - * We print %<char> to help the user identify what - * option is not understood. - * This is also useful in case the user wants to pass - * the output of format_converter to another function - * that understands some other %<char> (like syslog). - * Note that we can't point s inside fmt because the - * unknown <char> could be preceded by width etc. - */ - default: - char_buf[0] = '%'; - char_buf[1] = *fmt; - s = char_buf; - s_len = 2; - pad_char = ' '; - break; - } - - if (prefix_char != NUL && s != S_NULL && s != char_buf) { - *--s = prefix_char; - s_len++; - } - - if (adjust_width && adjust == RIGHT && min_width > s_len) { - if (pad_char == '0' && prefix_char != NUL) { - INS_CHAR(*s, sp, bep, cc); - s++; - s_len--; - min_width--; - } - PAD(min_width, s_len, pad_char); - } - - /* - * Print the string s. - */ - for (i = s_len; i != 0; i--) { - INS_CHAR(*s, sp, bep, cc); - s++; - } - - if (adjust_width && adjust == LEFT && min_width > s_len) - PAD(min_width, s_len, pad_char); - } - fmt++; - } - vbuff->curpos = sp; - return cc; -} - - -static int snprintf_flush(ap_vformatter_buff_t *vbuff) -{ - /* if the buffer fills we have to abort immediately, there is no way - * to "flush" an ap_snprintf... there's nowhere to flush it to. - */ - return -1; -} - - -API_EXPORT(int) ap_snprintf(char *buf, size_t len, const char *format,...) -{ - int cc; - va_list ap; - ap_vformatter_buff_t vbuff; - - if (len == 0) - return 0; - - /* save one byte for nul terminator */ - vbuff.curpos = buf; - vbuff.endpos = buf + len - 1; - va_start(ap, format); - cc = ap_vformatter(snprintf_flush, &vbuff, format, ap); - va_end(ap); - *vbuff.curpos = '\0'; - return (cc == -1) ? len : cc; -} - - -API_EXPORT(int) ap_vsnprintf(char *buf, size_t len, const char *format, - va_list ap) -{ - int cc; - ap_vformatter_buff_t vbuff; - - if (len == 0) - return 0; - - /* save one byte for nul terminator */ - vbuff.curpos = buf; - vbuff.endpos = buf + len - 1; - cc = ap_vformatter(snprintf_flush, &vbuff, format, ap); - *vbuff.curpos = '\0'; - return (cc == -1) ? len : cc; -} - diff --git a/lib/apr_tables.c b/lib/apr_tables.c deleted file mode 100644 index ccc16a298..000000000 --- a/lib/apr_tables.c +++ /dev/null @@ -1,775 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. 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 acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ - -/* - * Resource allocation code... the code here is responsible for making - * sure that nothing leaks. - * - * rst --- 4/95 --- 6/95 - */ - -#ifndef WIN32 -#include "apr_config.h" -#else -#include "apr_win.h" -#endif - -#include "apr_general.h" -#include "apr_pools.h" -#include "apr_lib.h" -#include "misc.h" -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif - -/***************************************************************** - * This file contains array and table functions only. - */ - -/***************************************************************** - * - * The 'array' functions... - */ - -static void make_array_core(ap_array_header_t *res, struct context_t *c, - int nelts, int elt_size) -{ - /* - * Assure sanity if someone asks for - * array of zero elts. - */ - if (nelts < 1) { - nelts = 1; - } - - res->elts = ap_pcalloc(c, nelts * elt_size); - - res->cont = c; - res->elt_size = elt_size; - res->nelts = 0; /* No active elements yet... */ - res->nalloc = nelts; /* ...but this many allocated */ -} - -API_EXPORT(ap_array_header_t *) ap_make_array(struct context_t *p, - int nelts, int elt_size) -{ - ap_array_header_t *res; - - res = (ap_array_header_t *) ap_palloc(p, sizeof(ap_array_header_t)); - make_array_core(res, p, nelts, elt_size); - return res; -} - -API_EXPORT(void *) ap_push_array(ap_array_header_t *arr) -{ - if (arr->nelts == arr->nalloc) { - int new_size = (arr->nalloc <= 0) ? 1 : arr->nalloc * 2; - char *new_data; - - new_data = ap_pcalloc(arr->cont, arr->elt_size * new_size); - - memcpy(new_data, arr->elts, arr->nalloc * arr->elt_size); - arr->elts = new_data; - arr->nalloc = new_size; - } - - ++arr->nelts; - return arr->elts + (arr->elt_size * (arr->nelts - 1)); -} - -API_EXPORT(void) ap_array_cat(ap_array_header_t *dst, - const ap_array_header_t *src) -{ - int elt_size = dst->elt_size; - - if (dst->nelts + src->nelts > dst->nalloc) { - int new_size = (dst->nalloc <= 0) ? 1 : dst->nalloc * 2; - char *new_data; - - while (dst->nelts + src->nelts > new_size) { - new_size *= 2; - } - - new_data = ap_pcalloc(dst->cont, elt_size * new_size); - memcpy(new_data, dst->elts, dst->nalloc * elt_size); - - dst->elts = new_data; - dst->nalloc = new_size; - } - - memcpy(dst->elts + dst->nelts * elt_size, src->elts, - elt_size * src->nelts); - dst->nelts += src->nelts; -} - -API_EXPORT(ap_array_header_t *) ap_copy_array(struct context_t *p, - const ap_array_header_t *arr) -{ - ap_array_header_t *res = ap_make_array(p, arr->nalloc, arr->elt_size); - - memcpy(res->elts, arr->elts, arr->elt_size * arr->nelts); - res->nelts = arr->nelts; - return res; -} - -/* This cute function copies the array header *only*, but arranges - * for the data section to be copied on the first push or arraycat. - * It's useful when the elements of the array being copied are - * read only, but new stuff *might* get added on the end; we have the - * overhead of the full copy only where it is really needed. - */ - -static APR_INLINE void copy_array_hdr_core(ap_array_header_t *res, - const ap_array_header_t *arr) -{ - res->elts = arr->elts; - res->elt_size = arr->elt_size; - res->nelts = arr->nelts; - res->nalloc = arr->nelts; /* Force overflow on push */ -} - -API_EXPORT(ap_array_header_t *) - ap_copy_array_hdr(struct context_t *p, - const ap_array_header_t *arr) -{ - ap_array_header_t *res; - - res = (ap_array_header_t *) ap_palloc(p, sizeof(ap_array_header_t)); - res->cont = p; - copy_array_hdr_core(res, arr); - return res; -} - -/* The above is used here to avoid consing multiple new array bodies... */ - -API_EXPORT(ap_array_header_t *) - ap_append_arrays(struct context_t *p, - const ap_array_header_t *first, - const ap_array_header_t *second) -{ - ap_array_header_t *res = ap_copy_array_hdr(p, first); - - ap_array_cat(res, second); - return res; -} - -/* ap_array_pstrcat generates a new string from the pool 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. - */ -API_EXPORT(char *) ap_array_pstrcat(struct context_t *p, - const ap_array_header_t *arr, - const char sep) -{ - char *cp, *res, **strpp; - int i, len; - - if (arr->nelts <= 0 || arr->elts == NULL) { /* Empty table? */ - return (char *) ap_pcalloc(p, 1); - } - - /* Pass one --- find length of required string */ - - len = 0; - for (i = 0, strpp = (char **) arr->elts; ; ++strpp) { - if (strpp && *strpp != NULL) { - len += strlen(*strpp); - } - if (++i >= arr->nelts) { - break; - } - if (sep) { - ++len; - } - } - - /* Allocate the required string */ - - res = (char *) ap_palloc(p, len + 1); - cp = res; - - /* Pass two --- copy the argument strings into the result space */ - - for (i = 0, strpp = (char **) arr->elts; ; ++strpp) { - if (strpp && *strpp != NULL) { - len = strlen(*strpp); - memcpy(cp, *strpp, len); - cp += len; - } - if (++i >= arr->nelts) { - break; - } - if (sep) { - *cp++ = sep; - } - } - - *cp = '\0'; - - /* Return the result string */ - - return res; -} - - -/***************************************************************** - * - * The "table" functions. - */ - -/* - * XXX: if you tweak this you should look at is_empty_table() and table_elts() - * in alloc.h - */ -#ifdef MAKE_TABLE_PROFILE -static ap_table_entry_t *table_push(ap_table_t *t) -{ - if (t->a.nelts == t->a.nalloc) { - fprintf(stderr, - "table_push: table created by %p hit limit of %u\n", - t->creator, t->a.nalloc); - } - return (ap_table_entry_t *) ap_push_array(&t->a); -} -#else /* MAKE_TABLE_PROFILE */ -#define table_push(t) ((ap_table_entry_t *) ap_push_array(&(t)->a)) -#endif /* MAKE_TABLE_PROFILE */ - - -API_EXPORT(ap_table_t *) ap_make_table(struct context_t *p, int nelts) -{ - ap_table_t *t = ap_palloc(p, sizeof(ap_table_t)); - - make_array_core(&t->a, p, nelts, sizeof(ap_table_entry_t)); -#ifdef MAKE_TABLE_PROFILE - t->creator = __builtin_return_address(0); -#endif - return t; -} - -API_EXPORT(ap_table_t *) ap_copy_table(struct context_t *p, const ap_table_t *t) -{ - ap_table_t *new = ap_palloc(p, sizeof(ap_table_t)); - -#ifdef POOL_DEBUG - /* we don't copy keys and values, so it's necessary that t->a.pool - * have a life span at least as long as p - */ - if (!ap_pool_is_ancestor(t->a.pool, p)) { - fprintf(stderr, "copy_table: t's pool is not an ancestor of p\n"); - abort(); - } -#endif - make_array_core(&new->a, p, t->a.nalloc, sizeof(ap_table_entry_t)); - memcpy(new->a.elts, t->a.elts, t->a.nelts * sizeof(ap_table_entry_t)); - new->a.nelts = t->a.nelts; - return new; -} - -API_EXPORT(void) ap_clear_table(ap_table_t *t) -{ - t->a.nelts = 0; -} - -API_EXPORT(const char *) ap_table_get(const ap_table_t *t, const char *key) -{ - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - int i; - - if (key == NULL) { - return NULL; - } - - for (i = 0; i < t->a.nelts; ++i) { - if (!strcasecmp(elts[i].key, key)) { - return elts[i].val; - } - } - - return NULL; -} - -API_EXPORT(void) ap_table_set(ap_table_t *t, const char *key, - const char *val) -{ - register int i, j, k; - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - int done = 0; - - for (i = 0; i < t->a.nelts; ) { - if (!strcasecmp(elts[i].key, key)) { - if (!done) { - elts[i].val = ap_pstrdup(t->a.cont, val); - done = 1; - ++i; - } - else { /* delete an extraneous element */ - for (j = i, k = i + 1; k < t->a.nelts; ++j, ++k) { - elts[j].key = elts[k].key; - elts[j].val = elts[k].val; - } - --t->a.nelts; - } - } - else { - ++i; - } - } - - if (!done) { - elts = (ap_table_entry_t *) table_push(t); - elts->key = ap_pstrdup(t->a.cont, key); - elts->val = ap_pstrdup(t->a.cont, val); - } -} - -API_EXPORT(void) ap_table_setn(ap_table_t *t, const char *key, - const char *val) -{ - register int i, j, k; - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - int done = 0; - -#ifdef POOL_DEBUG - { - if (!ap_pool_is_ancestor(ap_find_pool(key), t->a.pool)) { - fprintf(stderr, "table_set: key not in ancestor pool of t\n"); - abort(); - } - if (!ap_pool_is_ancestor(ap_find_pool(val), t->a.pool)) { - fprintf(stderr, "table_set: val not in ancestor pool of t\n"); - abort(); - } - } -#endif - - for (i = 0; i < t->a.nelts; ) { - if (!strcasecmp(elts[i].key, key)) { - if (!done) { - elts[i].val = (char *)val; - done = 1; - ++i; - } - else { /* delete an extraneous element */ - for (j = i, k = i + 1; k < t->a.nelts; ++j, ++k) { - elts[j].key = elts[k].key; - elts[j].val = elts[k].val; - } - --t->a.nelts; - } - } - else { - ++i; - } - } - - if (!done) { - elts = (ap_table_entry_t *) table_push(t); - elts->key = (char *)key; - elts->val = (char *)val; - } -} - -API_EXPORT(void) ap_table_unset(ap_table_t *t, const char *key) -{ - register int i, j, k; - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - - for (i = 0; i < t->a.nelts; ) { - if (!strcasecmp(elts[i].key, key)) { - - /* found an element to skip over - * there are any number of ways to remove an element from - * a contiguous block of memory. I've chosen one that - * doesn't do a memcpy/bcopy/array_delete, *shrug*... - */ - for (j = i, k = i + 1; k < t->a.nelts; ++j, ++k) { - elts[j].key = elts[k].key; - elts[j].val = elts[k].val; - } - --t->a.nelts; - } - else { - ++i; - } - } -} - -API_EXPORT(void) ap_table_merge(ap_table_t *t, const char *key, - const char *val) -{ - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - int i; - - for (i = 0; i < t->a.nelts; ++i) { - if (!strcasecmp(elts[i].key, key)) { - elts[i].val = ap_pstrcat(t->a.cont, elts[i].val, ", ", val, NULL); - return; - } - } - - elts = (ap_table_entry_t *) table_push(t); - elts->key = ap_pstrdup(t->a.cont, key); - elts->val = ap_pstrdup(t->a.cont, val); -} - -API_EXPORT(void) ap_table_mergen(ap_table_t *t, const char *key, - const char *val) -{ - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - int i; - -#ifdef POOL_DEBUG - { - if (!ap_pool_is_ancestor(ap_find_pool(key), t->a.pool)) { - fprintf(stderr, "table_set: key not in ancestor pool of t\n"); - abort(); - } - if (!ap_pool_is_ancestor(ap_find_pool(val), t->a.pool)) { - fprintf(stderr, "table_set: key not in ancestor pool of t\n"); - abort(); - } - } -#endif - - for (i = 0; i < t->a.nelts; ++i) { - if (!strcasecmp(elts[i].key, key)) { - elts[i].val = ap_pstrcat(t->a.cont, elts[i].val, ", ", val, NULL); - return; - } - } - - elts = (ap_table_entry_t *) table_push(t); - elts->key = (char *)key; - elts->val = (char *)val; -} - -API_EXPORT(void) ap_table_add(ap_table_t *t, const char *key, - const char *val) -{ - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - - elts = (ap_table_entry_t *) table_push(t); - elts->key = ap_pstrdup(t->a.cont, key); - elts->val = ap_pstrdup(t->a.cont, val); -} - -API_EXPORT(void) ap_table_addn(ap_table_t *t, const char *key, - const char *val) -{ - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - -#ifdef POOL_DEBUG - { - if (!ap_pool_is_ancestor(ap_find_pool(key), t->a.pool)) { - fprintf(stderr, "table_set: key not in ancestor pool of t\n"); - abort(); - } - if (!ap_pool_is_ancestor(ap_find_pool(val), t->a.pool)) { - fprintf(stderr, "table_set: key not in ancestor pool of t\n"); - abort(); - } - } -#endif - - elts = (ap_table_entry_t *) table_push(t); - elts->key = (char *)key; - elts->val = (char *)val; -} - -API_EXPORT(ap_table_t *) ap_overlay_tables(struct context_t *p, - const ap_table_t *overlay, - const ap_table_t *base) -{ - ap_table_t *res; - -#ifdef POOL_DEBUG - /* we don't copy keys and values, so it's necessary that - * overlay->a.pool and base->a.pool have a life span at least - * as long as p - */ - if (!ap_pool_is_ancestor(overlay->a.pool, p->pool)) { - fprintf(stderr, - "overlay_tables: overlay's pool is not an ancestor of p\n"); - abort(); - } - if (!ap_pool_is_ancestor(base->a.pool, p->pool)) { - fprintf(stderr, - "overlay_tables: base's pool is not an ancestor of p\n"); - abort(); - } -#endif - - res = ap_palloc(p, sizeof(ap_table_t)); - /* behave like append_arrays */ - res->a.cont = p; - copy_array_hdr_core(&res->a, &overlay->a); - ap_array_cat(&res->a, &base->a); - - return res; -} - -/* And now for something completely abstract ... - - * For each key value given as a vararg: - * run the function pointed to as - * int comp(void *r, char *key, char *value); - * on each valid key-value pair in the table t that matches the vararg key, - * or once for every valid key-value pair if the vararg list is empty, - * until the function returns false (0) or we finish the table. - * - * Note that we restart the traversal for each vararg, which means that - * duplicate varargs will result in multiple executions of the function - * for each matching key. Note also that if the vararg list is empty, - * only one traversal will be made and will cut short if comp returns 0. - * - * Note that the table_get and table_merge functions assume that each key in - * the table is unique (i.e., no multiple entries with the same key). This - * function does not make that assumption, since it (unfortunately) isn't - * true for some of Apache's tables. - * - * Note that rec is simply passed-on to the comp function, so that the - * caller can pass additional info for the task. - */ -API_EXPORT(void) ap_table_do(int (*comp) (void *, const char *, const char *), - void *rec, const ap_table_t *t, ...) -{ - va_list vp; - char *argp; - ap_table_entry_t *elts = (ap_table_entry_t *) t->a.elts; - int rv, i; - - va_start(vp, t); - - argp = va_arg(vp, char *); - - do { - for (rv = 1, i = 0; rv && (i < t->a.nelts); ++i) { - if (elts[i].key && (!argp || !strcasecmp(elts[i].key, argp))) { - rv = (*comp) (rec, elts[i].key, elts[i].val); - } - } - } while (argp && ((argp = va_arg(vp, char *)) != NULL)); - - va_end(vp); -} - -/* Curse libc and the fact that it doesn't guarantee a stable sort. We - * have to enforce stability ourselves by using the order field. If it - * provided a stable sort then we wouldn't even need temporary storage to - * do the work below. -djg - * - * ("stable sort" means that equal keys retain their original relative - * ordering in the output.) - */ -typedef struct { - char *key; - char *val; - int order; -} overlap_key; - -static int sort_overlap(const void *va, const void *vb) -{ - const overlap_key *a = va; - const overlap_key *b = vb; - int r; - - r = strcasecmp(a->key, b->key); - if (r) { - return r; - } - return a->order - b->order; -} - -/* prefer to use the stack for temp storage for overlaps smaller than this */ -#ifndef ap_OVERLAP_TABLES_ON_STACK -#define ap_OVERLAP_TABLES_ON_STACK (512) -#endif - -API_EXPORT(void) ap_overlap_tables(ap_table_t *a, const ap_table_t *b, - unsigned flags) -{ - overlap_key cat_keys_buf[ap_OVERLAP_TABLES_ON_STACK]; - overlap_key *cat_keys; - int nkeys; - ap_table_entry_t *e; - ap_table_entry_t *last_e; - overlap_key *left; - overlap_key *right; - overlap_key *last; - - nkeys = a->a.nelts + b->a.nelts; - if (nkeys < ap_OVERLAP_TABLES_ON_STACK) { - cat_keys = cat_keys_buf; - } - else { - /* XXX: could use scratch free space in a or b's pool instead... - * which could save an allocation in b's pool. - */ - cat_keys = ap_palloc(b->a.cont, sizeof(overlap_key) * nkeys); - } - - nkeys = 0; - - /* Create a list of the entries from a concatenated with the entries - * from b. - */ - e = (ap_table_entry_t *)a->a.elts; - last_e = e + a->a.nelts; - while (e < last_e) { - cat_keys[nkeys].key = e->key; - cat_keys[nkeys].val = e->val; - cat_keys[nkeys].order = nkeys; - ++nkeys; - ++e; - } - - e = (ap_table_entry_t *)b->a.elts; - last_e = e + b->a.nelts; - while (e < last_e) { - cat_keys[nkeys].key = e->key; - cat_keys[nkeys].val = e->val; - cat_keys[nkeys].order = nkeys; - ++nkeys; - ++e; - } - - qsort(cat_keys, nkeys, sizeof(overlap_key), sort_overlap); - - /* Now iterate over the sorted list and rebuild a. - * Start by making sure it has enough space. - */ - a->a.nelts = 0; - if (a->a.nalloc < nkeys) { - a->a.elts = ap_palloc(a->a.cont, a->a.elt_size * nkeys * 2); - a->a.nalloc = nkeys * 2; - } - - /* - * In both the merge and set cases we retain the invariant: - * - * left->key, (left+1)->key, (left+2)->key, ..., (right-1)->key - * are all equal keys. (i.e. strcasecmp returns 0) - * - * We essentially need to find the maximal - * right for each key, then we can do a quick merge or set as - * appropriate. - */ - - if (flags & ap_OVERLAP_TABLES_MERGE) { - left = cat_keys; - last = left + nkeys; - while (left < last) { - right = left + 1; - if (right == last - || strcasecmp(left->key, right->key)) { - ap_table_addn(a, left->key, left->val); - left = right; - } - else { - char *strp; - char *value; - size_t len; - - /* Have to merge some headers. Let's re-use the order field, - * since it's handy... we'll store the length of val there. - */ - left->order = strlen(left->val); - len = left->order; - do { - right->order = strlen(right->val); - len += 2 + right->order; - ++right; - } while (right < last - && !strcasecmp(left->key, right->key)); - /* right points one past the last header to merge */ - value = ap_palloc(a->a.cont, len + 1); - strp = value; - for (;;) { - memcpy(strp, left->val, left->order); - strp += left->order; - ++left; - if (left == right) { - break; - } - *strp++ = ','; - *strp++ = ' '; - } - *strp = 0; - ap_table_addn(a, (left-1)->key, value); - } - } - } - else { - left = cat_keys; - last = left + nkeys; - while (left < last) { - right = left + 1; - while (right < last && !strcasecmp(left->key, right->key)) { - ++right; - } - ap_table_addn(a, (right-1)->key, (right-1)->val); - left = right; - } - } -} - diff --git a/lib/lib.def b/lib/lib.def deleted file mode 100644 index 20996d469..000000000 --- a/lib/lib.def +++ /dev/null @@ -1,60 +0,0 @@ -; lib.def : - -LIBRARY lib -DESCRIPTION '' - -EXPORTS - ; Add new API calls to the end of this list. - apr_MD5Final @1 - apr_MD5Init @2 - apr_MD5Update @3 - apr_cpystrn @4 - ap_register_cleanup @5 - ap_kill_cleanup @6 - apr_fnmatch @7 - apr_is_fnmatch @8 - apr_MD5Encode @9 - apr_validate_password @10 - ap_make_sub_pool @11 - ap_init_alloc @12 - ap_clear_pool @13 - ap_destroy_pool @14 - ap_bytes_in_pool @15 - ap_bytes_in_free_blocks @16 - ap_palloc @20 - ap_pcalloc @21 - ap_pstrdup @22 - ap_pstrndup @23 - ap_pstrcat @24 - ap_pvsprintf @25 - ap_psprintf @26 - ap_make_array @27 - ap_push_array @28 - ap_array_cat @29 - ap_copy_array @30 - ap_copy_array_hdr @31 - ap_append_arrays @32 - ap_array_pstrcat @33 - ap_make_table @34 - ap_copy_table @35 - ap_clear_table @36 - ap_table_get @37 - ap_table_set @38 - ap_table_setn @39 - ap_table_unset @40 - ap_table_merge @41 - ap_table_mergen @42 - ap_table_add @43 - ap_table_addn @44 - ap_overlay_tables @45 - ap_table_do @46 - ap_overlap_tables @47 - ap_run_cleanup @48 - ap_cleanup_for_exec @49 - ap_null_cleanup @50 - ap_note_subprocess @51 - apr_slack @54 - ap_vformatter @55 - ap_snprintf @56 - ap_vsnprintf @57 - ap_getpass @58 diff --git a/lib/lib.dsp b/lib/lib.dsp deleted file mode 100644 index f9b63059d..000000000 --- a/lib/lib.dsp +++ /dev/null @@ -1,129 +0,0 @@ -# Microsoft Developer Studio Project File - Name="lib" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 5.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=lib - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "lib.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "lib.mak" CFG="lib - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "lib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "lib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "lib - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include ..\..\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 - -!ELSEIF "$(CFG)" == "lib - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\include" /I "..\misc\win32" /I "..\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "lib - Win32 Release" -# Name "lib - Win32 Debug" -# Begin Source File - -SOURCE=.\apr_cpystrn.c -# End Source File -# Begin Source File - -SOURCE=.\apr_execve.c -# End Source File -# Begin Source File - -SOURCE=.\apr_fnmatch.c -# End Source File -# Begin Source File - -SOURCE=.\apr_getpass.c -# End Source File -# Begin Source File - -SOURCE=.\apr_md5.c -# End Source File -# Begin Source File - -SOURCE=.\apr_pools.c -# End Source File -# Begin Source File - -SOURCE=.\apr_slack.c -# End Source File -# Begin Source File - -SOURCE=.\apr_snprintf.c -# End Source File -# Begin Source File - -SOURCE=.\apr_tables.c -# End Source File -# Begin Source File - -SOURCE=.\lib.def -# End Source File -# End Target -# End Project |