mod_autoindex.c revision 404e2e1f8ad30c2d996f5fb6b3a9a4a4a14a004b
3802a3d3d7af51ddff31943d5514382f01265770Lennart Poettering/* ====================================================================
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * The Apache Software License, Version 1.1
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Copyright (c) 2000 The Apache Software Foundation. All rights
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Redistribution and use in source and binary forms, with or without
5de0ccffcc4a5a946102a14e0b0e681d964e3225Zbigniew Jędrzejewski-Szmek * modification, are permitted provided that the following conditions
5de0ccffcc4a5a946102a14e0b0e681d964e3225Zbigniew Jędrzejewski-Szmek * 1. Redistributions of source code must retain the above copyright
5de0ccffcc4a5a946102a14e0b0e681d964e3225Zbigniew Jędrzejewski-Szmek * notice, this list of conditions and the following disclaimer.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * 2. Redistributions in binary form must reproduce the above copyright
5de0ccffcc4a5a946102a14e0b0e681d964e3225Zbigniew Jędrzejewski-Szmek * notice, this list of conditions and the following disclaimer in
5de0ccffcc4a5a946102a14e0b0e681d964e3225Zbigniew Jędrzejewski-Szmek * the documentation and/or other materials provided with the
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * 3. The end-user documentation included with the redistribution,
5de0ccffcc4a5a946102a14e0b0e681d964e3225Zbigniew Jędrzejewski-Szmek * if any, must include the following acknowledgment:
5de0ccffcc4a5a946102a14e0b0e681d964e3225Zbigniew Jędrzejewski-Szmek * "This product includes software developed by the
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Apache Software Foundation (http://www.apache.org/)."
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Alternately, this acknowledgment may appear in the software itself,
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * if and wherever such third-party acknowledgments normally appear.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * 4. The names "Apache" and "Apache Software Foundation" must
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * not be used to endorse or promote products derived from this
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * software without prior written permission. For written
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * permission, please contact apache@apache.org.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * 5. Products derived from this software may not be called "Apache",
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * nor may "Apache" appear in their name, without prior written
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * permission of the Apache Software Foundation.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * ====================================================================
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * This software consists of voluntary contributions made by many
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * individuals on behalf of the Apache Software Foundation. For more
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * information on the Apache Software Foundation, please see
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Portions of this software are based upon public domain software
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * originally written at the National Center for Supercomputing Applications,
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * University of Illinois, Urbana-Champaign.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * mod_autoindex.c: Handles the on-the-fly html index generation
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Adapted to Apache by rst.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmekmodule MODULE_VAR_EXPORT autoindex_module;
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek/****************************************************************
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Handling configuration directives...
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering#define FANCY_INDEXING 1 /* Indexing options */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * Define keys for sorting.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering#define K_NAME 'N' /* Sort by file name (default) */
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek#define K_LAST_MOD 'M' /* Last modification date */
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek#define K_SIZE 'S' /* Size (absolute, not as displayed) */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * These are the dimensions of the default icons supplied with Apache.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * Other default dimensions.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poetteringtypedef struct ai_desc_t {
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmekstatic char c_by_encoding, c_by_type, c_by_path;
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek#define BY_ENCODING &c_by_encoding
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * Return true if the specified string refers to the parent directory (i.e.,
8474b70c3a3842cdf3d51f331dd117ab6421f6d0Zbigniew Jędrzejewski-Szmek * matches ".." or "../"). Hopefully this one call is significantly less
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * expensive than multiple strcmp() calls.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmekstatic ap_inline int is_parent(const char *name)
8474b70c3a3842cdf3d51f331dd117ab6421f6d0Zbigniew Jędrzejewski-Szmek * Now, IFF the first two bytes are dots, and the third byte is either
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * EOS (\0) or a slash followed by EOS, we have a match.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek || ((name[2] == '/') && (name[3] == '\0')))) {
8474b70c3a3842cdf3d51f331dd117ab6421f6d0Zbigniew Jędrzejewski-Szmek * This routine puts the standard HTML header at the top of the index page.
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek * We include the DOCTYPE because we may be using features therefrom (i.e.,
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt * HEIGHT and WIDTH attributes on the icons if we're FancyIndexing).
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmekstatic void emit_preamble(request_rec *r, char *title)
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek "<HTML>\n <HEAD>\n <TITLE>Index of ", title,
8474b70c3a3842cdf3d51f331dd117ab6421f6d0Zbigniew Jędrzejewski-Szmek "</TITLE>\n </HEAD>\n <BODY>\n", NULL);
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmekstatic void push_item(ap_array_header_t *arr, char *type, char *to, char *path,
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek struct item *p = (struct item *) ap_push_array(arr);
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering p->data = data ? ap_pstrdup(arr->cont, data) : NULL;
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering p->apply_path = ap_pstrcat(arr->cont, path, "*", NULL);
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering if ((type == BY_PATH) && (!ap_is_matchexp(to))) {
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek p->apply_to = ap_pstrcat(arr->cont, "*", to, NULL);
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmekstatic const char *add_alt(cmd_parms *cmd, void *d, char *alt, char *to)
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek if (!strcmp(to, "**DIRECTORY**")) {
edf2573743b25273bee020230a60f1a054b8ec60Zbigniew Jędrzejewski-Szmek push_item(((autoindex_config_rec *) d)->alt_list, cmd->info, to,
char *alt;
return NULL;
#ifdef CASE_BLIND_FILESYSTEM
#define WILDCARDS_REQUIRED 0
return NULL;
return NULL;
name);
return NULL;
name);
return NULL;
int curopts;
int newopts;
return NULL;
int opts;
int opts_add;
int opts_remove;
char action;
while (optstr[0]) {
int option = 0;
action = *(w++);
opts_add = 0;
opts_remove = 0;
opts_add = 0;
opts_remove = 0;
return NULL;
char *key)
return NULL;
{NULL}
return (void *) new;
return new;
struct ent {
char *name;
char *icon;
char *alt;
char *desc;
int ascending;
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 i, c, ch;
ap_ssize_t n;
while (!ap_eof(f)) {
n = sizeof(char) * 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);
ap_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);
ap_close(f);
if (!suppress_sig) {
if (!suppress_post) {
ap_ssize_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;
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;
d->icon_height,
d->icon_width
int nwidth;
ap_getparents(t);
t2 = t;
: d->default_icon),
NULL);
autoindex_opts), r);
int result = 0;
case K_LAST_MOD:
case K_SIZE:
case K_DESC:
if (result) {
return result;
char *title_endp;
ap_dir_t *d;
int num_ent = 0, x;
const char *qstring;
char keyid;
char direction;
return HTTP_FORBIDDEN;
if (r->header_only) {
ap_closedir(d);
char *d_name;
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);
ap_closedir(d);
return DECLINED;
return index_directory(r, d);
return HTTP_FORBIDDEN;
{NULL}