/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * mod_autoindex.c: Handles the on-the-fly html index generation
 *
 * Rob McCool
 * 3/23/93
 *
 * Adapted to Apache by rst.
 *
 * Version sort added by Martin Pool <mbp@humbug.org.au>.
 */

#include "apr_strings.h"
#include "apr_fnmatch.h"
#include "apr_strings.h"
#include "apr_lib.h"

#define APR_WANT_STRFUNC
#include "apr_want.h"

#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_request.h"
#include "http_protocol.h"
#include "http_log.h"
#include "http_main.h"
#include "util_script.h"

#include "mod_core.h"

module AP_MODULE_DECLARE_DATA autoindex_module;

/****************************************************************
 *
 * Handling configuration directives...
 */

#define NO_OPTIONS          (1 <<  0)  /* Indexing options */
#define ICONS_ARE_LINKS     (1 <<  1)
#define SCAN_HTML_TITLES    (1 <<  2)
#define SUPPRESS_ICON       (1 <<  3)
#define SUPPRESS_LAST_MOD   (1 <<  4)
#define SUPPRESS_SIZE       (1 <<  5)
#define SUPPRESS_DESC       (1 <<  6)
#define SUPPRESS_PREAMBLE   (1 <<  7)
#define SUPPRESS_COLSORT    (1 <<  8)
#define SUPPRESS_RULES      (1 <<  9)
#define FOLDERS_FIRST       (1 << 10)
#define VERSION_SORT        (1 << 11)
#define TRACK_MODIFIED      (1 << 12)
#define FANCY_INDEXING      (1 << 13)
#define TABLE_INDEXING      (1 << 14)
#define IGNORE_CLIENT       (1 << 15)
#define IGNORE_CASE         (1 << 16)
#define EMIT_XHTML          (1 << 17)
#define SHOW_FORBIDDEN      (1 << 18)
#define ADDALTCLASS         (1 << 19)
#define OPTION_UNSET        (1 << 20)

#define K_NOADJUST 0
#define K_ADJUST 1
#define K_UNSET 2

/*
 * Define keys for sorting.
 */
#define K_NAME 'N'              /* Sort by file name (default) */
#define K_LAST_MOD 'M'          /* Last modification date */
#define K_SIZE 'S'              /* Size (absolute, not as displayed) */
#define K_DESC 'D'              /* Description */
#define K_VALID "NMSD"          /* String containing _all_ valid K_ opts */

#define D_ASCENDING 'A'
#define D_DESCENDING 'D'
#define D_VALID "AD"            /* String containing _all_ valid D_ opts */

/*
 * These are the dimensions of the default icons supplied with Apache.
 */
#define DEFAULT_ICON_WIDTH 20
#define DEFAULT_ICON_HEIGHT 22

/*
 * Other default dimensions.
 */
#define DEFAULT_NAME_WIDTH 23
#define DEFAULT_DESC_WIDTH 23

struct item {
    char *type;
    char *apply_to;
    char *apply_path;
    char *data;
};

typedef struct ai_desc_t {
    char *pattern;
    char *description;
    int full_path;
    int wildcards;
} ai_desc_t;

typedef struct autoindex_config_struct {

    char *default_icon;
    char *style_sheet;
    char *head_insert;
    char *header;
    char *readme;
    apr_int32_t opts;
    apr_int32_t incremented_opts;
    apr_int32_t decremented_opts;
    int name_width;
    int name_adjust;
    int desc_width;
    int desc_adjust;
    int icon_width;
    int icon_height;
    char default_keyid;
    char default_direction;

    apr_array_header_t *icon_list;
    apr_array_header_t *alt_list;
    apr_array_header_t *desc_list;
    apr_array_header_t *ign_list;
    int ign_noinherit;

    char *ctype;
    char *charset;
} autoindex_config_rec;

static char c_by_encoding, c_by_type, c_by_path;

#define BY_ENCODING &c_by_encoding
#define BY_TYPE &c_by_type
#define BY_PATH &c_by_path

static APR_INLINE int response_is_html(request_rec *r)
{
    char *ctype = ap_field_noparam(r->pool, r->content_type);
    ap_str_tolower(ctype);
    return !strcmp(ctype, "text/html")
        || !strcmp(ctype, "application/xhtml+xml");
}

/*
 * This routine puts the standard HTML header at the top of the index page.
 * We include the DOCTYPE because we may be using features therefrom (i.e.,
 * HEIGHT and WIDTH attributes on the icons if we're FancyIndexing).
 */
static void emit_preamble(request_rec *r, int xhtml, const char *title)
{
    autoindex_config_rec *d;

    d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config,
                                                      &autoindex_module);

    if (xhtml) {
        ap_rvputs(r, DOCTYPE_XHTML_1_0T,
                  "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
                  " <head>\n  <title>Index of ", title,
                  "</title>\n", NULL);
    } else {
        ap_rvputs(r, DOCTYPE_HTML_3_2,
                  "<html>\n <head>\n"
                  "  <title>Index of ", title,
                  "</title>\n", NULL);
    }

    if (d->style_sheet != NULL) {
        ap_rvputs(r, "  <link rel=\"stylesheet\" href=\"", d->style_sheet,
                "\" type=\"text/css\"", xhtml ? " />\n" : ">\n", NULL);
    }
    if (d->head_insert != NULL) {
        ap_rputs(d->head_insert, r);
    }
    ap_rputs(" </head>\n <body>\n", r);
}

static void push_item(apr_array_header_t *arr, char *type, const char *to,
                      const char *path, const char *data)
{
    struct item *p = (struct item *) apr_array_push(arr);

    if (!to) {
        to = "";
    }
    if (!path) {
        path = "";
    }

    p->type = type;
    p->data = apr_pstrdup(arr->pool, data);
    p->apply_path = apr_pstrcat(arr->pool, path, "*", NULL);

    if ((type == BY_PATH) && (!ap_is_matchexp(to))) {
        p->apply_to = apr_pstrcat(arr->pool, "*", to, NULL);
    }
    else if (to) {
        p->apply_to = apr_pstrdup(arr->pool, to);
    }
    else {
        p->apply_to = NULL;
    }
}

static const char *add_alt(cmd_parms *cmd, void *d, const char *alt,
                           const char *to)
{
    if (cmd->info == BY_PATH) {
        if (!strcmp(to, "**DIRECTORY**")) {
            to = "^^DIRECTORY^^";
        }
    }
    if (cmd->info == BY_ENCODING) {
        char *tmp = apr_pstrdup(cmd->pool, to);
        ap_str_tolower(tmp);
        to = tmp;
    }

    push_item(((autoindex_config_rec *) d)->alt_list, cmd->info, to,
              cmd->path, alt);
    return NULL;
}

static const char *add_icon(cmd_parms *cmd, void *d, const char *icon,
                            const char *to)
{
    char *iconbak = apr_pstrdup(cmd->pool, icon);

    if (icon[0] == '(') {
        char *alt;
        char *cl = strchr(iconbak, ')');

        if (cl == NULL) {
            return "missing closing paren";
        }
        alt = ap_getword_nc(cmd->pool, &iconbak, ',');
        *cl = '\0';                             /* Lose closing paren */
        add_alt(cmd, d, &alt[1], to);
    }
    if (cmd->info == BY_PATH) {
        if (!strcmp(to, "**DIRECTORY**")) {
            to = "^^DIRECTORY^^";
        }
    }
    if (cmd->info == BY_ENCODING) {
        char *tmp = apr_pstrdup(cmd->pool, to);
        ap_str_tolower(tmp);
        to = tmp;
    }

    push_item(((autoindex_config_rec *) d)->icon_list, cmd->info, to,
              cmd->path, iconbak);
    return NULL;
}

/*
 * Add description text for a filename pattern.  If the pattern has
 * wildcards already (or we need to add them), add leading and
 * trailing wildcards to it to ensure substring processing.  If the
 * pattern contains a '/' anywhere, force wildcard matching mode,
 * add a slash to the prefix so that "bar/bletch" won't be matched
 * by "foobar/bletch", and make a note that there's a delimiter;
 * the matching routine simplifies to just the actual filename
 * whenever it can.  This allows definitions in parent directories
 * to be made for files in subordinate ones using relative paths.
 */

/*
 * Absent a strcasestr() function, we have to force wildcards on
 * systems for which "AAA" and "aaa" mean the same file.
 */
#ifdef CASE_BLIND_FILESYSTEM
#define WILDCARDS_REQUIRED 1
#else
#define WILDCARDS_REQUIRED 0
#endif

static const char *add_desc(cmd_parms *cmd, void *d, const char *desc,
                            const char *to)
{
    autoindex_config_rec *dcfg = (autoindex_config_rec *) d;
    ai_desc_t *desc_entry;
    char *prefix = "";

    desc_entry = (ai_desc_t *) apr_array_push(dcfg->desc_list);
    desc_entry->full_path = (ap_strchr_c(to, '/') == NULL) ? 0 : 1;
    desc_entry->wildcards = (WILDCARDS_REQUIRED
                             || desc_entry->full_path
                             || apr_fnmatch_test(to));
    if (desc_entry->wildcards) {
        prefix = desc_entry->full_path ? "*/" : "*";
        desc_entry->pattern = apr_pstrcat(dcfg->desc_list->pool,
                                          prefix, to, "*", NULL);
    }
    else {
        desc_entry->pattern = apr_pstrdup(dcfg->desc_list->pool, to);
    }
    desc_entry->description = apr_pstrdup(dcfg->desc_list->pool, desc);
    return NULL;
}

static const char *add_ignore(cmd_parms *cmd, void *d, const char *ext)
{
    push_item(((autoindex_config_rec *) d)->ign_list, 0, ext, cmd->path, NULL);
    return NULL;
}

static const char *add_opts(cmd_parms *cmd, void *d, int argc, char *const argv[])
{
    int i;
    char *w;
    apr_int32_t opts;
    apr_int32_t opts_add;
    apr_int32_t opts_remove;
    char action;
    autoindex_config_rec *d_cfg = (autoindex_config_rec *) d;

    opts = d_cfg->opts;
    opts_add = d_cfg->incremented_opts;
    opts_remove = d_cfg->decremented_opts;

    for (i = 0; i < argc; i++) {
        int option = 0;
        w = argv[i];

        if ((*w == '+') || (*w == '-')) {
            action = *(w++);
        }
        else {
            action = '\0';
        }
        if (!strcasecmp(w, "FancyIndexing")) {
            option = FANCY_INDEXING;
        }
        else if (!strcasecmp(w, "FoldersFirst")) {
            option = FOLDERS_FIRST;
        }
        else if (!strcasecmp(w, "HTMLTable")) {
            option = TABLE_INDEXING;
        }
        else if (!strcasecmp(w, "IconsAreLinks")) {
            option = ICONS_ARE_LINKS;
        }
        else if (!strcasecmp(w, "IgnoreCase")) {
            option = IGNORE_CASE;
        }
        else if (!strcasecmp(w, "IgnoreClient")) {
            option = IGNORE_CLIENT;
        }
        else if (!strcasecmp(w, "ScanHTMLTitles")) {
            option = SCAN_HTML_TITLES;
        }
        else if (!strcasecmp(w, "SuppressColumnSorting")) {
            option = SUPPRESS_COLSORT;
        }
        else if (!strcasecmp(w, "SuppressDescription")) {
            option = SUPPRESS_DESC;
        }
        else if (!strcasecmp(w, "SuppressHTMLPreamble")) {
            option = SUPPRESS_PREAMBLE;
        }
        else if (!strcasecmp(w, "SuppressIcon")) {
            option = SUPPRESS_ICON;
        }
        else if (!strcasecmp(w, "SuppressLastModified")) {
            option = SUPPRESS_LAST_MOD;
        }
        else if (!strcasecmp(w, "SuppressSize")) {
            option = SUPPRESS_SIZE;
        }
        else if (!strcasecmp(w, "SuppressRules")) {
            option = SUPPRESS_RULES;
        }
        else if (!strcasecmp(w, "TrackModified")) {
            option = TRACK_MODIFIED;
        }
        else if (!strcasecmp(w, "VersionSort")) {
            option = VERSION_SORT;
        }
        else if (!strcasecmp(w, "XHTML")) {
            option = EMIT_XHTML;
        }
        else if (!strcasecmp(w, "ShowForbidden")) {
            option = SHOW_FORBIDDEN;
        }
        else if (!strcasecmp(w, "AddAltClass")) {
            option = ADDALTCLASS;
        }
        else if (!strcasecmp(w, "None")) {
            if (action != '\0') {
                return "Cannot combine '+' or '-' with 'None' keyword";
            }
            opts = NO_OPTIONS;
            opts_add = 0;
            opts_remove = 0;
        }
        else if (!strcasecmp(w, "IconWidth")) {
            if (action != '-') {
                d_cfg->icon_width = DEFAULT_ICON_WIDTH;
            }
            else {
                d_cfg->icon_width = 0;
            }
        }
        else if (!strncasecmp(w, "IconWidth=", 10)) {
            if (action == '-') {
                return "Cannot combine '-' with IconWidth=n";
            }
            d_cfg->icon_width = atoi(&w[10]);
        }
        else if (!strcasecmp(w, "IconHeight")) {
            if (action != '-') {
                d_cfg->icon_height = DEFAULT_ICON_HEIGHT;
            }
            else {
                d_cfg->icon_height = 0;
            }
        }
        else if (!strncasecmp(w, "IconHeight=", 11)) {
            if (action == '-') {
                return "Cannot combine '-' with IconHeight=n";
            }
            d_cfg->icon_height = atoi(&w[11]);
        }
        else if (!strcasecmp(w, "NameWidth")) {
            if (action != '-') {
                return "NameWidth with no value may only appear as "
                       "'-NameWidth'";
            }
            d_cfg->name_width = DEFAULT_NAME_WIDTH;
            d_cfg->name_adjust = K_NOADJUST;
        }
        else if (!strncasecmp(w, "NameWidth=", 10)) {
            if (action == '-') {
                return "Cannot combine '-' with NameWidth=n";
            }
            if (w[10] == '*') {
                d_cfg->name_adjust = K_ADJUST;
            }
            else {
                int width = atoi(&w[10]);

                if (width && (width < 5)) {
                    return "NameWidth value must be greater than 5";
                }
                d_cfg->name_width = width;
                d_cfg->name_adjust = K_NOADJUST;
            }
        }
        else if (!strcasecmp(w, "DescriptionWidth")) {
            if (action != '-') {
                return "DescriptionWidth with no value may only appear as "
                       "'-DescriptionWidth'";
            }
            d_cfg->desc_width = DEFAULT_DESC_WIDTH;
            d_cfg->desc_adjust = K_NOADJUST;
        }
        else if (!strncasecmp(w, "DescriptionWidth=", 17)) {
            if (action == '-') {
                return "Cannot combine '-' with DescriptionWidth=n";
            }
            if (w[17] == '*') {
                d_cfg->desc_adjust = K_ADJUST;
            }
            else {
                int width = atoi(&w[17]);

                if (width && (width < 12)) {
                    return "DescriptionWidth value must be greater than 12";
                }
                d_cfg->desc_width = width;
                d_cfg->desc_adjust = K_NOADJUST;
            }
        }
        else if (!strncasecmp(w, "Type=", 5)) {
            d_cfg->ctype = apr_pstrdup(cmd->pool, &w[5]);
        }
        else if (!strncasecmp(w, "Charset=", 8)) {
            d_cfg->charset = apr_pstrdup(cmd->pool, &w[8]);
        }
        else {
            return "Invalid directory indexing option";
        }
        if (action == '\0') {
            opts |= option;
            opts_add = 0;
            opts_remove = 0;
        }
        else if (action == '+') {
            opts_add |= option;
            opts_remove &= ~option;
        }
        else {
            opts_remove |= option;
            opts_add &= ~option;
        }
    }
    if ((opts & NO_OPTIONS) && (opts & ~NO_OPTIONS)) {
        return "Cannot combine other IndexOptions keywords with 'None'";
    }
    d_cfg->incremented_opts = opts_add;
    d_cfg->decremented_opts = opts_remove;
    d_cfg->opts = opts;
    return NULL;
}

static const char *set_default_order(cmd_parms *cmd, void *m,
                                     const char *direction, const char *key)
{
    autoindex_config_rec *d_cfg = (autoindex_config_rec *) m;

    if (!strcasecmp(direction, "Ascending")) {
        d_cfg->default_direction = D_ASCENDING;
    }
    else if (!strcasecmp(direction, "Descending")) {
        d_cfg->default_direction = D_DESCENDING;
    }
    else {
        return "First keyword must be 'Ascending' or 'Descending'";
    }

    if (!strcasecmp(key, "Name")) {
        d_cfg->default_keyid = K_NAME;
    }
    else if (!strcasecmp(key, "Date")) {
        d_cfg->default_keyid = K_LAST_MOD;
    }
    else if (!strcasecmp(key, "Size")) {
        d_cfg->default_keyid = K_SIZE;
    }
    else if (!strcasecmp(key, "Description")) {
        d_cfg->default_keyid = K_DESC;
    }
    else {
        return "Second keyword must be 'Name', 'Date', 'Size', or "
               "'Description'";
    }

    return NULL;
}

#define DIR_CMD_PERMS OR_INDEXES

static const command_rec autoindex_cmds[] =
{
    AP_INIT_ITERATE2("AddIcon", add_icon, BY_PATH, DIR_CMD_PERMS,
                     "an icon URL followed by one or more filenames"),
    AP_INIT_ITERATE2("AddIconByType", add_icon, BY_TYPE, DIR_CMD_PERMS,
                     "an icon URL followed by one or more MIME types"),
    AP_INIT_ITERATE2("AddIconByEncoding", add_icon, BY_ENCODING, DIR_CMD_PERMS,
                     "an icon URL followed by one or more content encodings"),
    AP_INIT_ITERATE2("AddAlt", add_alt, BY_PATH, DIR_CMD_PERMS,
                     "alternate descriptive text followed by one or more "
                     "filenames"),
    AP_INIT_ITERATE2("AddAltByType", add_alt, BY_TYPE, DIR_CMD_PERMS,
                     "alternate descriptive text followed by one or more MIME "
                     "types"),
    AP_INIT_ITERATE2("AddAltByEncoding", add_alt, BY_ENCODING, DIR_CMD_PERMS,
                     "alternate descriptive text followed by one or more "
                     "content encodings"),
    AP_INIT_TAKE_ARGV("IndexOptions", add_opts, NULL, DIR_CMD_PERMS,
                      "one or more index options [+|-][]"),
    AP_INIT_TAKE2("IndexOrderDefault", set_default_order, NULL, DIR_CMD_PERMS,
                  "{Ascending,Descending} {Name,Size,Description,Date}"),
    AP_INIT_ITERATE("IndexIgnore", add_ignore, NULL, DIR_CMD_PERMS,
                    "one or more file extensions"),
    AP_INIT_FLAG("IndexIgnoreReset", ap_set_flag_slot,
                 (void *)APR_OFFSETOF(autoindex_config_rec, ign_noinherit),
                 DIR_CMD_PERMS,
                 "Reset the inherited list of IndexIgnore filenames"),
    AP_INIT_ITERATE2("AddDescription", add_desc, BY_PATH, DIR_CMD_PERMS,
                     "Descriptive text followed by one or more filenames"),
    AP_INIT_TAKE1("HeaderName", ap_set_string_slot,
                  (void *)APR_OFFSETOF(autoindex_config_rec, header),
                  DIR_CMD_PERMS, "a filename"),
    AP_INIT_TAKE1("ReadmeName", ap_set_string_slot,
                  (void *)APR_OFFSETOF(autoindex_config_rec, readme),
                  DIR_CMD_PERMS, "a filename"),
    AP_INIT_RAW_ARGS("FancyIndexing", ap_set_deprecated, NULL, OR_ALL,
                     "The FancyIndexing directive is no longer supported. "
                     "Use IndexOptions FancyIndexing."),
    AP_INIT_TAKE1("DefaultIcon", ap_set_string_slot,
                  (void *)APR_OFFSETOF(autoindex_config_rec, default_icon),
                  DIR_CMD_PERMS, "an icon URL"),
    AP_INIT_TAKE1("IndexStyleSheet", ap_set_string_slot,
                  (void *)APR_OFFSETOF(autoindex_config_rec, style_sheet),
                  DIR_CMD_PERMS, "URL to style sheet"),
    AP_INIT_TAKE1("IndexHeadInsert", ap_set_string_slot,
                  (void *)APR_OFFSETOF(autoindex_config_rec, head_insert),
                  DIR_CMD_PERMS, "String to insert in HTML HEAD section"),
    {NULL}
};

static void *create_autoindex_config(apr_pool_t *p, char *dummy)
{
    autoindex_config_rec *new =
    (autoindex_config_rec *) apr_pcalloc(p, sizeof(autoindex_config_rec));

    new->icon_width = 0;
    new->icon_height = 0;
    new->name_width = DEFAULT_NAME_WIDTH;
    new->name_adjust = K_UNSET;
    new->desc_width = DEFAULT_DESC_WIDTH;
    new->desc_adjust = K_UNSET;
    new->icon_list = apr_array_make(p, 4, sizeof(struct item));
    new->alt_list = apr_array_make(p, 4, sizeof(struct item));
    new->desc_list = apr_array_make(p, 4, sizeof(ai_desc_t));
    new->ign_list = apr_array_make(p, 4, sizeof(struct item));
    new->opts = OPTION_UNSET;
    new->incremented_opts = 0;
    new->decremented_opts = 0;
    new->default_keyid = '\0';
    new->default_direction = '\0';

    return (void *) new;
}

static void *merge_autoindex_configs(apr_pool_t *p, void *basev, void *addv)
{
    autoindex_config_rec *new;
    autoindex_config_rec *base = (autoindex_config_rec *) basev;
    autoindex_config_rec *add = (autoindex_config_rec *) addv;

    new = (autoindex_config_rec *) apr_pcalloc(p, sizeof(autoindex_config_rec));
    new->default_icon = add->default_icon ? add->default_icon
                                          : base->default_icon;
    new->style_sheet = add->style_sheet ? add->style_sheet
                                          : base->style_sheet;
    new->head_insert = add->head_insert ? add->head_insert
                                          : base->head_insert;
    new->header = add->header ? add->header
                                : base->header;
    new->readme = add->readme ? add->readme
                                : base->readme;
    new->icon_height = add->icon_height ? add->icon_height : base->icon_height;
    new->icon_width = add->icon_width ? add->icon_width : base->icon_width;

    new->ctype = add->ctype ? add->ctype : base->ctype;
    new->charset = add->charset ? add->charset : base->charset;

    new->alt_list = apr_array_append(p, add->alt_list, base->alt_list);
    new->desc_list = apr_array_append(p, add->desc_list, base->desc_list);
    new->icon_list = apr_array_append(p, add->icon_list, base->icon_list);
    new->ign_list = add->ign_noinherit ? add->ign_list : apr_array_append(p, add->ign_list, base->ign_list);
    if (add->opts == NO_OPTIONS) {
        /*
         * If the current directory explicitly says 'no options' then we also
         * clear any incremental mods from being inheritable further down.
         */
        new->opts = NO_OPTIONS;
        new->incremented_opts = 0;
        new->decremented_opts = 0;
    }
    else {
        /*
         * If there were any nonincremental options selected for
         * this directory, they dominate and we don't inherit *anything.*
         * Contrariwise, we *do* inherit if the only settings here are
         * incremental ones.
         */
        if (add->opts == OPTION_UNSET) {
            new->incremented_opts = (base->incremented_opts
                                     | add->incremented_opts)
                                    & ~add->decremented_opts;
            new->decremented_opts = (base->decremented_opts
                                     | add->decremented_opts);
            /*
             * We may have incremental settings, so make sure we don't
             * inadvertently inherit an IndexOptions None from above.
             */
            new->opts = (base->opts & ~NO_OPTIONS);
        }
        else {
            /*
             * There are local nonincremental settings, which clear
             * all inheritance from above.  They *are* the new base settings.
             */
            new->opts = add->opts;
        }
        /*
         * We're guaranteed that there'll be no overlap between
         * the add-options and the remove-options.
         */
        new->opts |= new->incremented_opts;
        new->opts &= ~new->decremented_opts;
    }
    /*
     * Inherit the NameWidth settings if there aren't any specific to
     * the new location; otherwise we'll end up using the defaults set in the
     * config-rec creation routine.
     */
    if (add->name_adjust == K_UNSET) {
        new->name_width = base->name_width;
        new->name_adjust = base->name_adjust;
    }
    else {
        new->name_width = add->name_width;
        new->name_adjust = add->name_adjust;
    }

    /*
     * Likewise for DescriptionWidth.
     */
    if (add->desc_adjust == K_UNSET) {
        new->desc_width = base->desc_width;
        new->desc_adjust = base->desc_adjust;
    }
    else {
        new->desc_width = add->desc_width;
        new->desc_adjust = add->desc_adjust;
    }

    new->default_keyid = add->default_keyid ? add->default_keyid
                                            : base->default_keyid;
    new->default_direction = add->default_direction ? add->default_direction
                                                    : base->default_direction;
    return new;
}

/****************************************************************
 *
 * Looking things up in config entries...
 */

/* Structure used to hold entries when we're actually building an index */

struct ent {
    char *name;
    char *icon;
    char *alt;
    char *desc;
    apr_off_t size;
    apr_time_t lm;
    struct ent *next;
    int ascending, ignore_case, version_sort;
    char key;
    int isdir;
};

static char *find_item(const char *content_type, const char *content_encoding,
                       char *path, apr_array_header_t *list, int path_only)
{
    struct item *items = (struct item *) list->elts;
    int i;

    for (i = 0; i < list->nelts; ++i) {
        struct item *p = &items[i];

        /* Special cased for ^^DIRECTORY^^ and ^^BLANKICON^^ */
        if ((path[0] == '^') || (!ap_strcmp_match(path, p->apply_path))) {
            if (!*(p->apply_to)) {
                return p->data;
            }
            else if (p->type == BY_PATH || path[0] == '^') {
                if (!ap_strcmp_match(path, p->apply_to)) {
                    return p->data;
                }
            }
            else if (!path_only) {
                if (!content_encoding) {
                    if (p->type == BY_TYPE) {
                        if (content_type
                            && !ap_strcasecmp_match(content_type,
                                                    p->apply_to)) {
                            return p->data;
                        }
                    }
                }
                else {
                    if (p->type == BY_ENCODING) {
                        if (!ap_strcasecmp_match(content_encoding,
                                                 p->apply_to)) {
                            return p->data;
                        }
                    }
                }
            }
        }
    }
    return NULL;
}

static char *find_item_by_request(request_rec *r, apr_array_header_t *list, int path_only)
{
    return find_item(ap_field_noparam(r->pool, r->content_type),
                     r->content_encoding, r->filename, list, path_only);
}

#define find_icon(d,p,t) find_item_by_request(p,d->icon_list,t)
#define find_alt(d,p,t) find_item_by_request(p,d->alt_list,t)
#define find_default_icon(d,n) find_item(NULL, NULL, n, d->icon_list, 1)
#define find_default_alt(d,n) find_item(NULL, NULL, n, d->alt_list, 1)

/*
 * Look through the list of pattern/description pairs and return the first one
 * if any) that matches the filename in the request.  If multiple patterns
 * match, only the first one is used; since the order in the array is the
 * same as the order in which directives were processed, earlier matching
 * directives will dominate.
 */

#ifdef CASE_BLIND_FILESYSTEM
#define MATCH_FLAGS APR_FNM_CASE_BLIND
#else
#define MATCH_FLAGS 0
#endif

static char *find_desc(autoindex_config_rec *dcfg, const char *filename_full)
{
    int i;
    ai_desc_t *list = (ai_desc_t *) dcfg->desc_list->elts;
    const char *filename_only;
    const char *filename;

    /*
     * If the filename includes a path, extract just the name itself
     * for the simple matches.
     */
    if ((filename_only = ap_strrchr_c(filename_full, '/')) == NULL) {
        filename_only = filename_full;
    }
    else {
        filename_only++;
    }
    for (i = 0; i < dcfg->desc_list->nelts; ++i) {
        ai_desc_t *tuple = &list[i];
        int found;

        /*
         * Only use the full-path filename if the pattern contains '/'s.
         */
        filename = (tuple->full_path) ? filename_full : filename_only;
        /*
         * Make the comparison using the cheapest method; only do
         * wildcard checking if we must.
         */
        if (tuple->wildcards) {
            found = (apr_fnmatch(tuple->pattern, filename, MATCH_FLAGS) == 0);
        }
        else {
            found = (ap_strstr_c(filename, tuple->pattern) != NULL);
        }
        if (found) {
            return tuple->description;
        }
    }
    return NULL;
}

static int ignore_entry(autoindex_config_rec *d, char *path)
{
    apr_array_header_t *list = d->ign_list;
    struct item *items = (struct item *) list->elts;
    char *tt;
    int i;

    if ((tt = strrchr(path, '/')) == NULL) {
        tt = path;
    }
    else {
        tt++;
    }

    for (i = 0; i < list->nelts; ++i) {
        struct item *p = &items[i];
        char *ap;

        if ((ap = strrchr(p->apply_to, '/')) == NULL) {
            ap = p->apply_to;
        }
        else {
            ap++;
        }

#ifndef CASE_BLIND_FILESYSTEM
        if (!ap_strcmp_match(path, p->apply_path)
            && !ap_strcmp_match(tt, ap)) {
            return 1;
        }
#else  /* !CASE_BLIND_FILESYSTEM */
        /*
         * On some platforms, the match must be case-blind.  This is really
         * a factor of the filesystem involved, but we can't detect that
         * reliably - so we have to granularise at the OS level.
         */
        if (!ap_strcasecmp_match(path, p->apply_path)
            && !ap_strcasecmp_match(tt, ap)) {
            return 1;
        }
#endif /* !CASE_BLIND_FILESYSTEM */
    }
    return 0;
}

/*****************************************************************
 *
 * Actually generating output
 */

/*
 * Elements of the emitted document:
 *      Preamble
 *              Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req
 *              succeeds for the (content_type == text/html) header file.
 *      Header file
 *              Emitted if found (and able).
 *      H1 tag line
 *              Emitted if a header file is NOT emitted.
 *      Directory stuff
 *              Always emitted.
 *      HR
 *              Emitted if FANCY_INDEXING is set.
 *      Readme file
 *              Emitted if found (and able).
 *      ServerSig
 *              Emitted if ServerSignature is not Off AND a readme file
 *              is NOT emitted.
 *      Postamble
 *              Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req
 *              succeeds for the (content_type == text/html) readme file.
 */


/*
 * emit a plain text file
 */
static void do_emit_plain(request_rec *r, apr_file_t *f)
{
    char buf[AP_IOBUFSIZE + 1];
    int ch;
    apr_size_t i, c, n;
    apr_status_t rv;

    ap_rputs("<pre>\n", r);
    while (!apr_file_eof(f)) {
        do {
            n = sizeof(char) * AP_IOBUFSIZE;
            rv = apr_file_read(f, buf, &n);
        } while (APR_STATUS_IS_EINTR(rv));
        if (n == 0 || rv != APR_SUCCESS) {
            /* ###: better error here? */
            break;
        }
        buf[n] = '\0';
        c = 0;
        while (c < n) {
            for (i = c; i < n; i++) {
                if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') {
                    break;
                }
            }
            ch = buf[i];
            buf[i] = '\0';
            ap_rputs(&buf[c], r);
            if (ch == '<') {
                ap_rputs("&lt;", r);
            }
            else if (ch == '>') {
                ap_rputs("&gt;", r);
            }
            else if (ch == '&') {
                ap_rputs("&amp;", r);
            }
            c = i + 1;
        }
    }
    ap_rputs("</pre>\n", r);
}

/*
 * Handle the preamble through the H1 tag line, inclusive.  Locate
 * the file with a subrequests.  Process text/html documents by actually
 * running the subrequest; text/xxx documents get copied verbatim,
 * and any other content type is ignored.  This means that a non-text
 * document (such as HEADER.gif) might get multiviewed as the result
 * instead of a text document, meaning nothing will be displayed, but
 * oh well.
 */
static void emit_head(request_rec *r, char *header_fname, int suppress_amble,
                      int emit_xhtml, char *title)
{
    autoindex_config_rec *d;
    apr_table_t *hdrs = r->headers_in;
    apr_file_t *f = NULL;
    request_rec *rr = NULL;
    int emit_amble = 1;
    int emit_H1 = 1;
    const char *r_accept;
    const char *r_accept_enc;

    /*
     * If there's a header file, send a subrequest to look for it.  If it's
     * found and html do the subrequest, otherwise handle it
     */
    r_accept = apr_table_get(hdrs, "Accept");
    r_accept_enc = apr_table_get(hdrs, "Accept-Encoding");
    apr_table_setn(hdrs, "Accept", "text/html, text/plain");
    apr_table_unset(hdrs, "Accept-Encoding");


    if ((header_fname != NULL) && r->args) {
        header_fname = apr_pstrcat(r->pool, header_fname, "?", r->args, NULL);
    }

    if ((header_fname != NULL)
        && (rr = ap_sub_req_lookup_uri(header_fname, r, r->output_filters))
        && (rr->status == HTTP_OK)
        && (rr->filename != NULL)
        && (rr->finfo.filetype == APR_REG)) {
        /*
         * Check for the two specific cases we allow: text/html and
         * text/anything-else.  The former is allowed to be processed for
         * SSIs.
         */
        if (rr->content_type != NULL) {
            if (response_is_html(rr)) {
                ap_filter_t *f;
               /* Hope everything will work... */
                emit_amble = 0;
                emit_H1 = 0;

                if (! suppress_amble) {
                    emit_preamble(r, emit_xhtml, title);
                }
                /* This is a hack, but I can't find any better way to do this.
                 * The problem is that we have already created the sub-request,
                 * but we just inserted the OLD_WRITE filter, and the
                 * sub-request needs to pass its data through the OLD_WRITE
                 * filter, or things go horribly wrong (missing data, data in
                 * the wrong order, etc).  To fix it, if you create a
                 * sub-request and then insert the OLD_WRITE filter before you
                 * run the request, you need to make sure that the sub-request
                 * data goes through the OLD_WRITE filter.  Just steal this
                 * code.  The long-term solution is to remove the ap_r*
                 * functions.
                 */
                for (f=rr->output_filters;
                     f->frec != ap_subreq_core_filter_handle; f = f->next);
                f->next = r->output_filters;

                /*
                 * If there's a problem running the subrequest, display the
                 * preamble if we didn't do it before -- the header file
                 * didn't get displayed.
                 */
                if (ap_run_sub_req(rr) != OK) {
                    /* It didn't work */
                    emit_amble = suppress_amble;
                    emit_H1 = 1;
                }
            }
            else if (!ap_cstr_casecmpn("text/", rr->content_type, 5)) {
                /*
                 * If we can open the file, prefix it with the preamble
                 * regardless; since we'll be sending a <pre> block around
                 * the file's contents, any HTML header it had won't end up
                 * where it belongs.
                 */
                if (apr_file_open(&f, rr->filename, APR_READ,
                                  APR_OS_DEFAULT, r->pool) == APR_SUCCESS) {
                    emit_preamble(r, emit_xhtml, title);
                    emit_amble = 0;
                    do_emit_plain(r, f);
                    apr_file_close(f);
                    emit_H1 = 0;
                }
            }
        }
    }

    if (r_accept) {
        apr_table_setn(hdrs, "Accept", r_accept);
    }
    else {
        apr_table_unset(hdrs, "Accept");
    }

    if (r_accept_enc) {
        apr_table_setn(hdrs, "Accept-Encoding", r_accept_enc);
    }

    if (emit_amble) {
        emit_preamble(r, emit_xhtml, title);
    }

    d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config, &autoindex_module);

    if (emit_H1) {
        if (d->style_sheet != NULL) {
            /* Insert style id if stylesheet used */
            ap_rvputs(r, "  <h1 id=\"indextitle\">Index of ", title, "</h1>\n", NULL);
        } else {
            ap_rvputs(r, "<h1>Index of ", title, "</h1>\n", NULL);
        }
    }
    if (rr != NULL) {
        ap_destroy_sub_req(rr);
    }
}


/*
 * Handle the Readme file through the postamble, inclusive.  Locate
 * the file with a subrequests.  Process text/html documents by actually
 * running the subrequest; text/xxx documents get copied verbatim,
 * and any other content type is ignored.  This means that a non-text
 * document (such as FOOTER.gif) might get multiviewed as the result
 * instead of a text document, meaning nothing will be displayed, but
 * oh well.
 */
static void emit_tail(request_rec *r, char *readme_fname, int suppress_amble)
{
    apr_file_t *f = NULL;
    request_rec *rr = NULL;
    int suppress_post = 0;
    int suppress_sig = 0;

    /*
     * If there's a readme file, send a subrequest to look for it.  If it's
     * found and a text file, handle it -- otherwise fall through and
     * pretend there's nothing there.
     */
    if ((readme_fname != NULL)
        && (rr = ap_sub_req_lookup_uri(readme_fname, r, r->output_filters))
        && (rr->status == HTTP_OK)
        && (rr->filename != NULL)
        && rr->finfo.filetype == APR_REG) {
        /*
         * Check for the two specific cases we allow: text/html and
         * text/anything-else.  The former is allowed to be processed for
         * SSIs.
         */
        if (rr->content_type != NULL) {
            if (response_is_html(rr)) {
                ap_filter_t *f;
                for (f=rr->output_filters;
                     f->frec != ap_subreq_core_filter_handle; f = f->next);
                f->next = r->output_filters;


                if (ap_run_sub_req(rr) == OK) {
                    /* worked... */
                    suppress_sig = 1;
                    suppress_post = suppress_amble;
                }
            }
            else if (!ap_cstr_casecmpn("text/", rr->content_type, 5)) {
                /*
                 * If we can open the file, suppress the signature.
                 */
                if (apr_file_open(&f, rr->filename, APR_READ,
                                  APR_OS_DEFAULT, r->pool) == APR_SUCCESS) {
                    do_emit_plain(r, f);
                    apr_file_close(f);
                    suppress_sig = 1;
                }
            }
        }
    }

    if (!suppress_sig) {
        ap_rputs(ap_psignature("", r), r);
    }
    if (!suppress_post) {
        ap_rputs("</body></html>\n", r);
    }
    if (rr != NULL) {
        ap_destroy_sub_req(rr);
    }
}


static char *find_title(request_rec *r)
{
    char titlebuf[MAX_STRING_LEN], *find = "<title>";
    apr_file_t *thefile = NULL;
    int x, y, p;
    apr_size_t n;

    if (r->status != HTTP_OK) {
        return NULL;
    }
    if ((r->content_type != NULL)
        && (response_is_html(r)
            || !strcmp(r->content_type, INCLUDES_MAGIC_TYPE))
        && !r->content_encoding) {
        if (apr_file_open(&thefile, r->filename, APR_READ,
                          APR_OS_DEFAULT, r->pool) != APR_SUCCESS) {
            return NULL;
        }
        n = sizeof(char) * (MAX_STRING_LEN - 1);
        apr_file_read(thefile, titlebuf, &n);
        if (n == 0) {
            apr_file_close(thefile);
            return NULL;
        }
        titlebuf[n] = '\0';
        for (x = 0, p = 0; titlebuf[x]; x++) {
            if (apr_tolower(titlebuf[x]) == find[p]) {
                if (!find[++p]) {
                    if ((p = ap_ind(&titlebuf[++x], '<')) != -1) {
                        titlebuf[x + p] = '\0';
                    }
                    /* Scan for line breaks for Tanmoy's secretary */
                    for (y = x; titlebuf[y]; y++) {
                        if ((titlebuf[y] == CR) || (titlebuf[y] == LF)) {
                            if (y == x) {
                                x++;
                            }
                            else {
                                titlebuf[y] = ' ';
                            }
                        }
                    }
                    apr_file_close(thefile);
                    return apr_pstrdup(r->pool, &titlebuf[x]);
                }
            }
            else {
                p = 0;
            }
        }
        apr_file_close(thefile);
    }
    return NULL;
}

static struct ent *make_parent_entry(apr_int32_t autoindex_opts,
                                     autoindex_config_rec *d,
                                     request_rec *r, char keyid,
                                     char direction)
{
    struct ent *p = (struct ent *) apr_pcalloc(r->pool, sizeof(struct ent));
    char *testpath;
    /*
     * p->name is now the true parent URI.
     * testpath is a crafted lie, so that the syntax '/some/..'
     * (or simply '..')be used to describe 'up' from '/some/'
     * when processeing IndexIgnore, and Icon|Alt|Desc configs.
     */

    /* The output has always been to the parent.  Don't make ourself
     * our own parent (worthless cyclical reference).
     */
    if (!(p->name = ap_make_full_path(r->pool, r->uri, "../"))) {
        return (NULL);
    }
    ap_getparents(p->name);
    if (!*p->name) {
        return (NULL);
    }

    /* IndexIgnore has always compared "/thispath/.." */
    testpath = ap_make_full_path(r->pool, r->filename, "..");
    if (ignore_entry(d, testpath)) {
        return (NULL);
    }

    p->size = -1;
    p->lm = -1;
    p->key = apr_toupper(keyid);
    p->ascending = (apr_toupper(direction) == D_ASCENDING);
    p->version_sort = autoindex_opts & VERSION_SORT;
    if (autoindex_opts & FANCY_INDEXING) {
        if (!(p->icon = find_default_icon(d, testpath))) {
            p->icon = find_default_icon(d, "^^DIRECTORY^^");
        }
        if (!(p->alt = find_default_alt(d, testpath))) {
            if (!(p->alt = find_default_alt(d, "^^DIRECTORY^^"))) {
                /* Special alt text for parent dir to distinguish it from other directories
                   this is essential when trying to style this dir entry via AddAltClass */
                p->alt = "PARENTDIR";
            }
        }
        p->desc = find_desc(d, testpath);
    }
    return p;
}

static struct ent *make_autoindex_entry(const apr_finfo_t *dirent,
                                        int autoindex_opts,
                                        autoindex_config_rec *d,
                                        request_rec *r, char keyid,
                                        char direction,
                                        const char *pattern)
{
    request_rec *rr;
    struct ent *p;
    int show_forbidden = 0;

    /* Dot is ignored, Parent is handled by make_parent_entry() */
    if ((dirent->name[0] == '.') && (!dirent->name[1]
        || ((dirent->name[1] == '.') && !dirent->name[2])))
        return (NULL);

    /*
     * On some platforms, the match must be case-blind.  This is really
     * a factor of the filesystem involved, but we can't detect that
     * reliably - so we have to granularise at the OS level.
     */
    if (pattern && (apr_fnmatch(pattern, dirent->name,
                                APR_FNM_NOESCAPE | APR_FNM_PERIOD
#ifdef CASE_BLIND_FILESYSTEM
                                | APR_FNM_CASE_BLIND
#endif
                                )
                    != APR_SUCCESS)) {
        return (NULL);
    }

    if (ignore_entry(d, ap_make_full_path(r->pool,
                                          r->filename, dirent->name))) {
        return (NULL);
    }

    if (!(rr = ap_sub_req_lookup_dirent(dirent, r, AP_SUBREQ_NO_ARGS, NULL))) {
        return (NULL);
    }

    if ((autoindex_opts & SHOW_FORBIDDEN)
        && (rr->status == HTTP_UNAUTHORIZED || rr->status == HTTP_FORBIDDEN)) {
        show_forbidden = 1;
    }

    if ((rr->finfo.filetype != APR_DIR && rr->finfo.filetype != APR_REG)
        || !(rr->status == OK || ap_is_HTTP_SUCCESS(rr->status)
                              || ap_is_HTTP_REDIRECT(rr->status)
                              || show_forbidden == 1)) {
        ap_destroy_sub_req(rr);
        return (NULL);
    }

    p = (struct ent *) apr_pcalloc(r->pool, sizeof(struct ent));
    if (dirent->filetype == APR_DIR) {
        p->name = apr_pstrcat(r->pool, dirent->name, "/", NULL);
    }
    else {
        p->name = apr_pstrdup(r->pool, dirent->name);
    }
    p->size = -1;
    p->icon = NULL;
    p->alt = NULL;
    p->desc = NULL;
    p->lm = -1;
    p->isdir = 0;
    p->key = apr_toupper(keyid);
    p->ascending = (apr_toupper(direction) == D_ASCENDING);
    p->version_sort = !!(autoindex_opts & VERSION_SORT);
    p->ignore_case = !!(autoindex_opts & IGNORE_CASE);

    if (autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING)) {
        p->lm = rr->finfo.mtime;
        if (dirent->filetype == APR_DIR) {
            if (autoindex_opts & FOLDERS_FIRST) {
                p->isdir = 1;
            }
            rr->filename = ap_make_dirstr_parent (rr->pool, rr->filename);

            /* omit the trailing slash (1.3 compat) */
            rr->filename[strlen(rr->filename) - 1] = '\0';

            if (!(p->icon = find_icon(d, rr, 1))) {
                p->icon = find_default_icon(d, "^^DIRECTORY^^");
            }
            if (!(p->alt = find_alt(d, rr, 1))) {
                if (!(p->alt = find_default_alt(d, "^^DIRECTORY^^"))) {
                    p->alt = "DIR";
                }
            }
        }
        else {
            p->icon = find_icon(d, rr, 0);
            p->alt = find_alt(d, rr, 0);
            p->size = rr->finfo.size;
        }

        p->desc = find_desc(d, rr->filename);

        if ((!p->desc) && (autoindex_opts & SCAN_HTML_TITLES)) {
            p->desc = apr_pstrdup(r->pool, find_title(rr));
        }
    }
    ap_destroy_sub_req(rr);
    /*
     * We don't need to take any special action for the file size key.
     * If we did, it would go here.
     */
    if (keyid == K_LAST_MOD) {
        if (p->lm < 0) {
            p->lm = 0;
        }
    }
    return (p);
}

static char *terminate_description(autoindex_config_rec *d, char *desc,
                                   apr_int32_t autoindex_opts, int desc_width)
{
    int maxsize = desc_width;
    int x;

    /*
     * If there's no DescriptionWidth in effect, default to the old
     * behaviour of adjusting the description size depending upon
     * what else is being displayed.  Otherwise, stick with the
     * setting.
     */
    if (d->desc_adjust == K_UNSET) {
        if (autoindex_opts & SUPPRESS_ICON) {
            maxsize += 6;
        }
        if (autoindex_opts & SUPPRESS_LAST_MOD) {
            maxsize += 19;
        }
        if (autoindex_opts & SUPPRESS_SIZE) {
            maxsize += 7;
        }
    }
    for (x = 0; desc[x] && ((maxsize > 0) || (desc[x] == '<')); x++) {
        if (desc[x] == '<') {
            while (desc[x] != '>') {
                if (!desc[x]) {
                    maxsize = 0;
                    break;
                }
                ++x;
            }
        }
        else if (desc[x] == '&') {
            /* entities like &auml; count as one character */
            --maxsize;
            for ( ; desc[x] != ';'; ++x) {
                if (desc[x] == '\0') {
                     maxsize = 0;
                     break;
                }
            }
        }
        else {
            --maxsize;
        }
    }
    if (!maxsize && desc[x] != '\0') {
        desc[x - 1] = '>';      /* Grump. */
        desc[x] = '\0';         /* Double Grump! */
    }
    return desc;
}

/*
 * Emit the anchor for the specified field.  If a field is the key for the
 * current request, the link changes its meaning to reverse the order when
 * selected again.  Non-active fields always start in ascending order.
 */
static void emit_link(request_rec *r, const char *anchor, char column,
                      char curkey, char curdirection,
                      const char *colargs, int nosort)
{
    if (!nosort) {
        char qvalue[9];

        qvalue[0] = '?';
        qvalue[1] = 'C';
        qvalue[2] = '=';
        qvalue[3] = column;
        qvalue[4] = ';';
        qvalue[5] = 'O';
        qvalue[6] = '=';
                    /* reverse? */
        qvalue[7] = ((curkey == column) && (curdirection == D_ASCENDING))
                      ? D_DESCENDING : D_ASCENDING;
        qvalue[8] = '\0';
        ap_rvputs(r, "<a href=\"", qvalue, colargs ? colargs : "",
                     "\">", anchor, "</a>", NULL);
    }
    else {
        ap_rputs(anchor, r);
    }
}

static void output_directories(struct ent **ar, int n,
                               autoindex_config_rec *d, request_rec *r,
                               apr_int32_t autoindex_opts, char keyid,
                               char direction, const char *colargs)
{
    int x;
    apr_size_t rv;
    char *tp;
    int static_columns = !!(autoindex_opts & SUPPRESS_COLSORT);
    apr_pool_t *scratch;
    int name_width;
    int desc_width;
    char *name_scratch;
    char *pad_scratch;
    char *breakrow = "";

    apr_pool_create(&scratch, r->pool);

    name_width = d->name_width;
    desc_width = d->desc_width;

    if ((autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING))
                        == FANCY_INDEXING) {
        if (d->name_adjust == K_ADJUST) {
            for (x = 0; x < n; x++) {
                int t = strlen(ar[x]->name);
                if (t > name_width) {
                    name_width = t;
                }
            }
        }

        if (d->desc_adjust == K_ADJUST) {
            for (x = 0; x < n; x++) {
                if (ar[x]->desc != NULL) {
                    int t = strlen(ar[x]->desc);
                    if (t > desc_width) {
                        desc_width = t;
                    }
                }
            }
        }
    }
    name_scratch = apr_palloc(r->pool, name_width + 1);
    pad_scratch = apr_palloc(r->pool, name_width + 1);
    memset(pad_scratch, ' ', name_width);
    pad_scratch[name_width] = '\0';

    if (autoindex_opts & TABLE_INDEXING) {
        int cols = 1;
        if (d->style_sheet != NULL) {
            /* Emit table with style id */
            ap_rputs("  <table id=\"indexlist\">\n   <tr class=\"indexhead\">", r);
        } else {
            ap_rputs("  <table>\n   <tr>", r);
        }
        if (!(autoindex_opts & SUPPRESS_ICON)) {
            ap_rvputs(r, "<th", (d->style_sheet != NULL) ? " class=\"indexcolicon\">" : " valign=\"top\">", NULL);
            if ((tp = find_default_icon(d, "^^BLANKICON^^"))) {
                ap_rvputs(r, "<img src=\"", ap_escape_html(scratch, tp),
                             "\" alt=\"[ICO]\"", NULL);
                if (d->icon_width) {
                    ap_rprintf(r, " width=\"%d\"", d->icon_width);
                }
                if (d->icon_height) {
                    ap_rprintf(r, " height=\"%d\"", d->icon_height);
                }

                if (autoindex_opts & EMIT_XHTML) {
                    ap_rputs(" /", r);
                }
                ap_rputs("></th>", r);
            }
            else {
                ap_rputs("&nbsp;</th>", r);
            }

            ++cols;
        }
        ap_rvputs(r, "<th", (d->style_sheet != NULL) ? " class=\"indexcolname\">" : ">", NULL);
        emit_link(r, "Name", K_NAME, keyid, direction,
                  colargs, static_columns);
        if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
            ap_rvputs(r, "</th><th", (d->style_sheet != NULL) ? " class=\"indexcollastmod\">" : ">", NULL);
            emit_link(r, "Last modified", K_LAST_MOD, keyid, direction,
                      colargs, static_columns);
            ++cols;
        }
        if (!(autoindex_opts & SUPPRESS_SIZE)) {
            ap_rvputs(r, "</th><th", (d->style_sheet != NULL) ? " class=\"indexcolsize\">" : ">", NULL);
            emit_link(r, "Size", K_SIZE, keyid, direction,
                      colargs, static_columns);
            ++cols;
        }
        if (!(autoindex_opts & SUPPRESS_DESC)) {
            ap_rvputs(r, "</th><th", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">", NULL);
            emit_link(r, "Description", K_DESC, keyid, direction,
                      colargs, static_columns);
            ++cols;
        }
        if (!(autoindex_opts & SUPPRESS_RULES)) {
            breakrow = apr_psprintf(r->pool,
                                    "   <tr%s><th colspan=\"%d\">"
                                    "<hr%s></th></tr>\n",
                                    (d->style_sheet != NULL) ? " class=\"indexbreakrow\"" : "",
                                    cols,
                                    (autoindex_opts & EMIT_XHTML) ? " /" : "");
        }
        ap_rvputs(r, "</th></tr>\n", breakrow, NULL);
    }
    else if (autoindex_opts & FANCY_INDEXING) {
        ap_rputs("<pre>", r);
        if (!(autoindex_opts & SUPPRESS_ICON)) {
            if ((tp = find_default_icon(d, "^^BLANKICON^^"))) {
                ap_rvputs(r, "<img src=\"", ap_escape_html(scratch, tp),
                             "\" alt=\"Icon \"", NULL);
                if (d->icon_width) {
                    ap_rprintf(r, " width=\"%d\"", d->icon_width);
                }
                if (d->icon_height) {
                    ap_rprintf(r, " height=\"%d\"", d->icon_height);
                }

                if (autoindex_opts & EMIT_XHTML) {
                    ap_rputs(" /", r);
                }
                ap_rputs("> ", r);
            }
            else {
                ap_rputs("      ", r);
            }
        }
        emit_link(r, "Name", K_NAME, keyid, direction,
                  colargs, static_columns);
        ap_rputs(pad_scratch + 4, r);
        /*
         * Emit the guaranteed-at-least-one-space-between-columns byte.
         */
        ap_rputs(" ", r);
        if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
            emit_link(r, "Last modified", K_LAST_MOD, keyid, direction,
                      colargs, static_columns);
            ap_rputs("      ", r);
        }
        if (!(autoindex_opts & SUPPRESS_SIZE)) {
            emit_link(r, "Size", K_SIZE, keyid, direction,
                      colargs, static_columns);
            ap_rputs("  ", r);
        }
        if (!(autoindex_opts & SUPPRESS_DESC)) {
            emit_link(r, "Description", K_DESC, keyid, direction,
                      colargs, static_columns);
        }
        if (!(autoindex_opts & SUPPRESS_RULES)) {
            ap_rputs("<hr", r);
            if (autoindex_opts & EMIT_XHTML) {
                ap_rputs(" /", r);
            }
            ap_rputs(">", r);
        }
        else {
            ap_rputc('\n', r);
        }
    }
    else {
        ap_rputs("<ul>", r);
    }

    for (x = 0; x < n; x++) {
        char *anchor, *t, *t2;
        int nwidth;

        apr_pool_clear(scratch);

        t = ar[x]->name;
        anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0));

        if (!x && t[0] == '/') {
            t2 = "Parent Directory";
        }
        else {
            t2 = t;
        }

        if (autoindex_opts & TABLE_INDEXING) {
            /* Even/Odd rows for IndexStyleSheet */
            if (d->style_sheet != NULL) {
                if (ar[x]->alt && (autoindex_opts & ADDALTCLASS)) {
                    /* Include alt text in class name, distinguish between odd and even rows */
                    char *altclass = apr_pstrdup(scratch, ar[x]->alt);
                    ap_str_tolower(altclass);
                    ap_rvputs(r, "   <tr class=\"", ( x & 0x1) ? "odd-" : "even-", altclass, "\">", NULL);
                } else {
                    /* Distinguish between odd and even rows */
                    ap_rvputs(r, "   <tr class=\"", ( x & 0x1) ? "odd" : "even", "\">", NULL);
                }
            } else {
                ap_rputs("<tr>", r);
            }

            if (!(autoindex_opts & SUPPRESS_ICON)) {
                ap_rvputs(r, "<td", (d->style_sheet != NULL) ? " class=\"indexcolicon\">" : " valign=\"top\">", NULL);
                if (autoindex_opts & ICONS_ARE_LINKS) {
                    ap_rvputs(r, "<a href=\"", anchor, "\">", NULL);
                }
                if ((ar[x]->icon) || d->default_icon) {
                    ap_rvputs(r, "<img src=\"",
                              ap_escape_html(scratch,
                                             ar[x]->icon ? ar[x]->icon
                                                         : d->default_icon),
                              "\" alt=\"[", (ar[x]->alt ? ar[x]->alt : "   "),
                              "]\"", NULL);
                    if (d->icon_width) {
                        ap_rprintf(r, " width=\"%d\"", d->icon_width);
                    }
                    if (d->icon_height) {
                        ap_rprintf(r, " height=\"%d\"", d->icon_height);
                    }

                    if (autoindex_opts & EMIT_XHTML) {
                        ap_rputs(" /", r);
                    }
                    ap_rputs(">", r);
                }
                else {
                    ap_rputs("&nbsp;", r);
                }
                if (autoindex_opts & ICONS_ARE_LINKS) {
                    ap_rputs("</a></td>", r);
                }
                else {
                    ap_rputs("</td>", r);
                }
            }
            if (d->name_adjust == K_ADJUST) {
                ap_rvputs(r, "<td", (d->style_sheet != NULL) ? " class=\"indexcolname\">" : ">", "<a href=\"", anchor, "\">",
                          ap_escape_html(scratch, t2), "</a>", NULL);
            }
            else {
                nwidth = strlen(t2);
                if (nwidth > name_width) {
                  memcpy(name_scratch, t2, name_width - 3);
                  name_scratch[name_width - 3] = '.';
                  name_scratch[name_width - 2] = '.';
                  name_scratch[name_width - 1] = '>';
                  name_scratch[name_width] = 0;
                  t2 = name_scratch;
                  nwidth = name_width;
                }
                ap_rvputs(r, "<td", (d->style_sheet != NULL) ? " class=\"indexcolname\">" : ">", "<a href=\"", anchor, "\">",
                          ap_escape_html(scratch, t2),
                          "</a>", pad_scratch + nwidth, NULL);
            }
            if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
                if (ar[x]->lm != -1) {
                    char time_str[32];
                    apr_time_exp_t ts;
                    apr_time_exp_lt(&ts, ar[x]->lm);
                    apr_strftime(time_str, &rv, sizeof(time_str),
                                 "%Y-%m-%d %H:%M  ",
                                 &ts);
                    ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcollastmod\">" : " align=\"right\">",time_str, NULL);
                }
                else {
                    ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcollastmod\">&nbsp;" : ">&nbsp;", NULL);
                }
            }
            if (!(autoindex_opts & SUPPRESS_SIZE)) {
                char buf[5];
                ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcolsize\">" : " align=\"right\">",
                          apr_strfsize(ar[x]->size, buf), NULL);
            }
            if (!(autoindex_opts & SUPPRESS_DESC)) {
                if (ar[x]->desc) {
                    if (d->desc_adjust == K_ADJUST) {
                        ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">", ar[x]->desc, NULL);
                    }
                    else {
                        ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">",
                                  terminate_description(d, ar[x]->desc,
                                                        autoindex_opts,
                                                        desc_width), NULL);
                    }
                }
                else {
                    ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">", "&nbsp;", NULL);
                }
            }
            ap_rputs("</td></tr>\n", r);
        }
        else if (autoindex_opts & FANCY_INDEXING) {
            if (!(autoindex_opts & SUPPRESS_ICON)) {
                if (autoindex_opts & ICONS_ARE_LINKS) {
                    ap_rvputs(r, "<a href=\"", anchor, "\">", NULL);
                }
                if ((ar[x]->icon) || d->default_icon) {
                    ap_rvputs(r, "<img src=\"",
                              ap_escape_html(scratch,
                                             ar[x]->icon ? ar[x]->icon
                                                         : d->default_icon),
                              "\" alt=\"[", (ar[x]->alt ? ar[x]->alt : "   "),
                              "]\"", NULL);
                    if (d->icon_width) {
                        ap_rprintf(r, " width=\"%d\"", d->icon_width);
                    }
                    if (d->icon_height) {
                        ap_rprintf(r, " height=\"%d\"", d->icon_height);
                    }

                    if (autoindex_opts & EMIT_XHTML) {
                        ap_rputs(" /", r);
                    }
                    ap_rputs(">", r);
                }
                else {
                    ap_rputs("     ", r);
                }
                if (autoindex_opts & ICONS_ARE_LINKS) {
                    ap_rputs("</a> ", r);
                }
                else {
                    ap_rputc(' ', r);
                }
            }
            nwidth = strlen(t2);
            if (nwidth > name_width) {
                memcpy(name_scratch, t2, name_width - 3);
                name_scratch[name_width - 3] = '.';
                name_scratch[name_width - 2] = '.';
                name_scratch[name_width - 1] = '>';
                name_scratch[name_width] = 0;
                t2 = name_scratch;
                nwidth = name_width;
            }
            ap_rvputs(r, "<a href=\"", anchor, "\">",
                      ap_escape_html(scratch, t2),
                      "</a>", pad_scratch + nwidth, NULL);
            /*
             * The blank before the storm.. er, before the next field.
             */
            ap_rputs(" ", r);
            if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
                if (ar[x]->lm != -1) {
                    char time_str[32];
                    apr_time_exp_t ts;
                    apr_time_exp_lt(&ts, ar[x]->lm);
                    apr_strftime(time_str, &rv, sizeof(time_str),
                                "%Y-%m-%d %H:%M  ", &ts);
                    ap_rputs(time_str, r);
                }
                else {
                    /*Length="1975-04-07 01:23  " (see 4 lines above) */
                    ap_rputs("                   ", r);
                }
            }
            if (!(autoindex_opts & SUPPRESS_SIZE)) {
                char buf[5];
                ap_rputs(apr_strfsize(ar[x]->size, buf), r);
                ap_rputs("  ", r);
            }
            if (!(autoindex_opts & SUPPRESS_DESC)) {
                if (ar[x]->desc) {
                    ap_rputs(terminate_description(d, ar[x]->desc,
                                                   autoindex_opts,
                                                   desc_width), r);
                }
            }
            ap_rputc('\n', r);
        }
        else {
            ap_rvputs(r, "<li><a href=\"", anchor, "\"> ",
                      ap_escape_html(scratch, t2),
                      "</a></li>\n", NULL);
        }
    }
    if (autoindex_opts & TABLE_INDEXING) {
        ap_rvputs(r, breakrow, "</table>\n", NULL);
    }
    else if (autoindex_opts & FANCY_INDEXING) {
        if (!(autoindex_opts & SUPPRESS_RULES)) {
            ap_rputs("<hr", r);
            if (autoindex_opts & EMIT_XHTML) {
                ap_rputs(" /", r);
            }
            ap_rputs("></pre>\n", r);
        }
        else {
            ap_rputs("</pre>\n", r);
        }
    }
    else {
        ap_rputs("</ul>\n", r);
    }
}

/*
 * Compare two file entries according to the sort criteria.  The return
 * is essentially a signum function value.
 */

static int dsortf(struct ent **e1, struct ent **e2)
{
    struct ent *c1;
    struct ent *c2;
    int result = 0;

    /*
     * First, see if either of the entries is for the parent directory.
     * If so, that *always* sorts lower than anything else.
     */
    if ((*e1)->name[0] == '/') {
        return -1;
    }
    if ((*e2)->name[0] == '/') {
        return 1;
    }
    /*
     * Now see if one's a directory and one isn't, if we're set
     * isdir for FOLDERS_FIRST.
     */
    if ((*e1)->isdir != (*e2)->isdir) {
        return (*e1)->isdir ? -1 : 1;
    }
    /*
     * All of our comparisons will be of the c1 entry against the c2 one,
     * so assign them appropriately to take care of the ordering.
     */
    if ((*e1)->ascending) {
        c1 = *e1;
        c2 = *e2;
    }
    else {
        c1 = *e2;
        c2 = *e1;
    }

    switch (c1->key) {
    case K_LAST_MOD:
        if (c1->lm > c2->lm) {
            return 1;
        }
        else if (c1->lm < c2->lm) {
            return -1;
        }
        break;
    case K_SIZE:
        if (c1->size > c2->size) {
            return 1;
        }
        else if (c1->size < c2->size) {
            return -1;
        }
        break;
    case K_DESC:
        if (c1->version_sort) {
            result = apr_strnatcmp(c1->desc ? c1->desc : "",
                                   c2->desc ? c2->desc : "");
        }
        else {
            result = strcmp(c1->desc ? c1->desc : "",
                            c2->desc ? c2->desc : "");
        }
        if (result) {
            return result;
        }
        break;
    }

    /* names may identical when treated case-insensitively,
     * so always fall back on strcmp() flavors to put entries
     * in deterministic order.  This means that 'ABC' and 'abc'
     * will always appear in the same order, rather than
     * variably between 'ABC abc' and 'abc ABC' order.
     */

    if (c1->version_sort) {
        if (c1->ignore_case) {
            result = apr_strnatcasecmp (c1->name, c2->name);
        }
        if (!result) {
            result = apr_strnatcmp(c1->name, c2->name);
        }
    }

    /* The names may be identical in respects other than
     * filename case when strnatcmp is used above, so fall back
     * to strcmp on conflicts so that fn1.01.zzz and fn1.1.zzz
     * are also sorted in a deterministic order.
     */

    if (!result && c1->ignore_case) {
        result = strcasecmp (c1->name, c2->name);
    }

    if (!result) {
        result = strcmp (c1->name, c2->name);
    }

    return result;
}


static int index_directory(request_rec *r,
                           autoindex_config_rec *autoindex_conf)
{
    char *title_name = ap_escape_html(r->pool, r->uri);
    char *title_endp;
    char *name = r->filename;
    char *pstring = NULL;
    apr_finfo_t dirent;
    apr_dir_t *thedir;
    apr_status_t status;
    int num_ent = 0, x;
    struct ent *head, *p;
    struct ent **ar = NULL;
    const char *qstring;
    apr_int32_t autoindex_opts = autoindex_conf->opts;
    char keyid;
    char direction;
    char *colargs;
    char *fullpath;
    apr_size_t dirpathlen;
    char *ctype = "text/html";
    char *charset;

    if ((status = apr_dir_open(&thedir, name, r->pool)) != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01275)
                      "Can't open directory for index: %s", r->filename);
        return HTTP_FORBIDDEN;
    }

    if (autoindex_conf->ctype) {
        ctype = autoindex_conf->ctype;
    }
    if (autoindex_conf->charset) {
        charset = autoindex_conf->charset;
    }
    else {
#if APR_HAS_UNICODE_FS
        charset = "UTF-8";
#else
        charset = "ISO-8859-1";
#endif
    }
    if (*charset) {
        ap_set_content_type(r, apr_pstrcat(r->pool, ctype, ";charset=",
                            charset, NULL));
    }
    else {
        ap_set_content_type(r, ctype);
    }

    if (autoindex_opts & TRACK_MODIFIED) {
        ap_update_mtime(r, r->finfo.mtime);
        ap_set_last_modified(r);
        ap_set_etag(r);
    }
    if (r->header_only) {
        apr_dir_close(thedir);
        return 0;
    }

    /*
     * If there is no specific ordering defined for this directory,
     * default to ascending by filename.
     */
    keyid = autoindex_conf->default_keyid
                ? autoindex_conf->default_keyid : K_NAME;
    direction = autoindex_conf->default_direction
                ? autoindex_conf->default_direction : D_ASCENDING;

    /*
     * Figure out what sort of indexing (if any) we're supposed to use.
     *
     * If no QUERY_STRING was specified or client query strings have been
     * explicitly disabled.
     * If we are ignoring the client, suppress column sorting as well.
     */
    if (autoindex_opts & IGNORE_CLIENT) {
        qstring = NULL;
        autoindex_opts |= SUPPRESS_COLSORT;
        colargs = "";
    }
    else {
        char fval[5], vval[5], *ppre = "", *epattern = "";
        fval[0] = '\0'; vval[0] = '\0';
        qstring = r->args;

        while (qstring && *qstring) {

            /* C= First Sort key Column (N, M, S, D) */
            if (   qstring[0] == 'C' && qstring[1] == '='
                && qstring[2] && strchr(K_VALID, qstring[2])
                && (   qstring[3] == '&' || qstring[3] == ';'
                    || !qstring[3])) {
                keyid = qstring[2];
                qstring += qstring[3] ? 4 : 3;
            }

            /* O= Sort order (A, D) */
            else if (   qstring[0] == 'O' && qstring[1] == '='
                     && (   (qstring[2] == D_ASCENDING)
                         || (qstring[2] == D_DESCENDING))
                     && (   qstring[3] == '&' || qstring[3] == ';'
                         || !qstring[3])) {
                direction = qstring[2];
                qstring += qstring[3] ? 4 : 3;
            }

            /* F= Output Format (0 plain, 1 fancy (pre), 2 table) */
            else if (   qstring[0] == 'F' && qstring[1] == '='
                     && qstring[2] && strchr("012", qstring[2])
                     && (   qstring[3] == '&' || qstring[3] == ';'
                         || !qstring[3])) {
                if (qstring[2] == '0') {
                    autoindex_opts &= ~(FANCY_INDEXING | TABLE_INDEXING);
                }
                else if (qstring[2] == '1') {
                    autoindex_opts = (autoindex_opts | FANCY_INDEXING)
                        & ~TABLE_INDEXING;
                }
                else if (qstring[2] == '2') {
                    autoindex_opts |= FANCY_INDEXING | TABLE_INDEXING;
                }
                strcpy(fval, ";F= ");
                fval[3] = qstring[2];
                qstring += qstring[3] ? 4 : 3;
            }

            /* V= Version sort (0, 1) */
            else if (   qstring[0] == 'V' && qstring[1] == '='
                     && (qstring[2] == '0' || qstring[2] == '1')
                     && (   qstring[3] == '&' || qstring[3] == ';'
                         || !qstring[3])) {
                if (qstring[2] == '0') {
                    autoindex_opts &= ~VERSION_SORT;
                }
                else if (qstring[2] == '1') {
                    autoindex_opts |= VERSION_SORT;
                }
                strcpy(vval, ";V= ");
                vval[3] = qstring[2];
                qstring += qstring[3] ? 4 : 3;
            }

            /* P= wildcard pattern (*.foo) */
            else if (qstring[0] == 'P' && qstring[1] == '=') {
                const char *eos = qstring += 2; /* for efficiency */

                while (*eos && *eos != '&' && *eos != ';') {
                    ++eos;
                }

                if (eos == qstring) {
                    pstring = NULL;
                }
                else {
                    pstring = apr_pstrndup(r->pool, qstring, eos - qstring);
                    if (ap_unescape_url(pstring) != OK) {
                        /* ignore the pattern, if it's bad. */
                        pstring = NULL;
                    }
                    else {
                        ppre = ";P=";
                        /* be correct */
                        epattern = ap_escape_uri(r->pool, pstring);
                    }
                }

                if (*eos && *++eos) {
                    qstring = eos;
                }
                else {
                    qstring = NULL;
                }
            }

            /* Syntax error?  Ignore the remainder! */
            else {
                qstring = NULL;
            }
        }
        colargs = apr_pstrcat(r->pool, fval, vval, ppre, epattern, NULL);
    }

    /* Spew HTML preamble */
    title_endp = title_name + strlen(title_name) - 1;

    while (title_endp > title_name && *title_endp == '/') {
        *title_endp-- = '\0';
    }

    emit_head(r, autoindex_conf->header,
              autoindex_opts & SUPPRESS_PREAMBLE,
              autoindex_opts & EMIT_XHTML, title_name);

    /*
     * Since we don't know how many dir. entries there are, put them into a
     * linked list and then arrayificate them so qsort can use them.
     */
    head = NULL;
    p = make_parent_entry(autoindex_opts, autoindex_conf, r, keyid, direction);
    if (p != NULL) {
        p->next = head;
        head = p;
        num_ent++;
    }
    fullpath = apr_palloc(r->pool, APR_PATH_MAX);
    dirpathlen = strlen(name);
    memcpy(fullpath, name, dirpathlen);

    do {
        status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, thedir);
        if (APR_STATUS_IS_INCOMPLETE(status)) {
            continue; /* ignore un-stat()able files */
        }
        else if (status != APR_SUCCESS) {
            break;
        }

        /* We want to explode symlinks here. */
        if (dirent.filetype == APR_LNK) {
            const char *savename;
            apr_finfo_t fi;
            /* We *must* have FNAME. */
            savename = dirent.name;
            apr_cpystrn(fullpath + dirpathlen, dirent.name,
                        APR_PATH_MAX - dirpathlen);
            status = apr_stat(&fi, fullpath,
                              dirent.valid & ~(APR_FINFO_NAME), r->pool);
            if (status != APR_SUCCESS) {
                /* Something bad happened, skip this file. */
                continue;
            }
            memcpy(&dirent, &fi, sizeof(fi));
            dirent.name = savename;
            dirent.valid |= APR_FINFO_NAME;
        }
        p = make_autoindex_entry(&dirent, autoindex_opts, autoindex_conf, r,
                                 keyid, direction, pstring);
        if (p != NULL) {
            p->next = head;
            head = p;
            num_ent++;
        }
    } while (1);

    if (num_ent > 0) {
        ar = (struct ent **) apr_palloc(r->pool,
                                        num_ent * sizeof(struct ent *));
        p = head;
        x = 0;
        while (p) {
            ar[x++] = p;
            p = p->next;
        }

        qsort((void *) ar, num_ent, sizeof(struct ent *),
              (int (*)(const void *, const void *)) dsortf);
    }
    output_directories(ar, num_ent, autoindex_conf, r, autoindex_opts,
                       keyid, direction, colargs);
    apr_dir_close(thedir);

    emit_tail(r, autoindex_conf->readme,
              autoindex_opts & SUPPRESS_PREAMBLE);

    return 0;
}

/* The formal handler... */

static int handle_autoindex(request_rec *r)
{
    autoindex_config_rec *d;
    int allow_opts;

    if (strcmp(r->handler,DIR_MAGIC_TYPE) && !AP_IS_DEFAULT_HANDLER_NAME(r->handler)) {
        return DECLINED;
    }
    if (r->finfo.filetype != APR_DIR) {
        return DECLINED;
    }

    allow_opts = ap_allow_options(r);

    d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config,
                                                      &autoindex_module);

    r->allowed |= (AP_METHOD_BIT << M_GET);
    if (r->method_number != M_GET) {
        return DECLINED;
    }

    /* OK, nothing easy.  Trot out the heavy artillery... */

    if (allow_opts & OPT_INDEXES) {
        int errstatus;

        if ((errstatus = ap_discard_request_body(r)) != OK) {
            return errstatus;
        }

        /* KLUDGE --- make the sub_req lookups happen in the right directory.
         * Fixing this in the sub_req_lookup functions themselves is difficult,
         * and would probably break virtual includes...
         */

        if (r->filename[strlen(r->filename) - 1] != '/') {
            r->filename = apr_pstrcat(r->pool, r->filename, "/", NULL);
        }
        return index_directory(r, d);
    }
    else {
        const char *index_names = apr_table_get(r->notes, "dir-index-names");

        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01276)
                      "Cannot serve directory %s: No matching DirectoryIndex (%s) found, and "
                      "server-generated directory index forbidden by "
                      "Options directive",
                       r->filename,
                       index_names ? index_names : "none");
        return HTTP_FORBIDDEN;
    }
}

static void register_hooks(apr_pool_t *p)
{
    ap_hook_handler(handle_autoindex,NULL,NULL,APR_HOOK_MIDDLE);
}

AP_DECLARE_MODULE(autoindex) =
{
    STANDARD20_MODULE_STUFF,
    create_autoindex_config,    /* dir config creater */
    merge_autoindex_configs,    /* dir merger --- default is to override */
    NULL,                       /* server config */
    NULL,                       /* merge server config */
    autoindex_cmds,             /* command apr_table_t */
    register_hooks              /* register hooks */
};
