From 795f15723d05c36afe2ece9a641032e29626e03f Mon Sep 17 00:00:00 2001 From: Justin Erenkrantz Date: Thu, 7 Feb 2002 06:37:09 +0000 Subject: [PATCH] Allow mod_autoindex to serve symlinks if permitted and optimize our stats so that only one stat() is needed. If we get APR_FINFO_MIN bits, lookup_dirent won't do a repeated stat() call. So, let's do it here. Also, if we see a symlink, expand it. (Technically, we don't *have* to expand the symlinks - the resolve_symlink fix handles that, but we can't really assume that.) Since we know that dirent will be rr->finfo anyway, go back to relying on dirent only for APR_DIR checks. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93329 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ modules/generators/mod_autoindex.c | 31 +++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 4209926a62..44b72a0eab 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ Changes with Apache 2.0.32-dev + *) Allow mod_autoindex to serve symlinks if permitted and attempt to + do only one stat() call when generating the directory listings. + [Justin Erenkrantz] + *) Fix resolve_symlink to save the original symlink name if known. [Justin Erenkrantz] diff --git a/modules/generators/mod_autoindex.c b/modules/generators/mod_autoindex.c index aad5199b2b..3848e41b99 100644 --- a/modules/generators/mod_autoindex.c +++ b/modules/generators/mod_autoindex.c @@ -1298,7 +1298,7 @@ static struct ent *make_autoindex_entry(const apr_finfo_t *dirent, } p = (struct ent *) apr_pcalloc(r->pool, sizeof(struct ent)); - if (rr->finfo.filetype == APR_DIR) { + if (dirent->filetype == APR_DIR) { p->name = apr_pstrcat(r->pool, dirent->name, "/", NULL); } else { @@ -1316,7 +1316,7 @@ static struct ent *make_autoindex_entry(const apr_finfo_t *dirent, if (autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING)) { p->lm = rr->finfo.mtime; - if (rr->finfo.filetype == APR_DIR) { + if (dirent->filetype == APR_DIR) { if (autoindex_opts & FOLDERS_FIRST) { p->isdir = 1; } @@ -1885,6 +1885,8 @@ static int index_directory(request_rec *r, char keyid; char direction; char *colargs; + char *fullpath; + apr_size_t dirpathlen; if ((status = apr_dir_open(&thedir, name, r->pool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, @@ -2023,7 +2025,30 @@ static int index_directory(request_rec *r, head = p; num_ent++; } - while (apr_dir_read(&dirent, APR_FINFO_DIRENT, thedir) == APR_SUCCESS) { + fullpath = apr_palloc(r->pool, APR_PATH_MAX); + dirpathlen = strlen(name); + memcpy(fullpath, name, dirpathlen); + while (apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, thedir) == APR_SUCCESS) { + /* We want to explode symlinks here. */ + if (dirent.filetype == APR_LNK) { + const char *savename; + apr_finfo_t fi; + /* We *must* have FNAME. */ + savename = dirent.name; + apr_cpystrn(fullpath + dirpathlen, dirent.name, + APR_PATH_MAX - dirpathlen); + status = apr_stat(&fi, fullpath, + dirent.valid & ~(APR_FINFO_NAME), r->pool); + if (status != APR_SUCCESS) { + /* Something bad happened, skip this file. */ + continue; + } + memcpy(&dirent, &fi, sizeof(fi)); + if (savename) { + dirent.name = savename; + dirent.valid |= APR_FINFO_NAME; + } + } p = make_autoindex_entry(&dirent, autoindex_opts, autoindex_conf, r, keyid, direction, pstring); if (p != NULL) { -- 2.40.0