]> granicus.if.org Git - apache/commitdiff
Port over the config directory stuff...
authorJim Jagielski <jim@apache.org>
Thu, 5 Oct 2000 22:35:08 +0000 (22:35 +0000)
committerJim Jagielski <jim@apache.org>
Thu, 5 Oct 2000 22:35:08 +0000 (22:35 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@86409 13f79535-47bb-0310-9956-ffa450edef68

include/httpd.h
modules/generators/mod_info.c
server/config.c
server/util.c

index ad5cbe91176f3643bae3e6a4bd9b5af544664ed9..77f7c7ca638bf1c1e36b8ddc20c0c9a9b7ef936e 100644 (file)
@@ -1371,6 +1371,15 @@ API_EXPORT(int) ap_strcasecmp_match(const char *str, const char *exp);
  */
 API_EXPORT(char *) ap_strcasestr(const char *s1, const char *s2);
 
+/**
+ * Return a pointer to the location inside of bigstring immediately after prefix
+ * @param bigstring The input string
+ * @param prefix The prefix to strip away
+ * @return A pointer relative to bigstring after prefix
+ * deffunc char *ap_stripprefix(const char *bigstring, const char *prefix);
+ */
+API_EXPORT(char *) ap_stripprefix(const char *bigstring, const char *prefix);
+
 /**
  * Decode a base64 encoded string into memory allocated out of a pool
  * @param p The pool to allocate out of
@@ -1525,6 +1534,13 @@ API_EXPORT(gid_t) ap_gname2id(const char *name);
  * Given the name of an object in the file system determine if it is a directory
  * @param name The name of the object to check
  * @return 1 if it is a directory, 0 otherwise
+ * @deffunc int ap_is_rdirectory(const char *name)
+ */
+API_EXPORT(int) ap_is_rdirectory(const char *name);
+/**
+ * Given the name of an object in the file system determine if it is a directory - this version is symlink aware
+ * @param name The name of the object to check
+ * @return 1 if it is a directory, 0 otherwise
  * @deffunc int ap_is_directory(const char *name)
  */
 API_EXPORT(int) ap_is_directory(const char *name);
index 44992589435c3fc495327d0d4987ac343f5069a1..6a8758cbf8cd2a0d64dcf5c619ce60e02fe40bb1 100644 (file)
@@ -103,9 +103,27 @@ typedef struct info_cfg_lines {
     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 *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(apr_pool_t *p, server_rec *s)
 {
     info_svr_conf *conf = (info_svr_conf *) apr_pcalloc(p, sizeof(info_svr_conf));
@@ -356,6 +374,53 @@ static char *find_more_info(server_rec *s, const char *module_name)
     return 0;
 }
 
+static void mod_info_dirwalk(pool *p, const char *fname,
+                             request_rec *r, apr_array_header_t *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 *) apr_push_array(carray);
+        cnew->fname = ap_pstrdup(p, fname);
+        cnew->clines = mod_info_cfg_tmp;
+    } else {
+        apr_dir_t *dirp;
+        int current;
+        apr_array_header_t *candidates = NULL;
+        info_fnames *fnew;
+
+       if (apr_opendir(&dirp, fname, p) != APR_SUCCESS) {
+            ap_log_rerror(APLOG_MARK, APLOG_WARNING, r, 
+                    "mod_info: couldn't open config directory %s",
+                    fname);
+            return;
+       }
+       candidates = apr_make_array(p, 1, sizeof(info_fnames));
+        while (apr_readdir(dirp) == APR_SUCCESS) {
+            char *d_name;
+           apr_get_dir_filename(&d_name, dirp);
+           /* strip out '.' and '..' */
+           if (strcmp(d_name, ".") &&
+               strcmp(d_name, "..")) {
+               fnew = (info_fnames *) apr_push_array(candidates);
+               fnew->fname = ap_make_full_path(p, fname, d_name);
+           }
+       }
+       apr_closedir(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;
@@ -365,13 +430,14 @@ static int display_info(request_rec *r)
     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;
+    apr_array_header_t *allconfigs = NULL;
+    info_clines *cnew = NULL;
+    int current;
+    char *relpath;
 
     r->allowed |= (1 << M_GET);
     if (r->method_number != M_GET)
-       return DECLINED;
+        return DECLINED;
 
     r->content_type = "text/html";
     ap_send_http_header(r);
@@ -383,8 +449,9 @@ static int display_info(request_rec *r)
             "<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 = apr_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);
         if (!r->args) {
             ap_rputs("<tt><a href=\"#server\">Server Settings</a>, ", r);
             for (modp = top_module; modp; modp = modp->next) {
@@ -595,12 +662,16 @@ static int display_info(request_rec *r)
                         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];
+                        /* get relative pathname with some safeguards */
+                       relpath = ap_stripprefix(cnew->fname,ap_server_root);
+                       if (*relpath != '\0' && relpath != cnew->fname &&
+                            *relpath == '/')
+                            relpath++;
+                        mod_info_module_cmds(r, cnew->clines, modp->cmds,
+                                             relpath);
+                    }
                 }
                 else {
                     ap_rputs("<tt> none</tt>\n", r);
index f965592cc097279d498b4da92bb7655f2aa8c349..51fe37a14d76535510aa135d449fb896231bfaeb 100644 (file)
@@ -1318,6 +1318,18 @@ static void process_command_config(server_rec *s, apr_array_header_t *arr,
     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, const char *fname, 
                                 ap_directive_t **conftree, apr_pool_t *p, 
                                 apr_pool_t *ptemp)
@@ -1337,6 +1349,58 @@ void ap_process_resource_config(server_rec *s, const char *fname,
            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)) {
+        apr_dir_t *dirp;
+       int current;
+       apr_array_header_t *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);
+       if (apr_opendir(&dirp, fname, p) != APR_SUCCESS) {
+           perror("fopen");
+           fprintf(stderr, "%s: could not open config directory %s\n",
+               ap_server_argv0, fname);
+           exit(1);
+       }
+       candidates = apr_make_array(p, 1, sizeof(fnames));
+        while (apr_readdir(dirp) == APR_SUCCESS) {
+            char *d_name;
+           apr_get_dir_filename(&d_name, dirp);
+           /* strip out '.' and '..' */
+           if (strcmp(d_name, ".") &&
+               strcmp(d_name, "..")) {
+               fnew = (fnames *) apr_push_array(candidates);
+               fnew->fname = ap_make_full_path(p, fname, d_name);
+           }
+       }
+       apr_closedir(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, conftree, p, ptemp);
+           }
+       }
+       return;
+    }
+    
     /* GCC's initialization extensions are soooo nice here... */
 
     parms = default_parms;
@@ -1472,7 +1536,6 @@ int ap_parse_htaccess(void **result, request_rec *r, int override,
     return OK;
 }
 
-
 CORE_EXPORT(const char *) ap_init_virtual_host(apr_pool_t *p, const char *hostname,
                              server_rec *main_server, server_rec **ps)
 {
index 2273058283f70e2eb40c82110047e8e7a496d521..9191ad0df9db8f727a5efd930c77e0485ba251f7 100644 (file)
@@ -333,6 +333,32 @@ API_EXPORT(char *) ap_strcasestr(const char *s1, const char *s2)
     }
     return((char *)s1);
 }
+
+/*
+ * Returns an offsetted pointer in bigstring immediately after
+ * prefix. Returns bigstring if bigstring doesn't start with
+ * prefix or if prefix is longer than bigstring while still matching.
+ * NOTE: pointer returned is relative to bigstring, so we
+ * can use standard pointer comparisons in the calling function
+ * (eg: test if ap_stripprefix(a,b) == a)
+ */
+API_EXPORT(char *) ap_stripprefix(const char *bigstring, const char *prefix)
+{
+    char *p1;
+    if (*prefix == '\0') {
+        return( (char *)bigstring);
+    }
+    p1 = (char *)bigstring;
+    while(*p1 && *prefix) {
+        if (*p1++ != *prefix++)
+            return( (char *)bigstring);
+    }
+    if (*prefix == '\0')
+        return(p1);
+    else /* hit the end of bigstring! */
+        return( (char *)bigstring);
+}
+
 /* 
  * Apache stub function for the regex libraries regexec() to make sure the
  * whole regex(3) API is available through the Apache (exported) namespace.
@@ -1652,6 +1678,16 @@ API_EXPORT(int) ap_is_directory(const char *path)
     return (finfo.filetype == APR_DIR);
 }
 
+API_EXPORT(int) ap_is_rdirectory(const char *path)
+{
+    apr_finfo_t finfo;
+
+    if (apr_lstat(&finfo, path, NULL) == -1)
+       return 0;               /* in error condition, just return no */
+
+    return (finfo.filetype == APR_DIR);
+}
+
 API_EXPORT(char *) ap_make_full_path(apr_pool_t *a, const char *src1,
                                  const char *src2)
 {