Here we go... updated mod_info to be aware of the directory
capability as well. No place else seems to worry :)
I may decide to strip off ap_server_root from the pathnames for
the config file names in the mod_info output...
Index: src/CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1582
diff -u -r1.1582 CHANGES
--- src/CHANGES 2000/09/28 13:32:31 1.1582
+++ src/CHANGES 2000/10/02 21:21:49
@@ -1,5 +1,11 @@
Changes with Apache 1.3.13
+ *) Add support for a "conf directory" which operates similar to
+ /etc/rc.d/init. Basically, if a config file is actually a
+ directory, all the files in that directory will be parsed
+ as conf files. PR #6397 [Jim Jagielski, Lionel Clark
+ <bishop@platypus.bc.ca>]
+
*) Initial support added for mod_proxy under MPE/iX.
[Mark Bixby <mark_bixby@hp.com>]
Index: src/include/ap_mmn.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/ap_mmn.h,v
retrieving revision 1.50
diff -u -r1.50 ap_mmn.h
--- src/include/ap_mmn.h 2000/07/30 17:26:31 1.50
+++ src/include/ap_mmn.h 2000/10/02 21:22:02
@@ -229,6 +229,7 @@
* 19990320.7 - add ap_strcasestr()
* 19990320.8 - add request_rec.case_preserved_filename
* 19990320.9 - renamed alloc.h to ap_alloc.h
+ * 19990320.10 - add ap_is_rdirectory()
*/
#define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
@@ -236,7 +237,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 19990320
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 9 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 10 /* 0...n */
/* Useful for testing for features. */
#define AP_MODULE_MAGIC_AT_LEAST(major,minor) \
Index: src/include/httpd.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v
retrieving revision 1.315
diff -u -r1.315 httpd.h
--- src/include/httpd.h 2000/09/22 18:17:48 1.315
+++ src/include/httpd.h 2000/10/02 21:22:03
@@ -1090,6 +1090,7 @@
API_EXPORT(uid_t) ap_uname2id(const char *name);
API_EXPORT(gid_t) ap_gname2id(const char *name);
API_EXPORT(int) ap_is_directory(const char *name);
+API_EXPORT(int) ap_is_rdirectory(const char *name);
API_EXPORT(int) ap_can_exec(const struct stat *);
API_EXPORT(void) ap_chdir_file(const char *file);
Index: src/main/http_config.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_config.c,v
retrieving revision 1.153
diff -u -r1.153 http_config.c
--- src/main/http_config.c 2000/06/01 23:42:24 1.153
+++ src/main/http_config.c 2000/10/02 21:22:14
@@ -1187,6 +1187,18 @@
ap_cfg_closefile(parms.config_file);
}
+typedef struct {
+ char *fname;
+} fnames;
+
+static int fname_alphasort(const void *fn1, const void *fn2)
+{
+ const fnames *f1 = fn1;
+ const fnames *f2 = fn2;
+
+ return strcmp(f1->fname,f2->fname);
+}
+
void ap_process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp)
{
const char *errmsg;
@@ -1208,6 +1220,62 @@
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(fname)) {
+ DIR *dirp;
+ struct DIR_TYPE *dir_entry;
+ int current;
+ array_header *candidates = NULL;
+ fnames *fnew;
+
+ /*
+ * 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);
+ dirp = ap_popendir(p, fname);
+ if (dirp == NULL) {
+ perror("fopen");
+ fprintf(stderr, "%s: could not open config directory %s\n",
+ ap_server_argv0, fname);
+#ifdef NETWARE
+ clean_parent_exit(1);
+#else
+ exit(1);
+#endif
+ }
+ candidates = ap_make_array(p, 1, sizeof(fnames));
+ while ((dir_entry = readdir(dirp)) != NULL) {
+ /* strip out '.' and '..' */
+ if (strcmp(dir_entry->d_name, ".") &&
+ strcmp(dir_entry->d_name, "..")) {
+ fnew = (fnames *) ap_push_array(candidates);
+ fnew->fname = ap_make_full_path(p, fname, dir_entry->d_name);
+ }
+ }
+ ap_pclosedir(p, dirp);
+ if (candidates->nelts != 0) {
+ qsort((void *) candidates->elts, candidates->nelts,
+ sizeof(fnames), fname_alphasort);
+ /*
+ * Now recurse these... we handle errors and subdirectories
+ * via the recursion, which is nice
+ */
+ 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, p, ptemp);
+ }
+ }
+ return;
+ }
+
/* GCC's initialization extensions are soooo nice here... */
parms = default_parms;
@@ -1242,7 +1310,6 @@
ap_cfg_closefile(parms.config_file);
}
-
int ap_parse_htaccess(void **result, request_rec *r, int override,
const char *d, const char *access_name)
Index: src/main/util.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/util.c,v
retrieving revision 1.187
diff -u -r1.187 util.c
--- src/main/util.c 2000/09/22 18:33:17 1.187
+++ src/main/util.c 2000/10/02 21:22:16
@@ -1652,6 +1652,20 @@
return (S_ISDIR(finfo.st_mode));
}
+/*
+ * see ap_is_directory() except this one is symlink aware, so it
+ * checks for a "real" directory
+ */
+API_EXPORT(int) ap_is_rdirectory(const char *path)
+{
+ struct stat finfo;
+
+ if (lstat(path, &finfo) == -1)
+ return 0; /* in error condition, just return no */
+
+ return ((!(S_ISLNK(finfo.st_mode))) && (S_ISDIR(finfo.st_mode)));
+}
+
API_EXPORT(char *) ap_make_full_path(pool *a, const char *src1,
const char *src2)
{
Index: src/modules/standard/mod_info.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_info.c,v
retrieving revision 1.49
diff -u -r1.49 mod_info.c
--- src/modules/standard/mod_info.c 2000/06/01 23:42:28 1.49
+++ src/modules/standard/mod_info.c 2000/10/02 21:22:38
@@ -102,9 +102,27 @@
struct info_cfg_lines *next;
} info_cfg_lines;
+typedef struct { /* shamelessly lifted from http_config.c */
+ char *fname;
+} info_fnames;
+
+typedef struct {
+ info_cfg_lines *clines;
+ char *fname;
+} info_clines;
+
module MODULE_VAR_EXPORT info_module;
extern module API_VAR_EXPORT *top_module;
+/* shamelessly lifted from http_config.c */
+static int fname_alphasort(const void *fn1, const void *fn2)
+{
+ const info_fnames *f1 = fn1;
+ const info_fnames *f2 = fn2;
+
+ return strcmp(f1->fname,f2->fname);
+}
+
static void *create_info_config(pool *p, server_rec *s)
{
info_svr_conf *conf = (info_svr_conf *) ap_pcalloc(p, sizeof(info_svr_conf));
@@ -354,6 +372,53 @@
return 0;
}
+static void mod_info_dirwalk(pool *p, const char *fname,
+ request_rec *r, array_header *carray)
+{
+ info_clines *cnew = NULL;
+ info_cfg_lines *mod_info_cfg_tmp = NULL;
+
+ if (!ap_is_rdirectory(fname)) {
+ mod_info_cfg_tmp = mod_info_load_config(p, fname, r);
+ cnew = (info_clines *) ap_push_array(carray);
+ cnew->fname = ap_pstrdup(p, fname);
+ cnew->clines = mod_info_cfg_tmp;
+ } else {
+ DIR *dirp;
+ struct DIR_TYPE *dir_entry;
+ int current;
+ array_header *candidates = NULL;
+ info_fnames *fnew;
+
+ dirp = ap_popendir(p, fname);
+ if (dirp == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
+ "mod_info: couldn't open config directory %s",
+ fname);
+ return;
+ }
+ candidates = ap_make_array(p, 1, sizeof(info_fnames));
+ while ((dir_entry = readdir(dirp)) != NULL) {
+ /* strip out '.' and '..' */
+ if (strcmp(dir_entry->d_name, ".") &&
+ strcmp(dir_entry->d_name, "..")) {
+ fnew = (info_fnames *) ap_push_array(candidates);
+ fnew->fname = ap_make_full_path(p, fname, dir_entry->d_name);
+ }
+ }
+ ap_pclosedir(p, dirp);
+ if (candidates->nelts != 0) {
+ qsort((void *) candidates->elts, candidates->nelts,
+ sizeof(info_fnames), fname_alphasort);
+ for (current = 0; current < candidates->nelts; ++current) {
+ fnew = &((info_fnames *) candidates->elts)[current];
+ mod_info_dirwalk(p, fnew->fname, r, carray);
+ }
+ }
+ }
+ return;
+}
+
static int display_info(request_rec *r)
{
module *modp = NULL;
@@ -363,9 +428,9 @@
const handler_rec *hand = NULL;
server_rec *serv = r->server;
int comma = 0;
- info_cfg_lines *mod_info_cfg_httpd = NULL;
- info_cfg_lines *mod_info_cfg_srm = NULL;
- info_cfg_lines *mod_info_cfg_access = NULL;
+ array_header *allconfigs = NULL;
+ info_clines *cnew = NULL;
+ int current;
r->allowed |= (1 << M_GET);
if (r->method_number != M_GET)
@@ -382,12 +447,13 @@
"<html><head><title>Server Information</title></head>\n",
r);
ap_rputs("<body><h1 align=center>Apache Server Information</h1>\n",
r);
if (!r->args || strcasecmp(r->args, "list")) {
+ allconfigs = ap_make_array(r->pool, 1, sizeof(info_clines));
cfname = ap_server_root_relative(r->pool, ap_server_confname);
- mod_info_cfg_httpd = mod_info_load_config(r->pool, cfname, r);
+ mod_info_dirwalk(r->pool, cfname, r, allconfigs);
cfname = ap_server_root_relative(r->pool, serv->srm_confname);
- mod_info_cfg_srm = mod_info_load_config(r->pool, cfname, r);
+ mod_info_dirwalk(r->pool, cfname, r, allconfigs);
cfname = ap_server_root_relative(r->pool, serv->access_confname);
- mod_info_cfg_access = mod_info_load_config(r->pool, cfname, r);
+ mod_info_dirwalk(r->pool, cfname, r, allconfigs);
if (!r->args) {
ap_rputs("<tt><a href=\"#server\">Server Settings</a>, ", r);
for (modp = top_module; modp; modp = modp->next) {
@@ -603,12 +669,11 @@
cmd++;
}
ap_rputs("<dt><strong>Current Configuration:</strong>\n",
r);
- mod_info_module_cmds(r, mod_info_cfg_httpd, modp->cmds,
- "httpd.conf");
- mod_info_module_cmds(r, mod_info_cfg_srm, modp->cmds,
- "srm.conf");
- mod_info_module_cmds(r, mod_info_cfg_access, modp->cmds,
- "access.conf");
+ for (current = 0; current < allconfigs->nelts; ++current) {
+ cnew = &((info_clines *) allconfigs->elts)[current];
+ mod_info_module_cmds(r, cnew->clines, modp->cmds,
+ cnew->fname);
+ }
}
else {
ap_rputs("<tt> none</tt>\n", r);
--
===========================================================================
Jim Jagielski [|] jim@jaguNET.com [|] http://www.jaguNET.com/
"Are you suggesting coconuts migrate??"
|