/* ====================================================================
 * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * 4. The names "Apache Server" and "Apache Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Group and was originally based
 * on public domain software written at the National Center for
 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
 * For more information on the Apache Group and the Apache HTTP server
 * project, please see <http://www.apache.org/>.
 *
 */

/*
 * http_config.c: once was auxillary functions for reading httpd's config
 * file and converting filenames into a namespace
 *
 * Rob McCool 
 * 
 * Wall-to-wall rewrite for Apache... commands which are part of the
 * server core can now be found next door in "http_core.c".  Now contains
 * general command loop, and functions which do bookkeeping for the new
 * Apache config stuff (modules and configuration vectors).
 *
 * rst
 *
 */

#define CORE_PRIVATE

#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"		/* for errors in parse_htaccess */
#include "http_request.h"	/* for default_handler (see invoke_handler) */
#include "http_conf_globals.h"	/* Sigh... */
#include "http_vhost.h"
#include "explain.h"

DEF_Explain

/****************************************************************
 *
 * We begin with the functions which deal with the linked list
 * of modules which control just about all of the server operation.
 */

/* total_modules is the number of modules that have been linked
 * into the server.
 */
static int total_modules = 0;
/* dynamic_modules is the number of modules that have been added
 * after the pre-loaded ones have been set up. It shouldn't be larger
 * than DYNAMIC_MODULE_LIMIT.
 */
static int dynamic_modules = 0;
API_VAR_EXPORT module *top_module = NULL;
API_VAR_EXPORT module **ap_loaded_modules=NULL;

typedef int (*handler_func) (request_rec *);
typedef void *(*dir_maker_func) (pool *, char *);
typedef void *(*merger_func) (pool *, void *, void *);

/* Dealing with config vectors.  These are associated with per-directory,
 * per-server, and per-request configuration, and have a void* pointer for
 * each modules.  The nature of the structure pointed to is private to the
 * module in question... the core doesn't (and can't) know.  However, there
 * are defined interfaces which allow it to create instances of its private
 * per-directory and per-server structures, and to merge the per-directory
 * structures of a directory and its subdirectory (producing a new one in
 * which the defaults applying to the base directory have been properly
 * overridden).
 */

#ifndef ap_get_module_config
API_EXPORT(void *) ap_get_module_config(void *conf_vector, module *m)
{
    void **confv = (void **) conf_vector;
    return confv[m->module_index];
}
#endif

#ifndef ap_set_module_config
API_EXPORT(void) ap_set_module_config(void *conf_vector, module *m, void *val)
{
    void **confv = (void **) conf_vector;
    confv[m->module_index] = val;
}
#endif

static void *create_empty_config(pool *p)
{
    void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) *
				    (total_modules + DYNAMIC_MODULE_LIMIT));
    return (void *) conf_vector;
}

static void *create_default_per_dir_config(pool *p)
{
    void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
    module *modp;

    for (modp = top_module; modp; modp = modp->next) {
	dir_maker_func df = modp->create_dir_config;

	if (df)
	    conf_vector[modp->module_index] = (*df) (p, NULL);
    }

    return (void *) conf_vector;
}

void *
     ap_merge_per_dir_configs(pool *p, void *base, void *new)
{
    void **conf_vector = (void **) ap_palloc(p, sizeof(void *) * total_modules);
    void **base_vector = (void **) base;
    void **new_vector = (void **) new;
    module *modp;

    for (modp = top_module; modp; modp = modp->next) {
	merger_func df = modp->merge_dir_config;
	int i = modp->module_index;

	if (df && new_vector[i])
	    conf_vector[i] = (*df) (p, base_vector[i], new_vector[i]);
	else
	    conf_vector[i] = new_vector[i] ? new_vector[i] : base_vector[i];
    }

    return (void *) conf_vector;
}

static void *create_server_config(pool *p, server_rec *s)
{
    void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
    module *modp;

    for (modp = top_module; modp; modp = modp->next) {
	if (modp->create_server_config)
	    conf_vector[modp->module_index] = (*modp->create_server_config) (p, s);
    }

    return (void *) conf_vector;
}

static void merge_server_configs(pool *p, void *base, void *virt)
{
    /* Can reuse the 'virt' vector for the spine of it, since we don't
     * have to deal with the moral equivalent of .htaccess files here...
     */

    void **base_vector = (void **) base;
    void **virt_vector = (void **) virt;
    module *modp;

    for (modp = top_module; modp; modp = modp->next) {
	merger_func df = modp->merge_server_config;
	int i = modp->module_index;

	if (!virt_vector[i])
	    virt_vector[i] = base_vector[i];
	else if (df)
	    virt_vector[i] = (*df) (p, base_vector[i], virt_vector[i]);
    }
}

void *ap_create_request_config(pool *p)
{
    return create_empty_config(p);
}

CORE_EXPORT(void *) ap_create_per_dir_config(pool *p)
{
    return create_empty_config(p);
}

#ifdef EXPLAIN

struct {
    int offset;
    char *method;
} aMethods[] =

{
#define m(meth)	{ XtOffsetOf(module,meth),#meth }
    m(translate_handler),
    m(ap_check_user_id),
    m(auth_checker),
    m(type_checker),
    m(fixer_upper),
    m(logger),
    { -1, "?" },
#undef m
};

char *ShowMethod(module *modp, int offset)
{
    int n;
    static char buf[200];

    for (n = 0; aMethods[n].offset >= 0; ++n)
	if (aMethods[n].offset == offset)
	    break;
    ap_snprintf(buf, sizeof(buf), "%s:%s", modp->name, aMethods[n].method);
    return buf;
}
#else
#define ShowMethod(modp,offset)
#endif

/****************************************************************
 *
 * Dispatch through the modules to find handlers for various phases
 * of request handling.  These are invoked by http_request.c to actually
 * do the dirty work of slogging through the module structures.
 */

/*
 * Optimized run_method routines.  The observation here is that many modules
 * have NULL for most of the methods.  So we build optimized lists of
 * everything.  If you think about it, this is really just like a sparse array
 * implementation to avoid scanning the zero entries.
 */
static const int method_offsets[] =
{
    XtOffsetOf(module, translate_handler),
    XtOffsetOf(module, ap_check_user_id),
    XtOffsetOf(module, auth_checker),
    XtOffsetOf(module, access_checker),
    XtOffsetOf(module, type_checker),
    XtOffsetOf(module, fixer_upper),
    XtOffsetOf(module, logger),
    XtOffsetOf(module, header_parser),
    XtOffsetOf(module, post_read_request)
};
#define NMETHODS	(sizeof (method_offsets)/sizeof (method_offsets[0]))

static struct {
    int translate_handler;
    int ap_check_user_id;
    int auth_checker;
    int access_checker;
    int type_checker;
    int fixer_upper;
    int logger;
    int header_parser;
    int post_read_request;
} offsets_into_method_ptrs;

/*
 * This is just one big array of method_ptrs.  It's constructed such that,
 * for example, method_ptrs[ offsets_into_method_ptrs.logger ] is the first
 * logger function.  You go one-by-one from there until you hit a NULL.
 * This structure was designed to hopefully maximize cache-coolness.
 */
static handler_func *method_ptrs;

/* routine to reconstruct all these shortcuts... called after every
 * add_module.
 * XXX: this breaks if modules dink with their methods pointers
 */
static void build_method_shortcuts(void)
{
    module *modp;
    int how_many_ptrs;
    int i;
    int next_ptr;
    handler_func fp;

    if (method_ptrs) {
	/* free up any previous set of method_ptrs */
	free(method_ptrs);
    }

    /* first we count how many functions we have */
    how_many_ptrs = 0;
    for (modp = top_module; modp; modp = modp->next) {
	for (i = 0; i < NMETHODS; ++i) {
	    if (*(handler_func *) (method_offsets[i] + (char *) modp)) {
		++how_many_ptrs;
	    }
	}
    }
    method_ptrs = malloc((how_many_ptrs + NMETHODS) * sizeof(handler_func));
    if (method_ptrs == NULL) {
	fprintf(stderr, "Ouch!  Out of memory in build_method_shortcuts()!\n");
    }
    next_ptr = 0;
    for (i = 0; i < NMETHODS; ++i) {
	/* XXX: This is an itsy bit presumptuous about the alignment
	 * constraints on offsets_into_method_ptrs.  I can't remember if
	 * ANSI says this has to be true... -djg */
	((int *) &offsets_into_method_ptrs)[i] = next_ptr;
	for (modp = top_module; modp; modp = modp->next) {
	    fp = *(handler_func *) (method_offsets[i] + (char *) modp);
	    if (fp) {
		method_ptrs[next_ptr++] = fp;
	    }
	}
	method_ptrs[next_ptr++] = NULL;
    }
}


static int run_method(request_rec *r, int offset, int run_all)
{
    int i;

    for (i = offset; method_ptrs[i]; ++i) {
	handler_func mod_handler = method_ptrs[i];

	if (mod_handler) {
	    int result;

	    result = (*mod_handler) (r);

	    if (result != DECLINED && (!run_all || result != OK))
		return result;
	}
    }

    return run_all ? OK : DECLINED;
}

int ap_translate_name(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.translate_handler, 0);
}

int ap_check_access(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.access_checker, 1);
}

int ap_find_types(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.type_checker, 0);
}

int ap_run_fixups(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.fixer_upper, 1);
}

int ap_log_transaction(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.logger, 1);
}

int ap_header_parse(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.header_parser, 1);
}

int ap_run_post_read_request(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.post_read_request, 1);
}

/* Auth stuff --- anything that defines one of these will presumably
 * want to define something for the other.  Note that check_auth is
 * separate from check_access to make catching some config errors easier.
 */

int ap_check_user_id(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.ap_check_user_id, 0);
}

int ap_check_auth(request_rec *r)
{
    return run_method(r, offsets_into_method_ptrs.auth_checker, 0);
}

/*
 * For speed/efficiency we generate a compact list of all the handlers
 * and wildcard handlers.  This means we won't have to scan the entire
 * module list looking for handlers... where we'll find a whole whack
 * of NULLs.
 */
typedef struct {
    handler_rec hr;
    size_t len;
} fast_handler_rec;

static fast_handler_rec *handlers;
static fast_handler_rec *wildhandlers;

static void init_handlers(pool *p)
{
    module *modp;
    int nhandlers = 0;
    int nwildhandlers = 0;
    const handler_rec *handp;
    fast_handler_rec *ph, *pw;
    char *starp;

    for (modp = top_module; modp; modp = modp->next) {
	if (!modp->handlers)
	    continue;
	for (handp = modp->handlers; handp->content_type; ++handp) {
	    if (strchr(handp->content_type, '*')) {
                nwildhandlers ++;
            } else {
                nhandlers ++;
            }
        }
    }
    ph = handlers = ap_palloc(p, sizeof(*ph)*(nhandlers + 1));
    pw = wildhandlers = ap_palloc(p, sizeof(*pw)*(nwildhandlers + 1));
    for (modp = top_module; modp; modp = modp->next) {
	if (!modp->handlers)
	    continue;
	for (handp = modp->handlers; handp->content_type; ++handp) {
	    if ((starp = strchr(handp->content_type, '*'))) {
                pw->hr.content_type = handp->content_type;
                pw->hr.handler = handp->handler;
		pw->len = starp - handp->content_type;
                pw ++;
            } else {
                ph->hr.content_type = handp->content_type;
                ph->hr.handler = handp->handler;
		ph->len = strlen(handp->content_type);
                ph ++;
            }
        }
    }
    pw->hr.content_type = NULL;
    pw->hr.handler = NULL;
    ph->hr.content_type = NULL;
    ph->hr.handler = NULL;
}

int ap_invoke_handler(request_rec *r)
{
    fast_handler_rec *handp;
    const char *handler;
    char *p;
    size_t handler_len;
    int result = HTTP_INTERNAL_SERVER_ERROR;

    if (r->handler) {
	handler = r->handler;
	handler_len = strlen(handler);
    }
    else {
	handler = r->content_type ? r->content_type : ap_default_type(r);
	if ((p = strchr(handler, ';')) != NULL) { /* MIME type arguments */
	    while (p > handler && p[-1] == ' ')
		--p;		/* strip trailing spaces */
	    handler_len = p - handler;
	}
	else {
	    handler_len = strlen(handler);
	}
    }

    /* Pass one --- direct matches */

    for (handp = handlers; handp->hr.content_type; ++handp) {
	if (handler_len == handp->len
	    && !strncmp(handler, handp->hr.content_type, handler_len)) {
            result = (*handp->hr.handler) (r);

            if (result != DECLINED)
                return result;
        }
    }

    if (result == HTTP_INTERNAL_SERVER_ERROR && r->handler) {
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r,
            "handler \"%s\" not found for: %s", r->handler, r->filename);
    }

    /* Pass two --- wildcard matches */

    for (handp = wildhandlers; handp->hr.content_type; ++handp) {
	if (handler_len >= handp->len
	    && !strncmp(handler, handp->hr.content_type, handp->len)) {
             result = (*handp->hr.handler) (r);

             if (result != DECLINED)
                 return result;
         }
    }

    return HTTP_INTERNAL_SERVER_ERROR;
}

/* One-time setup for precompiled modules --- NOT to be done on restart */

API_EXPORT(void) ap_add_module(module *m)
{
    /* This could be called from an AddModule httpd.conf command,
     * after the file has been linked and the module structure within it
     * teased out...
     */

    if (m->version != MODULE_MAGIC_NUMBER_MAJOR) {
	fprintf(stderr, "%s: module \"%s\" is not compatible with this "
		"version of Apache.\n", ap_server_argv0, m->name);
	fprintf(stderr, "Please contact the vendor for the correct version.\n");
	exit(1);
    }

    if (m->next == NULL) {
	m->next = top_module;
	top_module = m;
    }
    if (m->module_index == -1) {
	m->module_index = total_modules++;
	dynamic_modules++;

	if (dynamic_modules > DYNAMIC_MODULE_LIMIT) {
	    fprintf(stderr, "%s: module \"%s\" could not be loaded, because"
		    " the dynamic\n", ap_server_argv0, m->name);
	    fprintf(stderr, "module limit was reached. Please increase "
		    "DYNAMIC_MODULE_LIMIT and recompile.\n");
	    exit(1);
	}
    }

    /* Some C compilers put a complete path into __FILE__, but we want
     * only the filename (e.g. mod_includes.c). So check for path
     * components (Unix and DOS), and remove them.
     */

    if (strrchr(m->name, '/'))
	m->name = 1 + strrchr(m->name, '/');
    if (strrchr(m->name, '\\'))
	m->name = 1 + strrchr(m->name, '\\');

#ifdef _OSD_POSIX /* __FILE__="*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)" */
    /* We cannot fix the string in-place, because it's const */
    if (m->name[strlen(m->name)-1]==')') {
	char *tmp = strdup(m->name);	/* FIXME:memory leak, albeit a small one */
	tmp[strlen(tmp)-1] = '\0';
	m->name = tmp;
    }
#endif /*_OSD_POSIX*/
}

/* 
 * remove_module undoes what add_module did. There are some caveats:
 * when the module is removed, its slot is lost so all the current
 * per-dir and per-server configurations are invalid. So we should
 * only ever call this function when you are invalidating almost
 * all our current data. I.e. when doing a restart.
 */

API_EXPORT(void) ap_remove_module(module *m)
{
    module *modp;

    modp = top_module;
    if (modp == m) {
	/* We are the top module, special case */
	top_module = modp->next;
	m->next = NULL;
    }
    else {
	/* Not the top module, find use. When found modp will
	 * point to the module _before_ us in the list
	 */

	while (modp && modp->next != m) {
	    modp = modp->next;
	}
	if (!modp) {
	    /* Uh-oh, this module doesn't exist */
	    ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL,
		"Cannot remove module %s: not found in module list",
		m->name);
	    return;
	}
	/* Eliminate us from the module list */
	modp->next = modp->next->next;
    }

    m->module_index = -1;	/* simulate being unloaded, should
				 * be unnecessary */
    dynamic_modules--;
    total_modules--;
}

API_EXPORT(void) ap_add_loaded_module(module *mod)
{
    module **m;

    /* 
     *  Add module pointer to top of chained module list 
     */
    ap_add_module(mod);

    /* 
     *  And module pointer to list of loaded modules 
     *
     *  Notes: 1. ap_add_module() would already complain if no more space
     *            exists for adding a dynamically loaded module
     *         2. ap_add_module() accepts double-inclusion, so we have
     *            to accept this, too.
     */
    for (m = ap_loaded_modules; *m != NULL; m++)
        ;
    *m++ = mod;
    *m = NULL;
}

API_EXPORT(void) ap_remove_loaded_module(module *mod)
{
    module **m;
    module **m2;
    int done;

    /* 
     *  Remove module pointer from chained module list 
     */
    ap_remove_module(mod);

    /* 
     *  Remove module pointer from list of loaded modules
     *
     *  Note: 1. We cannot determine if the module was successfully
     *           removed by ap_remove_module().
     *        2. We have not to complain explicity when the module
     *           is not found because ap_remove_module() did it
     *           for us already.
     */
    for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) {
        if (*m2 == mod && done == 0)
            done = 1;
        else
            *m++ = *m2;
    }
    *m = NULL;
}

void ap_setup_prelinked_modules()
{
    module **m;
    module **m2;

    /*
     *  Initialise total_modules variable and module indices
     */
    total_modules = 0;
    for (m = ap_preloaded_modules; *m != NULL; m++)
        (*m)->module_index = total_modules++;

    /* 
     *  Initialise list of loaded modules
     */
    ap_loaded_modules = (module **)malloc(
        sizeof(module *)*(total_modules+DYNAMIC_MODULE_LIMIT+1));
    if (ap_loaded_modules == NULL) {
	fprintf(stderr, "Ouch!  Out of memory in ap_setup_prelinked_modules()!\n");
    }
    for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; )
        *m2++ = *m++;
    *m2 = NULL;

    /*
     *   Initialize chain of linked (=activate) modules
     */
    for (m = ap_prelinked_modules; *m != NULL; m++)
        ap_add_module(*m);
}

API_EXPORT(const char *) ap_find_module_name(module *m)
{
    return m->name;
}

API_EXPORT(module *) ap_find_linked_module(const char *name)
{
    module *modp;

    for (modp = top_module; modp; modp = modp->next) {
	if (strcmp(modp->name, name) == 0)
	    return modp;
    }
    return NULL;
}

/* Add a named module.  Returns 1 if module found, 0 otherwise.  */
API_EXPORT(int) ap_add_named_module(const char *name)
{
    module *modp;
    int i = 0;

    for (modp = ap_loaded_modules[i]; modp; modp = ap_loaded_modules[++i]) {
	if (strcmp(modp->name, name) == 0) {
	    /* Only add modules that are not already enabled.  */
	    if (modp->next == NULL) {
		ap_add_module(modp);
	    }
	    return 1;
	}
    }

    return 0;
}

/* Clear the internal list of modules, in preparation for starting over. */
API_EXPORT(void) ap_clear_module_list()
{
    module **m = &top_module;
    module **next_m;

    while (*m) {
	next_m = &((*m)->next);
	*m = NULL;
	m = next_m;
    }

    /* This is required; so we add it always.  */
    ap_add_named_module("http_core.c");
}

/*****************************************************************
 *
 * Resource, access, and .htaccess config files now parsed by a common
 * command loop.
 *
 * Let's begin with the basics; parsing the line and
 * invoking the function...
 */

static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
			    void *mconfig, const char *args)
{
    char *w, *w2, *w3;
    const char *errmsg;

    if ((parms->override & cmd->req_override) == 0)
	return ap_pstrcat(parms->pool, cmd->name, " not allowed here", NULL);

    parms->info = cmd->cmd_data;
    parms->cmd = cmd;

    switch (cmd->args_how) {
    case RAW_ARGS:
	return ((const char *(*)(cmd_parms *, void *, const char *))
		(cmd->func)) (parms, mconfig, args);

    case NO_ARGS:
	if (*args != 0)
	    return ap_pstrcat(parms->pool, cmd->name, " takes no arguments",
			   NULL);

	return ((const char *(*)(cmd_parms *, void *))
		(cmd->func)) (parms, mconfig);

    case TAKE1:
	w = ap_getword_conf(parms->pool, &args);

	if (*w == '\0' || *args != 0)
	    return ap_pstrcat(parms->pool, cmd->name, " takes one argument",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

	return ((const char *(*)(cmd_parms *, void *, const char *))
		(cmd->func)) (parms, mconfig, w);

    case TAKE2:

	w = ap_getword_conf(parms->pool, &args);
	w2 = ap_getword_conf(parms->pool, &args);

	if (*w == '\0' || *w2 == '\0' || *args != 0)
	    return ap_pstrcat(parms->pool, cmd->name, " takes two arguments",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

	return ((const char *(*)(cmd_parms *, void *, const char *,
			const char *)) (cmd->func)) (parms, mconfig, w, w2);

    case TAKE12:

	w = ap_getword_conf(parms->pool, &args);
	w2 = ap_getword_conf(parms->pool, &args);

	if (*w == '\0' || *args != 0)
	    return ap_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

	return ((const char *(*)(cmd_parms *, void *, const char *,
			    const char *)) (cmd->func)) (parms, mconfig, w,
							    *w2 ? w2 : NULL);

    case TAKE3:

	w = ap_getword_conf(parms->pool, &args);
	w2 = ap_getword_conf(parms->pool, &args);
	w3 = ap_getword_conf(parms->pool, &args);

	if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
	    return ap_pstrcat(parms->pool, cmd->name, " takes three arguments",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

	return ((const char *(*)(cmd_parms *, void *, const char *,
			    const char *, const char *)) (cmd->func)) (parms,
							mconfig, w, w2, w3);

    case TAKE23:

	w = ap_getword_conf(parms->pool, &args);
	w2 = ap_getword_conf(parms->pool, &args);
	w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;

	if (*w == '\0' || *w2 == '\0' || *args != 0)
	    return ap_pstrcat(parms->pool, cmd->name,
			    " takes two or three arguments",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

	return ((const char *(*)(cmd_parms *, void *, const char *,
			    const char *, const char *)) (cmd->func)) (parms,
							mconfig, w, w2, w3);

    case TAKE123:

	w = ap_getword_conf(parms->pool, &args);
	w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
	w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;

	if (*w == '\0' || *args != 0)
	    return ap_pstrcat(parms->pool, cmd->name,
			    " takes one, two or three arguments",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

	return ((const char *(*)(cmd_parms *, void *, const char *,
			    const char *, const char *)) (cmd->func)) (parms,
							mconfig, w, w2, w3);

    case TAKE13:

	w = ap_getword_conf(parms->pool, &args);
	w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
	w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;

	if (*w == '\0' || (*w2 && !w3) || *args != 0)
	    return ap_pstrcat(parms->pool, cmd->name,
			    " takes one or three arguments",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);

	return ((const char *(*)(cmd_parms *, void *, const char *,
			    const char *, const char *)) (cmd->func)) (parms,
							mconfig, w, w2, w3);

    case ITERATE:

	while (*(w = ap_getword_conf(parms->pool, &args)) != '\0')
	if   ((errmsg = ((const char *(*)(cmd_parms *, void *,
			const char *)) (cmd->func)) (parms, mconfig, w)))
		    return errmsg;

	return NULL;

    case ITERATE2:

	w = ap_getword_conf(parms->pool, &args);

	if (*w == '\0' || *args == 0)
	    return ap_pstrcat(parms->pool, cmd->name,
			    " requires at least two arguments",
			    cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);


	while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0')
	    if   ((errmsg = ((const char *(*)(cmd_parms *, void *,
			    const char *, const char *)) (cmd->func)) (parms,
							    mconfig, w, w2)))
			return errmsg;

	return NULL;

    case FLAG:

	w = ap_getword_conf(parms->pool, &args);

	if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off")))
	    return ap_pstrcat(parms->pool, cmd->name, " must be On or Off",
			    NULL);

	return ((const char *(*)(cmd_parms *, void *, int))
		(cmd->func)) (parms, mconfig, strcasecmp(w, "off") != 0);

    default:

	return ap_pstrcat(parms->pool, cmd->name,
		    " is improperly configured internally (server bug)",
			NULL);
    }
}

CORE_EXPORT(const command_rec *) ap_find_command(const char *name, const command_rec *cmds)
{
    while (cmds->name)
	if (!strcasecmp(name, cmds->name))
	    return cmds;
	else
	    ++cmds;

    return NULL;
}

CORE_EXPORT(const command_rec *) ap_find_command_in_modules(const char *cmd_name, module **mod)
{
    const command_rec *cmdp;
    module *modp;

    for (modp = *mod; modp; modp = modp->next)
	if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) {
	    *mod = modp;
	    return cmdp;
	}

    return NULL;
}

CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module *mod)
{
    void *mconfig = ap_get_module_config(config, mod);
    void *sconfig = ap_get_module_config(parms->server->module_config, mod);

    if (!mconfig && mod->create_dir_config) {
	mconfig = (*mod->create_dir_config) (parms->pool, parms->path);
	ap_set_module_config(config, mod, mconfig);
    }

    if (!sconfig && mod->create_server_config) {
	sconfig = (*mod->create_server_config) (parms->pool, parms->server);
	ap_set_module_config(parms->server->module_config, mod, sconfig);
    }
    return mconfig;
}

CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l)
{
    void *oldconfig;
    const char *args, *cmd_name, *retval;
    const command_rec *cmd;
    module *mod = top_module;

    if ((l[0] == '#') || (!l[0]))
	return NULL;

    args = l;
    cmd_name = ap_getword_conf(parms->temp_pool, &args);
    if (*cmd_name == '\0')
	return NULL;

    oldconfig = parms->context;
    parms->context = config;
    do {
	if (!(cmd = ap_find_command_in_modules(cmd_name, &mod))) {
            errno = EINVAL;
            return ap_pstrcat(parms->pool, "Invalid command '", cmd_name,
                           "', perhaps mis-spelled or defined by a module "
                           "not included in the server configuration", NULL);
	}
	else {
	    void *mconfig = ap_set_config_vectors(parms,config, mod);

	    retval = invoke_cmd(cmd, parms, mconfig, args);
	    mod = mod->next;	/* Next time around, skip this one */
	}
    } while (retval && !strcmp(retval, DECLINE_CMD));
    parms->context = oldconfig;

    return retval;
}

API_EXPORT(const char *) ap_srm_command_loop(cmd_parms *parms, void *config)
{
    char l[MAX_STRING_LEN];

    while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
	const char *errmsg = ap_handle_command(parms, config, l);
        if (errmsg) {
	    return errmsg;
	}
    }

    return NULL;
}

/*
 * Generic command functions...
 */

API_EXPORT_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd,
						char *struct_ptr, char *arg)
{
    /* This one's pretty generic... */

    int offset = (int) (long) cmd->info;
    *(char **) (struct_ptr + offset) = arg;
    return NULL;
}

API_EXPORT_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd,
						char *struct_ptr, char *arg)
{
    /* This one's pretty generic... */

    int offset = (int) (long) cmd->info;
    ap_str_tolower(arg);
    *(char **) (struct_ptr + offset) = arg;
    return NULL;
}

API_EXPORT_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd,
					      char *struct_ptr, int arg)
{
    /* This one's pretty generic too... */

    int offset = (int) (long) cmd->info;
    *(int *) (struct_ptr + offset) = arg ? 1 : 0;
    return NULL;
}

API_EXPORT_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, char *struct_ptr, char *arg)
{
    /* Prepend server_root to relative arg.
       This allows .htaccess to be independent of server_root,
       so the server can be moved or mirrored with less pain.  */
    char *p;
    int offset = (int) (long) cmd->info;
    if (ap_os_is_path_absolute(arg))
	p = arg;
    else
	p = ap_make_full_path(cmd->pool, ap_server_root, arg);
    *(char **) (struct_ptr + offset) = p;
    return NULL;
}

/*****************************************************************
 *
 * Reading whole config files...
 */

static cmd_parms default_parms =
{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

API_EXPORT(char *) ap_server_root_relative(pool *p, char *file)
{
    if(ap_os_is_path_absolute(file))
	return file;
    return ap_make_full_path(p, ap_server_root, file);
}


/* This structure and the following functions are needed for the
 * table-based config file reading. They are passed to the
 * cfg_open_custom() routine.
 */

/* Structure to be passed to cfg_open_custom(): it contains an
 * index which is incremented from 0 to nelts on each call to
 * cfg_getline() (which in turn calls arr_elts_getstr())
 * and an array_header pointer for the string array.
 */
typedef struct {
    array_header *array;
    int curr_idx;
} arr_elts_param_t;


/* arr_elts_getstr() returns the next line from the string array. */
static void *arr_elts_getstr(void *buf, size_t bufsiz, void *param)
{
    arr_elts_param_t *arr_param = (arr_elts_param_t *) param;

    /* End of array reached? */
    if (++arr_param->curr_idx > arr_param->array->nelts)
        return NULL;

    /* return the line */
    ap_cpystrn(buf, ((char **) arr_param->array->elts)[arr_param->curr_idx - 1], bufsiz);

    return buf;
}


/* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */
static int arr_elts_close(void *param)
{
    arr_elts_param_t *arr_param = (arr_elts_param_t *) param;
    arr_param->curr_idx = arr_param->array->nelts;
    return 0;
}

static void process_command_config(server_rec *s, array_header *arr, pool *p,
				    pool *ptemp)
{
    const char *errmsg;
    cmd_parms parms;
    arr_elts_param_t arr_parms;

    arr_parms.curr_idx = 0;
    arr_parms.array = arr;

    parms = default_parms;
    parms.pool = p;
    parms.temp_pool = ptemp;
    parms.server = s;
    parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
    parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
                                         &arr_parms, NULL,
                                         arr_elts_getstr, arr_elts_close);

    errmsg = ap_srm_command_loop(&parms, s->lookup_defaults);

    if (errmsg) {
        fprintf(stderr, "Syntax error in -C/-c directive:\n%s\n", errmsg);
        exit(1);
    }

    ap_cfg_closefile(parms.config_file);
}

void ap_process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp)
{
    const char *errmsg;
    cmd_parms parms;
    struct stat finfo;

    fname = ap_server_root_relative(p, fname);

    if (!(strcmp(fname, ap_server_root_relative(p, RESOURCE_CONFIG_FILE))) ||
	!(strcmp(fname, ap_server_root_relative(p, ACCESS_CONFIG_FILE)))) {
	if (stat(fname, &finfo) == -1)
	    return;
    }

    /* don't require conf/httpd.conf if we have a -C or -c switch */
    if((ap_server_pre_read_config->nelts || ap_server_post_read_config->nelts) &&
       !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) {
	if (stat(fname, &finfo) == -1)
	    return;
    }

    /* GCC's initialization extensions are soooo nice here... */

    parms = default_parms;
    parms.pool = p;
    parms.temp_pool = ptemp;
    parms.server = s;
    parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);

    if (!(parms.config_file = ap_pcfg_openfile(p,fname))) {
	perror("fopen");
	fprintf(stderr, "%s: could not open document config file %s\n",
		ap_server_argv0, fname);
	exit(1);
    }

    errmsg = ap_srm_command_loop(&parms, s->lookup_defaults);

    if (errmsg) {
	fprintf(stderr, "Syntax error on line %d of %s:\n",
		parms.config_file->line_number, parms.config_file->name);
	fprintf(stderr, "%s\n", errmsg);
	exit(1);
    }

    ap_cfg_closefile(parms.config_file);
}


int ap_parse_htaccess(void **result, request_rec *r, int override,
		   const char *d, const char *access_name)
{
    configfile_t *f = NULL;
    cmd_parms parms;
    const char *errmsg;
    char *filename = NULL;
    const struct htaccess_result *cache;
    struct htaccess_result *new;
    void *dc = NULL;

/* firstly, search cache */
    for (cache = r->htaccess; cache != NULL; cache = cache->next)
	if (cache->override == override && strcmp(cache->dir, d) == 0) {
	    if (cache->htaccess != NULL)
		*result = cache->htaccess;
	    return OK;
	}

    parms = default_parms;
    parms.override = override;
    parms.pool = r->pool;
    parms.temp_pool = r->pool;
    parms.server = r->server;
    parms.path = ap_pstrdup(r->pool, d);

    /* loop through the access names and find the first one */

    while (access_name[0]) {
        filename = ap_make_full_path(r->pool, d,
                                     ap_getword_conf(r->pool, &access_name));

        if ((f = ap_pcfg_openfile(r->pool, filename)) != NULL) {

            dc = ap_create_per_dir_config(r->pool);

            parms.config_file = f;

            errmsg = ap_srm_command_loop(&parms, dc);

            ap_cfg_closefile(f);

            if (errmsg) {
                ap_log_rerror(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, r,
                              "%s: %s", filename, errmsg);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            *result = dc;
            break;
        }
        else if (errno != ENOENT && errno != ENOTDIR) {
            ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
                          "%s pcfg_openfile: unable to check htaccess file, "
                          "ensure it is readable",
                          filename);
            ap_table_setn(r->notes, "error-notes",
                          "Server unable to read htaccess file, denying "
                          "access to be safe");
            return HTTP_FORBIDDEN;
        }
    }

/* cache it */
    new = ap_palloc(r->pool, sizeof(struct htaccess_result));
    new->dir = parms.path;
    new->override = override;
    new->htaccess = dc;
/* add to head of list */
    new->next = r->htaccess;
    r->htaccess = new;

    return OK;
}


CORE_EXPORT(const char *) ap_init_virtual_host(pool *p, const char *hostname,
			      server_rec *main_server, server_rec **ps)
{
    server_rec *s = (server_rec *) ap_pcalloc(p, sizeof(server_rec));

#ifdef RLIMIT_NOFILE
    struct rlimit limits;

    getrlimit(RLIMIT_NOFILE, &limits);
    if (limits.rlim_cur < limits.rlim_max) {
	limits.rlim_cur += 2;
	if (setrlimit(RLIMIT_NOFILE, &limits) < 0) {
	    perror("setrlimit(RLIMIT_NOFILE)");
	    fprintf(stderr, "Cannot exceed hard limit for open files");
	}
    }
#endif

    s->server_admin = NULL;
    s->server_hostname = NULL;
    s->error_fname = NULL;
    s->srm_confname = NULL;
    s->access_confname = NULL;
    s->timeout = 0;
    s->keep_alive_timeout = 0;
    s->keep_alive = -1;
    s->keep_alive_max = -1;
    s->error_log = main_server->error_log;
    s->loglevel = main_server->loglevel;
    /* useful default, otherwise we get a port of 0 on redirects */
    s->port = main_server->port;
    s->next = NULL;

    s->is_virtual = 1;
    s->names = ap_make_array(p, 4, sizeof(char **));
    s->wild_names = ap_make_array(p, 4, sizeof(char **));

    s->module_config = create_empty_config(p);
    s->lookup_defaults = ap_create_per_dir_config(p);

    s->server_uid = ap_user_id;
    s->server_gid = ap_group_id;

    s->limit_req_line = main_server->limit_req_line;
    s->limit_req_fieldsize = main_server->limit_req_fieldsize;
    s->limit_req_fields = main_server->limit_req_fields;

    *ps = s;

    return ap_parse_vhost_addrs(p, hostname, s);
}


static void fixup_virtual_hosts(pool *p, server_rec *main_server)
{
    server_rec *virt;

    for (virt = main_server->next; virt; virt = virt->next) {
	merge_server_configs(p, main_server->module_config,
			     virt->module_config);

	virt->lookup_defaults =
	    ap_merge_per_dir_configs(p, main_server->lookup_defaults,
				  virt->lookup_defaults);

	if (virt->server_admin == NULL)
	    virt->server_admin = main_server->server_admin;

	if (virt->srm_confname == NULL)
	    virt->srm_confname = main_server->srm_confname;

	if (virt->access_confname == NULL)
	    virt->access_confname = main_server->access_confname;

	if (virt->timeout == 0)
	    virt->timeout = main_server->timeout;

	if (virt->keep_alive_timeout == 0)
	    virt->keep_alive_timeout = main_server->keep_alive_timeout;

	if (virt->keep_alive == -1)
	    virt->keep_alive = main_server->keep_alive;

	if (virt->keep_alive_max == -1)
	    virt->keep_alive_max = main_server->keep_alive_max;

	if (virt->send_buffer_size == 0)
	    virt->send_buffer_size = main_server->send_buffer_size;

	/* XXX: this is really something that should be dealt with by a
	 * post-config api phase */
	ap_core_reorder_directories(p, virt);
    }
    ap_core_reorder_directories(p, main_server);
}

/*****************************************************************
 *
 * Getting *everything* configured... 
 */

static void init_config_globals(pool *p)
{
    /* ServerRoot, server_confname set in httpd.c */

    ap_standalone = 1;
    ap_user_name = DEFAULT_USER;
    ap_user_id = ap_uname2id(DEFAULT_USER);
    ap_group_id = ap_gname2id(DEFAULT_GROUP);
    ap_daemons_to_start = DEFAULT_START_DAEMON;
    ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
    ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
    ap_daemons_limit = HARD_SERVER_LIMIT;
    ap_pid_fname = DEFAULT_PIDLOG;
    ap_scoreboard_fname = DEFAULT_SCOREBOARD;
    ap_lock_fname = DEFAULT_LOCKFILE;
    ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
    ap_bind_address.s_addr = htonl(INADDR_ANY);
    ap_listeners = NULL;
    ap_listenbacklog = DEFAULT_LISTENBACKLOG;
    ap_extended_status = 0;

    /* Global virtual host hash bucket pointers.  Init to null. */
    ap_init_vhost_config(p);

    ap_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
}

static server_rec *init_server_config(pool *p)
{
    server_rec *s = (server_rec *) ap_pcalloc(p, sizeof(server_rec));

    s->port = 0;
    s->server_admin = DEFAULT_ADMIN;
    s->server_hostname = NULL;
    s->error_fname = DEFAULT_ERRORLOG;
    s->error_log = stderr;
    s->loglevel = DEFAULT_LOGLEVEL;
    s->srm_confname = RESOURCE_CONFIG_FILE;
    s->access_confname = ACCESS_CONFIG_FILE;
    s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
    s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
    s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
    s->timeout = DEFAULT_TIMEOUT;
    s->keep_alive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
    s->keep_alive_max = DEFAULT_KEEPALIVE;
    s->keep_alive = 1;
    s->next = NULL;
    s->addrs = ap_pcalloc(p, sizeof(server_addr_rec));
    /* NOT virtual host; don't match any real network interface */
    s->addrs->host_addr.s_addr = htonl(INADDR_ANY);
    s->addrs->host_port = 0;	/* matches any port */
    s->addrs->virthost = "";	/* must be non-NULL */
    s->names = s->wild_names = NULL;

    s->module_config = create_server_config(p, s);
    s->lookup_defaults = create_default_per_dir_config(p);

    return s;
}


static void default_listeners(pool *p, server_rec *s)
{
    listen_rec *new;

    if (ap_listeners != NULL) {
	return;
    }
    /* allocate a default listener */
    new = ap_pcalloc(p, sizeof(listen_rec));
    new->local_addr.sin_family = AF_INET;
    new->local_addr.sin_addr = ap_bind_address;
    new->local_addr.sin_port = htons(s->port ? s->port : DEFAULT_HTTP_PORT);
    new->fd = -1;
    new->used = 0;
    new->next = NULL;
    ap_listeners = new;
}


server_rec *ap_read_config(pool *p, pool *ptemp, char *confname)
{
    server_rec *s = init_server_config(p);

    init_config_globals(p);

    /* All server-wide config files now have the SAME syntax... */

    process_command_config(s, ap_server_pre_read_config, p, ptemp);

    ap_process_resource_config(s, confname, p, ptemp);
    ap_process_resource_config(s, s->srm_confname, p, ptemp);
    ap_process_resource_config(s, s->access_confname, p, ptemp);

    process_command_config(s, ap_server_post_read_config, p, ptemp);

    fixup_virtual_hosts(p, s);
    default_listeners(p, s);
    ap_fini_vhost_config(p, s);

    return s;
}

void ap_single_module_configure(pool *p, server_rec *s, module *m)
{
    if (m->create_server_config)
        ap_set_module_config(s->module_config, m,
                             (*m->create_server_config)(p, s));
    if (m->create_dir_config)
        ap_set_module_config(s->lookup_defaults, m,
                             (*m->create_dir_config)(p, NULL));
}

void ap_init_modules(pool *p, server_rec *s)
{
    module *m;

    for (m = top_module; m; m = m->next)
	if (m->init)
	    (*m->init) (s, p);
    build_method_shortcuts();
    init_handlers(p);
}

void ap_child_init_modules(pool *p, server_rec *s)
{
    module *m;

    for (m = top_module; m; m = m->next)
	if (m->child_init)
	    (*m->child_init) (s, p);
}

void ap_child_exit_modules(pool *p, server_rec *s)
{
    module *m;

#ifdef SIGHUP
    signal(SIGHUP, SIG_IGN);
#endif
#ifdef SIGUSR1
    signal(SIGUSR1, SIG_IGN);
#endif

    for (m = top_module; m; m = m->next)
	if (m->child_exit)
	    (*m->child_exit) (s, p);

}

/********************************************************************
 * Configuration directives are restricted in terms of where they may
 * appear in the main configuration files and/or .htaccess files according
 * to the bitmask req_override in the command_rec structure.
 * If any of the overrides set in req_override are also allowed in the
 * context in which the command is read, then the command is allowed.
 * The context is determined as follows:
 *
 *    inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
 *    within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;
 *    within .htaccess --> override = AllowOverride for current directory;
 *
 * the result is, well, a rather confusing set of possibilities for when
 * a particular directive is allowed to be used.  This procedure prints
 * in English where the given (pc) directive can be used.
 */
static void show_overrides(const command_rec *pc, module *pm)
{
    int n = 0;

    printf("\tAllowed in *.conf ");
    if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES)) ||
	((pc->req_override & RSRC_CONF) &&
	 ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT)))))
	printf("anywhere");
    else if (pc->req_override & RSRC_CONF)
	printf("only outside <Directory>, <Files> or <Location>");
    else
	printf("only inside <Directory>, <Files> or <Location>");

    /* Warn if the directive is allowed inside <Directory> or .htaccess
     * but module doesn't support per-dir configuration */

    if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config)
	printf(" [no per-dir config]");

    if (pc->req_override & OR_ALL) {
	printf(" and in .htaccess\n\twhen AllowOverride");

	if ((pc->req_override & OR_ALL) == OR_ALL)
	    printf(" isn't None");
	else {
	    printf(" includes ");

	    if (pc->req_override & OR_AUTHCFG) {
		if (n++)
		    printf(" or ");
		printf("AuthConfig");
	    }
	    if (pc->req_override & OR_LIMIT) {
		if (n++)
		    printf(" or ");
		printf("Limit");
	    }
	    if (pc->req_override & OR_OPTIONS) {
		if (n++)
		    printf(" or ");
		printf("Options");
	    }
	    if (pc->req_override & OR_FILEINFO) {
		if (n++)
		    printf(" or ");
		printf("FileInfo");
	    }
	    if (pc->req_override & OR_INDEXES) {
		if (n++)
		    printf(" or ");
		printf("Indexes");
	    }
	}
    }
    printf("\n");
}

/* Show the preloaded configuration directives, the help string explaining
 * the directive arguments, in what module they are handled, and in
 * what parts of the configuration they are allowed.  Used for httpd -h.
 */
void ap_show_directives()
{
    const command_rec *pc;
    int n;

    for (n = 0; ap_loaded_modules[n]; ++n)
	for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) {
	    printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name);
	    if (pc->errmsg)
		printf("\t%s\n", pc->errmsg);
	    show_overrides(pc, ap_loaded_modules[n]);
	}
}

/* Show the preloaded module names.  Used for httpd -l. */
void ap_show_modules()
{
    int n;

    printf("Compiled-in modules:\n");
    for (n = 0; ap_loaded_modules[n]; ++n)
	printf("  %s\n", ap_loaded_modules[n]->name);
}
