joes 2002/12/18 22:31:37
Modified: patches README apache-1.3+apreq.patch
Log:
Simplify patch; adding more instuctions.
Revision Changes Path
1.3 +3 -1 httpd-apreq/patches/README
Index: README
===================================================================
RCS file: /home/cvs/httpd-apreq/patches/README,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- README 19 Dec 2002 06:16:42 -0000 1.2
+++ README 19 Dec 2002 06:31:37 -0000 1.3
@@ -3,10 +3,12 @@
apache-1.3+apreq.patch
patches apache-1.3 source to build libapreq directly into httpd.
- To apply:
+ To apply (assuming the apache-1.3.XX source is along side of the
+ apreq-1.X source):
% cd ../../apache-1.3.XX/
% patch -p0 < ../httpd-apreq/patches/apache-1.3+apreq.patch
+ % cp ../httpd-apreq/c/*.[ch] src/lib/apreq/
Then build and install apache (+modperl) as normal. If you want to
use Apache::Request and Apache::Cookie, you'll also need to remove
1.2 +0 -1452 httpd-apreq/patches/apache-1.3+apreq.patch
Index: apache-1.3+apreq.patch
===================================================================
RCS file: /home/cvs/httpd-apreq/patches/apache-1.3+apreq.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- apache-1.3+apreq.patch 19 Dec 2002 06:15:04 -0000 1.1
+++ apache-1.3+apreq.patch 19 Dec 2002 06:31:37 -0000 1.2
@@ -105,1458 +105,6 @@
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $<
-diff -urN ../apache-1.3/src/lib/apreq/apache_cookie.c
./src/lib/apreq/apache_cookie.c
---- ../apache-1.3/src/lib/apreq/apache_cookie.c Wed Dec 31 19:00:00 1969
-+++ ./src/lib/apreq/apache_cookie.c Thu Dec 19 00:22:38 2002
-@@ -0,0 +1,269 @@
-+/* ====================================================================
-+ * The Apache Software License, Version 1.1
-+ *
-+ * Copyright (c) 2000 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
-+ * if any, must include the following acknowledgment:
-+ * "This product includes software developed by the
-+ * Apache Software Foundation (http://www.apache.org/)."
-+ * Alternately, this acknowledgment may appear in the software itself,
-+ * if and wherever such third-party acknowledgments normally appear.
-+ *
-+ * 4. The names "Apache" and "Apache Software Foundation" must
-+ * not be used to endorse or promote products derived from this
-+ * software without prior written permission. For written
-+ * permission, please contact [EMAIL PROTECTED]
-+ *
-+ * 5. Products derived from this software may not be called "Apache",
-+ * nor may "Apache" appear in their name, without prior written
-+ * permission of the Apache Software Foundation.
-+ *
-+ * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation. For more
-+ * information on the Apache Software Foundation, please see
-+ * <http://www.apache.org/>.
-+ *
-+ * Portions of this software are based upon public domain software
-+ * originally written at the National Center for Supercomputing
Applications,
-+ * University of Illinois, Urbana-Champaign.
-+ */
-+
-+#include "apache_cookie.h"
-+
-+char *ApacheCookie_expires(ApacheCookie *c, char *time_str)
-+{
-+ char *expires;
-+
-+ expires = ApacheUtil_expires(c->r->pool, time_str, EXPIRES_COOKIE);
-+ if (expires)
-+ c->expires = expires;
-+
-+ return c->expires;
-+}
-+
-+#define cookie_get_set(thing,val) \
-+ retval = thing; \
-+ if(val) thing = ap_pstrdup(c->r->pool, val)
-+
-+char *ApacheCookie_attr(ApacheCookie *c, char *key, char *val)
-+{
-+ char *retval = NULL;
-+ int ix = key[0] == '-' ? 1 : 0;
-+
-+ switch (key[ix]) {
-+ case 'n':
-+ cookie_get_set(c->name, val);
-+ break;
-+ case 'v':
-+ ApacheCookieAdd(c, val);
-+ break;
-+ case 'e':
-+ retval = ApacheCookie_expires(c, val);
-+ break;
-+ case 'd':
-+ cookie_get_set(c->domain, val);
-+ break;
-+ case 'p':
-+ cookie_get_set(c->path, val);
-+ break;
-+ case 's':
-+ if(val) {
-+ c->secure =
-+ !strcaseEQ(val, "off") &&
-+ !strcaseEQ(val, "0");
-+ }
-+ retval = c->secure ? "on" : "";
-+ break;
-+ default:
-+ ap_log_rerror(APC_ERROR,
-+ "[libapreq] unknown cookie pair: `%s' => `%s'", key, val);
-+ };
-+
-+ return retval;
-+}
-+
-+ApacheCookie *ApacheCookie_new(request_rec *r, ...)
-+{
-+ va_list args;
-+ ApacheRequest req;
-+ ApacheCookie *c =
-+ ap_pcalloc(r->pool, sizeof(ApacheCookie));
-+
-+ req.r = r;
-+ c->r = r;
-+ c->values = ap_make_array(r->pool, 1, sizeof(char *));
-+ c->secure = 0;
-+ c->name = c->expires = NULL;
-+
-+ c->domain = NULL;
-+ c->path = ApacheRequest_script_path(&req);
-+
-+ va_start(args, r);
-+ for(;;) {
-+ char *key, *val;
-+ key = va_arg(args, char *);
-+ if (key == NULL)
-+ break;
-+
-+ val = va_arg(args, char *);
-+ (void)ApacheCookie_attr(c, key, val);
-+ }
-+ va_end(args);
-+
-+ return c;
-+}
-+
-+ApacheCookieJar *ApacheCookie_parse(request_rec *r, const char *data)
-+{
-+ const char *pair;
-+ ApacheCookieJar *retval =
-+ ap_make_array(r->pool, 1, sizeof(ApacheCookie *));
-+
-+ if (!data)
-+ if (!(data = ap_table_get(r->headers_in, "Cookie")))
-+ return retval;
-+
-+ while (*data && (pair = ap_getword(r->pool, &data, ';'))) {
-+ const char *key, *val;
-+ ApacheCookie *c;
-+
-+ while (ap_isspace(*data))
-+ ++data;
-+
-+ key = ap_getword(r->pool, &pair, '=');
-+ ap_unescape_url((char *)key);
-+ c = ApacheCookie_new(r, "-name", key, NULL);
-+
-+ if (c->values)
-+ c->values->nelts = 0;
-+ else
-+ c->values = ap_make_array(r->pool, 4, sizeof(char *));
-+
-+ if (!*pair)
-+ ApacheCookieAdd(c, "");
-+
-+
-+ while (*pair && (val = ap_getword_nulls(r->pool, &pair, '&'))) {
-+ ap_unescape_url((char *)val);
-+#ifdef DEBUG
-+ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
-+ "[apache_cookie] added (%s)", val);
-+#endif
-+ ApacheCookieAdd(c, val);
-+ }
-+ ApacheCookieJarAdd(retval, c);
-+ }
-+
-+ return retval;
-+}
-+
-+#define cookie_push_arr(arr, val) \
-+ *(char **)ap_push_array(arr) = (char *)val
-+
-+#define cookie_push_named(arr, name, val) \
-+ if(val && strlen(val) > 0) { \
-+ cookie_push_arr(arr, ap_pstrcat(p, name, "=", val, NULL)); \
-+ }
-+
-+static char * escape_url(pool *p, char *val)
-+{
-+ char *result = ap_os_escape_path(p, val?val:"", 1);
-+ char *end = result + strlen(result);
-+ char *seek;
-+
-+ /* touchup result to ensure that special chars are escaped */
-+ for ( seek = end-1; seek >= result; --seek) {
-+ char *ptr, *replacement;
-+
-+ switch (*seek) {
-+
-+ case '&':
-+ replacement = "%26";
-+ break;
-+ case '=':
-+ replacement = "%3d";
-+ break;
-+ /* additional cases here */
-+
-+ default:
-+ continue; /* next for() */
-+ }
-+
-+ for (ptr = end; ptr > seek; --ptr)
-+ ptr[2] = ptr[0];
-+
-+ strncpy(seek, replacement, 3);
-+ end += 2;
-+ }
-+
-+ return(result);
-+}
-+
-+char *ApacheCookie_as_string(ApacheCookie *c)
-+{
-+ array_header *values;
-+ pool *p = c->r->pool;
-+ char *cookie, *retval;
-+ int i;
-+
-+ if (!c->name)
-+ return "";
-+
-+ values = ap_make_array(p, 6, sizeof(char *));
-+ cookie_push_named(values, "domain", c->domain);
-+ cookie_push_named(values, "path", c->path);
-+ cookie_push_named(values, "expires", c->expires);
-+ if (c->secure) {
-+ cookie_push_arr(values, "secure");
-+ }
-+
-+ cookie = ap_pstrcat(p, escape_url(p, c->name), "=", NULL);
-+ for (i=0; i<c->values->nelts; i++) {
-+ cookie = ap_pstrcat(p, cookie,
-+ escape_url(p, ((char**)c->values->elts)[i]),
-+ (i < (c->values->nelts -1) ? "&" : NULL),
-+ NULL);
-+ }
-+
-+ retval = cookie;
-+ for (i=0; i<values->nelts; i++) {
-+ retval = ap_pstrcat(p, retval, "; ",
-+ ((char**)values->elts)[i], NULL);
-+ }
-+
-+ return retval;
-+}
-+
-+void ApacheCookie_bake(ApacheCookie *c)
-+{
-+ ap_table_add(c->r->err_headers_out, "Set-Cookie",
-+ ApacheCookie_as_string(c));
-+}
-diff -urN ../apache-1.3/src/lib/apreq/apache_cookie.h
./src/lib/apreq/apache_cookie.h
---- ../apache-1.3/src/lib/apreq/apache_cookie.h Wed Dec 31 19:00:00 1969
-+++ ./src/lib/apreq/apache_cookie.h Thu Dec 19 00:22:38 2002
-@@ -0,0 +1,57 @@
-+#ifndef _APACHE_COOKIE_H
-+#define _APACHE_COOKIE_H
-+
-+#include "apache_request.h"
-+
-+typedef array_header ApacheCookieJar;
-+
-+typedef struct {
-+ request_rec *r;
-+ char *name;
-+ array_header *values;
-+ char *domain;
-+ char *expires;
-+ char *path;
-+ int secure;
-+} ApacheCookie;
-+
-+#ifdef __cplusplus
-+ extern "C" {
-+#endif
-+
-+#define ApacheCookieJarItems(arr) arr->nelts
-+
-+#define ApacheCookieJarFetch(arr,i) \
-+((ApacheCookie *)(((ApacheCookie **)arr->elts)[i]))
-+
-+#define ApacheCookieJarAdd(arr,c) \
-+*(ApacheCookie **)ap_push_array(arr) = c
-+
-+#define ApacheCookieItems(c) c->values->nelts
-+
-+#define ApacheCookieFetch(c,i) \
-+((char *)(((char **)c->values->elts)[i]))
-+
-+#define ApacheCookieAddn(c,val) \
-+ if(val) *(char **)ap_push_array(c->values) = (char *)val
-+
-+#define ApacheCookieAdd(c,val) \
-+ ApacheCookieAddn(c, ap_pstrdup(c->r->pool, val))
-+
-+#define ApacheCookieAddLen(c,val,len) \
-+ ApacheCookieAddn(c, ap_pstrndup(c->r->pool, val, len))
-+
-+ApacheCookie *ApacheCookie_new(request_rec *r, ...);
-+ApacheCookieJar *ApacheCookie_parse(request_rec *r, const char *data);
-+char *ApacheCookie_as_string(ApacheCookie *c);
-+char *ApacheCookie_attr(ApacheCookie *c, char *key, char *val);
-+char *ApacheCookie_expires(ApacheCookie *c, char *time_str);
-+void ApacheCookie_bake(ApacheCookie *c);
-+
-+#ifdef __cplusplus
-+ }
-+#endif
-+
-+#define APC_ERROR APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, c->r
-+
-+#endif
-diff -urN ../apache-1.3/src/lib/apreq/apache_multipart_buffer.c
./src/lib/apreq/apache_multipart_buffer.c
---- ../apache-1.3/src/lib/apreq/apache_multipart_buffer.c Wed Dec 31
19:00:00 1969
-+++ ./src/lib/apreq/apache_multipart_buffer.c Thu Dec 19 00:22:38 2002
-@@ -0,0 +1,338 @@
-+/* ====================================================================
-+ * The Apache Software License, Version 1.1
-+ *
-+ * Copyright (c) 2000 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
-+ * if any, must include the following acknowledgment:
-+ * "This product includes software developed by the
-+ * Apache Software Foundation (http://www.apache.org/)."
-+ * Alternately, this acknowledgment may appear in the software itself,
-+ * if and wherever such third-party acknowledgments normally appear.
-+ *
-+ * 4. The names "Apache" and "Apache Software Foundation" must
-+ * not be used to endorse or promote products derived from this
-+ * software without prior written permission. For written
-+ * permission, please contact [EMAIL PROTECTED]
-+ *
-+ * 5. Products derived from this software may not be called "Apache",
-+ * nor may "Apache" appear in their name, without prior written
-+ * permission of the Apache Software Foundation.
-+ *
-+ * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation. For more
-+ * information on the Apache Software Foundation, please see
-+ * <http://www.apache.org/>.
-+ *
-+ * Portions of this software are based upon public domain software
-+ * originally written at the National Center for Supercomputing
Applications,
-+ * University of Illinois, Urbana-Champaign.
-+ */
-+
-+#include "apache_multipart_buffer.h"
-+
-+/*********************** internal functions *********************/
-+
-+/*
-+ search for a string in a fixed-length byte string.
-+ if partial is true, partial matches are allowed at the end of the buffer.
-+ returns NULL if not found, or a pointer to the start of the first match.
-+*/
-+void* my_memstr(char* haystack, int haystacklen, const char* needle,
-+ int partial)
-+{
-+ int needlen = strlen(needle);
-+ int len = haystacklen;
-+ char *ptr = haystack;
-+
-+ /* iterate through first character matches */
-+ while( (ptr = memchr(ptr, needle[0], len)) ) {
-+ /* calculate length after match */
-+ len = haystacklen - (ptr - (char *)haystack);
-+
-+ /* done if matches up to capacity of buffer */
-+ if(memcmp(needle, ptr, needlen < len ? needlen : len) == 0 &&
-+ (partial || len >= needlen))
-+ break;
-+
-+ /* next character */
-+ ptr++; len--;
-+ }
-+
-+ return ptr;
-+}
-+
-+/*
-+ fill up the buffer with client data.
-+ returns number of bytes added to buffer.
-+*/
-+int fill_buffer(multipart_buffer *self)
-+{
-+ int bytes_to_read, actual_read = 0;
-+
-+ /* shift the existing data if necessary */
-+ if(self->bytes_in_buffer > 0 && self->buf_begin != self->buffer)
-+ memmove(self->buffer, self->buf_begin, self->bytes_in_buffer);
-+ self->buf_begin = self->buffer;
-+
-+ /* calculate the free space in the buffer */
-+ bytes_to_read = self->bufsize - self->bytes_in_buffer;
-+
-+ if (bytes_to_read >= self->r->remaining) {
-+ bytes_to_read = self->r->remaining - strlen(self->boundary);
-+#ifdef DEBUG
-+ ap_log_rerror(MPB_ERROR, "mozilla 0.97 hack: '%ld'",
self->r->remaining);
-+#endif
-+ }
-+
-+ /* read the required number of bytes */
-+ if(bytes_to_read > 0) {
-+ char *buf = self->buffer + self->bytes_in_buffer;
-+ ap_hard_timeout("[libapreq] multipart_buffer.c:fill_buffer", self->r);
-+ actual_read = ap_get_client_block(self->r, buf, bytes_to_read);
-+ ap_kill_timeout(self->r);
-+
-+ /* update the buffer length */
-+ if(actual_read > 0)
-+ self->bytes_in_buffer += actual_read;
-+ }
-+
-+ return actual_read;
-+}
-+
-+/*
-+ gets the next CRLF terminated line from the input buffer.
-+ if it doesn't find a CRLF, and the buffer isn't completely full, returns
-+ NULL; otherwise, returns the beginning of the null-terminated line,
-+ minus the CRLF.
-+
-+ note that we really just look for LF terminated lines. this works
-+ around a bug in internet explorer for the macintosh which sends mime
-+ boundaries that are only LF terminated when you use an image submit
-+ button in a multipart/form-data form.
-+ */
-+char* next_line(multipart_buffer *self)
-+{
-+ /* look for LF in the data */
-+ char* line = self->buf_begin;
-+ char* ptr = memchr(self->buf_begin, '\n', self->bytes_in_buffer);
-+
-+ /* LF found */
-+ if(ptr) {
-+ /* terminate the string, remove CRLF */
-+ if((ptr - line) > 0 && *(ptr-1) == '\r') *(ptr-1) = 0;
-+ else *ptr = 0;
-+
-+ /* bump the pointer */
-+ self->buf_begin = ptr + 1;
-+ self->bytes_in_buffer -= (self->buf_begin - line);
-+ }
-+
-+ /* no LF found */
-+ else {
-+ /* buffer isn't completely full, fail */
-+ if(self->bytes_in_buffer < self->bufsize)
-+ return NULL;
-+
-+ /* return entire buffer as a partial line */
-+ line[self->bufsize] = 0;
-+ self->buf_begin = ptr;
-+ self->bytes_in_buffer = 0;
-+ }
-+
-+ return line;
-+}
-+
-+/* returns the next CRLF terminated line from the client */
-+char* get_line(multipart_buffer *self)
-+{
-+ char* ptr = next_line(self);
-+
-+ if(!ptr) {
-+ fill_buffer(self);
-+ ptr = next_line(self);
-+ }
-+
-+#ifdef DEBUG
-+ ap_log_rerror(MPB_ERROR, "get_line: '%s'", ptr);
-+#endif
-+
-+ return ptr;
-+}
-+
-+/* finds a boundary */
-+int find_boundary(multipart_buffer *self, char *boundary)
-+{
-+ char *line;
-+
-+ /* loop thru lines */
-+ while( (line = get_line(self)) ) {
-+#ifdef DEBUG
-+ ap_log_rerror(MPB_ERROR, "find_boundary: '%s' ?= '%s'",
-+ line, boundary);
-+#endif
-+
-+ /* finished if we found the boundary */
-+ if(strEQ(line, boundary))
-+ return 1;
-+ }
-+
-+ /* didn't find the boundary */
-+ return 0;
-+}
-+
-+/*********************** external functions *********************/
-+
-+/* create new multipart_buffer structure */
-+multipart_buffer *multipart_buffer_new(char *boundary, long length,
request_rec *r)
-+{
-+ multipart_buffer *self = (multipart_buffer *)
-+ ap_pcalloc(r->pool, sizeof(multipart_buffer));
-+
-+ int minsize = strlen(boundary)+6;
-+ if(minsize < FILLUNIT) minsize = FILLUNIT;
-+
-+ self->r = r;
-+ self->buffer = (char *) ap_pcalloc(r->pool, minsize+1);
-+ self->bufsize = minsize;
-+ self->request_length = length;
-+ self->boundary = ap_pstrcat(r->pool, "--", boundary, NULL);
-+ self->boundary_next = ap_pstrcat(r->pool, "\n", self->boundary, NULL);
-+ self->buf_begin = self->buffer;
-+ self->bytes_in_buffer = 0;
-+
-+ return self;
-+}
-+
-+/* parse headers and return them in an apache table */
-+table *multipart_buffer_headers(multipart_buffer *self)
-+{
-+ table *tab;
-+ char *line;
-+
-+ /* didn't find boundary, abort */
-+ if(!find_boundary(self, self->boundary)) return NULL;
-+
-+ /* get lines of text, or CRLF_CRLF */
-+ tab = ap_make_table(self->r->pool, 10);
-+ while( (line = get_line(self)) && strlen(line) > 0 ) {
-+ /* add header to table */
-+ char *key = line;
-+ char *value = strchr(line, ':');
-+
-+ if(value) {
-+ *value = 0;
-+ do { value++; } while(ap_isspace(*value));
-+
-+#ifdef DEBUG
-+ ap_log_rerror(MPB_ERROR,
-+ "multipart_buffer_headers: '%s' = '%s'",
-+ key, value);
-+#endif
-+
-+ ap_table_add(tab, key, value);
-+ }
-+ else {
-+#ifdef DEBUG
-+ ap_log_rerror(MPB_ERROR,
-+ "multipart_buffer_headers: '%s' = ''", key);
-+#endif
-+
-+ ap_table_add(tab, key, "");
-+ }
-+ }
-+
-+ return tab;
-+}
-+
-+/* read until a boundary condition */
-+int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes)
-+{
-+ int len, max;
-+ char *bound;
-+
-+ /* fill buffer if needed */
-+ if(bytes > self->bytes_in_buffer) fill_buffer(self);
-+
-+ /* look for a potential boundary match, only read data up to that point
*/
-+ if( (bound = my_memstr(self->buf_begin, self->bytes_in_buffer,
-+ self->boundary_next, 1)) )
-+ max = bound - self->buf_begin;
-+ else
-+ max = self->bytes_in_buffer;
-+
-+ /* maximum number of bytes we are reading */
-+ len = max < bytes-1 ? max : bytes-1;
-+
-+ /* if we read any data... */
-+ if(len > 0) {
-+ /* copy the data */
-+ memcpy(buf, self->buf_begin, len);
-+ buf[len] = 0;
-+ if(bound && len > 0 && buf[len-1] == '\r') buf[--len] = 0;
-+
-+ /* update the buffer */
-+ self->bytes_in_buffer -= len;
-+ self->buf_begin += len;
-+ }
-+
-+#ifdef DEBUG
-+ ap_log_rerror(MPB_ERROR, "multipart_buffer_read: %d bytes", len);
-+#endif
-+
-+ return len;
-+}
-+
-+/*
-+ XXX: this is horrible memory-usage-wise, but we only expect
-+ to do this on small pieces of form data.
-+*/
-+char *multipart_buffer_read_body(multipart_buffer *self)
-+{
-+ char buf[FILLUNIT], *out = "";
-+
-+ while(multipart_buffer_read(self, buf, sizeof(buf)))
-+ out = ap_pstrcat(self->r->pool, out, buf, NULL);
-+
-+#ifdef DEBUG
-+ ap_log_rerror(MPB_ERROR, "multipart_buffer_read_body: '%s'", out);
-+#endif
-+
-+ return out;
-+}
-+
-+/* eof if we are out of bytes, or if we hit the final boundary */
-+int multipart_buffer_eof(multipart_buffer *self)
-+{
-+ if( (self->bytes_in_buffer == 0 && fill_buffer(self) < 1) )
-+ return 1;
-+ else
-+ return 0;
-+}
-diff -urN ../apache-1.3/src/lib/apreq/apache_multipart_buffer.h
./src/lib/apreq/apache_multipart_buffer.h
---- ../apache-1.3/src/lib/apreq/apache_multipart_buffer.h Wed Dec 31
19:00:00 1969
-+++ ./src/lib/apreq/apache_multipart_buffer.h Thu Dec 19 00:22:38 2002
-@@ -0,0 +1,42 @@
-+#ifndef _APACHE_MULTIPART_BUFFER_H
-+#define _APACHE_MULTIPART_BUFFER_H
-+
-+#include "apache_request.h"
-+
-+/*#define DEBUG 1*/
-+#define FILLUNIT (1024 * 5)
-+#define MPB_ERROR APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, self->r
-+
-+#ifdef __cplusplus
-+ extern "C" {
-+#endif
-+
-+typedef struct {
-+ /* request info */
-+ request_rec *r;
-+ long request_length;
-+
-+ /* read buffer */
-+ char *buffer;
-+ char *buf_begin;
-+ int bufsize;
-+ int bytes_in_buffer;
-+
-+ /* boundary info */
-+ char *boundary;
-+ char *boundary_next;
-+ char *boundary_end;
-+} multipart_buffer;
-+
-+multipart_buffer *
-+ multipart_buffer_new(char *boundary, long length, request_rec *r);
-+table *multipart_buffer_headers(multipart_buffer *self);
-+int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes);
-+char *multipart_buffer_read_body(multipart_buffer *self);
-+int multipart_buffer_eof(multipart_buffer *self);
-+
-+#ifdef __cplusplus
-+ }
-+#endif
-+
-+#endif
-diff -urN ../apache-1.3/src/lib/apreq/apache_request.c
./src/lib/apreq/apache_request.c
---- ../apache-1.3/src/lib/apreq/apache_request.c Wed Dec 31 19:00:00 1969
-+++ ./src/lib/apreq/apache_request.c Thu Dec 19 00:22:38 2002
-@@ -0,0 +1,584 @@
-+/* ====================================================================
-+ * The Apache Software License, Version 1.1
-+ *
-+ * Copyright (c) 2000 The Apache Software Foundation. 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. The end-user documentation included with the redistribution,
-+ * if any, must include the following acknowledgment:
-+ * "This product includes software developed by the
-+ * Apache Software Foundation (http://www.apache.org/)."
-+ * Alternately, this acknowledgment may appear in the software itself,
-+ * if and wherever such third-party acknowledgments normally appear.
-+ *
-+ * 4. The names "Apache" and "Apache Software Foundation" must
-+ * not be used to endorse or promote products derived from this
-+ * software without prior written permission. For written
-+ * permission, please contact [EMAIL PROTECTED]
-+ *
-+ * 5. Products derived from this software may not be called "Apache",
-+ * nor may "Apache" appear in their name, without prior written
-+ * permission of the Apache Software Foundation.
-+ *
-+ * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation. For more
-+ * information on the Apache Software Foundation, please see
-+ * <http://www.apache.org/>.
-+ *
-+ * Portions of this software are based upon public domain software
-+ * originally written at the National Center for Supercomputing
Applications,
-+ * University of Illinois, Urbana-Champaign.
-+ */
-+
-+#include "apache_request.h"
-+#include "apache_multipart_buffer.h"
-+int fill_buffer(multipart_buffer *self); /* needed for mozilla hack */
-+
-+static void req_plustospace(char *str)
-+{
-+ register int x;
-+ for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' ';
-+}
-+
-+static int util_read(ApacheRequest *req, const char **rbuf)
-+{
-+ request_rec *r = req->r;
-+ int rc = OK;
-+
-+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
-+ return rc;
-+ }
-+
-+ if (ap_should_client_block(r)) {
-+ char buff[HUGE_STRING_LEN];
-+ int rsize, len_read, rpos=0;
-+ long length = r->remaining;
-+
-+ if (length > req->post_max && req->post_max > 0) {
-+ ap_log_rerror(REQ_ERROR, "[libapreq] entity too large (%d, max=%d)",
-+ (int)length, req->post_max);
-+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
-+ }
-+
-+ *rbuf = ap_pcalloc(r->pool, length + 1);
-+
-+ ap_hard_timeout("[libapreq] util_read", r);
-+
-+ while ((len_read =
-+ ap_get_client_block(r, buff, sizeof(buff))) > 0) {
-+ if ((rpos + len_read) > length) {
-+ rsize = length - rpos;
-+ }
-+ else {
-+ rsize = len_read;
-+ }
-+ memcpy((char*)*rbuf + rpos, buff, rsize);
-+ rpos += rsize;
-+ }
-+
-+ ap_kill_timeout(r);
-+ }
-+
-+ return rc;
-+}
-+
-+char *ApacheRequest_script_name(ApacheRequest *req)
-+{
-+ request_rec *r = req->r;
-+ char *tmp;
-+
-+ if (r->path_info && *r->path_info) {
-+ int path_info_start = ap_find_path_info(r->uri, r->path_info);
-+ tmp = ap_pstrndup(r->pool, r->uri, path_info_start);
-+ }
-+ else {
-+ tmp = r->uri;
-+ }
-+
-+ return tmp;
-+}
-+
-+char *ApacheRequest_script_path(ApacheRequest *req)
-+{
-+ return ap_make_dirstr_parent(req->r->pool,
ApacheRequest_script_name(req));
-+}
-+
-+const char *ApacheRequest_param(ApacheRequest *req, const char *key)
-+{
-+ ApacheRequest_parse(req);
-+ return ap_table_get(req->parms, key);
-+}
-+
-+static int make_params(void *data, const char *key, const char *val)
-+{
-+ array_header *arr = (array_header *)data;
-+ *(char **)ap_push_array(arr) = (char *)val;
-+ return 1;
-+}
-+
-+array_header *ApacheRequest_params(ApacheRequest *req, const char *key)
-+{
-+ array_header *values = ap_make_array(req->r->pool, 4, sizeof(char *));
-+ ApacheRequest_parse(req);
-+ ap_table_do(make_params, (void*)values, req->parms, key, NULL);
-+ return values;
-+}
-+
-+char *ApacheRequest_params_as_string(ApacheRequest *req, const char *key)
-+{
-+ char *retval = NULL;
-+ array_header *values = ApacheRequest_params(req, key);
-+ int i;
-+
-+ for (i=0; i<values->nelts; i++) {
-+ retval = ap_pstrcat(req->r->pool,
-+ retval ? retval : "",
-+ ((char **)values->elts)[i],
-+ (i == (values->nelts - 1)) ? NULL : ", ",
-+ NULL);
-+ }
-+
-+ return retval;
-+}
-+
-+ApacheUpload *ApacheUpload_new(ApacheRequest *req)
-+{
-+ ApacheUpload *upload = (ApacheUpload *)
-+ ap_pcalloc(req->r->pool, sizeof(ApacheUpload));
-+
-+ upload->next = NULL;
-+ upload->name = NULL;
-+ upload->info = NULL;
-+ upload->fp = NULL;
-+ upload->size = 0;
-+ upload->req = req;
-+
-+ return upload;
-+}
-+
-+ApacheUpload *ApacheUpload_find(ApacheUpload *upload, char *name)
-+{
-+ ApacheUpload *uptr;
-+
-+ for (uptr = upload; uptr; uptr = uptr->next) {
-+ if (strEQ(uptr->name, name)) {
-+ return uptr;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+ApacheRequest *ApacheRequest_new(request_rec *r)
-+{
-+ ApacheRequest *req = (ApacheRequest *)
-+ ap_pcalloc(r->pool, sizeof(ApacheRequest));
-+
-+ req->status = OK;
-+ req->parms = ap_make_table(r->pool, DEFAULT_TABLE_NELTS);
-+ req->upload = NULL;
-+ req->post_max = -1;
-+ req->disable_uploads = 0;
-+ req->upload_hook = NULL;
-+ req->hook_data = NULL;
-+ req->temp_dir = NULL;
-+ req->parsed = 0;
-+ req->r = r;
-+
-+ return req;
-+}
-+
-+static int urlword_dlm[] = {'&', ';', 0};
-+
-+static char *my_urlword(pool *p, const char **line)
-+{
-+ char *res = NULL;
-+ const char *pos = *line;
-+ char ch;
-+
-+ while ( (ch = *pos) != '\0' && ch != ';' && ch != '&') {
-+ ++pos;
-+ }
-+
-+ res = ap_pstrndup(p, *line, pos - *line);
-+
-+ while (ch == ';' || ch == '&') {
-+ ++pos;
-+ ch = *pos;
-+ }
-+
-+ *line = pos;
-+
-+ return res;
-+}
-+
-+
-+static void split_to_parms(ApacheRequest *req, const char *data)
-+{
-+ request_rec *r = req->r;
-+ const char *val;
-+
-+ while (*data && (val = my_urlword(r->pool, &data))) {
-+ const char *key = ap_getword(r->pool, &val, '=');
-+
-+ req_plustospace((char*)key);
-+ ap_unescape_url((char*)key);
-+ req_plustospace((char*)val);
-+ ap_unescape_url((char*)val);
-+
-+ ap_table_add(req->parms, key, val);
-+ }
-+
-+}
-+
-+int ApacheRequest___parse(ApacheRequest *req)
-+{
-+ request_rec *r = req->r;
-+ int result;
-+
-+ if (r->args) {
-+ split_to_parms(req, r->args);
-+ }
-+
-+ if (r->method_number == M_POST) {
-+ const char *ct = ap_table_get(r->headers_in, "Content-type");
-+ if (ct && strncaseEQ(ct, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH)) {
-+ result = ApacheRequest_parse_urlencoded(req);
-+ }
-+ else if (ct && strncaseEQ(ct, MULTIPART_ENCTYPE,
MULTIPART_ENCTYPE_LENGTH)) {
-+ result = ApacheRequest_parse_multipart(req);
-+ }
-+ else {
-+ ap_log_rerror(REQ_ERROR,
-+ "[libapreq] unknown content-type: `%s'", ct);
-+ result = HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+ }
-+ else {
-+ result = ApacheRequest_parse_urlencoded(req);
-+ }
-+
-+ req->parsed = 1;
-+ return result;
-+
-+}
-+
-+int ApacheRequest_parse_urlencoded(ApacheRequest *req)
-+{
-+ request_rec *r = req->r;
-+ int rc = OK;
-+
-+ if (r->method_number == M_POST) {
-+ const char *data = NULL, *type;
-+
-+ type = ap_table_get(r->headers_in, "Content-Type");
-+
-+ if (!strncaseEQ(type, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH)) {
-+ return DECLINED;
-+ }
-+ if ((rc = util_read(req, &data)) != OK) {
-+ return rc;
-+ }
-+ if (data) {
-+ split_to_parms(req, data);
-+ }
-+ }
-+
-+ return OK;
-+}
-+
-+static void remove_tmpfile(void *data) {
-+ ApacheUpload *upload = (ApacheUpload *) data;
-+ ApacheRequest *req = upload->req;
-+
-+ if( ap_pfclose(req->r->pool, upload->fp) )
-+ ap_log_rerror(REQ_ERROR,
-+ "[libapreq] close error on '%s'", upload->tempname);
-+#ifndef DEBUG
-+ if( remove(upload->tempname) )
-+ ap_log_rerror(REQ_ERROR,
-+ "[libapreq] remove error on '%s'", upload->tempname);
-+#endif
-+
-+ free(upload->tempname);
-+}
-+
-+FILE *ApacheRequest_tmpfile(ApacheRequest *req, ApacheUpload *upload)
-+{
-+ request_rec *r = req->r;
-+ FILE *fp;
-+ char prefix[] = "apreq";
-+ char *name = NULL;
-+ int fd = 0;
-+ int tries = 100;
-+
-+ while (--tries > 0) {
-+ if ( (name = tempnam(req->temp_dir, prefix)) == NULL )
-+ continue;
-+ fd = ap_popenf(r->pool, name, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600);
-+ if ( fd >= 0 )
-+ break; /* success */
-+ else
-+ free(name);
-+ }
-+
-+ if ( tries == 0 || (fp = ap_pfdopen(r->pool, fd, "w+" "b") ) == NULL )
{
-+ ap_log_rerror(REQ_ERROR, "[libapreq] could not create/open temp file");
-+ if ( fd >= 0 ) { remove(name); free(name); }
-+ return NULL;
-+ }
-+
-+ upload->fp = fp;
-+ upload->tempname = name;
-+ ap_register_cleanup(r->pool, (void *)upload,
-+ remove_tmpfile, ap_null_cleanup);
-+ return fp;
-+
-+}
-+
-+int ApacheRequest_parse_multipart(ApacheRequest *req)
-+{
-+ request_rec *r = req->r;
-+ int rc = OK;
-+ const char *ct = ap_table_get(r->headers_in, "Content-Type");
-+ long length;
-+ char *boundary;
-+ multipart_buffer *mbuff;
-+ ApacheUpload *upload = NULL;
-+
-+ if (!ct) {
-+ ap_log_rerror(REQ_ERROR, "[libapreq] no Content-type header!");
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+
-+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
-+ return rc;
-+ }
-+
-+ if (!ap_should_client_block(r)) {
-+ return rc;
-+ }
-+
-+ if ((length = r->remaining) > req->post_max && req->post_max > 0) {
-+ ap_log_rerror(REQ_ERROR, "[libapreq] entity too large (%d, max=%d)",
-+ (int)length, req->post_max);
-+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
-+ }
-+
-+ (void)ap_getword(r->pool, &ct, '=');
-+ boundary = ap_getword_conf(r->pool, &ct);
-+
-+ if (!(mbuff = multipart_buffer_new(boundary, length, r))) {
-+ return DECLINED;
-+ }
-+
-+ while (!multipart_buffer_eof(mbuff)) {
-+ table *header = multipart_buffer_headers(mbuff);
-+ const char *cd, *param=NULL, *filename=NULL;
-+ char buff[FILLUNIT];
-+ int blen, wlen;
-+
-+ if (!header) {
-+#ifdef DEBUG
-+ ap_log_rerror(REQ_ERROR,
-+ "[libapreq] silently drop remaining '%ld' bytes",
r->remaining);
-+#endif
-+ ap_hard_timeout("[libapreq] parse_multipart", r);
-+ while ( ap_get_client_block(r, buff, sizeof(buff)) > 0 )
-+ /* wait for more input to ignore */ ;
-+ ap_kill_timeout(r);
-+ return OK;
-+ }
-+
-+ if ((cd = ap_table_get(header, "Content-Disposition"))) {
-+ const char *pair;
-+
-+ while (*cd && (pair = ap_getword(r->pool, &cd, ';'))) {
-+ const char *key;
-+
-+ while (ap_isspace(*cd)) {
-+ ++cd;
-+ }
-+ if (ap_ind(pair, '=')) {
-+ key = ap_getword(r->pool, &pair, '=');
-+ if(strEQ(key, "name")) {
-+ param = ap_getword_conf(r->pool, &pair);
-+ }
-+ else if(strEQ(key, "filename")) {
-+ filename = ap_getword_conf(r->pool, &pair);
-+ }
-+ }
-+ }
-+ if (!filename) {
-+ char *value = multipart_buffer_read_body(mbuff);
-+ ap_table_add(req->parms, param, value);
-+ continue;
-+ }
-+ if (!param) continue; /* shouldn't happen, but just in case. */
-+
-+ if (req->disable_uploads) {
-+ ap_log_rerror(REQ_ERROR, "[libapreq] file upload
forbidden");
-+ return HTTP_FORBIDDEN;
-+ }
-+
-+ ap_table_add(req->parms, param, filename);
-+
-+ if (upload) {
-+ upload->next = ApacheUpload_new(req);
-+ upload = upload->next;
-+ }
-+ else {
-+ upload = ApacheUpload_new(req);
-+ req->upload = upload;
-+ }
-+
-+ if (! req->upload_hook && ! ApacheRequest_tmpfile(req, upload) ) {
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+
-+ upload->info = header;
-+ upload->filename = ap_pstrdup(req->r->pool, filename);
-+ upload->name = ap_pstrdup(req->r->pool, param);
-+
-+ /* mozilla empty-file (missing CRLF) hack */
-+ fill_buffer(mbuff);
-+ if( strEQN(mbuff->buf_begin, mbuff->boundary,
-+ strlen(mbuff->boundary)) ) {
-+ r->remaining -= 2;
-+ continue;
-+ }
-+
-+ while ((blen = multipart_buffer_read(mbuff, buff, sizeof(buff)))) {
-+ if (req->upload_hook != NULL) {
-+ wlen = req->upload_hook(req->hook_data, buff, blen, upload);
-+ } else {
-+ wlen = fwrite(buff, 1, blen, upload->fp);
-+ }
-+ if (wlen != blen) {
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+ upload->size += wlen;
-+ }
-+
-+ if (upload->size > 0 && (upload->fp != NULL)) {
-+ fseek(upload->fp, 0, 0);
-+ }
-+ }
-+ }
-+
-+ return OK;
-+}
-+
-+#define Mult_s 1
-+#define Mult_m 60
-+#define Mult_h (60*60)
-+#define Mult_d (60*60*24)
-+#define Mult_M (60*60*24*30)
-+#define Mult_y (60*60*24*365)
-+
-+static int expire_mult(char s)
-+{
-+ switch (s) {
-+ case 's':
-+ return Mult_s;
-+ case 'm':
-+ return Mult_m;
-+ case 'h':
-+ return Mult_h;
-+ case 'd':
-+ return Mult_d;
-+ case 'M':
-+ return Mult_M;
-+ case 'y':
-+ return Mult_y;
-+ default:
-+ return 1;
-+ };
-+}
-+
-+static time_t expire_calc(char *time_str)
-+{
-+ int is_neg = 0, offset = 0;
-+ char buf[256];
-+ int ix = 0;
-+
-+ if (*time_str == '-') {
-+ is_neg = 1;
-+ ++time_str;
-+ }
-+ else if (*time_str == '+') {
-+ ++time_str;
-+ }
-+ else if (strcaseEQ(time_str, "now")) {
-+ /*ok*/
-+ }
-+ else {
-+ return 0;
-+ }
-+
-+ /* wtf, ap_isdigit() returns false for '1' !? */
-+ while (*time_str && (ap_isdigit(*time_str) || (*time_str == '1'))) {
-+ buf[ix++] = *time_str++;
-+ }
-+ buf[ix] = '\0';
-+ offset = atoi(buf);
-+
-+ return time(NULL) +
-+ (expire_mult(*time_str) * (is_neg ? (0 - offset) : offset));
-+}
-+
-+char *ApacheUtil_expires(pool *p, char *time_str, int type)
-+{
-+ time_t when;
-+ struct tm *tms;
-+ int sep = (type == EXPIRES_HTTP) ? ' ' : '-';
-+
-+ if (!time_str) {
-+ return NULL;
-+ }
-+
-+ when = expire_calc(time_str);
-+
-+ if (!when) {
-+ return ap_pstrdup(p, time_str);
-+ }
-+
-+ tms = gmtime(&when);
-+ return ap_psprintf(p,
-+ "%s, %.2d%c%s%c%.2d %.2d:%.2d:%.2d GMT",
-+ ap_day_snames[tms->tm_wday],
-+ tms->tm_mday, sep, ap_month_snames[tms->tm_mon], sep,
-+ tms->tm_year + 1900,
-+ tms->tm_hour, tms->tm_min, tms->tm_sec);
-+}
-+
-+char *ApacheRequest_expires(ApacheRequest *req, char *time_str)
-+{
-+ return ApacheUtil_expires(req->r->pool, time_str, EXPIRES_HTTP);
-+}
-diff -urN ../apache-1.3/src/lib/apreq/apache_request.h
./src/lib/apreq/apache_request.h
---- ../apache-1.3/src/lib/apreq/apache_request.h Wed Dec 31 19:00:00 1969
-+++ ./src/lib/apreq/apache_request.h Thu Dec 19 00:22:38 2002
-@@ -0,0 +1,138 @@
-+#ifndef _APACHE_REQUEST_H
-+
-+#define _APACHE_REQUEST_H
-+
-+#include "httpd.h"
-+#include "http_config.h"
-+#include "http_core.h"
-+#include "http_log.h"
-+#include "http_main.h"
-+#include "http_protocol.h"
-+#include "util_script.h"
-+
-+#ifdef SFIO
-+#include "sfio.h"
-+
-+/* sfio 2000 changed _stdopen to _stdfdopen */
-+#if SFIO_VERSION >= 20000101L
-+#define _stdopen _stdfdopen
-+#endif
-+
-+extern Sfio_t* _stdopen _ARG_((int, const char*)); /*1999*/
-+
-+#undef FILE
-+#define FILE Sfio_t
-+#undef fwrite
-+#define fwrite(p,s,n,f) sfwrite((f),(p),(s)*(n))
-+#undef fseek
-+#define fseek(f,a,b) sfseek((f),(a),(b))
-+#undef ap_pfdopen
-+#define ap_pfdopen(p,q,r) _stdopen((q),(r))
-+#undef ap_pfclose
-+#define ap_pfclose(p,q) sfclose(q)
-+#endif /*SFIO*/
-+
-+typedef struct ApacheUpload ApacheUpload;
-+
-+typedef struct {
-+ table *parms;
-+ ApacheUpload *upload;
-+ int status;
-+ int parsed;
-+ int post_max;
-+ int disable_uploads;
-+ int (*upload_hook)(void *ptr, char *buf, int len, ApacheUpload *upload);
-+ void *hook_data;
-+ char* temp_dir;
-+ request_rec *r;
-+} ApacheRequest;
-+
-+struct ApacheUpload {
-+ ApacheUpload *next;
-+ char *filename;
-+ char *name;
-+ char *tempname;
-+ table *info;
-+ FILE *fp;
-+ long size;
-+ ApacheRequest *req;
-+};
-+
-+#ifndef strEQ
-+#define strEQ(s1,s2) (!strcmp(s1,s2))
-+#endif
-+
-+#ifndef strEQN
-+#define strEQN(s1,s2,n) (!strncmp(s1,s2,n))
-+#endif
-+
-+#ifndef strcaseEQ
-+#define strcaseEQ(s1,s2) (!strcasecmp(s1,s2))
-+#endif
-+
-+#ifndef strncaseEQ
-+#define strncaseEQ(s1,s2,n) (!strncasecmp(s1,s2,n))
-+#endif
-+
-+#define DEFAULT_TABLE_NELTS 10
-+
-+#define DEFAULT_ENCTYPE "application/x-www-form-urlencoded"
-+#define DEFAULT_ENCTYPE_LENGTH 33
-+
-+#define MULTIPART_ENCTYPE "multipart/form-data"
-+#define MULTIPART_ENCTYPE_LENGTH 19
-+
-+#ifdef __cplusplus
-+ extern "C" {
-+#endif
-+
-+ApacheRequest *ApacheRequest_new(request_rec *r);
-+int ApacheRequest_parse_multipart(ApacheRequest *req);
-+int ApacheRequest_parse_urlencoded(ApacheRequest *req);
-+char *ApacheRequest_script_name(ApacheRequest *req);
-+char *ApacheRequest_script_path(ApacheRequest *req);
-+const char *ApacheRequest_param(ApacheRequest *req, const char *key);
-+array_header *ApacheRequest_params(ApacheRequest *req, const char *key);
-+char *ApacheRequest_params_as_string(ApacheRequest *req, const char *key);
-+int ApacheRequest___parse(ApacheRequest *req);
-+#define ApacheRequest_parse(req) \
-+ (req->status = req->parsed ? req->status : ApacheRequest___parse(req))
-+
-+FILE *ApacheRequest_tmpfile(ApacheRequest *req, ApacheUpload *upload);
-+ApacheUpload *ApacheUpload_new(ApacheRequest *req);
-+ApacheUpload *ApacheUpload_find(ApacheUpload *upload, char *name);
-+
-+#define ApacheRequest_upload(req) \
-+ ((req->parsed || (ApacheRequest_parse(req) == OK)) ? req->upload : NULL)
-+
-+#define ApacheUpload_FILE(upload) (upload->fp)
-+
-+#define ApacheUpload_size(upload) (upload->size)
-+
-+#define ApacheUpload_info(upload, key) \
-+ap_table_get(upload->info, key)
-+
-+#define ApacheUpload_type(upload) \
-+ApacheUpload_info(upload, "Content-Type")
-+
-+#define ApacheRequest_set_post_max(req, max) (req->post_max = max)
-+#define ApacheRequest_set_temp_dir(req, dir) (req->temp_dir = dir)
-+
-+char *ApacheUtil_expires(pool *p, char *time_str, int type);
-+#define EXPIRES_HTTP 1
-+#define EXPIRES_COOKIE 2
-+char *ApacheRequest_expires(ApacheRequest *req, char *time_str);
-+
-+#ifdef __cplusplus
-+ }
-+#endif
-+
-+#define REQ_ERROR APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, req->r
-+
-+#ifdef REQDEBUG
-+#define REQ_DEBUG(a) a
-+#else
-+#define REQ_DEBUG(a)
-+#endif
-+
-+#endif /* _APACHE_REQUEST_H */
diff -urN ../apache-1.3/src/main/http_main.c ./src/main/http_main.c
--- ../apache-1.3/src/main/http_main.c Fri Oct 25 17:12:23 2002
+++ ./src/main/http_main.c Thu Dec 19 00:19:21 2002