On Mon, May 27, 2002 at 10:43:32PM -0700, Brian Pane wrote:
> As a compromise solution, how about:
> 
>   * Implement user-defined patterns for now, using apr_fnmatch(), but
>     restrict the patterns to matching a single directory (so that we
>     only need fnmatch and not full glob support).
>   * Later, add a more general glob() function in APR, and retrofit it
>     into the httpd config processing so that people can do things like
>     "Include local/*/*.conf"

Sounds reasonable: patch is below.

This removes support for "Include <somedir>", by the argument that
include dirs will just trip people up unexpectedly, and "Include
<somedir>/*" is equivalent if they really want that behaviour. (Although
the ability to recurse into subdirectories is also removed, I don't
think that's particularly useful either)

Index: server/config.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/config.c,v
retrieving revision 1.151
diff -u -r1.151 config.c
--- server/config.c     20 May 2002 15:05:43 -0000      1.151
+++ server/config.c     28 May 2002 13:02:50 -0000
@@ -75,6 +75,7 @@
 #include "apr_strings.h"
 #include "apr_portable.h"
 #include "apr_file_io.h"
+#include "apr_fnmatch.h"
 
 #define APR_WANT_STDIO
 #define APR_WANT_STRFUNC
@@ -1422,31 +1423,50 @@
             return;
     }
 
-    /*
-     * here we want to check if the candidate file is really a
-     * directory, and most definitely NOT a symlink (to prevent
-     * horrible loops).  If so, let's recurse and toss it back
-     * into the function.
-     */
-    if (ap_is_rdirectory(ptemp, fname)) {
+    /* Disallow using whole-directory includes. */
+    if (ap_is_rdirectory(p, fname)) {
+        fprintf(stderr, "%s: Including a directory is not supported, use "
+                "a wildcard pattern\n", ap_server_argv0);
+        exit(1);
+    }
+
+    /* Load files matching fnmatch pattern */
+    if (apr_is_fnmatch(fname)) {
         apr_dir_t *dirp;
         apr_finfo_t dirent;
         int current;
         apr_array_header_t *candidates = NULL;
         fnames *fnew;
         apr_status_t rv;
-        char errmsg[120];
+        char errmsg[120], *pattern, *path = apr_pstrdup(p, fname);
+
+        pattern = ap_strrchr(path, '/');
+        
+        AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */
+        
+        *pattern++ = '\0';
+        
+        if (apr_is_fnmatch(path)) {
+            fprintf(stderr, "%s: multi-directory wildcard patterns not allowed "
+                    "in Include (%s)\n", ap_server_argv0, fname);
+            exit(1);
+        }
+        
+        if (!ap_is_rdirectory(p, path)) { 
+            fprintf(stderr, "%s: Include directory '%s' not found",
+                    ap_server_argv0, path);
+            exit(1);
+        }
 
         /*
          * first course of business is to grok all the directory
          * entries here and store 'em away. Recall we need full pathnames
          * for this.
          */
-        fprintf(stderr, "Processing config directory: %s\n", fname);
-        rv = apr_dir_open(&dirp, fname, p);
+        rv = apr_dir_open(&dirp, path, p);
         if (rv != APR_SUCCESS) {
             fprintf(stderr, "%s: could not open config directory %s: %s\n",
-                    ap_server_argv0, fname,
+                    ap_server_argv0, path,
                     apr_strerror(rv, errmsg, sizeof errmsg));
             exit(1);
         }
@@ -1455,9 +1475,11 @@
         while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
             /* strip out '.' and '..' */
             if (strcmp(dirent.name, ".")
-                && strcmp(dirent.name, "..")) {
+                && strcmp(dirent.name, "..")
+                && apr_fnmatch(pattern, dirent.name, 
+                               FNM_PERIOD) == APR_SUCCESS) {
                 fnew = (fnames *) apr_array_push(candidates);
-                fnew->fname = ap_make_full_path(p, fname, dirent.name);
+                fnew->fname = ap_make_full_path(p, path, dirent.name);
             }
         }
 
@@ -1472,7 +1494,6 @@
              */
             for (current = 0; current < candidates->nelts; ++current) {
                 fnew = &((fnames *) candidates->elts)[current];
-                fprintf(stderr, " Processing config file: %s\n", fnew->fname);
                 ap_process_resource_config(s, fnew->fname, conftree, p, ptemp);
             }
         }
Index: docs/manual/mod/core.xml
===================================================================
RCS file: /home/cvspublic/httpd-2.0/docs/manual/mod/core.xml,v
retrieving revision 1.10
diff -u -r1.10 core.xml
--- docs/manual/mod/core.xml    27 May 2002 02:22:09 -0000      1.10
+++ docs/manual/mod/core.xml    28 May 2002 13:02:50 -0000
@@ -1034,7 +1034,7 @@
 <name>Include</name>
 <description>Includes other configuration files from within
 the server configuration files</description>
-<syntax>Include <em>file-path</em>|<em>directory-path</em></syntax>
+<syntax>Include <em>file-path</em>|<em>wildcard-pattern</em></syntax>
 <contextlist><context>server config</context><context>virtual host</context>
 <context>directory</context>
 </contextlist>
@@ -1043,11 +1043,13 @@
     <p>This directive allows inclusion of other configuration files
     from within the server configuration files.</p>
 
-    <p>If <directive>Include</directive> points to a directory, rather than a
-    file, Apache will read all files in that directory, and any
-    subdirectory, and parse those as configuration files.</p>
+    <p>If <directive>Include</directive> is used with a wildcard
+    pattern, then Apache will read all the configuration files which
+    match the pattern.  The pattern may only select files from a
+    single directory; <code>/foo/*.conf</code> is valid, but
+    <code>/foo/*/*.conf</code> is not.</p>
 
-    <p>The file path specified may be a fully qualified path (i.e.
+    <p>The file path or pattern specified may be a fully qualified path (i.e.
     starting with a slash), or may be relative to the 
     <directive module="core">ServerRoot</directive> directory.</p>
 
@@ -1055,7 +1057,7 @@
 
 <example>
      Include /usr/local/apache/conf/ssl.conf<br />
-     Include /usr/local/apache/conf/vhosts/
+     Include /usr/local/apache/conf/vhosts/*.conf
 </example>
 
      <p>Or, providing paths relative to your <code>ServerRoot</code>
@@ -1063,27 +1065,9 @@
 
 <example>
      Include conf/ssl.conf<br />
-     Include conf/vhosts/
+     Include conf/vhosts/*.conf
 </example>
 
-     <p>Make sure that an included directory does not contain any stray
-     files, such as editor temporary files, for example, as Apache will
-     attempt to read them in and use the contents as configuration
-     directives, which may cause the server to fail on start up.
-     Running <code>apachectl configtest</code> will give you a list of
-     the files that are being processed during the configuration
-     check:</p>
-
-<example><pre>
- root@host# apachectl configtest
-  Processing config directory: /usr/local/apache/conf/vhosts
-  Processing config file: /usr/local/apache/conf/vhosts/vhost1
-  Processing config file: /usr/local/apache/conf/vhosts/vhost2
- Syntax OK
-</pre></example>
-
-     <p>This will help in verifying that you are getting only the files
-     that you intended as part of your configuration.</p>
 </usage>
 
 <seealso><a href="../programs/apachectl.html">apachectl</a></seealso>

Reply via email to