in modules/generators/mod_autoindex.c [1511:1911]
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 *datetime_format;
char *name_scratch;
char *pad_scratch;
char *breakrow = "";
apr_pool_create(&scratch, r->pool);
apr_pool_tag(scratch, "autoindex_scratch");
name_width = d->name_width;
desc_width = d->desc_width;
datetime_format = d->datetime_format ? d->datetime_format : "%Y-%m-%d %H:%M";
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(" </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(" ", 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),
datetime_format,
&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\"> " : "> ", 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\">" : ">", " ", 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),
datetime_format,
&ts);
ap_rvputs(r, time_str, " ", NULL);
}
else {
/* Length="1975-04-07 01:23 " (default in 2.4 and later) or
* Length="07-Apr-1975 01:24 ". (2.2 and UseOldDateFormat)
* See 'datetime_format' 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);
}
}