httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@locus.apache.org
Subject cvs commit: apache-1.3/src/modules/standard mod_info.c
Date Tue, 03 Oct 2000 16:39:48 GMT
jim         00/10/03 09:39:46

  Modified:    src      CHANGES
               src/include ap_mmn.h httpd.h
               src/main http_config.c util.c
               src/modules/standard mod_info.c
  Log:
  Add the concept and implementation for a runtime config
  directory, ala /etc/rc.d/init. Basically, if any of the
  config "files" are actually directories, all files in
  that directory (and in subdirectories) will be parsed as
  config files. Thus you can add new config directives with
  no file edits at all, simply file additions.
  PR: 6397
  Submitted by:	Lionel Clark <bishop@platypus.bc.ca> (concept + initial patch)
  Reviewed by:	William A. Rowe, Jr
  
  Revision  Changes    Path
  1.1583    +6 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1582
  retrieving revision 1.1583
  diff -u -r1.1582 -r1.1583
  --- CHANGES	2000/09/28 13:32:31	1.1582
  +++ CHANGES	2000/10/03 16:39:35	1.1583
  @@ -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>]
   
  
  
  
  1.51      +2 -1      apache-1.3/src/include/ap_mmn.h
  
  Index: ap_mmn.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/ap_mmn.h,v
  retrieving revision 1.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- ap_mmn.h	2000/07/30 17:26:31	1.50
  +++ ap_mmn.h	2000/10/03 16:39:38	1.51
  @@ -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() and ap_stripprefix()
    */
   
   #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)		\
  
  
  
  1.316     +2 -0      apache-1.3/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.315
  retrieving revision 1.316
  diff -u -r1.315 -r1.316
  --- httpd.h	2000/09/22 18:17:48	1.315
  +++ httpd.h	2000/10/03 16:39:38	1.316
  @@ -1026,6 +1026,7 @@
   API_EXPORT(int) ap_is_matchexp(const char *str);
   API_EXPORT(int) ap_strcmp_match(const char *str, const char *exp);
   API_EXPORT(int) ap_strcasecmp_match(const char *str, const char *exp);
  +API_EXPORT(char *) ap_stripprefix(const char *bigstring, const char *prefix);
   API_EXPORT(char *) ap_strcasestr(const char *s1, const char *s2);
   API_EXPORT(char *) ap_pbase64decode(pool *p, const char *bufcoded);
   API_EXPORT(char *) ap_pbase64encode(pool *p, char *string); 
  @@ -1090,6 +1091,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);
   
  
  
  
  1.154     +68 -1     apache-1.3/src/main/http_config.c
  
  Index: http_config.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/http_config.c,v
  retrieving revision 1.153
  retrieving revision 1.154
  diff -u -r1.153 -r1.154
  --- http_config.c	2000/06/01 23:42:24	1.153
  +++ http_config.c	2000/10/03 16:39:40	1.154
  @@ -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)
  
  
  
  1.188     +40 -0     apache-1.3/src/main/util.c
  
  Index: util.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/util.c,v
  retrieving revision 1.187
  retrieving revision 1.188
  diff -u -r1.187 -r1.188
  --- util.c	2000/09/22 18:33:17	1.187
  +++ util.c	2000/10/03 16:39:40	1.188
  @@ -335,6 +335,32 @@
       }
       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.
  @@ -1650,6 +1676,20 @@
   	return 0;		/* in error condition, just return no */
   
       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,
  
  
  
  1.50      +100 -29   apache-1.3/src/modules/standard/mod_info.c
  
  Index: mod_info.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_info.c,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- mod_info.c	2000/06/01 23:42:28	1.49
  +++ mod_info.c	2000/10/03 16:39:45	1.50
  @@ -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));
  @@ -153,10 +171,10 @@
       }
       /* oops, overflowed... don't overwrite */
       if (t > end_buf) {
  -	*end_buf = '\0';
  +        *end_buf = '\0';
       }
       else {
  -	*t = '\0';
  +        *t = '\0';
       }
       return (buf);
   }
  @@ -172,8 +190,8 @@
       fp = ap_pcfg_openfile(p, filename);
       if (!fp) {
           ap_log_rerror(APLOG_MARK, APLOG_WARNING, r, 
  -		    "mod_info: couldn't open config file %s",
  -		    filename);
  +                    "mod_info: couldn't open config file %s",
  +                    filename);
           return NULL;
       }
       ret = NULL;
  @@ -190,14 +208,14 @@
           if (prev) {
               prev->next = new;
           }
  -	t = s;
  -	new->cmd = ap_getword_conf(p, &t);
  -	if (*t) {
  -	    new->line = ap_pstrdup(p, t);
  -	}
  -	else {
  -	    new->line = NULL;
  -	}
  +        t = s;
  +        new->cmd = ap_getword_conf(p, &t);
  +        if (*t) {
  +            new->line = ap_pstrdup(p, t);
  +        }
  +        else {
  +            new->line = NULL;
  +        }
           prev = new;
       }
       ap_cfg_closefile(fp);
  @@ -324,7 +342,7 @@
                           ap_rputs(mod_info_html_cmd_string(li->line, buf, sizeof(buf)),
r);
                           ap_rputs("</i>", r);
                       }
  -		    ap_rputs("</tt>", r);
  +                    ap_rputs("</tt>", r);
                   }
               }
               else
  @@ -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,13 +428,14 @@
       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;
  +    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);
  @@ -379,15 +445,16 @@
       ap_hard_timeout("send server info", r);
   
       ap_rputs(DOCTYPE_HTML_3_2
  -	     "<html><head><title>Server Information</title></head>\n",
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 = 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) {
  @@ -590,8 +657,8 @@
                       while (cmd) {
                           if (cmd->name) {
                               ap_rprintf(r, "<dd><tt>%s - <i>",
  -				    mod_info_html_cmd_string(cmd->name,
  -					buf, sizeof(buf)));
  +                                    mod_info_html_cmd_string(cmd->name,
  +                                        buf, sizeof(buf)));
                               if (cmd->errmsg) {
                                   ap_rputs(cmd->errmsg, r);
                               }
  @@ -603,12 +670,16 @@
                           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);
  
  
  

Mime
View raw message