You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2001/08/07 06:33:58 UTC

cvs commit: httpd-2.0/docs/manual/mod mod_autoindex.html

wrowe       01/08/06 21:33:58

  Modified:    .        CHANGES
               modules/generators mod_autoindex.c
               docs/manual/mod mod_autoindex.html
  Log:
  Formatted output changes only...
  
       Introduced new mod_autoindex IndexOptions flags; SuppressIcon to
       drop the icon column and SuppressRules to drop the <hr> elements.
       These are necessary for HTML 3.2 final formatting rules.
  
       Introduced HTMLTable to create rudimentary HTML table listings
       (implies FancyIndexing).  Necessary for alternate charsets, since
       the columns are borked by multibyte characters.
  
       Re-Introduced the mod_autoindex IndexOptions flag TrackModified
       from Apache 1.3.15.  This is needed for two reasons, first, given
       multiple machines within a server farm, ETags and Last-Modified
       stamps won't correspond from machine to machine, and second, many
       Unixes don't capture changes to the date or time stamp of existing
       files, since these don't modify the dirent itself.
       [Originally for 1.3 by me]
  
       Re-Introduced the mod_autoindex InextOptions flag FoldersFirst
       and DirectoryWidth options from Apache 1.3.10.
       [Originally for 1.3 by Ken Coar]
  
  Revision  Changes    Path
  1.277     +22 -1     httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.276
  retrieving revision 1.277
  diff -u -r1.276 -r1.277
  --- CHANGES	2001/08/06 22:59:22	1.276
  +++ CHANGES	2001/08/07 04:33:58	1.277
  @@ -1,7 +1,28 @@
   Changes with Apache 2.0.23-dev
   
  +  *) Introduced new mod_autoindex IndexOptions flags; SuppressIcon to 
  +     drop the icon column, SuppressRules to drop the <hr> elements, 
  +     and HTMLTable to create rudimentary HTML table listings (implies 
  +     FancyIndexing).  [William Rowe]
  +
  +  *) Re-Introduced the mod_autoindex IndexOptions flag TrackModified
  +     from Apache 1.3.15.  This is needed for two reasons, first, given
  +     multiple machines within a server farm, ETags and Last-Modified 
  +     stamps won't correspond from machine to machine, and second, many 
  +     Unixes don't capture changes to the date or time stamp of existing 
  +     files, since these don't modify the dirent itself.  [William Rowe]
  +
  +  *) Re-Introduced the mod_autoindex InextOptions flag FoldersFirst 
  +     and DirectoryWidth options from Apache 1.3.10. 
  +     [William Rowe, Ken Coar]
  +
  +  *) Eliminated FancyIndexing directive, depricated early in Apache
  +     1.3 by the IndexOptions FancyIndexing syntax.  [William Rowe]
  +
     *) mod_autoindex now excludes any file names that would result in
  -     an error, other than a success or redirect.  [William Rowe]
  +     an error, other than a success or redirect.  Also optimized
  +     the parent directory, always included except in the URI '/'.
  +     [William Rowe]
   
     *) Refactored mod_negotiation and mod_mime to help mod_dir accept
        negotiated index pages, and prevent the server from defaulting
  
  
  
  1.80      +336 -109  httpd-2.0/modules/generators/mod_autoindex.c
  
  Index: mod_autoindex.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/generators/mod_autoindex.c,v
  retrieving revision 1.79
  retrieving revision 1.80
  diff -u -r1.79 -r1.80
  --- mod_autoindex.c	2001/08/03 21:44:34	1.79
  +++ mod_autoindex.c	2001/08/07 04:33:58	1.80
  @@ -94,25 +94,22 @@
    * Handling configuration directives...
    */
   
  -#define HRULE 1
  -#define NO_HRULE 0
  -#define FRONT_MATTER 1
  -#define END_MATTER 0
  -
  -#define FANCY_INDEXING 1	/* Indexing options */
  -#define ICONS_ARE_LINKS 2
  -#define SCAN_HTML_TITLES 4
  -#define SUPPRESS_LAST_MOD 8
  -#define SUPPRESS_SIZE 16
  -#define SUPPRESS_DESC 32
  -#define SUPPRESS_PREAMBLE 64
  -#define SUPPRESS_COLSORT 128
  -#define NO_OPTIONS 256
  -#define VERSION_SORT	512
  +#define NO_OPTIONS          0x0001  /* Indexing options */
  +#define ICONS_ARE_LINKS     0x0002
  +#define SCAN_HTML_TITLES    0x0004
  +#define SUPPRESS_ICON       0x0008
  +#define SUPPRESS_LAST_MOD   0x0010
  +#define SUPPRESS_SIZE       0x0020
  +#define SUPPRESS_DESC       0x0040
  +#define SUPPRESS_PREAMBLE   0x0080
  +#define SUPPRESS_COLSORT    0x0100
  +#define SUPPRESS_RULES      0x0200
  +#define FOLDERS_FIRST	    0x0400
  +#define VERSION_SORT	    0x0800
  +#define TRACK_MODIFIED      0x1000
  +#define FANCY_INDEXING      0x2000
  +#define TABLE_INDEXING      0x4000
   
  -#define K_PAD 1
  -#define K_NOPAD 0
  -
   #define K_NOADJUST 0
   #define K_ADJUST 1
   #define K_UNSET 2
  @@ -138,6 +135,7 @@
    * Other default dimensions.
    */
   #define DEFAULT_NAME_WIDTH 23
  +#define DEFAULT_DESC_WIDTH 23
   
   struct item {
       char *type;
  @@ -161,9 +159,12 @@
       int decremented_opts;
       int name_width;
       int name_adjust;
  +    int desc_width;
  +    int desc_adjust;
       int icon_width;
       int icon_height;
  -    char *default_order;
  +    char default_keyid;
  +    char default_direction;
   
       apr_array_header_t *icon_list;
       apr_array_header_t *alt_list;
  @@ -361,12 +362,21 @@
   	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, "ScanHTMLTitles")) {
   	    option = SCAN_HTML_TITLES;
   	}
  +	else if (!strcasecmp(w, "SuppressIcon")) {
  +	    option = SUPPRESS_ICON;
  +	}
   	else if (!strcasecmp(w, "SuppressLastModified")) {
   	    option = SUPPRESS_LAST_MOD;
   	}
  @@ -382,6 +392,12 @@
           else if (!strcasecmp(w, "SuppressColumnSorting")) {
               option = SUPPRESS_COLSORT;
   	}
  +        else if (!strcasecmp(w, "SuppressRules")) {
  +            option = SUPPRESS_RULES;
  +	}
  +        else if (!strcasecmp(w, "TrackModified")) { 
  +            option = TRACK_MODIFIED; 
  +        } 
           else if (!strcasecmp(w, "VersionSort")) {
               option = VERSION_SORT;
   	}
  @@ -439,13 +455,38 @@
   	    else {
   		int width = atoi(&w[10]);
   
  -		if (width < 5) {
  +		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 {
   	    return "Invalid directory indexing option";
   	}
  @@ -475,42 +516,35 @@
   static const char *set_default_order(cmd_parms *cmd, void *m, const char *direction,
   				     const char *key)
   {
  -    char temp[4];
       autoindex_config_rec *d_cfg = (autoindex_config_rec *) m;
   
  -    apr_cpystrn(temp, "k=d", sizeof(temp));
       if (!strcasecmp(direction, "Ascending")) {
  -	temp[2] = D_ASCENDING;
  +	d_cfg->default_direction = D_ASCENDING;
       }
       else if (!strcasecmp(direction, "Descending")) {
  -	temp[2] = D_DESCENDING;
  +	d_cfg->default_direction = D_DESCENDING;
       }
       else {
   	return "First keyword must be 'Ascending' or 'Descending'";
       }
   
       if (!strcasecmp(key, "Name")) {
  -	temp[0] = K_NAME;
  +	d_cfg->default_keyid = K_NAME;
       }
       else if (!strcasecmp(key, "Date")) {
  -	temp[0] = K_LAST_MOD;
  +	d_cfg->default_keyid = K_LAST_MOD;
       }
       else if (!strcasecmp(key, "Size")) {
  -	temp[0] = K_SIZE;
  +	d_cfg->default_keyid = K_SIZE;
       }
       else if (!strcasecmp(key, "Description")) {
  -	temp[0] = K_DESC;
  +	d_cfg->default_keyid = K_DESC;
       }
       else {
   	return "Second keyword must be 'Name', 'Date', 'Size', or "
   	    "'Description'";
       }
   
  -    if (d_cfg->default_order == NULL) {
  -	d_cfg->default_order = apr_palloc(cmd->pool, 4);
  -	d_cfg->default_order[3] = '\0';
  -    }
  -    apr_cpystrn(d_cfg->default_order, temp, sizeof(temp));
       return NULL;
   }
   
  @@ -559,6 +593,8 @@
       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));
  @@ -568,7 +604,8 @@
       new->opts = 0;
       new->incremented_opts = 0;
       new->decremented_opts = 0;
  -    new->default_order = NULL;
  +    new->default_keyid = '\0';
  +    new->default_direction = '\0';
   
       return (void *) new;
   }
  @@ -646,9 +683,22 @@
   	new->name_width = add->name_width;
   	new->name_adjust = add->name_adjust;
       }
  -
  -    new->default_order = (add->default_order != NULL)
  -	? add->default_order : base->default_order;
  +    /* 
  +     * 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;
   }
   
  @@ -669,6 +719,7 @@
       struct ent *next;
       int ascending, version_sort;
       char key;
  +    int isdir;
   };
   
   static char *find_item(request_rec *r, apr_array_header_t *list, int path_only)
  @@ -1198,14 +1249,17 @@
       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;
  - 
  -    if (autoindex_opts & FANCY_INDEXING) 
  +
  +    if (autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING))
       {
   	p->lm = rr->finfo.mtime;
   	if (rr->finfo.filetype == APR_DIR) {
  +            if (autoindex_opts & FOLDERS_FIRST)
  +                p->isdir = 1;
   	    if (!(p->icon = find_icon(d, rr, 1))) {
   		p->icon = find_default_icon(d, "^^DIRECTORY^^");
   	    }
  @@ -1241,19 +1295,29 @@
   }
   
   static char *terminate_description(autoindex_config_rec *d, char *desc,
  -				   int autoindex_opts)
  +				   int autoindex_opts, int desc_width)
   {
  -    int maxsize = 23;
  +    int maxsize = desc_width;
       register int x;
   
  -    if (autoindex_opts & SUPPRESS_LAST_MOD) {
  -	maxsize += 19;
  -    }
  -    if (autoindex_opts & SUPPRESS_SIZE) {
  -	maxsize += 7;
  +    /* 
  +     * 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++) {
  +    for (x = 0; desc[x] && ((maxsize > 0) || (desc[x] == '<')); x++) {
   	if (desc[x] == '<') {
   	    while (desc[x] != '>') {
   		if (!desc[x]) {
  @@ -1320,8 +1384,10 @@
       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);
       if (name[0] == '\0') {
  @@ -1329,30 +1395,92 @@
       }
   
       name_width = d->name_width;
  -    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;
  +    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 & FANCY_INDEXING) {
  -	ap_rputs("<pre>", r);
  -	if ((tp = find_default_icon(d, "^^BLANKICON^^"))) {
  -	    ap_rvputs(r, "<img src=\"", ap_escape_html(scratch, tp),
  -		   "\" 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);
  -	    ap_rputs(" /> ", r);
  +    if (autoindex_opts & TABLE_INDEXING) {
  +        int cols = 1;
  +	ap_rputs("<table><tr>", r);
  +	if (!(autoindex_opts & SUPPRESS_ICON)) {
  +            ap_rputs("<th title=\"Icon\">", r);
  +	    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);
  +	        ap_rputs(" /></th>", r);
  +            }
  +            else
  +                ap_rputs("&nbsp;</th>", r);
  +            ++cols;
  +        }
  +        ap_rputs("<th>", r);
  +        emit_link(r, "Name", K_NAME, keyid, direction, static_columns);
  +	if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
  +            ap_rputs("</th><th>", r);
  +	    emit_link(r, "Last modified", K_LAST_MOD, keyid, direction, static_columns);
  +	    ++cols;
   	}
  +	if (!(autoindex_opts & SUPPRESS_SIZE)) {
  +            ap_rputs("</th><th>", r);
  +	    emit_link(r, "Size", K_SIZE, keyid, direction, static_columns);
  +	    ++cols;
  +	}
  +	if (!(autoindex_opts & SUPPRESS_DESC)) {
  +            ap_rputs("</th><th>", r);
  +	    emit_link(r, "Description", K_DESC, keyid, direction, static_columns);
  +	    ++cols;
  +	}
  +        if (!(autoindex_opts & SUPPRESS_RULES))
  +            breakrow = apr_psprintf(r->pool, "<tr><th colspan=\"%d\">"
  +                                             "<hr /></th></tr>\n", cols);
  +        else
  +            breakrow = "";
  +	ap_rvputs(r, "</th></tr>", 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);
  +	        ap_rputs(" /> ", r);
  +	    }
  +            else
  +	        ap_rputs("      ", r);
  +        }
           emit_link(r, "Name", K_NAME, keyid, direction, static_columns);
   	ap_rputs(pad_scratch + 4, r);
   	/*
  @@ -1372,7 +1500,8 @@
               emit_link(r, "Description", K_DESC, keyid, direction,
                         static_columns);
   	}
  -	ap_rputs("<hr />", r);
  +	if (!(autoindex_opts & SUPPRESS_RULES))
  +            ap_rputs("<hr />", r);
       }
       else {
   	ap_rputs("<ul>", r);
  @@ -1392,27 +1521,108 @@
           else
   	    t2 = t;
   
  -	if (autoindex_opts & FANCY_INDEXING) {
  -	    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);
  -		ap_rputs(" />", r);
  +        if (autoindex_opts & TABLE_INDEXING) {
  +	    if (!(autoindex_opts & SUPPRESS_ICON)) {
  +	        ap_rputs("<tr><td valign=\"top\">", r);
  +                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);
  +		    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><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><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[MAX_STRING_LEN];
  +		    apr_exploded_time_t ts;
  +                    apr_explode_localtime(&ts, ar[x]->lm);
  +		    apr_strftime(time_str, &rv, MAX_STRING_LEN, 
  +                                 "</td><td align=\"right\">%d-%b-%Y %H:%M  ", &ts);
  +		    ap_rputs(time_str, r);
  +		}
  +		else {
  +		    ap_rputs("</td><td>&nbsp;", r);
  +		}
   	    }
  -	    if (autoindex_opts & ICONS_ARE_LINKS) {
  -		ap_rputs("</a>", r);
  +	    if (!(autoindex_opts & SUPPRESS_SIZE)) {
  +                char buf[5];
  +		ap_rvputs(r, "</td><td 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>", ar[x]->desc, NULL);
  +                    else
  +		        ap_rvputs(r, "</td><td>", 
  +                                  terminate_description(d, ar[x]->desc,
  +						        autoindex_opts, 
  +                                                        name_width), NULL);
  +		}
  +	    }
  +            else
  +                ap_rputs("</td><td>&nbsp;", r);
  +            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);
  +		    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);
  @@ -1423,7 +1633,7 @@
   	      t2 = name_scratch;
   	      nwidth = name_width;
   	    }
  -	    ap_rvputs(r, " <a href=\"", anchor, "\">",
  +	    ap_rvputs(r, "<a href=\"", anchor, "\">",
   	      ap_escape_html(scratch, t2), "</a>", pad_scratch + nwidth,
   	      NULL);
   	    /*
  @@ -1452,21 +1662,28 @@
   	    if (!(autoindex_opts & SUPPRESS_DESC)) {
   		if (ar[x]->desc) {
   		    ap_rputs(terminate_description(d, ar[x]->desc,
  -						   autoindex_opts), r);
  +						   autoindex_opts,
  +                                                   name_width), r);
   		}
   	    }
  +	    ap_rputc('\n', r);
   	}
   	else {
   	    ap_rvputs(r, "<li><a href=\"", anchor, "\"> ", t2,
  -		         "</a></li>", NULL);
  +		         "</a></li>\n", NULL);
   	}
  -	ap_rputc('\n', r);
       }
  -    if (autoindex_opts & FANCY_INDEXING) {
  -	ap_rputs("<hr /></pre>\n", r);
  +    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 /></pre>\n", r);
  +        else
  +            ap_rputs("</pre>\n", r);
  +    }
       else {
  -	ap_rputs("</ul>", r);
  +	ap_rputs("</ul>\n", r);
       }
   }
   
  @@ -1491,6 +1708,13 @@
       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.
  @@ -1566,15 +1790,25 @@
   #else
       r->content_type = "text/html";
   #endif
  -    ap_update_mtime(r, r->finfo.mtime);
  -    ap_set_last_modified(r);
  -    ap_set_etag(r);
  -
  +    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;
  +
       /* Spew HTML preamble */
   
       title_endp = title_name + strlen(title_name) - 1;
  @@ -1594,27 +1828,20 @@
        * IndexOrderDefault directive (if there is one); otherwise,
        * we fall back to ascending by name.
        */
  -    qstring = r->args;
  -    if ((autoindex_opts & SUPPRESS_COLSORT)
  -	|| ((qstring == NULL) || (*qstring == '\0'))) {
  -	qstring = autoindex_conf->default_order;
  -    }
  +    if (!(autoindex_opts & SUPPRESS_COLSORT))
  +        qstring = r->args;
  +    else
  +        qstring = NULL;
  +
       /*
        * If there is no specific ordering defined for this directory,
  -     * default to ascending by filename.
  +     * take the defaults above.
        */
  -    if ((qstring == NULL) || (*qstring == '\0')) {
  -	keyid = K_NAME;
  -	direction = D_ASCENDING;
  -    }
  -    else {
  +    if ((qstring != NULL) && (*qstring != '\0')) {
   	keyid = *qstring;
   	ap_getword(r->pool, &qstring, '=');
   	if (qstring != '\0') {
   	    direction = *qstring;
  -	}
  -	else {
  -	    direction = D_ASCENDING;
   	}
       }
   
  
  
  
  1.39      +145 -130  httpd-2.0/docs/manual/mod/mod_autoindex.html
  
  Index: mod_autoindex.html
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/docs/manual/mod/mod_autoindex.html,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- mod_autoindex.html	2001/08/03 00:33:24	1.38
  +++ mod_autoindex.html	2001/08/07 04:33:58	1.39
  @@ -15,7 +15,14 @@
   <!--#include virtual="header.html" -->
   <H1 ALIGN="CENTER">Module mod_autoindex</H1>
   
  -This module provides for automatic directory indexing.
  +The module mod_autoindex generates directory indexes, automatically, similar to 
  +the Unix <em>ls</em> command or the Win32 <em>dir</em> shell command.
  +<P>
  +
  +Automatic index generation must be enabled with by the <CODE>Options</CODE>
  +directive's <CODE><I>[+]</I>Indexes</CODE> option. See the
  +<A HREF="core.html#options"><CODE>Options</CODE></a> directive for
  +more details.
   
   <P><A
   HREF="module-dict.html#Status"
  @@ -35,7 +42,6 @@
   
   
   <H2>Summary</H2>
  -<!-- XXX: This should mention the necessity of Options +Indexes -->
   The index of a directory can come from one of two sources:
   <UL>
   
  @@ -55,14 +61,20 @@
   The two functions are separated so that you can completely remove
   (or replace) automatic index generation should you want to.
   <P>
  +Automatic index generation is enabled with using 
  +<CODE>Options +Indexes</CODE>. See the
  +<A HREF="core.html#options"><CODE>Options</CODE></a> directive for
  +more details.
  +<P>
   If the <SAMP><A HREF="#indexoptions:fancyindexing">FancyIndexing</A></SAMP> 
   option is given  with the <A HREF="#indexoptions"><SAMP>IndexOptions</SAMP></A>
   directive, the column headers are links that control the
   order of the display.  If you select a header link, the
   listing will be regenerated, sorted by the values in that
   column.  Selecting the same header repeatedly toggles
  -between ascending and descending order.  This can be suppressed with
  -<A HREF="#indexoptions">IndexOptions</A> <SAMP>SuppressColumnSorting</SAMP>.
  +between ascending and descending order.    These column header links are
  +suppressed with <A HREF="#indexoptions">IndexOptions</A> directive's
  +<SAMP>SuppressColumnSorting</SAMP> option.
   </P>
   <P>
   Note that when the display is sorted by &quot;Size&quot;,
  @@ -72,7 +84,23 @@
   order) even though they both are shown as &quot;1K&quot;.
   </P>
   
  +<H2>Autoindex Request Query Arguments</H2>
   
  +The column sorting headers are self-referencing hyperlinks that add the following
  +query options, they may be added to any request for the directory resource, where
  +They have no effect if the  <A HREF="#indexoptions">IndexOptions</A> directive's 
  +<SAMP>SuppressColumnSorting</SAMP> option is in effect.  In the list below, 
  +<EM>S</EM> is the desired sort order, either <SAMP>A</SAMP> for ascending or 
  +<SAMP>D</SAMP> for descending sequence.  
  +
  +<ul>
  +<li><SAMP>N=<EM>S</EM></SAMP> sorts the directory by file name
  +<li><SAMP>M=<EM>S</EM></SAMP> sorts the directory by last-modified date, then file name
  +<li><SAMP>S=<EM>S</EM></SAMP> sorts the directory by size, then file name
  +<li><SAMP>D=<EM>S</EM></SAMP> sorts the directory by description, then file name
  +</ul>
  +
  +
   <H2>Directives</H2>
   
   <UL>
  @@ -121,8 +149,8 @@
    REL="Help"
   ><STRONG>Module:</STRONG></A> mod_autoindex<P>
   
  -This provides the alternate text to display for a file, instead of an icon, for
  -<SAMP><A HREF="#indexoptions:fancyindexing">FancyIndexing</A></SAMP>. <EM>File</EM> 
  +<EM>AddAlt</EM> provides the alternate text to display for a file, instead of an icon, 
  +for <SAMP><A HREF="#indexoptions:fancyindexing">FancyIndexing</A></SAMP>. <EM>File</EM> 
   is a file extension, partial filename, wild-card expression or full filename for 
   files to describe. <EM>String</EM> is enclosed in double quotes (<CODE>&quot;</CODE>).
   This alternate text is displayed if the client is image-incapable, has image loading 
  @@ -154,8 +182,8 @@
    REL="Help"
   ><STRONG>Module:</STRONG></A> mod_autoindex<P>
   
  -This provides the alternate text to display for a file, instead of an icon, 
  -for <SAMP><A HREF="#indexoptions:fancyindexing">FancyIndexing</A></SAMP>. 
  +<EM>AddAltByEncoding</EM> provides the alternate text to display for a file, instead 
  +of an icon, for <SAMP><A HREF="#indexoptions:fancyindexing">FancyIndexing</A></SAMP>. 
   <EM>MIME-encoding</EM> is a valid content-encoding, such as <SAMP>x-compress</SAMP>.
   <EM>String</EM> is enclosed in double quotes (<CODE>&quot;</CODE>).  This alternate 
   text is displayed if the client is image-incapable, has image loading disabled, or 
  @@ -187,8 +215,8 @@
    REL="Help"
   ><STRONG>Module:</STRONG></A> mod_autoindex<P>
   
  -This sets the alternate text to display for a file, instead of an icon, for
  -<SAMP><A HREF="#indexoptions:fancyindexing">FancyIndexing</A></SAMP>.  
  +<EM>AddAltByType</EM> sets the alternate text to display for a file, instead of 
  +an icon, for <SAMP><A HREF="#indexoptions:fancyindexing">FancyIndexing</A></SAMP>.  
   <EM>MIME-type</EM> is a valid content-type, such as <SAMP>text/html</SAMP>. 
   <EM>String</EM> is enclosed in double quotes (<CODE>&quot;</CODE>).  This 
   alternate text is displayed if the client is image-incapable, has image loading 
  @@ -229,23 +257,23 @@
   <BLOCKQUOTE><CODE>AddDescription "The planet Mars" /web/pics/mars.gif
   </CODE></BLOCKQUOTE>
   <P>
  -The description field is 23 bytes wide.  7 more bytes may be
  -added if the directory is covered by an
  -<CODE>IndexOptions&nbsp;SuppressSize</CODE>, and 19 bytes may be
  -added if <CODE>IndexOptions&nbsp;SuppressLastModified</CODE> is
  -in effect.  The widest this column can be is therefore 49 bytes.
  +The typical, default description field is 23 bytes wide.  6 more bytes are
  +added by the <CODE>IndexOptions&nbsp;SuppressIcon</CODE> option, 7 bytes are 
  +added by the <CODE>IndexOptions&nbsp;SuppressSize</CODE> option, and 19 bytes
  +are added by the <CODE>IndexOptions&nbsp;SuppressLastModified</CODE> option.
  +Therefore, the widest default the description column is ever assigned is 55 bytes.
  +<P>
  +See the <a href="#indexoptions:descriptionwidth">DescriptionWidth</a>
  +<samp>IndexOptions</samp> keyword for details on overriding the size of this 
  +column, or allowing descriptions of unlimited length.
  +</P>
   <blockquote>
  -As of Apache 1.3.10, the
  -<a href="#indexoptions:descriptionwidth">DescriptionWidth</a>
  -<samp>IndexOptions</samp> keyword allows you to adjust this width
  -to any arbitrary size.
  -</blockquote>
   <b>Caution:</b> Descriptive text defined with <samp>AddDescription</samp>
   may contain HTML markup, such as tags and character entities.  If the
   width of the description column should happen to truncate a tagged
   element (such as cutting off the end of a bolded phrase), the results
   may affect the rest of the directory listing.
  -</P>
  +</blockquote>
   <HR>
   
   <H2><A NAME="addicon">AddIcon</A> directive</H2>
  @@ -437,31 +465,20 @@
     <A
      HREF="directive-dict.html#Compatibility"
      REL="Help"
  -  ><STRONG>Compatibility:</STRONG></A> some features only available after
  - 1.3.6; see text
  +  ><STRONG>Compatibility:</STRONG></A> behavior changed in version 1.3.7;
  + see text
   
   <P>
   The HeaderName directive sets the name of the file that will be inserted
   at the top of the index listing. <EM>Filename</EM> is the name of the file
   to include.
   </P>
  -<BLOCKQUOTE><STRONG>Apache 1.3.6 and earlier:</STRONG>
  -The module first attempts to include <EM>filename</EM><CODE>.html</CODE>
  -as an HTML document, otherwise it will try to include <EM>filename</EM> as
  -plain text.  <EM>Filename</EM> is treated as a filesystem path relative
  -to the directory being indexed.  In no case is SSI processing done.
  -Example:
  -<BLOCKQUOTE><CODE>HeaderName HEADER</CODE></BLOCKQUOTE>
  -when indexing the directory <CODE>/web</CODE>, the server will first look for
  -the HTML file <CODE>/web/HEADER.html</CODE> and include it if found, otherwise
  -it will include the plain text file <CODE>/web/HEADER</CODE>, if it exists.
  -</BLOCKQUOTE>
  -<BLOCKQUOTE><STRONG>Apache versions after 1.3.6:</STRONG>
  -<EM>Filename</EM> is treated as a URI path relative to the one used
  -to access the directory being indexed, and must resolve to a document
  -with a major content type of "<SAMP>text</SAMP>" (<EM>e.g.</EM>,
  -<SAMP>text/html</SAMP>, <SAMP>text/plain</SAMP>, <EM>etc.</EM>).
  -This means that <EM>filename</EM> may refer to a CGI script if the
  +<BLOCKQUOTE><STRONG>Changes with Apache 1.3.7:</STRONG>
  +Both HeaderName and <A HREF="#readmename">ReadmeName</A> now treat <EM>Filename</EM> 
  +as a URI path  relative to the one used to access the directory being indexed.  
  +<EM>Filename</EM>  must resolve to a document with a major content type of 
  +"<SAMP>text/*</SAMP>"  (<EM>e.g.</EM>, <SAMP>text/html</SAMP>, <SAMP>text/plain</SAMP>, 
  +<EM>etc.</EM>). This means that <EM>filename</EM> may refer to a CGI script if the
   script's actual file type (as opposed to its output) is marked as
   <SAMP>text/html</SAMP> such as with a directive like:
   <PRE>
  @@ -518,12 +535,6 @@
   <A
    HREF="directive-dict.html#Syntax"
    REL="Help"
  -><STRONG>Syntax:</STRONG></A> IndexOptions <EM>option</em> 
  -   [<em>option</em>] ... (Apache 1.3.2 and earlier)
  -<BR>
  -<A
  - HREF="directive-dict.html#Syntax"
  - REL="Help"
   ><STRONG>Syntax:</STRONG></A> IndexOptions [+|-]<em>option</em> 
      [[+|-]<em>option</em>] ... (Apache 1.3.3 and later)
   <BR>
  @@ -550,28 +561,27 @@
    REL="Help"
   ><STRONG>Compatibility:</STRONG></A> '+/-' syntax and merging of multiple
    <SAMP>IndexOptions</SAMP> directives is only available with
  - Apache 1.3.3 and later; the <samp>FoldersFirst</samp> and
  - <samp>DescriptionWidth</samp> options are only
  - available with Apache 1.3.10 and later
  + Apache 1.3.3 and later; specific options are listed below.
   <P>
   
   The IndexOptions directive specifies the behavior of the directory indexing.
   <EM>Option</EM> can be one of
   <DL>
   <dt><a name="indexoptions:descriptionwidth">DescriptionWidth=[<em>n</em> | *]
  - (<em>Apache 1.3.10 and later</em>)</a>
  -<dd>
  -The <samp>DescriptionWidth</samp> keyword allows you to specify the
  -width of the description column in characters.  If the keyword value
  -is '<samp>*</samp>', then the column is automatically sized to the
  -length of the longest filename in the display.
  -<b>See the section on <a href="#adddescription"><samp>AddDescription</samp></a>
  + (<em>Apache 1.3.10 or 2.0.23 and later</em>)</a></dt>
  +<dd>The <samp>DescriptionWidth</samp> keyword allows you to specify the
  +width of the description column in characters.</dd>
  +<dd><samp>-DescriptionWidth</samp> (or unset) allows mod_autoindex to calculate 
  +the best width.</dd>
  +<dd><samp>DescriptionWidth=n</samp> fixes the column width to n bytes wide.</dd>
  +<dd><samp>DescriptionWidth=*</samp> grows the column to the necessary width.</dd>
  +<dd><b>See the section on <a href="#adddescription"><samp>AddDescription</samp></a>
   for dangers inherent in truncating descriptions.</b></dd>
   <DT><A NAME="indexoptions:fancyindexing">FancyIndexing</A>
   <DD><!--%plaintext &lt;?INDEX {\tt FancyIndexing} index option&gt; -->
   This turns on fancy indexing of directories.
   <dt><a name="indexoptions:foldersfirst">FoldersFirst
  - (<i>Apache 1.3.10 and later</i>)</a></dt>
  + (<i>Apache 1.3.10  or 2.0.23 and later</i>)</a></dt>
   <dd>
   If this option is enabled, subdirectory listings
   will <i>always</i> appear first, followed by normal files in the
  @@ -585,6 +595,14 @@
   <b>This option only has an effect if
   <a href="#indexoptions:fancyindexing"><samp>FancyIndexing</samp></a>
   is also enabled.</b></dd>
  +<DT><A NAME="indexoptions:htmltable">HTMLTable</A>
  + <i>(Experimental, Apache 2.0.23 and later)</i>
  +<DD><!--%plaintext &lt;?INDEX {\tt HTMLTable} index option&gt; -->
  +This experimental option with FancyIndexing constructs a simple table for the 
  +fancy directory listing.  Note this will confuse older browsers.  It is particularly
  +necessary if file names or description text will alternate between left-to-right 
  +and right-to-left reading order, as can happen on WinNT or other utf-8 
  +enabled platforms.
   <DT><A NAME="indexoptions:iconheight">IconHeight[=pixels] (<EM>Apache 1.3 and later</EM>)</A>
   <DD>
   <!--%plaintext &lt;?INDEX {\tt IconHeight} index option&gt; -->
  @@ -613,34 +631,11 @@
   <DT><A NAME="indexoptions:namewidth">NameWidth=[<EM>n</EM> | *] (<EM>Apache 1.3.2 and later</EM>)</A>
   <DD>
   The NameWidth keyword allows you to specify the width of the
  -filename column in bytes.  If the keyword value is '<SAMP>*</SAMP>',
  -then the column is automatically sized to the length of the longest
  -filename in the display.
  -<DT><A NAME="indexoptions:versionsort">VersionSort (<EM>Apache 2.0a3 and later</EM>)</A>
  -<DD>
  -The VersionSort keyword causes files containing version numbers to
  -sort in a natural way.  Strings are sorted as usual, except that
  -substrings of digits in the name and description are compared
  -according to their numeric value.
  -
  -For example:
  -<BLOCKQUOTE><pre>
  -foo-1.7
  -foo-1.7.2
  -foo-1.7.12
  -foo-1.8.2
  -foo-1.8.2a
  -foo-1.12
  -</pre></BLOCKQUOTE>
  -
  -If the number starts with a zero, then it is considered to be a
  -	fraction:
  -<BLOCKQUOTE><pre>
  -foo-1.001
  -foo-1.002
  -foo-1.030
  -foo-1.04
  -</pre></BLOCKQUOTE>
  +filename column in bytes.  
  +<dd><samp>-NameWidth</samp> (or unset) allows mod_autoindex to calculate 
  +the best width.</dd>
  +<dd><samp>NameWidth=n</samp> fixes the column width to n bytes wide.</dd>
  +<dd><samp>NameWidth=*</samp> grows the column to the necessary width.</dd>
   <DT><A NAME="indexoptions:scanhtmltitles">ScanHTMLTitles</A>
   <DD><!--%plaintext &lt;?INDEX {\tt ScanHTMLTitles} index option&gt; -->
   This enables the extraction of the title from HTML documents for fancy
  @@ -648,13 +643,13 @@
   <A HREF="#adddescription">AddDescription</A> then httpd will read the
   document for the value of the TITLE tag.  This is CPU and disk intensive.
   <DT><A NAME="indexoptions:suppresscolumnsorting">SuppressColumnSorting</A>
  +    (<EM>Apache 1.3 and later</EM>)
   <DD>
   <!--%plaintext &lt;?INDEX {\tt SuppressColumnSorting} index option&gt; -->
   If specified, Apache will not make the column headings in a FancyIndexed
   directory listing into links for sorting.  The default behaviour is
   for them to be links; selecting the column heading will sort the directory
   listing by the values in that column.
  -<STRONG>Only available in Apache 1.3 and later.</STRONG>
   <DT><A NAME="indexoptions:suppressdescription">SuppressDescription</A>
   <DD>
   <!--%plaintext &lt;?INDEX {\tt SuppressDescription} index option&gt; -->
  @@ -673,45 +668,75 @@
   causing the module to start the display with the header file contents.
   The header file must contain appropriate HTML instructions in this case.
   If there is no header file, the preamble is generated as usual.
  +<DT><A NAME="indexoptions:suppressicon">SuppressIcon</A>
  +    (<EM>Apache 2.0.23 and later</EM>)
  +<DD>
  +<!--%plaintext &lt;?INDEX {\tt SuppressIcon} index option&gt; -->
  +This will suppress the icon in fancy indexing listings.  Combining
  +both <EM>SuppressIcon</EM> and <EM>SuppressRules</EM> yeilds proper 
  +HTML 3.2 output, which by the final specification prohibits IMG and HR 
  +tags from the PRE block (used to format FancyIndexed listings.)
   <DT><A NAME="indexoptions:suppresslastmodified">SuppressLastModified</A>
   <DD>
   <!--%plaintext &lt;?INDEX {\tt SuppressLastModified} index option&gt; -->
   This will suppress the display of the last modification date, in fancy
   indexing listings.
  +<DT><A NAME="indexoptions:suppressrules">SuppressRules</A>
  +    (<EM>Apache 2.0.23 and later</EM>)
  +<DD>
  +<!--%plaintext &lt;?INDEX {\tt SuppressRules} index option&gt; -->
  +This will suppress the horizontal rule lines (HR tags) in directory listings.  
  +Combining both <EM>SuppressIcon</EM> and <EM>SuppressRules</EM> yeilds proper 
  +HTML 3.2 output, which by the final specification prohibits IMG and HR tags 
  +from the PRE block (used to format FancyIndexed listings.)
   <DT><A NAME="indexoptions:suppresssize">SuppressSize</A>
   <DD>
   <!--%plaintext &lt;?INDEX {\tt SuppressSize} index option&gt; -->
   This will suppress the file size in fancy indexing listings.
  -</DL>
  -<P>
  -There are some noticeable differences in the behaviour of this
  -directive in recent (post-1.3.0) versions of Apache.
  -</P>
  -<DL>
  -<DT>Apache 1.3.2 and earlier:</DT>
  +<DT><A NAME="indexoptions:trackmodified">TrackModified 
  +(<EM>Apache 1.3.15 or 2.0.23 and later</EM>)</A>
   <DD>
  -<P>
  -The default is that no options are enabled. If multiple IndexOptions
  -could apply to a directory, then the most specific one is taken complete;
  -the options are not merged. For example:
  +<!--%plaintext &lt;?INDEX {\tt TrackModified} index option&gt; -->
  +This returns the Last-Modified and ETag values for the listed directory
  +in the HTTP header.  It is only valid if the operating system and file 
  +system return appropriate stat() results.  Some Unix systems do so, as 
  +do OS2's JFS and Win32's NTFS volumes.  OS2 and Win32 FAT volumes,
  +for example, do not.  Once this feature is enabled, the client or proxy 
  +can track changes to the list of files when they perform a HEAD request.
  +Note some operating systems correctly track new and removed files, but
  +do not track changes for sizes or dates of the files within the directory.
  +<STRONG>Changes to the size or date stamp of an existing file will not
  +update the Last-Modified header on all Unix platforms.</STRONG> If this
  +is a concern, leave this option disabled.
  +<DT><A NAME="indexoptions:versionsort">VersionSort (<EM>Apache 2.0a3 and later</EM>)</A>
  +<DD>
  +The VersionSort keyword causes files containing version numbers to
  +sort in a natural way.  Strings are sorted as usual, except that
  +substrings of digits in the name and description are compared
  +according to their numeric value.
  +
  +For example:
   <BLOCKQUOTE><pre>
  -&lt;Directory /web/docs&gt;
  -    IndexOptions FancyIndexing
  -&lt;/Directory&gt;
  -&lt;Directory /web/docs/spec&gt;
  -    IndexOptions ScanHTMLTitles
  -&lt;/Directory&gt;
  +foo-1.7
  +foo-1.7.2
  +foo-1.7.12
  +foo-1.8.2
  +foo-1.8.2a
  +foo-1.12
   </pre></BLOCKQUOTE>
  -then only <CODE>ScanHTMLTitles</CODE> will be set for the /web/docs/spec
  -directory.
  -</P>
  -</DD>
  -<DT>Apache 1.3.3 and later:</DT>
  -<DD>
  -<P>
  -Apache 1.3.3 introduced some significant changes in the handling of
  +
  +If the number starts with a zero, then it is considered to be a
  +	fraction:
  +<BLOCKQUOTE><pre>
  +foo-1.001
  +foo-1.002
  +foo-1.030
  +foo-1.04
  +</pre></BLOCKQUOTE>
  +<DT><H3>Incremental IndexOptions</H3>
  +<DD>Apache 1.3.3 introduced some significant changes in the handling of
   <SAMP>IndexOptions</SAMP> directives.  In particular,
  -</P>
  +<BR /><BR />
   <UL>
    <LI>Multiple <SAMP>IndexOptions</SAMP> directives for a single
     directory are now merged together.  The result of the example above
  @@ -722,30 +747,26 @@
     keywords with '+' or '-').
    </LI>
   </UL>
  -<P>
  +<BR />
   Whenever a '+' or '-' prefixed keyword is encountered, it is applied
   to the current <SAMP>IndexOptions</SAMP> settings (which may have been
   inherited from an upper-level directory).  However, whenever an unprefixed
   keyword is processed, it clears all inherited options and any incremental
   settings encountered so far.  Consider the following example:
  -</P>
   <BLOCKQUOTE><CODE>IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
  -<BR>
  +<BR />
   IndexOptions +SuppressSize
  -<BR>
  +<BR />
   </CODE></BLOCKQUOTE>
  -<P>
   The net effect is equivalent to
   <CODE>IndexOptions&nbsp;FancyIndexing&nbsp;+SuppressSize</CODE>, because
   the unprefixed <CODE>FancyIndexing</CODE> discarded the incremental
   keywords before it, but allowed them to start accumulating again
   afterward.
  -</P>
  -<P>
  +<BR /><BR />
   To unconditionally set the <CODE>IndexOptions</CODE> for a
   particular directory, clearing the inherited settings, specify
  -keywords without either '+' or '-' prefixes.
  -</P>
  +keywords without any '+' or '-' prefixes.
   </DD>
   </DL>
   
  @@ -839,21 +860,15 @@
      HREF="directive-dict.html#Compatibility"
      REL="Help"
     ><STRONG>Compatibility:</STRONG></A> some features only available after
  - 1.3.6; see text
  + 1.3.6; see <A HREF="#headername">HeaderName</A>
   
   <P>
   The ReadmeName directive sets the name of the file that will be appended
   to the end of the index listing. <EM>Filename</EM> is the name of the file
   to include, and is taken to be relative to the location being indexed.
   </P>
  -<BLOCKQUOTE>
  -<STRONG>The <EM>filename</EM> argument is treated as a stub filename
  -in Apache 1.3.6 and earlier, and as a relative URI in later versions.
  -Details of how it is handled may be found under the description of
  -the <A HREF="#headername">HeaderName</A> directive, which uses the
  -same mechanism and changed at the same time as ReadmeName.</STRONG>
  -</BLOCKQUOTE>
  -<P>See also <A HREF="#headername">HeaderName</A>.<P>
  +<P>See also <A HREF="#headername">HeaderName</A>, where this behavior is
  +described in greater detail.<P>
   
   
   <!--#include virtual="footer.html" -->