static void output_directories()

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("&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),
                                 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\">&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),
                                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);
    }
}