📄 mod_autoindex.c
字号:
x++; } else { titlebuf[y] = ' '; } } } apr_file_close(thefile); return apr_pstrdup(r->pool, &titlebuf[x]); } } else { p = 0; } } apr_file_close(thefile); } return NULL;}static struct ent *make_parent_entry(apr_int32_t autoindex_opts, autoindex_config_rec *d, request_rec *r, char keyid, char direction){ struct ent *p = (struct ent *) apr_pcalloc(r->pool, sizeof(struct ent)); char *testpath; /* * p->name is now the true parent URI. * testpath is a crafted lie, so that the syntax '/some/..' * (or simply '..')be used to describe 'up' from '/some/' * when processeing IndexIgnore, and Icon|Alt|Desc configs. */ /* The output has always been to the parent. Don't make ourself * our own parent (worthless cyclical reference). */ if (!(p->name = ap_make_full_path(r->pool, r->uri, "../"))) { return (NULL); } ap_getparents(p->name); if (!*p->name) { return (NULL); } /* IndexIgnore has always compared "/thispath/.." */ testpath = ap_make_full_path(r->pool, r->filename, ".."); if (ignore_entry(d, testpath)) { return (NULL); } p->size = -1; p->lm = -1; 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 (!(p->icon = find_default_icon(d, testpath))) { p->icon = find_default_icon(d, "^^DIRECTORY^^"); } if (!(p->alt = find_default_alt(d, testpath))) { if (!(p->alt = find_default_alt(d, "^^DIRECTORY^^"))) { p->alt = "DIR"; } } p->desc = find_desc(d, testpath); } return p;}static struct ent *make_autoindex_entry(const apr_finfo_t *dirent, int autoindex_opts, autoindex_config_rec *d, request_rec *r, char keyid, char direction, const char *pattern){ request_rec *rr; struct ent *p; int show_forbidden = 0; /* Dot is ignored, Parent is handled by make_parent_entry() */ if ((dirent->name[0] == '.') && (!dirent->name[1] || ((dirent->name[1] == '.') && !dirent->name[2]))) return (NULL); /* * On some platforms, the match must be case-blind. This is really * a factor of the filesystem involved, but we can't detect that * reliably - so we have to granularise at the OS level. */ if (pattern && (apr_fnmatch(pattern, dirent->name, APR_FNM_NOESCAPE | APR_FNM_PERIOD#ifdef CASE_BLIND_FILESYSTEM | APR_FNM_CASE_BLIND#endif ) != APR_SUCCESS)) { return (NULL); } if (ignore_entry(d, ap_make_full_path(r->pool, r->filename, dirent->name))) { return (NULL); } if (!(rr = ap_sub_req_lookup_dirent(dirent, r, AP_SUBREQ_NO_ARGS, NULL))) { return (NULL); } if((autoindex_opts & SHOW_FORBIDDEN) && (rr->status == HTTP_UNAUTHORIZED || rr->status == HTTP_FORBIDDEN)) { show_forbidden = 1; } if ((rr->finfo.filetype != APR_DIR && rr->finfo.filetype != APR_REG) || !(rr->status == OK || ap_is_HTTP_SUCCESS(rr->status) || ap_is_HTTP_REDIRECT(rr->status) || show_forbidden == 1)) { ap_destroy_sub_req(rr); return (NULL); } p = (struct ent *) apr_pcalloc(r->pool, sizeof(struct ent)); if (dirent->filetype == APR_DIR) { p->name = apr_pstrcat(r->pool, dirent->name, "/", NULL); } else { p->name = apr_pstrdup(r->pool, dirent->name); } p->size = -1; p->icon = NULL; 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); p->ignore_case = !!(autoindex_opts & IGNORE_CASE); if (autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING)) { p->lm = rr->finfo.mtime; if (dirent->filetype == APR_DIR) { if (autoindex_opts & FOLDERS_FIRST) { p->isdir = 1; } rr->filename = ap_make_dirstr_parent (rr->pool, rr->filename); /* omit the trailing slash (1.3 compat) */ rr->filename[strlen(rr->filename) - 1] = '\0'; if (!(p->icon = find_icon(d, rr, 1))) { p->icon = find_default_icon(d, "^^DIRECTORY^^"); } if (!(p->alt = find_alt(d, rr, 1))) { if (!(p->alt = find_default_alt(d, "^^DIRECTORY^^"))) { p->alt = "DIR"; } } } else { p->icon = find_icon(d, rr, 0); p->alt = find_alt(d, rr, 0); p->size = rr->finfo.size; } p->desc = find_desc(d, rr->filename); if ((!p->desc) && (autoindex_opts & SCAN_HTML_TITLES)) { p->desc = apr_pstrdup(r->pool, find_title(rr)); } } ap_destroy_sub_req(rr); /* * We don't need to take any special action for the file size key. * If we did, it would go here. */ if (keyid == K_LAST_MOD) { if (p->lm < 0) { p->lm = 0; } } return (p);}static char *terminate_description(autoindex_config_rec *d, char *desc, apr_int32_t autoindex_opts, int desc_width){ int maxsize = desc_width; register int x; /* * 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++) { if (desc[x] == '<') { while (desc[x] != '>') { if (!desc[x]) { maxsize = 0; break; } ++x; } } else if (desc[x] == '&') { /* entities like ä count as one character */ --maxsize; for ( ; desc[x] != ';'; ++x) { if (desc[x] == '\0') { maxsize = 0; break; } } } else { --maxsize; } } if (!maxsize && desc[x] != '\0') { desc[x - 1] = '>'; /* Grump. */ desc[x] = '\0'; /* Double Grump! */ } return desc;}/* * Emit the anchor for the specified field. If a field is the key for the * current request, the link changes its meaning to reverse the order when * selected again. Non-active fields always start in ascending order. */static void emit_link(request_rec *r, const char *anchor, char column, char curkey, char curdirection, const char *colargs, int nosort){ if (!nosort) { char qvalue[9]; qvalue[0] = '?'; qvalue[1] = 'C'; qvalue[2] = '='; qvalue[3] = column; qvalue[4] = ';'; qvalue[5] = 'O'; qvalue[6] = '='; /* reverse? */ qvalue[7] = ((curkey == column) && (curdirection == D_ASCENDING)) ? D_DESCENDING : D_ASCENDING; qvalue[8] = '\0'; ap_rvputs(r, "<a href=\"", qvalue, colargs ? colargs : "", "\">", anchor, "</a>", NULL); } else { ap_rputs(anchor, r); }}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 *name = r->uri; char *tp; 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') { name = "/"; } name_width = d->name_width; 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 & TABLE_INDEXING) { int cols = 1; ap_rputs("<table><tr>", r); if (!(autoindex_opts & SUPPRESS_ICON)) { ap_rputs("<th>", 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); } if (autoindex_opts & EMIT_XHTML) { ap_rputs(" /", r); } ap_rputs("></th>", r); } else { ap_rputs(" </th>", r); } ++cols; } ap_rputs("<th>", r); emit_link(r, "Name", K_NAME, keyid, direction, colargs, static_columns); if (!(autoindex_opts & SUPPRESS_LAST_MOD)) { ap_rputs("</th><th>", r); emit_link(r, "Last modified", K_LAST_MOD, keyid, direction, colargs, static_columns); ++cols; } if (!(autoindex_opts & SUPPRESS_SIZE)) { ap_rputs("</th><th>", r); emit_link(r, "Size", K_SIZE, keyid, direction, colargs, static_columns); ++cols; } if (!(autoindex_opts & SUPPRESS_DESC)) { ap_rputs("</th><th>", r); emit_link(r, "Description", K_DESC, keyid, direction, colargs, static_columns); ++cols; } if (!(autoindex_opts & SUPPRESS_RULES)) { breakrow = apr_psprintf(r->pool, "<tr><th colspan=\"%d\">" "<hr%s></th></tr>\n", cols, (autoindex_opts & EMIT_XHTML) ? " /" : ""); } 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); } if (autoindex_opts & EMIT_XHTML) { ap_rputs(" /", r); } ap_rputs("> ", r); } else { ap_rputs(" ", r); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -