]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
clean up cmd_parms: config_file is no longer valid; end_token is bogus;
authorGreg Stein <gstein@apache.org>
Mon, 24 Apr 2000 12:00:43 +0000 (12:00 +0000)
committerGreg Stein <gstein@apache.org>
Mon, 24 Apr 2000 12:00:43 +0000 (12:00 +0000)
    add directive.
move configfile_t and functions from httpd.h to http_config.h
new signature for ap_build_config() (since config_file removed from cmd_parms)
add "data" to ap_directive_t for future use by modules. add filename.
syntax checking for section-close directives: a section-open must exist,
    the section-close must be </FOO>, and the open/close must match.
    the file as a whole must be properly balanced (issue errors for each
    unmatched section-open).
</FOO> command_rec structures are obsolete. Remove from http_core.c.
do not store </FOO> directives in the config tree.
clean out section-close logic from http_core.c (and old, related comments)
<Limit> and <LimitExcept> must walk their children.
new mechanism in ap_check_cmd_context() for testing enclosure in a
    Directory/Location/File: find_parent()
<IfModule> and <IfDefine> must pass cmd->context when walking the children
several places: we had a walk followed by ap_get_module_config(). that
    assumed the walk would create a config that we could fetch, which is not
    true -- it is possible that the children are all from other modules
    (e.g. the <Files> section in httpd.conf-dist has no "core" directives).
    using ap_set_config_vectors() ensures we get a structure, and it returns
    it to us.
    [ note: when we had </Directory> (and friends) in the tree, the config
      would get created; removing the directive removed the config; this
      was a bitch to track down :-) ]

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85024 13f79535-47bb-0310-9956-ffa450edef68

include/http_config.h
include/httpd.h
include/util_cfgtree.h
modules/http/http_core.c
server/config.c
server/util.c

index a72f60a6669d65ee9499e8529f8b34916b740dd1..1be40d8518787829c0361ed3c5197b5a5942514f 100644 (file)
@@ -155,7 +155,7 @@ typedef struct {
     int override;              /* Which allow-override bits are set */
     int limited;               /* Which methods are <Limit>ed */
 
-    configfile_t *config_file; /* Config file structure from pcfg_openfile() */
+    ap_directive_t *directive; /* the directive specifying this command */
 
     ap_pool_t *pool;                   /* Pool to allocate new storage in */
     ap_pool_t *temp_pool;              /* Pool for scratch memory; persists during
@@ -173,7 +173,7 @@ typedef struct {
                                 * or being called in a dir context (path != NULL).
                                 */
     const command_rec *cmd;    /* configuration command */
-    const char *end_token;     /* end token required to end a nested section */
+
     void *context;             /* per_dir_config vector passed 
                                 * to handle_command */
 } cmd_parms;
@@ -304,8 +304,39 @@ API_EXPORT(void) ap_clear_module_list(void);
 API_EXPORT(const char *) ap_find_module_name(module *m);
 API_EXPORT(module *) ap_find_linked_module(const char *name);
 
+/* Common structure for reading of config files / passwd files etc. */
+typedef struct {
+    int (*getch) (void *param);        /* a getc()-like function */
+    void *(*getstr) (void *buf, size_t bufsiz, void *param); /* a fgets()-like function */
+    int (*close) (void *param);        /* a close hander function */
+    void *param;               /* the argument passed to getch/getstr/close */
+    const char *name;          /* the filename / description */
+    unsigned line_number;      /* current line number, starting at 1 */
+} configfile_t;
+
+/* Open a configfile_t as FILE, return open configfile_t struct pointer */
+API_EXPORT(ap_status_t) ap_pcfg_openfile(configfile_t **, ap_pool_t *p, const char *name);
+
+/* Allocate a configfile_t handle with user defined functions and params */
+API_EXPORT(configfile_t *) ap_pcfg_open_custom(ap_pool_t *p, const char *descr,
+    void *param,
+    int(*getc_func)(void*),
+    void *(*gets_func) (void *buf, size_t bufsiz, void *param),
+    int(*close_func)(void *param));
+
+/* Read one line from open configfile_t, strip LF, increase line number */
+API_EXPORT(int) ap_cfg_getline(char *buf, size_t bufsize, configfile_t *cfp);
+
+/* Read one char from open configfile_t, increase line number upon LF */
+API_EXPORT(int) ap_cfg_getc(configfile_t *cfp);
+
+/* Detach from open configfile_t, calling the close handler */
+API_EXPORT(int) ap_cfg_closefile(configfile_t *cfp);
+
 /* for implementing subconfigs and customized config files */
-API_EXPORT(const char *) ap_build_config(cmd_parms *parms,
+API_EXPORT(const char *) ap_build_config(configfile_t *cfp,
+                                        ap_pool_t *conf_pool,
+                                        ap_pool_t *temp_pool,
                                         ap_directive_t **conftree);
 API_EXPORT(const char *) ap_walk_config(ap_directive_t *conftree, cmd_parms *parms, void *config, int container);
 
index 1e9b63ed27decea8ddd84fd582324c2bb2d4912a..15740140985a73386562f9722aaed8b5c78f963f 100644 (file)
@@ -991,35 +991,6 @@ API_EXPORT(int) ap_rind(const char *, char);
 
 API_EXPORT(char *) ap_escape_quotes (ap_pool_t *p, const char *instring);
 
-/* Common structure for reading of config files / passwd files etc. */
-typedef struct {
-    int (*getch) (void *param);        /* a getc()-like function */
-    void *(*getstr) (void *buf, size_t bufsiz, void *param); /* a fgets()-like function */
-    int (*close) (void *param);        /* a close hander function */
-    void *param;               /* the argument passed to getch/getstr/close */
-    const char *name;          /* the filename / description */
-    unsigned line_number;      /* current line number, starting at 1 */
-} configfile_t;
-
-/* Open a configfile_t as FILE, return open configfile_t struct pointer */
-API_EXPORT(ap_status_t) ap_pcfg_openfile(configfile_t **, ap_pool_t *p, const char *name);
-
-/* Allocate a configfile_t handle with user defined functions and params */
-API_EXPORT(configfile_t *) ap_pcfg_open_custom(ap_pool_t *p, const char *descr,
-    void *param,
-    int(*getc_func)(void*),
-    void *(*gets_func) (void *buf, size_t bufsiz, void *param),
-    int(*close_func)(void *param));
-
-/* Read one line from open configfile_t, strip LF, increase line number */
-API_EXPORT(int) ap_cfg_getline(char *buf, size_t bufsize, configfile_t *cfp);
-
-/* Read one char from open configfile_t, increase line number upon LF */
-API_EXPORT(int) ap_cfg_getc(configfile_t *cfp);
-
-/* Detach from open configfile_t, calling the close handler */
-API_EXPORT(int) ap_cfg_closefile(configfile_t *cfp);
-
 /* Misc system hackery */
 
 API_EXPORT(uid_t) ap_uname2id(const char *name);
index 6a4a2f6f27eb0e223f33222d0dec52de6c8d0c74..d8e5bc8c7d7d250b751320bb0198a201650f4478 100644 (file)
 typedef struct ap_directive_t {
     const char *directive;
     const char *args;
-    int line_num;
     struct ap_directive_t *next;
     struct ap_directive_t *first_child;
     struct ap_directive_t *parent;
+
+    void *data;                /* directive's module can store add'l data here */
+
+    /* ### these may go away in the future, but are needed for now */
+    const char *filename;
+    int line_num;
+
 } ap_directive_t;
 
 ap_directive_t *ap_add_node(ap_directive_t **parent, ap_directive_t *current, 
index 541658a76c3a2ca0e699477b7cf52153bffc8c1d..f14f62254e5790e056dd7979a4e331111a5fd1a5 100644 (file)
@@ -928,16 +928,19 @@ API_EXPORT (file_type_e) ap_get_win32_interpreter(const  request_rec *r,
  * commands, but most of the old srm.conf is in the the modules.
  */
 
-static const char end_directory_section[] = "</Directory>";
-static const char end_directorymatch_section[] = "</DirectoryMatch>";
-static const char end_location_section[] = "</Location>";
-static const char end_locationmatch_section[] = "</LocationMatch>";
-static const char end_files_section[] = "</Files>";
-static const char end_filesmatch_section[] = "</FilesMatch>";
-static const char end_virtualhost_section[] = "</VirtualHost>";
-static const char end_ifmodule_section[] = "</IfModule>";
-static const char end_ifdefine_section[] = "</IfDefine>";
 
+/* returns a parent if it matches the given directive */
+static const ap_directive_t * find_parent(const ap_directive_t *dirp,
+                                         const char *what)
+{
+    while (dirp->parent != NULL) {
+       dirp = dirp->parent;
+       /* ### it would be nice to have atom-ized directives */
+       if (strcasecmp(dirp->directive, what) == 0)
+           return dirp;
+    }
+    return NULL;
+}
 
 API_EXPORT(const char *) ap_check_cmd_context(cmd_parms *cmd,
                                              unsigned forbidden)
@@ -945,6 +948,7 @@ API_EXPORT(const char *) ap_check_cmd_context(cmd_parms *cmd,
     const char *gt = (cmd->cmd->name[0] == '<'
                      && cmd->cmd->name[strlen(cmd->cmd->name)-1] != '>')
                          ? ">" : "";
+    const ap_directive_t *found;
 
     if ((forbidden & NOT_IN_VIRTUALHOST) && cmd->server->is_virtual) {
        return ap_pstrcat(cmd->pool, cmd->cmd->name, gt,
@@ -964,17 +968,17 @@ API_EXPORT(const char *) ap_check_cmd_context(cmd_parms *cmd,
     }
     
     if (((forbidden & NOT_IN_DIRECTORY)
-        && (cmd->end_token == end_directory_section
-            || cmd->end_token == end_directorymatch_section)) 
+        && ((found = find_parent(cmd->directive, "<Directory"))
+            || (found = find_parent(cmd->directive, "<DirectoryMatch"))))
        || ((forbidden & NOT_IN_LOCATION)
-           && (cmd->end_token == end_location_section
-               || cmd->end_token == end_locationmatch_section)) 
+           && ((found = find_parent(cmd->directive, "<Location"))
+               || (found = find_parent(cmd->directive, "<LocationMatch"))))
        || ((forbidden & NOT_IN_FILES)
-           && (cmd->end_token == end_files_section
-               || cmd->end_token == end_filesmatch_section))) {
+           && ((found = find_parent(cmd->directive, "<Files"))
+               || (found = find_parent(cmd->directive, "<FilesMatch"))))) {
        return ap_pstrcat(cmd->pool, cmd->cmd->name, gt,
-                         " cannot occur within <", cmd->end_token+2,
-                         " section", NULL);
+                         " cannot occur within ", found->directive,
+                         "> section", NULL);
     }
 
     return NULL;
@@ -1140,15 +1144,6 @@ static const char *set_error_document(cmd_parms *cmd, core_dir_config *conf,
     return NULL;
 }
 
-/* access.conf commands...
- *
- * The *only* thing that can appear in access.conf at top level is a
- * <Directory> section.  NB we need to have a way to cut the srm_command_loop
- * invoked by dirsection (i.e., <Directory>) short when </Directory> is seen.
- * We do that by returning an error, which dirsection itself recognizes and
- * discards as harmless.  Cheesy, but it works.
- */
-
 static const char *set_override(cmd_parms *cmd, core_dir_config *d,
                                const char *l)
 {
@@ -1297,16 +1292,12 @@ CORE_EXPORT_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy,
     const char *limited_methods = ap_getword(cmd->pool, &arg, '>');
     void *tog = cmd->cmd->cmd_data;
     int limited = 0;
+    const char *errmsg;
   
     const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
     if (err != NULL) {
         return err;
     }
-
-    /* XXX: NB: Currently, we have no way of checking
-     * whether <Limit> or <LimitExcept> sections are closed properly.
-     * (If we would add a srm_command_loop() here we might...)
-     */
     
     while (limited_methods[0]) {
         char *method = ap_getword_conf(cmd->pool, &limited_methods);
@@ -1328,33 +1319,12 @@ CORE_EXPORT_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy,
      * if (tog == NULL) <Limit>, else <LimitExcept>
      */
     cmd->limited = tog ? ~limited : limited;
-    return NULL;
-}
 
-static const char *endlimit_section(cmd_parms *cmd, void *dummy, void *dummy2)
-{
-    void *tog = cmd->cmd->cmd_data;
+    errmsg = ap_walk_config(NULL, cmd, cmd->context, 1);
 
-    if (cmd->limited == -1) {
-        return tog ? "</LimitExcept> unexpected" : "</Limit> unexpected";
-    }
-    
     cmd->limited = -1;
-    return NULL;
-}
 
-/*
- * When a section is not closed properly when end-of-file is reached,
- * then an error message should be printed:
- */
-static const char *missing_endsection(cmd_parms *cmd, int nest)
-{
-    if (nest < 2) {
-       return ap_psprintf(cmd->pool, "Missing %s directive at end-of-file",
-                          cmd->end_token);
-    }
-    return ap_psprintf(cmd->pool, "%d missing %s directives at end-of-file",
-                      nest, cmd->end_token);
+    return errmsg;
 }
 
 /* We use this in <DirectoryMatch> and <FilesMatch>, to ensure that 
@@ -1367,25 +1337,6 @@ static const char *missing_endsection(cmd_parms *cmd, int nest)
 #define USE_ICASE 0
 #endif
 
-static const char *end_nested_section(cmd_parms *cmd, void *dummy)
-{
-    if (cmd->end_token == NULL) {
-        return ap_pstrcat(cmd->pool, cmd->cmd->name,
-                         " without matching <", cmd->cmd->name + 2, 
-                         " section", NULL);
-    }
-    /*
-     * This '!=' may look weird on a string comparison, but it's correct --
-     * it's been set up so that checking for two pointers to the same datum
-     * is valid here.  And faster.
-     */
-    if (cmd->cmd->name != cmd->end_token) {
-       return ap_pstrcat(cmd->pool, "Expected ", cmd->end_token, " but saw ",
-                         cmd->cmd->name, NULL);
-    }
-    return NULL;
-}
-
 /*
  * Report a missing-'>' syntax error.
  */
@@ -1404,7 +1355,6 @@ static const char *dirsection(cmd_parms *cmd, void *dummy, const char *arg)
     core_dir_config *conf;
     void *new_dir_conf = ap_create_per_dir_config(cmd->pool);
     regex_t *r = NULL;
-    const char *old_end_token;
     const command_rec *thiscmd = cmd->cmd;
 
     const char *err = ap_check_cmd_context(cmd,
@@ -1434,15 +1384,14 @@ static const char *dirsection(cmd_parms *cmd, void *dummy, const char *arg)
        cmd->path = ap_os_canonical_filename(cmd->pool, cmd->path);
     }
 
-    old_end_token = cmd->end_token;
-    cmd->end_token = thiscmd->cmd_data ? end_directorymatch_section : end_directory_section;
+    /* initialize our config and fetch it */
+    conf = (core_dir_config *)ap_set_config_vectors(cmd, new_dir_conf,
+                                                   &core_module);
 
     errmsg = ap_walk_config(NULL, cmd, new_dir_conf, 1);
-    cmd->end_token = old_end_token;
     if (errmsg != NULL)
        return errmsg;
 
-    conf = (core_dir_config *)ap_get_module_config(new_dir_conf, &core_module);
     conf->r = r;
 
     ap_add_per_dir_conf(cmd->server, new_dir_conf);
@@ -1466,7 +1415,6 @@ static const char *urlsection(cmd_parms *cmd, void *dummy, const char *arg)
     char *old_path = cmd->path;
     core_dir_config *conf;
     regex_t *r = NULL;
-    const char *old_end_token;
     const command_rec *thiscmd = cmd->cmd;
 
     void *new_url_conf = ap_create_per_dir_config(cmd->pool);
@@ -1494,16 +1442,14 @@ static const char *urlsection(cmd_parms *cmd, void *dummy, const char *arg)
        r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
     }
 
-    old_end_token = cmd->end_token;
-    cmd->end_token = thiscmd->cmd_data ? end_locationmatch_section
-                                       : end_location_section;
+    /* initialize our config and fetch it */
+    conf = (core_dir_config *)ap_set_config_vectors(cmd, new_url_conf,
+                                                   &core_module);
 
     errmsg = ap_walk_config(NULL, cmd, new_url_conf, 1);
-    cmd->end_token = old_end_token;
     if (errmsg != NULL)
        return errmsg;
 
-    conf = (core_dir_config *)ap_get_module_config(new_url_conf, &core_module);
     conf->d = ap_pstrdup(cmd->pool, cmd->path);        /* No mangling, please */
     conf->d_is_fnmatch = ap_is_fnmatch(conf->d) != 0;
     conf->r = r;
@@ -1530,7 +1476,6 @@ static const char *filesection(cmd_parms *cmd, core_dir_config *c,
     char *old_path = cmd->path;
     core_dir_config *conf;
     regex_t *r = NULL;
-    const char *old_end_token;
     const command_rec *thiscmd = cmd->cmd;
 
     void *new_file_conf = ap_create_per_dir_config(cmd->pool);
@@ -1564,16 +1509,14 @@ static const char *filesection(cmd_parms *cmd, core_dir_config *c,
        cmd->path = ap_os_canonical_filename(cmd->pool, cmd->path);
     }
 
-    old_end_token = cmd->end_token;
-    cmd->end_token = thiscmd->cmd_data ? end_filesmatch_section : end_files_section;
+    /* initialize our config and fetch it */
+    conf = (core_dir_config *)ap_set_config_vectors(cmd, new_file_conf,
+                                                   &core_module);
 
     errmsg = ap_walk_config(NULL, cmd, new_file_conf, 1);
-    cmd->end_token = old_end_token;
     if (errmsg != NULL)
        return errmsg;
 
-    conf = (core_dir_config *)ap_get_module_config(new_file_conf,
-                                                  &core_module);
     conf->d = cmd->path;
     conf->d_is_fnmatch = ap_is_fnmatch(conf->d) != 0;
     conf->r = r;
@@ -1591,16 +1534,6 @@ static const char *filesection(cmd_parms *cmd, core_dir_config *c,
     return NULL;
 }
 
-/* XXX: NB: Currently, we have no way of checking
- * whether <IfModule> sections are closed properly.
- * Extra (redundant, unpaired) </IfModule> directives are
- * simply silently ignored.
- */
-static const char *end_ifmod(cmd_parms *cmd, void *dummy)
-{
-    return NULL;
-}
-
 static const char *start_ifmod(cmd_parms *cmd, void *dummy, char *arg)
 {
     char *endp = strrchr(arg, '>');
@@ -1620,7 +1553,7 @@ static const char *start_ifmod(cmd_parms *cmd, void *dummy, char *arg)
     found = ap_find_linked_module(arg);
 
     if ((!not && found) || (not && !found)) {
-        return ap_walk_config(NULL, cmd, cmd->server->lookup_defaults, 1);
+        return ap_walk_config(NULL, cmd, cmd->context, 1);
     }
 
     return NULL;
@@ -1640,11 +1573,6 @@ API_EXPORT(int) ap_exists_config_define(char *name)
     return 0;
 }
 
-static const char *end_ifdefine(cmd_parms *cmd, void *dummy) 
-{
-    return NULL;
-}
-
 static const char *start_ifdefine(cmd_parms *cmd, void *dummy, char *arg)
 {
     char *endp;
@@ -1666,7 +1594,7 @@ static const char *start_ifdefine(cmd_parms *cmd, void *dummy, char *arg)
     defined = ap_exists_config_define(arg);
 
     if ((!not && defined) || (not && !defined)) {
-        return ap_walk_config(NULL, cmd, dummy, 1);
+        return ap_walk_config(NULL, cmd, cmd->context, 1);
     }
 
     return NULL;
@@ -1680,7 +1608,6 @@ static const char *virtualhost_section(cmd_parms *cmd, void *dummy, char *arg)
     const char *errmsg;
     char *endp = strrchr(arg, '>');
     ap_pool_t *p = cmd->pool;
-    const char *old_end_token;
 
     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
     if (err != NULL) {
@@ -1710,15 +1637,13 @@ static const char *virtualhost_section(cmd_parms *cmd, void *dummy, char *arg)
     s->next = main_server->next;
     main_server->next = s;
 
-    s->defn_name = cmd->config_file->name;
-    s->defn_line_number = cmd->config_file->line_number;
+    s->defn_name = cmd->directive->filename;
+    s->defn_line_number = cmd->directive->line_num;
 
-    old_end_token = cmd->end_token;
-    cmd->end_token = end_virtualhost_section;
     cmd->server = s;
 
     errmsg = ap_walk_config(NULL, cmd, s->lookup_defaults, 1);
-    cmd->end_token = old_end_token;
+
     cmd->server = main_server;
 
     return errmsg;
@@ -2222,53 +2147,31 @@ static const command_rec core_cmds[] = {
 { "<Directory", dirsection, NULL, RSRC_CONF, RAW_ARGS,
   "Container for directives affecting resources located in the specified "
   "directories" },
-{ end_directory_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS,
-  "Marks end of <Directory>" },
 { "<Location", urlsection, NULL, RSRC_CONF, RAW_ARGS,
   "Container for directives affecting resources accessed through the "
   "specified URL paths" },
-{ end_location_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS,
-  "Marks end of <Location>" },
 { "<VirtualHost", virtualhost_section, NULL, RSRC_CONF, RAW_ARGS,
   "Container to map directives to a particular virtual host, takes one or "
   "more host addresses" },
-{ end_virtualhost_section, end_nested_section, NULL, RSRC_CONF, NO_ARGS,
-  "Marks end of <VirtualHost>" },
 { "<Files", filesection, NULL, OR_ALL, RAW_ARGS, "Container for directives "
   "affecting files matching specified patterns" },
-{ end_files_section, end_nested_section, NULL, OR_ALL, NO_ARGS,
-  "Marks end of <Files>" },
 { "<Limit", ap_limit_section, NULL, OR_ALL, RAW_ARGS, "Container for "
   "authentication directives when accessed using specified HTTP methods" },
-{ "</Limit>", endlimit_section, NULL, OR_ALL, NO_ARGS,
-  "Marks end of <Limit>" },
 { "<LimitExcept", ap_limit_section, (void*)1, OR_ALL, RAW_ARGS,
   "Container for authentication directives to be applied when any HTTP "
   "method other than those specified is used to access the resource" },
-{ "</LimitExcept>", endlimit_section, (void*)1, OR_ALL, NO_ARGS,
-  "Marks end of <LimitExcept>" },
 { "<IfModule", start_ifmod, NULL, OR_ALL, TAKE1,
   "Container for directives based on existance of specified modules" },
-{ end_ifmodule_section, end_ifmod, NULL, OR_ALL, NO_ARGS,
-  "Marks end of <IfModule>" },
 { "<IfDefine", start_ifdefine, NULL, OR_ALL, TAKE1,
   "Container for directives based on existance of command line defines" },
-{ end_ifdefine_section, end_ifdefine, NULL, OR_ALL, NO_ARGS,
-  "Marks end of <IfDefine>" },
 { "<DirectoryMatch", dirsection, (void*)1, RSRC_CONF, RAW_ARGS,
   "Container for directives affecting resources located in the "
   "specified directories" },
-{ end_directorymatch_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS,
-  "Marks end of <DirectoryMatch>" },
 { "<LocationMatch", urlsection, (void*)1, RSRC_CONF, RAW_ARGS,
   "Container for directives affecting resources accessed through the "
   "specified URL paths" },
-{ end_locationmatch_section, end_nested_section, NULL, ACCESS_CONF, NO_ARGS,
-  "Marks end of <LocationMatch>" },
 { "<FilesMatch", filesection, (void*)1, OR_ALL, RAW_ARGS,
   "Container for directives affecting files matching specified patterns" },
-{ end_filesmatch_section, end_nested_section, NULL, OR_ALL, NO_ARGS,
-  "Marks end of <FilesMatch>" },
 { "AuthType", ap_set_string_slot,
   (void*)XtOffsetOf(core_dir_config, ap_auth_type), OR_AUTHCFG, TAKE1,
   "An HTTP authorization type (e.g., \"Basic\")" },
index 0d9f2022b084ef27a9dffc0384e98783b167d3d0..c693d036a49fe7aa47c86597ed59bf70bd852fc1 100644 (file)
@@ -831,42 +831,64 @@ CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module
     return mconfig;
 }
 
-static const char * ap_build_config_sub(cmd_parms *parms, const char *l,
+static const char * ap_build_config_sub(ap_pool_t *p, ap_pool_t *temp_pool,
+                                       const configfile_t *cfp,
+                                       const char *l,
                                        ap_directive_t **current,
                                        ap_directive_t **curr_parent)
 {
-    const char *args, *cmd_name;
+    const char *args;
+    char *cmd_name;
     ap_directive_t *newdir;
 
-    if ((l[0] == '#') || (!l[0]))
+    if (*l == '#' || *l == '\0')
        return NULL;
 
 #if RESOLVE_ENV_PER_TOKEN
     args = l;
 #else
-    args = ap_resolve_env(parms->temp_pool,l); 
+    args = ap_resolve_env(temp_pool, l); 
 #endif
-    cmd_name = ap_getword_conf(parms->temp_pool, &args);
-    if (*cmd_name == '\0')
+    cmd_name = ap_getword_conf(p, &args);
+    if (*cmd_name == '\0') {
+       /* Note: this branch should not occur. An empty line should have
+        * triggered the exit further above.
+        */
        return NULL;
+    }
 
-    newdir = ap_pcalloc(parms->pool, sizeof(ap_directive_t));
-    newdir->line_num = parms->config_file->line_number;
-    newdir->directive = ap_pstrdup(parms->pool, cmd_name);
-    newdir->args = ap_pstrdup(parms->pool, args);
+    newdir = ap_pcalloc(p, sizeof(ap_directive_t));
+    newdir->filename = cfp->name;
+    newdir->line_num = cfp->line_number;
+    newdir->directive = cmd_name;
+    newdir->args = ap_pstrdup(p, args);
 
     if (cmd_name[0] == '<') {
         if (cmd_name[1] != '/') {
             (*current) = ap_add_node(curr_parent, *current, newdir, 1);
         }
-        else {
-            /* The next line needs to be removed once we have a validating
-             * tree building routine.
-             * It is left in for now, so that we can ensure that 
-             * a container directive is followed by an appropriate closing
-             * directive.
-             */
-            *current = ap_add_node(curr_parent, *current, newdir, 0);
+       else if (*curr_parent == NULL) {
+           return ap_pstrcat(p, cmd_name,
+                             " without matching <", cmd_name + 2,
+                             " section", NULL);
+       }
+       else {
+           char *bracket = cmd_name + strlen(cmd_name) - 1;
+
+           if (*bracket != '>') {
+               return ap_pstrcat(p, cmd_name,
+                                 "> directive missing closing '>'", NULL);
+           }
+           *bracket = '\0';
+           if (strcasecmp(cmd_name + 2,
+                           (*curr_parent)->directive + 1) != 0) {
+               return ap_pstrcat(p, "Expected </",
+                                 (*curr_parent)->directive + 1, "> but saw ",
+                                 cmd_name, ">", NULL);
+           }
+           *bracket = '>';
+
+           /* done with this section; move up a level */
             *current = *curr_parent;
             *curr_parent = (*current)->parent;
         }
@@ -886,6 +908,8 @@ static const char *ap_walk_config_sub(ap_directive_t *current,
     module *mod = top_module;
     const char *retval;
 
+    parms->directive = current;
+
     oldconfig = parms->context;
     parms->context = config;
     do {
@@ -941,19 +965,21 @@ API_EXPORT(const char *) ap_walk_config(ap_directive_t *conftree,
 }
 
 
-API_EXPORT(const char *) ap_build_config(cmd_parms *parms,
+API_EXPORT(const char *) ap_build_config(configfile_t *cfp,
+                                        ap_pool_t *p, ap_pool_t *temp_pool,
                                         ap_directive_t **conftree)
 {
     ap_directive_t *current = NULL;
     ap_directive_t *curr_parent = NULL;
     char l[MAX_STRING_LEN];
+    const char *errmsg;
 
     *conftree = NULL;
 
-    while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
-       const char *errmsg;
+    while (!(ap_cfg_getline(l, MAX_STRING_LEN, cfp))) {
 
-       errmsg = ap_build_config_sub(parms, l, &current, &curr_parent);
+       errmsg = ap_build_config_sub(p, temp_pool, cfp, l,
+                                    &current, &curr_parent);
        if (errmsg != NULL)
            return errmsg;
 
@@ -962,6 +988,20 @@ API_EXPORT(const char *) ap_build_config(cmd_parms *parms,
         }
     }
 
+    if (curr_parent != NULL) {
+       errmsg = "";
+       while (curr_parent != NULL) {
+           errmsg = ap_psprintf(p, "%s%s%s:%u: %s> was not closed.",
+                                errmsg,
+                                *errmsg == '\0' ? "" : "\n",
+                                curr_parent->filename,
+                                curr_parent->line_num,
+                                curr_parent->directive);
+           curr_parent = curr_parent->parent;
+       }
+       return errmsg;
+    }
+
     return NULL;
 }
 
@@ -1078,6 +1118,7 @@ static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_poo
     cmd_parms parms;
     arr_elts_param_t arr_parms;
     ap_directive_t *conftree;
+    configfile_t *cfp;
 
     arr_parms.curr_idx = 0;
     arr_parms.array = arr;
@@ -1087,11 +1128,12 @@ static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_poo
     parms.temp_pool = ptemp;
     parms.server = s;
     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
-    parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
-                                         &arr_parms, NULL,
-                                         arr_elts_getstr, arr_elts_close);
 
-    errmsg = ap_build_config(&parms, &conftree);
+    cfp = ap_pcfg_open_custom(p, "-c/-C directives",
+                             &arr_parms, NULL,
+                             arr_elts_getstr, arr_elts_close);
+
+    errmsg = ap_build_config(cfp, p, ptemp, &conftree);
     if (errmsg == NULL)
        errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults, 0);
     if (errmsg) {
@@ -1100,7 +1142,7 @@ static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_poo
         exit(1);
     }
 
-    ap_cfg_closefile(parms.config_file);
+    ap_cfg_closefile(cfp);
 }
 
 void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p, ap_pool_t *ptemp)
@@ -1109,6 +1151,7 @@ void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p,
     ap_finfo_t finfo;
     ap_directive_t *conftree;
     const char *errmsg;
+    configfile_t *cfp;
 
     fname = ap_server_root_relative(p, fname);
 
@@ -1127,14 +1170,14 @@ void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p,
     parms.server = s;
     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
 
-    if (ap_pcfg_openfile(&parms.config_file, p, fname) != APR_SUCCESS) {
+    if (ap_pcfg_openfile(&cfp, p, fname) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
                      "%s: could not open document config file %s",
                     ap_server_argv0, fname);
        exit(1);
     }
 
-    errmsg = ap_build_config(&parms, &conftree);
+    errmsg = ap_build_config(cfp, p, ptemp, &conftree);
     if (errmsg == NULL)
        errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults, 0);
 
@@ -1142,13 +1185,13 @@ void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p,
        /* ### wrong line number. need to pull from ap_directive_t */
        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
                      "Syntax error on line %d of %s:",
-                    parms.config_file->line_number, parms.config_file->name);
+                    cfp->line_number, cfp->name);
        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
                      "%s", errmsg);
        exit(1);
     }
 
-    ap_cfg_closefile(parms.config_file);
+    ap_cfg_closefile(cfp);
 }
 
 
@@ -1191,9 +1234,7 @@ int ap_parse_htaccess(void **result, request_rec *r, int override,
 
             dc = ap_create_per_dir_config(r->pool);
 
-            parms.config_file = f;
-
-            errmsg = ap_build_config(&parms, &conftree);
+            errmsg = ap_build_config(f, r->pool, r->pool, &conftree);
            if (errmsg == NULL)
                errmsg = ap_walk_config(conftree, &parms, dc, 0);
 
index 169eca0a4aa496eedd0de18fc875fde9842d4bb0..157b41021c34b38d56b1b7338d35862eb2f8610e 100644 (file)
@@ -77,6 +77,8 @@
 #include "http_main.h"
 #include "http_log.h"
 #include "http_protocol.h"
+#include "http_config.h"
+
 #if defined(SUNOS4)
 /* stdio.h has been read in ap_config.h already. Add missing prototypes here: */
 extern int fgetc(FILE *);