]> granicus.if.org Git - apache/commitdiff
Allow mod_autoindex to serve symlinks if permitted and optimize our stats
authorJustin Erenkrantz <jerenkrantz@apache.org>
Thu, 7 Feb 2002 06:37:09 +0000 (06:37 +0000)
committerJustin Erenkrantz <jerenkrantz@apache.org>
Thu, 7 Feb 2002 06:37:09 +0000 (06:37 +0000)
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
modules/generators/mod_autoindex.c

diff --git a/CHANGES b/CHANGES
index 4209926a62941ef7ba863f0e154dc4071e37f4f7..44b72a0eab3765017045a0b2853c28dd42ac302f 100644 (file)
--- 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]
 
index aad5199b2b9f04d9818a6088b0048d871b1f2f7d..3848e41b99bb2a26464a14b69e00c66bc67b872d 100644 (file)
@@ -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) {