On Tue, Sep 10, 2002 at 09:21:17PM -0700, Justin Erenkrantz wrote:
> On Tue, Sep 10, 2002 at 04:04:31PM -0700, Ian Holsman wrote:
> > does anyone recall if there was a good reason not to include this patch
> > in the main distribution ?
> 
> What patch is this?  -- justin

I hadn't had time to submit the revised patch yet: here it is.

This adds support for using fnmatch patterns in the final path segment
of an Include statement, e.g. "Include /foo/bar/*.conf".  It also
removes the noise on stderr during config dir processing.

(the ability to recursively process config directories is not removed,
as requested)

--- server/config.c     19 Aug 2002 20:40:08 -0000      1.155
+++ server/config.c     11 Sep 2002 05:47:36 -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
@@ -1442,6 +1443,7 @@
     apr_finfo_t finfo;
     const char *errmsg;
     ap_configfile_t *cfp;
+    int ispatt;
 
     /* don't require conf/httpd.conf if we have a -C or -c switch */
     if ((ap_server_pre_read_config->nelts
@@ -1451,31 +1453,52 @@
             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)) {
+    ispatt = apr_fnmatch_test(fname);
+    if (ispatt || ap_is_rdirectory(p, 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], *path = apr_pstrdup(p, fname), *pattern = NULL;
+
+        if (ispatt) {
+            pattern = ap_strrchr(path, '/');
+        
+            AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */
+        
+            *pattern++ = '\0';
+            
+            if (apr_fnmatch_test(path)) {
+                fprintf(stderr, "%s: 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);
+            }
+            
+            if (!apr_fnmatch_test(pattern)) {
+                fprintf(stderr, "%s: must include a wildcard pattern "
+                        "for Include %s\n", ap_server_argv0, fname);
+                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);
         }
@@ -1484,9 +1507,12 @@
         while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
             /* strip out '.' and '..' */
             if (strcmp(dirent.name, ".")
-                && strcmp(dirent.name, "..")) {
+                && strcmp(dirent.name, "..")
+                && (!ispatt ||
+                    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);
             }
         }
 
@@ -1501,7 +1527,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);
             }
         }

Reply via email to