mod_autoindex.c revision 9f402e84beae3849cc8841bef1de82a644cd8758
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse/* ====================================================================
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * The Apache Software License, Version 1.1
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * reserved.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Redistribution and use in source and binary forms, with or without
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * modification, are permitted provided that the following conditions
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * are met:
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 1. Redistributions of source code must retain the above copyright
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * notice, this list of conditions and the following disclaimer.
33bdcae1f7a1a65e351dda2a766a0cf28b1e695dnd * 2. Redistributions in binary form must reproduce the above copyright
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * notice, this list of conditions and the following disclaimer in
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * the documentation and/or other materials provided with the
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * distribution.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 3. The end-user documentation included with the redistribution,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * if any, must include the following acknowledgment:
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * "This product includes software developed by the
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Apache Software Foundation (http://www.apache.org/)."
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Alternately, this acknowledgment may appear in the software itself,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * if and wherever such third-party acknowledgments normally appear.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 4. The names "Apache" and "Apache Software Foundation" must
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * not be used to endorse or promote products derived from this
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * software without prior written permission. For written
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * permission, please contact apache@apache.org.
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * 5. Products derived from this software may not be called "Apache",
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * nor may "Apache" appear in their name, without prior written
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * permission of the Apache Software Foundation.
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * SUCH DAMAGE.
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * ====================================================================
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * This software consists of voluntary contributions made by many
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * individuals on behalf of the Apache Software Foundation. For more
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * information on the Apache Software Foundation, please see
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * Portions of this software are based upon public domain software
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * originally written at the National Center for Supercomputing Applications,
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * University of Illinois, Urbana-Champaign.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * mod_autoindex.c: Handles the on-the-fly html index generation
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Rob McCool
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Adapted to Apache by rst.
579fd9e90990eee18b5e504eb4c0d2ce18f76208aaron * Version sort added by Martin Pool <mbp@humbug.org.au>.
05413593151a238718198cc04ca849b2426be106rse/****************************************************************
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Handling configuration directives...
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Define keys for sorting.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse#define K_SIZE 'S' /* Size (absolute, not as displayed) */
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * These are the dimensions of the default icons supplied with Apache.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Other default dimensions.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrsetypedef struct ai_desc_t {
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rsetypedef struct autoindex_config_struct {
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Return true if the specified string refers to the parent directory (i.e.,
87a1c79b7b37702a254920ca5214fb282a4fb085dougm * matches ".." or "../"). Hopefully this one call is significantly less
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * expensive than multiple strcmp() calls.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Now, IFF the first two bytes are dots, and the third byte is either
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * EOS (\0) or a slash followed by EOS, we have a match.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * This routine puts the standard HTML header at the top of the index page.
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * We include the DOCTYPE because we may be using features therefrom (i.e.,
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * HEIGHT and WIDTH attributes on the icons if we're FancyIndexing).
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrsestatic void push_item(apr_array_header_t *arr, char *type, const char *to,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse p->apply_path = apr_pstrcat(arr->pool, path, "*", NULL);
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse else if (to) {
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrsestatic const char *add_alt(cmd_parms *cmd, void *d, const char *alt,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse const char *to)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse push_item(((autoindex_config_rec *) d)->alt_list, cmd->info, to,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrsestatic const char *add_icon(cmd_parms *cmd, void *d, const char *icon,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse const char *to)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return "missing closing paren";
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse push_item(((autoindex_config_rec *) d)->icon_list, cmd->info, to,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Add description text for a filename pattern. If the pattern has
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * wildcards already (or we need to add them), add leading and
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * trailing wildcards to it to ensure substring processing. If the
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * pattern contains a '/' anywhere, force wildcard matching mode,
421d9002d73db52972bcca8f4497fe5d603b6b8eaaron * add a slash to the prefix so that "bar/bletch" won't be matched
421d9002d73db52972bcca8f4497fe5d603b6b8eaaron * by "foobar/bletch", and make a note that there's a delimiter;
421d9002d73db52972bcca8f4497fe5d603b6b8eaaron * the matching routine simplifies to just the actual filename
184f5da95d14895f7f33c90b8b8f70653afb0d92wrowe * whenever it can. This allows definitions in parent directories
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * to be made for files in subordinate ones using relative paths.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Absent a strcasestr() function, we have to force wildcards on
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * systems for which "AAA" and "aaa" mean the same file.
a0e0d20b666cfc453ac76506079eb50e03997eefdougmstatic const char *add_desc(cmd_parms *cmd, void *d, const char *desc,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm const char *to)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm autoindex_config_rec *dcfg = (autoindex_config_rec *) d;
a0e0d20b666cfc453ac76506079eb50e03997eefdougm desc_entry = (ai_desc_t *) apr_array_push(dcfg->desc_list);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm desc_entry->full_path = (ap_strchr_c(to, '/') == NULL) ? 0 : 1;
a0e0d20b666cfc453ac76506079eb50e03997eefdougm desc_entry->pattern = apr_pstrcat(dcfg->desc_list->pool,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm desc_entry->pattern = apr_pstrdup(dcfg->desc_list->pool, to);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm desc_entry->description = apr_pstrdup(dcfg->desc_list->pool, desc);
a0e0d20b666cfc453ac76506079eb50e03997eefdougmstatic const char *add_ignore(cmd_parms *cmd, void *d, const char *ext)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm push_item(((autoindex_config_rec *) d)->ign_list, 0, ext, cmd->path, NULL);
a0e0d20b666cfc453ac76506079eb50e03997eefdougmstatic const char *add_header(cmd_parms *cmd, void *d, const char *name)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm push_item(((autoindex_config_rec *) d)->hdr_list, 0, NULL, cmd->path,
a0e0d20b666cfc453ac76506079eb50e03997eefdougmstatic const char *add_readme(cmd_parms *cmd, void *d, const char *name)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm push_item(((autoindex_config_rec *) d)->rdme_list, 0, NULL, cmd->path,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm/* A legacy directive, FancyIndexing is superseded by the IndexOptions
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * keyword. But for compatibility..
a0e0d20b666cfc453ac76506079eb50e03997eefdougmstatic const char *fancy_indexing(cmd_parms *cmd, void *d, int arg)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm return "FancyIndexing directive conflicts with existing "
a0e0d20b666cfc453ac76506079eb50e03997eefdougm "IndexOptions None";
a0e0d20b666cfc453ac76506079eb50e03997eefdougm newopts = (arg ? (curopts | FANCY_INDEXING) : (curopts & ~FANCY_INDEXING));
dd7c683f683624b082d430935b594df7406782c2dougmstatic const char *add_opts(cmd_parms *cmd, void *d, const char *optstr)
22357f10585a847ebf7b084cbe1db07ba071aeb6dougm autoindex_config_rec *d_cfg = (autoindex_config_rec *) d;
dd7c683f683624b082d430935b594df7406782c2dougm while (optstr[0]) {
b40799adcfd0f0a2a465c2934585986f7bbc9bbcwrowe return "Cannot combine '+' or '-' with 'None' keyword";
98f81eac9530d487f05013cda9df99755bb59689trawick return "Cannot combine '-' with IconWidth=n";
3c65aa88903de7330a07e133dfda779842fadad4wrowe return "Cannot combine '-' with IconHeight=n";
3c65aa88903de7330a07e133dfda779842fadad4wrowe return "NameWidth with no value may only appear as "
8464a9c46b967001e38fe3c8afff51a649e9de51dougm "'-NameWidth'";
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm return "Cannot combine '-' with NameWidth=n";
opts_add = 0;
opts_remove = 0;
return NULL;
const char *key)
return NULL;
{NULL}
return (void *) new;
return new;
struct ent {
char *name;
char *icon;
char *alt;
char *desc;
char key;
if (!*(p->apply_to)) {
return p->data;
return p->data;
else if (!path_only) {
if (!content_encoding) {
if (content_type
p->apply_to)) {
return p->data;
p->apply_to)) {
return p->data;
return NULL;
request_rec r;
* Look through the list of pattern/description pairs and return the first one
#ifdef CASE_BLIND_FILESYSTEM
#define MATCH_FLAGS 0
const char *filename_only;
const char *filename;
int found;
if (found) {
return NULL;
char *tt;
tt++;
char *ap;
ap++;
#ifndef CASE_BLIND_FILESYSTEM
int ch;
apr_size_t i, c, n;
while (!apr_file_eof(f)) {
n = sizeof(char) * AP_IOBUFSIZE;
char *title)
* text/anything-else. The former is allowed to be processed for
emit_amble = 0;
emit_H1 = 0;
if (! suppress_amble) {
emit_amble = 0;
do_emit_plain(r, f);
apr_file_close(f);
emit_H1 = 0;
if (emit_amble) {
if (emit_H1) {
int suppress_post = 0;
int suppress_sig = 0;
* text/anything-else. The former is allowed to be processed for
do_emit_plain(r, f);
apr_file_close(f);
if (!suppress_sig) {
if (!suppress_post) {
apr_size_t n;
return NULL;
&& !r->content_encoding) {
return NULL;
return NULL;
for (x = 0, p = 0; titlebuf[x]; x++) {
if (!find[++p]) {
for (y = x; titlebuf[y]; y++) {
return NULL;
int autoindex_opts,
char direction)
struct ent *p;
return (NULL);
return (NULL);
if (p->lm < 0) {
p->lm = 0;
int autoindex_opts)
if (!desc[x]) {
maxsize = 0;
--maxsize;
maxsize = 0;
--maxsize;
return desc;
int reverse;
if (!nosort) {
char *tp;
int name_width;
char *name_scratch;
char *pad_scratch;
if (t > name_width) {
name_width = t;
if (d->icon_width)
if (d->icon_height)
int nwidth;
ap_getparents(t);
t2 = t;
: d->default_icon),
if (d->icon_width)
if (d->icon_height)
NULL);
autoindex_opts), r);
int result = 0;
case K_LAST_MOD:
case K_SIZE:
case K_DESC:
if (result) {
return result;
char *title_endp;
int num_ent = 0, x;
const char *qstring;
char keyid;
char direction;
return HTTP_FORBIDDEN;
ap_set_etag(r);
if (r->header_only) {
if (p != NULL) {
head = p;
num_ent++;
if (num_ent > 0) {
p = head;
ar[x++] = p;
p = p->next;
(int (*)(const void *, const void *)) dsortf);
int allow_opts;
return DECLINED;
return DECLINED;
return index_directory(r, d);
return HTTP_FORBIDDEN;