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>