]> granicus.if.org Git - apache/blobdiff - modules/metadata/mod_mime_magic.c
*) continued header revamping
[apache] / modules / metadata / mod_mime_magic.c
index 5f23c34cca2303629cabc654de6f9630db61be30..67eb4409e2fdfbc8a7bbc0a8e73113640493b931 100644 (file)
@@ -1,5 +1,8 @@
 /* ====================================================================
- * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
+ * 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
  *    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.
+ * 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.
  *
- * 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.
+ * 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 apache@apache.org.
  *
- * 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/)."
+ * 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 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
+ * 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.
+ * 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/>.
+ * 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.
  */
 
 /*
  * mod_mime_magic: MIME type lookup via file magic numbers
  * Copyright (c) 1996-1997 Cisco Systems, Inc.
  *
- * This software was submitted by Cisco Systems to the Apache Group in July
+ * This software was submitted by Cisco Systems to the Apache Software Foundation in July
  * 1997.  Future revisions and derivatives of this source code must
  * acknowledge Cisco Systems as the original contributor of this module.
- * All other licensing and usage conditions are those of the Apache Group.
+ * All other licensing and usage conditions are those of the Apache Software Foundation.
  *
  * Some of this code is derived from the free version of the file command
  * originally posted to comp.sources.unix.  Copyright info for that program
@@ -95,7 +96,7 @@
  * modified from the free "file" command.
  * - all-in-one file for compilation convenience when moving from one
  *   version of Apache to the next.
- * - Memory allocation is done through the Apache API's pool structure.
+ * - Memory allocation is done through the Apache API's apr_pool_t structure.
  * - All functions have had necessary Apache API request or server
  *   structures passed to them where necessary to call other Apache API
  *   routines.  (i.e. usually for logging, files, or memory allocation in
  *
  * Initial installation          July/August 1996
  * Misc bug fixes                May 1997
- * Submission to Apache Group    July 1997
+ * Submission to Apache Software Foundation    July 1997
  *
  */
 
+#include "apr.h"
+#include "apr_strings.h"
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ap_config.h"
 #include "httpd.h"
 #include "http_config.h"
 #include "http_request.h"
 #include "http_core.h"
 #include "http_log.h"
 #include "http_protocol.h"
+#include "util_script.h"
 
+/* ### this isn't set by configure? does anybody set this? */
+#ifdef HAVE_UTIME_H
 #include <utime.h>
-
+#endif
 
 /*
  * data structures and related constants
@@ -239,25 +251,25 @@ union record {
 /*
  * file-function prototypes
  */
-static int ascmagic(request_rec *, unsigned char *, int);
-static int is_tar(unsigned char *, int);
-static int softmagic(request_rec *, unsigned char *, int);
-static void tryit(request_rec *, unsigned char *, int, int);
-static int zmagic(request_rec *, unsigned char *, int);
+static int ascmagic(request_rec *, unsigned char *, apr_size_t);
+static int is_tar(unsigned char *, apr_size_t);
+static int softmagic(request_rec *, unsigned char *, apr_size_t);
+static void tryit(request_rec *, unsigned char *, apr_size_t, int);
+static int zmagic(request_rec *, unsigned char *, apr_size_t);
 
 static int getvalue(server_rec *, struct magic *, char **);
 static int hextoint(int);
 static char *getstr(server_rec *, char *, char *, int, int *);
-static int parse(server_rec *, pool *p, char *, int);
+static int parse(server_rec *, apr_pool_t *p, char *, int);
 
-static int match(request_rec *, unsigned char *, int);
+static int match(request_rec *, unsigned char *, apr_size_t);
 static int mget(request_rec *, union VALUETYPE *, unsigned char *,
-               struct magic *, int);
+               struct magic *, apr_size_t);
 static int mcheck(request_rec *, union VALUETYPE *, struct magic *);
 static void mprint(request_rec *, union VALUETYPE *, struct magic *);
 
 static int uncompress(request_rec *, int, 
-                     unsigned char **, int);
+                     unsigned char **, apr_size_t);
 static long from_oct(int, char *);
 static int fsmagic(request_rec *r, const char *fn);
 
@@ -271,7 +283,7 @@ static int fsmagic(request_rec *r, const char *fn);
  * make HOWMANY too high unless you have a very fast CPU.
  */
 
-/* these types are used to index the table 'types': keep em in sync! */
+/* these types are used to index the apr_table_t 'types': keep em in sync! */
 /* HTML inserted in first because this is a web server module now */
 #define L_HTML    0            /* HTML */
 #define L_C       1            /* first and foremost on UNIX */
@@ -480,7 +492,7 @@ typedef struct magic_rsl_s {
 
 /* per-server info */
 typedef struct {
-    char *magicfile;           /* where magic be found */
+    const char *magicfile;             /* where magic be found */
     struct magic *magic;       /* head of magic config list */
     struct magic *last;
 } magic_server_config_rec;
@@ -498,18 +510,18 @@ typedef struct {
 
 module mime_magic_module;
 
-static void *create_magic_server_config(pool *p, server_rec *d)
+static void *create_magic_server_config(apr_pool_t *p, server_rec *d)
 {
     /* allocate the config - use pcalloc because it needs to be zeroed */
-    return ap_pcalloc(p, sizeof(magic_server_config_rec));
+    return apr_pcalloc(p, sizeof(magic_server_config_rec));
 }
 
-static void *merge_magic_server_config(pool *p, void *basev, void *addv)
+static void *merge_magic_server_config(apr_pool_t *p, void *basev, void *addv)
 {
     magic_server_config_rec *base = (magic_server_config_rec *) basev;
     magic_server_config_rec *add = (magic_server_config_rec *) addv;
     magic_server_config_rec *new = (magic_server_config_rec *)
-                           ap_palloc(p, sizeof(magic_server_config_rec));
+                           apr_palloc(p, sizeof(magic_server_config_rec));
 
     new->magicfile = add->magicfile ? add->magicfile : base->magicfile;
     new->magic = NULL;
@@ -517,7 +529,7 @@ static void *merge_magic_server_config(pool *p, void *basev, void *addv)
     return new;
 }
 
-static const char *set_magicfile(cmd_parms *cmd, char *d, char *arg)
+static const char *set_magicfile(cmd_parms *cmd, void *dummy, const char *arg)
 {
     magic_server_config_rec *conf = (magic_server_config_rec *)
     ap_get_module_config(cmd->server->module_config,
@@ -536,8 +548,8 @@ static const char *set_magicfile(cmd_parms *cmd, char *d, char *arg)
 
 static const command_rec mime_magic_cmds[] =
 {
-    {"MimeMagicFile", set_magicfile, NULL, RSRC_CONF, TAKE1,
-     "Path to MIME Magic file (in file(1) format)"},
+    AP_INIT_TAKE1("MimeMagicFile", set_magicfile, NULL, RSRC_CONF,
+     "Path to MIME Magic file (in file(1) format)"),
     {NULL}
 };
 
@@ -557,7 +569,7 @@ static const command_rec mime_magic_cmds[] =
 /* allocate a per-request structure and put it in the request record */
 static magic_req_rec *magic_set_config(request_rec *r)
 {
-    magic_req_rec *req_dat = (magic_req_rec *) ap_palloc(r->pool,
+    magic_req_rec *req_dat = (magic_req_rec *) apr_palloc(r->pool,
                                                      sizeof(magic_req_rec));
 
     req_dat->head = req_dat->tail = (magic_rsl *) NULL;
@@ -575,7 +587,7 @@ static int magic_rsl_add(request_rec *r, char *str)
 
     /* make sure we have a list to put it in */
     if (!req_dat) {
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, APR_EINVAL, r,
                    MODNAME ": request config should not be NULL");
        if (!(req_dat = magic_set_config(r))) {
            /* failure */
@@ -584,7 +596,7 @@ static int magic_rsl_add(request_rec *r, char *str)
     }
 
     /* allocate the list entry */
-    rsl = (magic_rsl *) ap_palloc(r->pool, sizeof(magic_rsl));
+    rsl = (magic_rsl *) apr_palloc(r->pool, sizeof(magic_rsl));
 
     /* fill it */
     rsl->str = str;
@@ -618,7 +630,7 @@ static int magic_rsl_printf(request_rec *r, char *str,...)
 
     /* assemble the string into the buffer */
     va_start(ap, str);
-    ap_vsnprintf(buf, sizeof(buf), str, ap);
+    apr_vsnprintf(buf, sizeof(buf), str, ap);
     va_end(ap);
 
     /* add the buffer to the list */
@@ -648,7 +660,7 @@ static char *rsl_strdup(request_rec *r, int start_frag, int start_pos, int len)
                    ap_get_module_config(r->request_config, &mime_magic_module);
 
     /* allocate the result string */
-    result = (char *) ap_palloc(r->pool, len + 1);
+    result = (char *) apr_palloc(r->pool, len + 1);
 
     /* loop through and collect the string */
     res_pos = 0;
@@ -677,7 +689,7 @@ static char *rsl_strdup(request_rec *r, int start_frag, int start_pos, int len)
     /* clean up and return */
     result[res_pos] = 0;
 #if MIME_MAGIC_DEBUG
-    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
             MODNAME ": rsl_strdup() %d chars: %s", res_pos - 1, result);
 #endif
     return result;
@@ -721,7 +733,7 @@ static int magic_rsl_to_request(request_rec *r)
         frag = frag->next, cur_frag++) {
        /* loop through the characters in the fragment */
        for (cur_pos = 0; frag->str[cur_pos]; cur_pos++) {
-           if (ap_isspace(frag->str[cur_pos])) {
+           if (apr_isspace(frag->str[cur_pos])) {
                /* process whitespace actions for each state */
                if (state == rsl_leading_space) {
                    /* eat whitespace in this state */
@@ -749,7 +761,7 @@ static int magic_rsl_to_request(request_rec *r)
                else {
                    /* should not be possible */
                    /* abandon malfunctioning module */
-                   ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+                   ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                                MODNAME ": bad state %d (ws)", state);
                    return DECLINED;
                }
@@ -793,7 +805,7 @@ static int magic_rsl_to_request(request_rec *r)
                else {
                    /* should not be possible */
                    /* abandon malfunctioning module */
-                   ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+                   ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                                MODNAME ": bad state %d (ns)", state);
                    return DECLINED;
                }
@@ -847,9 +859,9 @@ static int magic_rsl_to_request(request_rec *r)
  */
 static int magic_process(request_rec *r)
 {
-    int fd = 0;
+    apr_file_t *fd = NULL;
     unsigned char buf[HOWMANY + 1];    /* one extra for terminating '\0' */
-    int nbytes = 0;            /* number of bytes read from a datafile */
+    apr_size_t nbytes = 0;             /* number of bytes read from a datafile */
     int result;
 
     /*
@@ -866,9 +878,9 @@ static int magic_process(request_rec *r)
        return result;
     }
 
-    if ((fd = ap_popenf(r->pool, r->filename, O_RDONLY, 0)) < 0) {
+    if (apr_file_open(&fd, r->filename, APR_READ, APR_OS_DEFAULT, r->pool) != APR_SUCCESS) {
        /* We can't open it, but we were able to stat it. */
-       ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    MODNAME ": can't read `%s'", r->filename);
        /* let some other handler decide what the problem is */
        return DECLINED;
@@ -877,8 +889,9 @@ static int magic_process(request_rec *r)
     /*
      * try looking at the first HOWMANY bytes
      */
-    if ((nbytes = read(fd, (char *) buf, sizeof(buf) - 1)) == -1) {
-       ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+    nbytes = sizeof(buf) - 1;
+    if ((result = apr_file_read(fd, (char *) buf, &nbytes)) != APR_SUCCESS) {
+       ap_log_rerror(APLOG_MARK, APLOG_ERR, result, r,
                    MODNAME ": read failed: %s", r->filename);
        return HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -890,14 +903,14 @@ static int magic_process(request_rec *r)
        tryit(r, buf, nbytes, 1); 
     }
 
-    (void) ap_pclosef(r->pool, fd);
+    (void) apr_file_close(fd);
     (void) magic_rsl_putchar(r, '\n');
 
     return OK;
 }
 
 
-static void tryit(request_rec *r, unsigned char *buf, int nb, int checkzmagic)
+static void tryit(request_rec *r, unsigned char *buf, apr_size_t nb, int checkzmagic)
 {
     /*
      * Try compression stuff
@@ -925,15 +938,16 @@ static void tryit(request_rec *r, unsigned char *buf, int nb, int checkzmagic)
     magic_rsl_puts(r, MIME_BINARY_UNKNOWN);
 }
 
-#define    EATAB {while (ap_isspace((unsigned char) *l))  ++l;}
+#define    EATAB {while (apr_isspace((unsigned char) *l))  ++l;}
 
 /*
  * apprentice - load configuration from the magic file r
  *  API request record
  */
-static int apprentice(server_rec *s, pool *p)
+static int apprentice(server_rec *s, apr_pool_t *p)
 {
-    FILE *f;
+    apr_file_t *f = NULL;
+    apr_status_t result;
     char line[BUFSIZ + 1];
     int errs = 0;
     int lineno;
@@ -941,15 +955,13 @@ static int apprentice(server_rec *s, pool *p)
     int rule = 0;
     struct magic *m, *prevm;
 #endif
-    char *fname;
-
     magic_server_config_rec *conf = (magic_server_config_rec *)
                    ap_get_module_config(s->module_config, &mime_magic_module);
 
-    fname = ap_server_root_relative(p, conf->magicfile);
-    f = ap_pfopen(p, fname, "r");
-    if (f == NULL) {
-       ap_log_error(APLOG_MARK, APLOG_ERR, s,
+    const char *fname = ap_server_root_relative(p, conf->magicfile);
+    result = apr_file_open(&f, fname, APR_READ | APR_BUFFERED, APR_OS_DEFAULT, p);
+    if (result != APR_SUCCESS) {
+       ap_log_error(APLOG_MARK, APLOG_ERR, result, s,
                    MODNAME ": can't read magic file %s", fname);
        return -1;
     }
@@ -958,7 +970,7 @@ static int apprentice(server_rec *s, pool *p)
     conf->magic = conf->last = NULL;
 
     /* parse it */
-    for (lineno = 1; fgets(line, BUFSIZ, f) != NULL; lineno++) {
+    for (lineno = 1; apr_file_gets(line, BUFSIZ, f) == APR_SUCCESS; lineno++) {
        int ws_offset;
 
        /* delete newline */
@@ -968,7 +980,7 @@ static int apprentice(server_rec *s, pool *p)
 
        /* skip leading whitespace */
        ws_offset = 0;
-       while (line[ws_offset] && ap_isspace(line[ws_offset])) {
+       while (line[ws_offset] && apr_isspace(line[ws_offset])) {
            ws_offset++;
        }
 
@@ -991,31 +1003,31 @@ static int apprentice(server_rec *s, pool *p)
            ++errs;
     }
 
-    (void) ap_pfclose(p, f);
+    (void) apr_file_close(f);
 
 #if MIME_MAGIC_DEBUG
-    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, s,
+    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, s,
                MODNAME ": apprentice conf=%x file=%s m=%s m->next=%s last=%s",
                conf,
                conf->magicfile ? conf->magicfile : "NULL",
                conf->magic ? "set" : "NULL",
                (conf->magic && conf->magic->next) ? "set" : "NULL",
                conf->last ? "set" : "NULL");
-    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, s,
+    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, s,
                MODNAME ": apprentice read %d lines, %d rules, %d errors",
                lineno, rule, errs);
 #endif
 
 #if MIME_MAGIC_DEBUG
     prevm = 0;
-    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, s,
+    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, s,
                MODNAME ": apprentice test");
     for (m = conf->magic; m; m = m->next) {
-       if (ap_isprint((((unsigned long) m) >> 24) & 255) &&
-           ap_isprint((((unsigned long) m) >> 16) & 255) &&
-           ap_isprint((((unsigned long) m) >> 8) & 255) &&
-           ap_isprint(((unsigned long) m) & 255)) {
-           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, s,
+       if (apr_isprint((((unsigned long) m) >> 24) & 255) &&
+           apr_isprint((((unsigned long) m) >> 16) & 255) &&
+           apr_isprint((((unsigned long) m) >> 8) & 255) &&
+           apr_isprint(((unsigned long) m) & 255)) {
+           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, s,
                        MODNAME ": apprentice: POINTER CLOBBERED! "
                        "m=\"%c%c%c%c\" line=%d",
                        (((unsigned long) m) >> 24) & 255,
@@ -1062,7 +1074,7 @@ static unsigned long signextend(server_rec *s, struct magic *m, unsigned long v)
        case STRING:
            break;
        default:
-           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, s,
+           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, s,
                        MODNAME ": can't happen: m->type=%d", m->type);
            return -1;
        }
@@ -1072,7 +1084,7 @@ static unsigned long signextend(server_rec *s, struct magic *m, unsigned long v)
 /*
  * parse one line from magic file, put into magic[index++] if valid
  */
-static int parse(server_rec *serv, pool *p, char *l, int lineno)
+static int parse(server_rec *serv, apr_pool_t *p, char *l, int lineno)
 {
     struct magic *m;
     char *t, *s;
@@ -1080,7 +1092,7 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
                    ap_get_module_config(serv->module_config, &mime_magic_module);
 
     /* allocate magic structure entry */
-    m = (struct magic *) ap_pcalloc(p, sizeof(struct magic));
+    m = (struct magic *) apr_pcalloc(p, sizeof(struct magic));
 
     /* append to linked list */
     m->next = NULL;
@@ -1110,7 +1122,7 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
     /* get offset, then skip over it */
     m->offset = (int) strtol(l, &t, 0);
     if (l == t) {
-       ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, serv,
+       ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, serv,
                    MODNAME ": offset %s invalid", l);
     }
     l = t;
@@ -1133,7 +1145,7 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
                m->in.type = BYTE;
                break;
            default:
-               ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, serv,
+               ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, serv,
                        MODNAME ": indirect offset type %c invalid", *l);
                break;
            }
@@ -1142,7 +1154,7 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
        s = l;
        if (*l == '+' || *l == '-')
            l++;
-       if (ap_isdigit((unsigned char) *l)) {
+       if (apr_isdigit((unsigned char) *l)) {
            m->in.offset = strtol(l, &t, 0);
            if (*s == '-')
                m->in.offset = -m->in.offset;
@@ -1150,14 +1162,14 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
        else
            t = l;
        if (*t++ != ')') {
-           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, serv,
+           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, serv,
                        MODNAME ": missing ')' in indirect offset");
        }
        l = t;
     }
 
 
-    while (ap_isdigit((unsigned char) *l))
+    while (apr_isdigit((unsigned char) *l))
        ++l;
     EATAB;
 
@@ -1224,7 +1236,7 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
        l += NLEDATE;
     }
     else {
-       ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, serv,
+       ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, serv,
                    MODNAME ": type %s invalid", l);
        return -1;
     }
@@ -1255,7 +1267,7 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
        }
        /* FALL THROUGH */
     default:
-       if (*l == 'x' && ap_isspace((unsigned char) l[1])) {
+       if (*l == 'x' && apr_isspace((unsigned char) l[1])) {
            m->reln = *l;
            ++l;
            goto GetDesc;       /* Bill The Cat */
@@ -1287,7 +1299,7 @@ static int parse(server_rec *serv, pool *p, char *l, int lineno)
     m->desc[sizeof(m->desc) - 1] = '\0';
 
 #if MIME_MAGIC_DEBUG
-    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, serv,
+    ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, serv,
                MODNAME ": parse line=%d m=%x next=%x cont=%d desc=%s",
                lineno, m, m->next, m->cont_level, m->desc);
 #endif /* MIME_MAGIC_DEBUG */
@@ -1327,10 +1339,10 @@ static char *getstr(server_rec *serv, register char *s, register char *p,
     register int val;
 
     while ((c = *s++) != '\0') {
-       if (ap_isspace((unsigned char) c))
+       if (apr_isspace((unsigned char) c))
            break;
        if (p >= pmax) {
-           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, serv,
+           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, serv,
                        MODNAME ": string too long: %s", origs);
            break;
        }
@@ -1430,7 +1442,7 @@ static char *getstr(server_rec *serv, register char *s, register char *p,
 /* Single hex char to int; -1 if not a hex char. */
 static int hextoint(int c)
 {
-    if (ap_isdigit((unsigned char) c))
+    if (apr_isdigit((unsigned char) c))
        return c - '0';
     if ((c >= 'a') && (c <= 'f'))
        return c + 10 - 'a';
@@ -1447,19 +1459,18 @@ static int hextoint(int c)
  */
 static int fsmagic(request_rec *r, const char *fn)
 {
-    switch (r->finfo.st_mode & S_IFMT) {
-    case S_IFDIR:
+    switch (r->finfo.filetype) {
+    case APR_DIR:
        magic_rsl_puts(r, DIR_MAGIC_TYPE);
        return DONE;
-    case S_IFCHR:
+    case APR_CHR:
        /*
         * (void) magic_rsl_printf(r,"character special (%d/%d)",
         * major(sb->st_rdev), minor(sb->st_rdev));
         */
        (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN);
        return DONE;
-#ifdef S_IFBLK
-    case S_IFBLK:
+    case APR_BLK:
        /*
         * (void) magic_rsl_printf(r,"block special (%d/%d)",
         * major(sb->st_rdev), minor(sb->st_rdev));
@@ -1467,43 +1478,34 @@ static int fsmagic(request_rec *r, const char *fn)
        (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN);
        return DONE;
        /* TODO add code to handle V7 MUX and Blit MUX files */
-#endif
-#ifdef    S_IFIFO
-    case S_IFIFO:
+    case APR_PIPE:
        /*
         * magic_rsl_puts(r,"fifo (named pipe)");
         */
        (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN);
        return DONE;
-#endif
-#ifdef    S_IFLNK
-    case S_IFLNK:
+    case APR_LNK:
        /* We used stat(), the only possible reason for this is that the
         * symlink is broken.
         */
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                    MODNAME ": broken symlink (%s)", fn);
        return HTTP_INTERNAL_SERVER_ERROR;
-#endif
-#ifdef    S_IFSOCK
-#ifndef __COHERENT__
-    case S_IFSOCK:
+    case APR_SOCK:
        magic_rsl_puts(r, MIME_BINARY_UNKNOWN);
        return DONE;
-#endif
-#endif
-    case S_IFREG:
+    case APR_REG:
        break;
     default:
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
-                   MODNAME ": invalid mode 0%o.", (unsigned int)r->finfo.st_mode);
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
+                     MODNAME ": invalid file type %d.", r->finfo.filetype);
        return HTTP_INTERNAL_SERVER_ERROR;
     }
 
     /*
      * regular file, check next possibility
      */
-    if (r->finfo.st_size == 0) {
+    if (r->finfo.size == 0) {
        magic_rsl_puts(r, MIME_TEXT_UNKNOWN);
        return DONE;
     }
@@ -1515,7 +1517,7 @@ static int fsmagic(request_rec *r, const char *fn)
  * apprentice.c). Passed the name and FILE * of one file to be typed.
  */
                /* ARGSUSED1 *//* nbytes passed for regularity, maybe need later */
-static int softmagic(request_rec *r, unsigned char *buf, int nbytes)
+static int softmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes)
 {
     if (match(r, buf, nbytes))
        return 1;
@@ -1549,7 +1551,7 @@ static int softmagic(request_rec *r, unsigned char *buf, int nbytes)
  * If a continuation matches, we bump the current continuation level so that
  * higher-level continuations are processed.
  */
-static int match(request_rec *r, unsigned char *s, int nbytes)
+static int match(request_rec *r, unsigned char *s, apr_size_t nbytes)
 {
 #if MIME_MAGIC_DEBUG
     int rule_counter = 0;
@@ -1562,7 +1564,7 @@ static int match(request_rec *r, unsigned char *s, int nbytes)
     struct magic *m;
 
 #if MIME_MAGIC_DEBUG
-    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                MODNAME ": match conf=%x file=%s m=%s m->next=%s last=%s",
                conf,
                conf->magicfile ? conf->magicfile : "NULL",
@@ -1573,11 +1575,11 @@ static int match(request_rec *r, unsigned char *s, int nbytes)
 
 #if MIME_MAGIC_DEBUG
     for (m = conf->magic; m; m = m->next) {
-       if (ap_isprint((((unsigned long) m) >> 24) & 255) &&
-           ap_isprint((((unsigned long) m) >> 16) & 255) &&
-           ap_isprint((((unsigned long) m) >> 8) & 255) &&
-           ap_isprint(((unsigned long) m) & 255)) {
-           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       if (apr_isprint((((unsigned long) m) >> 24) & 255) &&
+           apr_isprint((((unsigned long) m) >> 16) & 255) &&
+           apr_isprint((((unsigned long) m) >> 8) & 255) &&
+           apr_isprint(((unsigned long) m) & 255)) {
+           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                        MODNAME ": match: POINTER CLOBBERED! "
                        "m=\"%c%c%c%c\"",
                        (((unsigned long) m) >> 24) & 255,
@@ -1592,7 +1594,7 @@ static int match(request_rec *r, unsigned char *s, int nbytes)
     for (m = conf->magic; m; m = m->next) {
 #if MIME_MAGIC_DEBUG
        rule_counter++;
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    MODNAME ": line=%d desc=%s", m->lineno, m->desc);
 #endif
 
@@ -1612,7 +1614,7 @@ static int match(request_rec *r, unsigned char *s, int nbytes)
            while (m_cont && (m_cont->cont_level != 0)) {
 #if MIME_MAGIC_DEBUG
                rule_counter++;
-               ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+               ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                        MODNAME ": line=%d mc=%x mc->next=%x cont=%d desc=%s",
                            m_cont->lineno, m_cont,
                            m_cont->next, m_cont->cont_level,
@@ -1631,7 +1633,7 @@ static int match(request_rec *r, unsigned char *s, int nbytes)
        /* if we get here, the main entry rule was a match */
        /* this will be the last run through the loop */
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    MODNAME ": rule matched, line=%d type=%d %s",
                    m->lineno, m->type,
                    (m->type == STRING) ? m->value.s : "");
@@ -1655,7 +1657,7 @@ static int match(request_rec *r, unsigned char *s, int nbytes)
        m = m->next;
        while (m && (m->cont_level != 0)) {
 #if MIME_MAGIC_DEBUG
-           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                        MODNAME ": match line=%d cont=%d type=%d %s",
                        m->lineno, m->cont_level, m->type,
                        (m->type == STRING) ? m->value.s : "");
@@ -1699,13 +1701,13 @@ static int match(request_rec *r, unsigned char *s, int nbytes)
            m = m->next;
        }
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    MODNAME ": matched after %d rules", rule_counter);
 #endif
        return 1;               /* all through */
     }
 #if MIME_MAGIC_DEBUG
-    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                MODNAME ": failed after %d rules", rule_counter);
 #endif
     return 0;                  /* no match at all */
@@ -1752,7 +1754,7 @@ static void mprint(request_rec *r, union VALUETYPE *p, struct magic *m)
        (void) magic_rsl_printf(r, m->desc, pp);
        return;
     default:
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                    MODNAME ": invalid m->type (%d) in mprint().",
                    m->type);
        return;
@@ -1798,7 +1800,7 @@ static int mconvert(request_rec *r, union VALUETYPE *p, struct magic *m)
            ((p->hl[3] << 24) | (p->hl[2] << 16) | (p->hl[1] << 8) | (p->hl[0]));
        return 1;
     default:
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                    MODNAME ": invalid type %d in mconvert().", m->type);
        return 0;
     }
@@ -1806,7 +1808,7 @@ static int mconvert(request_rec *r, union VALUETYPE *p, struct magic *m)
 
 
 static int mget(request_rec *r, union VALUETYPE *p, unsigned char *s,
-               struct magic *m, int nbytes)
+               struct magic *m, apr_size_t nbytes)
 {
     long offset = m->offset;
 
@@ -1850,7 +1852,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
     int matched;
 
     if ((m->value.s[0] == 'x') && (m->value.s[1] == '\0')) {
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                    MODNAME ": BOINK");
        return 1;
     }
@@ -1895,7 +1897,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
        break;
     default:
        /*  bogosity, pretend that it just wasn't a match */
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                    MODNAME ": invalid type %d in mcheck().", m->type);
        return 0;
     }
@@ -1905,7 +1907,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
     switch (m->reln) {
     case 'x':
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    "%lu == *any* = 1", v);
 #endif
        matched = 1;
@@ -1914,7 +1916,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
     case '!':
        matched = v != l;
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    "%lu != %lu = %d", v, l, matched);
 #endif
        break;
@@ -1922,7 +1924,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
     case '=':
        matched = v == l;
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    "%lu == %lu = %d", v, l, matched);
 #endif
        break;
@@ -1931,14 +1933,14 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
        if (m->flag & UNSIGNED) {
            matched = v > l;
 #if MIME_MAGIC_DEBUG
-           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                        "%lu > %lu = %d", v, l, matched);
 #endif
        }
        else {
            matched = (long) v > (long) l;
 #if MIME_MAGIC_DEBUG
-           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                        "%ld > %ld = %d", v, l, matched);
 #endif
        }
@@ -1948,14 +1950,14 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
        if (m->flag & UNSIGNED) {
            matched = v < l;
 #if MIME_MAGIC_DEBUG
-           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                        "%lu < %lu = %d", v, l, matched);
 #endif
        }
        else {
            matched = (long) v < (long) l;
 #if MIME_MAGIC_DEBUG
-           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                        "%ld < %ld = %d", v, l, matched);
 #endif
        }
@@ -1964,7 +1966,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
     case '&':
        matched = (v & l) == l;
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    "((%lx & %lx) == %lx) = %d", v, l, l, matched);
 #endif
        break;
@@ -1972,7 +1974,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
     case '^':
        matched = (v & l) != l;
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    "((%lx & %lx) != %lx) = %d", v, l, l, matched);
 #endif
        break;
@@ -1980,7 +1982,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
     default:
        /* bogosity, pretend it didn't match */
        matched = 0;
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 0, r,
                    MODNAME ": mcheck: can't happen: invalid relation %d.",
                    m->reln);
        break;
@@ -1992,7 +1994,7 @@ static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m)
 /* an optimization over plain strcmp() */
 #define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
 
-static int ascmagic(request_rec *r, unsigned char *buf, int nbytes)
+static int ascmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes)
 {
     int has_escapes = 0;
     unsigned char *s;
@@ -2011,15 +2013,15 @@ static int ascmagic(request_rec *r, unsigned char *buf, int nbytes)
     if (*buf == '.') {
        unsigned char *tp = buf + 1;
 
-       while (ap_isspace(*tp))
+       while (apr_isspace(*tp))
            ++tp;               /* skip leading whitespace */
-       if ((ap_isalnum(*tp) || *tp == '\\') &&
-            (ap_isalnum(*(tp + 1)) || *tp == '"')) {
+       if ((apr_isalnum(*tp) || *tp == '\\') &&
+            (apr_isalnum(*(tp + 1)) || *tp == '"')) {
            magic_rsl_puts(r, "application/x-troff");
            return 1;
        }
     }
-    if ((*buf == 'c' || *buf == 'C') && ap_isspace(*(buf + 1))) {
+    if ((*buf == 'c' || *buf == 'C') && apr_isspace(*(buf + 1))) {
        /* Fortran */
        magic_rsl_puts(r, "text/plain");
        return 1;
@@ -2111,7 +2113,7 @@ static struct {
 
 static int ncompr = sizeof(compr) / sizeof(compr[0]);
 
-static int zmagic(request_rec *r, unsigned char *buf, int nbytes)
+static int zmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes)
 {
     unsigned char *newbuf;
     int newsize;
@@ -2142,37 +2144,64 @@ struct uncompress_parms {
     int method;
 };
 
-static int uncompress_child(void *data, child_info *pinfo)
+static int uncompress_child(struct uncompress_parms *parm, apr_pool_t *cntxt,
+                            apr_file_t **pipe_in)
 {
-    struct uncompress_parms *parm = data;
-    int child_pid;
-    char *new_argv[4];
-
-    new_argv[0] = compr[parm->method].argv[0];
-    new_argv[1] = compr[parm->method].argv[1];
-    new_argv[2] = parm->r->filename;
-    new_argv[3] = NULL;
-
-    if (compr[parm->method].silent) {
-       close(STDERR_FILENO);
-    }
-
-    child_pid = ap_spawnvp(compr[parm->method].argv[0],
-                       new_argv);
-    if (child_pid == -1)
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, parm->r,
-               MODNAME ": could not execute `%s'.",
-               compr[parm->method].argv[0]);
-    return (child_pid);
+    int rc = 1;
+    const char *new_argv[4];
+    const char *const *env;
+    request_rec *r = parm->r;
+    apr_pool_t *child_context = cntxt;
+    apr_procattr_t *procattr;
+    apr_proc_t *procnew;
+
+    env = (const char *const *)ap_create_environment(child_context, r->subprocess_env);
+
+    if ((apr_procattr_create(&procattr, child_context) != APR_SUCCESS) ||
+        (apr_procattr_io_set(procattr, APR_FULL_BLOCK, 
+                           APR_FULL_BLOCK, APR_NO_PIPE)   != APR_SUCCESS) ||
+        (apr_procattr_dir_set(procattr, r->filename)        != APR_SUCCESS) ||
+        (apr_procattr_cmdtype_set(procattr, APR_PROGRAM)    != APR_SUCCESS)) {
+        /* Something bad happened, tell the world. */
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOPROC, r,
+               "couldn't setup child process: %s", r->filename);
+    }
+    else {
+        new_argv[0] = compr[parm->method].argv[0];
+        new_argv[1] = compr[parm->method].argv[1];
+        new_argv[2] = r->filename;
+        new_argv[3] = NULL;
+
+        if (compr[parm->method].silent) {
+            close(STDERR_FILENO);
+        }
+
+        procnew = apr_pcalloc(child_context, sizeof(*procnew));
+        rc = apr_proc_create(procnew, compr[parm->method].argv[0],
+                               new_argv, env, procattr, child_context);
+
+        if (rc != APR_SUCCESS) {
+            /* Bad things happened. Everyone should have cleaned up. */
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOPROC, r,
+                          MODNAME ": could not execute `%s'.",
+                          compr[parm->method].argv[0]);
+        }
+        else {
+            apr_pool_note_subprocess(child_context, procnew, kill_after_timeout);
+            *pipe_in = procnew->out;
+        }
+    }
+
+    return (rc);
 }
 
-
 static int uncompress(request_rec *r, int method, 
-                     unsigned char **newch, int n)
+                     unsigned char **newch, apr_size_t n)
 {
     struct uncompress_parms parm;
-    BUFF *bout;
-    pool *sub_pool;
+    apr_file_t *pipe_out = NULL;
+    apr_pool_t *sub_context;
+    apr_status_t rv;
 
     parm.r = r;
     parm.method = method;
@@ -2181,23 +2210,24 @@ static int uncompress(request_rec *r, int method,
      * there are cases (i.e. generating directory indicies with mod_autoindex)
      * where we would end up with LOTS of zombies.
      */
-    sub_pool = ap_make_sub_pool(r->pool);
+    if (apr_pool_create(&sub_context, r->pool) != APR_SUCCESS)
+        return -1;
 
-    if (!ap_bspawn_child(sub_pool, uncompress_child, &parm, kill_always,
-                        NULL, &bout, NULL)) {
-       ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+    if ((rv = uncompress_child(&parm, sub_context, &pipe_out)) != APR_SUCCESS) {
+       ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                    MODNAME ": couldn't spawn uncompress process: %s", r->uri);
        return -1;
     }
 
-    *newch = (unsigned char *) ap_palloc(r->pool, n);
-    if ((n = ap_bread(bout, *newch, n)) <= 0) {
-       ap_destroy_pool(sub_pool);
-       ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+    *newch = (unsigned char *) apr_palloc(r->pool, n);
+    rv = apr_file_read(pipe_out, *newch, &n);
+    if (n == 0) {
+       apr_pool_destroy(sub_context);
+       ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
            MODNAME ": read failed %s", r->filename);
        return -1;
     }
-    ap_destroy_pool(sub_pool);
+    apr_pool_destroy(sub_context);
     return n;
 }
 
@@ -2221,7 +2251,7 @@ static int uncompress(request_rec *r, int method,
  * old UNIX tar file, 2 for Unix Std (POSIX) tar file.
  */
 
-static int is_tar(unsigned char *buf, int nbytes)
+static int is_tar(unsigned char *buf, apr_size_t nbytes)
 {
     register union record *header = (union record *) buf;
     register int i;
@@ -2266,7 +2296,7 @@ static long from_oct(int digs, char *where)
 {
     register long value;
 
-    while (ap_isspace(*where)) {       /* Skip spaces */
+    while (apr_isspace(*where)) {      /* Skip spaces */
        where++;
        if (--digs <= 0)
            return -1;          /* All blank field */
@@ -2277,7 +2307,7 @@ static long from_oct(int digs, char *where)
        --digs;
     }
 
-    if (digs > 0 && *where && !ap_isspace(*where))
+    if (digs > 0 && *where && !apr_isspace(*where))
        return -1;              /* Ended on non-space/nul */
 
     return value;
@@ -2300,16 +2330,16 @@ static int revision_suffix(request_rec *r)
     request_rec *sub;
 
 #if MIME_MAGIC_DEBUG
-    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                MODNAME ": revision_suffix checking %s", r->filename);
 #endif /* MIME_MAGIC_DEBUG */
 
     /* check for recognized revision suffix */
     suffix_pos = strlen(r->filename) - 1;
-    if (!ap_isdigit(r->filename[suffix_pos])) {
+    if (!apr_isdigit(r->filename[suffix_pos])) {
        return 0;
     }
-    while (suffix_pos >= 0 && ap_isdigit(r->filename[suffix_pos]))
+    while (suffix_pos >= 0 && apr_isdigit(r->filename[suffix_pos]))
        suffix_pos--;
     if (suffix_pos < 0 || r->filename[suffix_pos] != '@') {
        return 0;
@@ -2317,27 +2347,27 @@ static int revision_suffix(request_rec *r)
 
     /* perform sub-request for the file name without the suffix */
     result = 0;
-    sub_filename = ap_pstrndup(r->pool, r->filename, suffix_pos);
+    sub_filename = apr_pstrndup(r->pool, r->filename, suffix_pos);
 #if MIME_MAGIC_DEBUG
-    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                MODNAME ": subrequest lookup for %s", sub_filename);
 #endif /* MIME_MAGIC_DEBUG */
-    sub = ap_sub_req_lookup_file(sub_filename, r);
+    sub = ap_sub_req_lookup_file(sub_filename, r, NULL);
 
     /* extract content type/encoding/language from sub-request */
     if (sub->content_type) {
-       r->content_type = ap_pstrdup(r->pool, sub->content_type);
+       r->content_type = apr_pstrdup(r->pool, sub->content_type);
 #if MIME_MAGIC_DEBUG
-       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,
+       ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r,
                    MODNAME ": subrequest %s got %s",
                    sub_filename, r->content_type);
 #endif /* MIME_MAGIC_DEBUG */
        if (sub->content_encoding)
            r->content_encoding =
-               ap_pstrdup(r->pool, sub->content_encoding);
+               apr_pstrdup(r->pool, sub->content_encoding);
        if (sub->content_language)
            r->content_language =
-               ap_pstrdup(r->pool, sub->content_language);
+               apr_pstrdup(r->pool, sub->content_language);
        result = 1;
     }
 
@@ -2350,8 +2380,7 @@ static int revision_suffix(request_rec *r)
 /*
  * initialize the module
  */
-
-static void magic_init(server_rec *main_server, pool *p)
+static void magic_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server)
 {
     int result;
     magic_server_config_rec *conf;
@@ -2374,14 +2403,14 @@ static void magic_init(server_rec *main_server, pool *p)
                return;
 #if MIME_MAGIC_DEBUG
            prevm = 0;
-           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, s,
+           ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, s,
                        MODNAME ": magic_init 1 test");
            for (m = conf->magic; m; m = m->next) {
-               if (ap_isprint((((unsigned long) m) >> 24) & 255) &&
-                   ap_isprint((((unsigned long) m) >> 16) & 255) &&
-                   ap_isprint((((unsigned long) m) >> 8) & 255) &&
-                   ap_isprint(((unsigned long) m) & 255)) {
-                   ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, s,
+               if (apr_isprint((((unsigned long) m) >> 24) & 255) &&
+                   apr_isprint((((unsigned long) m) >> 16) & 255) &&
+                   apr_isprint((((unsigned long) m) >> 8) & 255) &&
+                   apr_isprint(((unsigned long) m) & 255)) {
+                   ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, s,
                                MODNAME ": magic_init 1: POINTER CLOBBERED! "
                                "m=\"%c%c%c%c\" line=%d",
                                (((unsigned long) m) >> 24) & 255,
@@ -2408,7 +2437,7 @@ static int magic_find_ct(request_rec *r)
     magic_server_config_rec *conf;
 
     /* the file has to exist */
-    if (r->finfo.st_mode == 0 || !r->filename) {
+    if (r->finfo.filetype == 0 || !r->filename) {
        return DECLINED;
     }
 
@@ -2439,29 +2468,29 @@ static int magic_find_ct(request_rec *r)
     return magic_rsl_to_request(r);
 }
 
+static void register_hooks(apr_pool_t *p)
+{
+    static const char * const aszPre[]={ "mod_mime.c", NULL };
+
+    /* mod_mime_magic should be run after mod_mime, if at all. */
+
+    ap_hook_type_checker(magic_find_ct, aszPre, NULL, APR_HOOK_MIDDLE);
+    ap_hook_post_config(magic_init, NULL, NULL, APR_HOOK_FIRST);
+}
+
 /*
  * Apache API module interface
  */
 
 module mime_magic_module =
 {
-    STANDARD_MODULE_STUFF,
-    magic_init,                        /* initializer */
-    NULL,                      /* dir config creator */
-    NULL,                      /* dir merger --- default is to override */
-    create_magic_server_config,        /* server config */
-    merge_magic_server_config, /* merge server config */
-    mime_magic_cmds,           /* command table */
-    NULL,                      /* handlers */
-    NULL,                      /* filename translation */
-    NULL,                      /* check_user_id */
-    NULL,                      /* check auth */
-    NULL,                      /* check access */
-    magic_find_ct,             /* type_checker */
-    NULL,                      /* fixups */
-    NULL,                      /* logger */
-    NULL,                      /* header parser */
-    NULL,                      /* child_init */
-    NULL,                      /* child_exit */
-    NULL                       /* post read-request */
+    STANDARD20_MODULE_STUFF,
+    NULL,                      /* dir config creator */
+    NULL,                      /* dir merger --- default is to override */
+    create_magic_server_config,        /* server config */
+    merge_magic_server_config, /* merge server config */
+    mime_magic_cmds,           /* command apr_table_t */
+    register_hooks              /* register hooks */
 };
+
+