]> granicus.if.org Git - apache/commitdiff
Commit the EXEC_ON_READ changes. This allows modules to hook into the
authorRyan Bloom <rbb@apache.org>
Mon, 15 May 2000 19:21:40 +0000 (19:21 +0000)
committerRyan Bloom <rbb@apache.org>
Mon, 15 May 2000 19:21:40 +0000 (19:21 +0000)
config file read phase.  Full details are in the CHANGES file blurb.
Examples to see how this should be used are provided for <IfModule>
<IfDefine> LoadModule, AddModule and ClearModuleList expect docs in the
next day or two.

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

include/http_config.h
modules/http/http_core.c
modules/mappers/mod_so.c
server/config.c

index d2ef076e786f68a55e92b8b199803c8de3ed160f..30a80cc0e2b2baa261fb60b350c0dbc7a1a1b711 100644 (file)
@@ -135,6 +135,7 @@ typedef struct command_struct {
 #define OR_UNSET 32
 #define ACCESS_CONF 64
 #define RSRC_CONF 128
+#define EXEC_ON_READ 256
 #define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)
 
 /* This can be returned by a function if they don't wish to handle
@@ -144,6 +145,16 @@ typedef struct command_struct {
 
 #define DECLINE_CMD "\a\b"
 
+/* 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;
+
 /*
  * This structure is passed to a command which is being invoked,
  * to carry a large variety of miscellaneous data which is all of
@@ -155,6 +166,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. */
     ap_directive_t *directive; /* the directive specifying this command */
 
     ap_pool_t *pool;                   /* Pool to allocate new storage in */
@@ -304,16 +316,6 @@ 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);
 
@@ -334,7 +336,13 @@ API_EXPORT(int) ap_cfg_getc(configfile_t *cfp);
 API_EXPORT(int) ap_cfg_closefile(configfile_t *cfp);
 
 /* for implementing subconfigs and customized config files */
-API_EXPORT(const char *) ap_build_config(configfile_t *cfp,
+API_EXPORT(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive);
+const char * ap_build_cont_config(ap_pool_t *p, ap_pool_t *temp_pool,
+                                        cmd_parms *parms,
+                                        ap_directive_t **current,
+                                        ap_directive_t **curr_parent,
+                                        char *orig_directive);
+API_EXPORT(const char *) ap_build_config(cmd_parms *parms,
                                         ap_pool_t *conf_pool,
                                         ap_pool_t *temp_pool,
                                         ap_directive_t **conftree);
index 68550e4976355128508e1882102cb41f97048596..34e0f75c6b52374f61bdbbcf1b6e6bac7fae618e 100644 (file)
@@ -1554,10 +1554,19 @@ 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(cmd->directive->first_child, cmd, cmd->context);
-    }
+        ap_directive_t *parent = NULL;
+        ap_directive_t *current = NULL;
+        const char *retval;
 
-    return NULL;
+        retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, 
+                                      &current, &parent, "<IfModule");
+        *(ap_directive_t **)dummy = current;
+        return retval;
+    }
+    else { 
+        *(ap_directive_t **)dummy = NULL;
+        return ap_soak_end_container(cmd, "<IfModule");
+    }
 }
 
 API_EXPORT(int) ap_exists_config_define(char *name)
@@ -1593,12 +1602,20 @@ 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(cmd->directive->first_child, cmd, cmd->context);
-    }
+        ap_directive_t *parent = NULL;
+        ap_directive_t *current = NULL;
+        const char *retval;
 
-    return NULL;
+        retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, 
+                                      &current, &parent, "<IfDefine");
+        *(ap_directive_t **)dummy = current;
+        return retval;
+    }
+    else { 
+        *(ap_directive_t **)dummy = NULL;
+        return ap_soak_end_container(cmd, "<IfDefine");
+    }
 }
 
 /* httpd.conf commands... beginning with the <VirtualHost> business */
@@ -1681,6 +1698,7 @@ static const char *add_module_command(cmd_parms *cmd, void *dummy, char *arg)
        return ap_pstrcat(cmd->pool, "Cannot add module via name '", arg, 
                          "': not in list of loaded modules", NULL);
     }
+    *(ap_directive_t **)dummy = NULL;
     return NULL;
 }
 
@@ -1692,6 +1710,7 @@ static const char *clear_module_list_command(cmd_parms *cmd, void *dummy)
     }
 
     ap_clear_module_list();
+    *(ap_directive_t **)dummy = NULL;
     return NULL;
 }
 
@@ -2162,9 +2181,9 @@ static const command_rec core_cmds[] = {
 { "<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" },
-{ "<IfModule", start_ifmod, NULL, OR_ALL, TAKE1,
+{ "<IfModule", start_ifmod, NULL, EXEC_ON_READ | OR_ALL, TAKE1,
   "Container for directives based on existance of specified modules" },
-{ "<IfDefine", start_ifdefine, NULL, OR_ALL, TAKE1,
+{ "<IfDefine", start_ifdefine, NULL, EXEC_ON_READ | OR_ALL, TAKE1,
   "Container for directives based on existance of command line defines" },
 { "<DirectoryMatch", dirsection, (void*)1, RSRC_CONF, RAW_ARGS,
   "Container for directives affecting resources located in the "
@@ -2245,10 +2264,10 @@ static const command_rec core_cmds[] = {
   RSRC_CONF|ACCESS_CONF, TAKE1,
   "How to work out the ServerName : Port when constructing URLs" },
 /* TODO: RlimitFoo should all be part of mod_cgi, not in the core */
-{ "AddModule", add_module_command, NULL, RSRC_CONF, ITERATE,
+{ "AddModule", add_module_command, NULL, RSRC_CONF | EXEC_ON_READ, ITERATE,
   "The name of a module" },
-{ "ClearModuleList", clear_module_list_command, NULL, RSRC_CONF, NO_ARGS, 
-  NULL },
+{ "ClearModuleList", clear_module_list_command, NULL, RSRC_CONF | EXEC_ON_READ,
+  NO_ARGS, NULL },
 /* TODO: ListenBacklog in MPM */
 { "Include", include_config, NULL, (RSRC_CONF | ACCESS_CONF), TAKE1,
   "Name of the config file to be included" },
index 30b9b31714c93b04ba98440fcc9d51a165669e88..e684d21dc71dbe245206d2136d2d1c0ce4e79a3e 100644 (file)
@@ -230,6 +230,12 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
     moduleinfo *modie;
     int i;
 
+    /* we need to setup this value for dummy to make sure that we don't try
+     * to add a non-existant tree into the build when we return to
+     * execute_now.
+     */
+    *(ap_directive_t **)dummy = NULL;
+
     /* 
      * check for already existing module
      * If it already exists, we have nothing to do 
@@ -349,7 +355,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
 #endif /* NO_DLOPEN */
 
 static const command_rec so_cmds[] = {
-    { "LoadModule", load_module, NULL, RSRC_CONF, TAKE2,
+    { "LoadModule", load_module, NULL, RSRC_CONF | EXEC_ON_READ, TAKE2,
       "a module name and the name of a shared object file to load it from"},
     { "LoadFile", load_file, NULL, RSRC_CONF, ITERATE,
       "shared object file or library to load into the server at runtime"},
index bb4cbb52468b8ab3d5eea8bf11caf18b594701d2..ef510a7230f21e22867e1781c888877d2c767586 100644 (file)
@@ -831,15 +831,20 @@ CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module
     return mconfig;
 }
 
+static const char *execute_now(char *cmd_line, const char *args, cmd_parms *parms, 
+                         ap_pool_t *p, ap_pool_t *ptemp,
+                         ap_directive_t **sub_tree, ap_directive_t *parent);
+
 static const char * ap_build_config_sub(ap_pool_t *p, ap_pool_t *temp_pool,
-                                       const configfile_t *cfp,
-                                       const char *l,
+                                       const char *l, cmd_parms *parms,
                                        ap_directive_t **current,
                                        ap_directive_t **curr_parent)
 {
     const char *args;
     char *cmd_name;
     ap_directive_t *newdir;
+    module *mod = top_module;
+    const command_rec *cmd;
 
     if (*l == '#' || *l == '\0')
        return NULL;
@@ -857,9 +862,24 @@ static const char * ap_build_config_sub(ap_pool_t *p, ap_pool_t *temp_pool,
        return NULL;
     }
 
+    if ((cmd = ap_find_command_in_modules(cmd_name, &mod)) != NULL) {
+        if (cmd->req_override & EXEC_ON_READ) {
+            const char *retval;
+            ap_directive_t *sub_tree = NULL;
+
+            retval = execute_now(cmd_name, args, parms, p, temp_pool, 
+                                 &sub_tree, *curr_parent);
+            (*current)->next = sub_tree;
+            while ((*current)->next != NULL) {
+                (*current) = (*current)->next;
+            }
+            return retval;
+        }
+    }
+
     newdir = ap_pcalloc(p, sizeof(ap_directive_t));
-    newdir->filename = cfp->name;
-    newdir->line_num = cfp->line_number;
+    newdir->filename = parms->config_file->name;
+    newdir->line_num = parms->config_file->line_number;
     newdir->directive = cmd_name;
     newdir->args = ap_pstrdup(p, args);
 
@@ -900,6 +920,38 @@ static const char * ap_build_config_sub(ap_pool_t *p, ap_pool_t *temp_pool,
     return NULL;
 }
 
+const char * ap_build_cont_config(ap_pool_t *p, ap_pool_t *temp_pool,
+                                       cmd_parms *parms,
+                                       ap_directive_t **current,
+                                       ap_directive_t **curr_parent,
+                                        char *orig_directive)
+{
+    char l[MAX_STRING_LEN];
+    char *bracket;
+    const char *retval;
+    ap_directive_t *conftree = NULL;
+
+    bracket = ap_pstrcat(p, orig_directive + 1, ">", NULL);
+    while(!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
+        if ((strcasecmp(l + 2, bracket) == 0) &&
+            (*curr_parent == NULL)) {
+            break;
+        } 
+        retval = ap_build_config_sub(p, temp_pool, l, parms, current, 
+                                     curr_parent);
+        if (retval != NULL)
+            return retval;
+        if (conftree == NULL && curr_parent != NULL) { 
+            conftree = *curr_parent;
+        }
+        if (conftree == NULL && current != NULL) {
+            conftree = *current;
+        }
+    }
+    *current = conftree;
+    return NULL;
+}
+
 static const char *ap_walk_config_sub(const ap_directive_t *current,
                                      cmd_parms *parms, void *config)
 {
@@ -956,7 +1008,7 @@ API_EXPORT(const char *) ap_walk_config(ap_directive_t *current,
 }
 
 
-API_EXPORT(const char *) ap_build_config(configfile_t *cfp,
+API_EXPORT(const char *) ap_build_config(cmd_parms *parms,
                                         ap_pool_t *p, ap_pool_t *temp_pool,
                                         ap_directive_t **conftree)
 {
@@ -967,9 +1019,9 @@ API_EXPORT(const char *) ap_build_config(configfile_t *cfp,
 
     *conftree = NULL;
 
-    while (!(ap_cfg_getline(l, MAX_STRING_LEN, cfp))) {
+    while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
 
-       errmsg = ap_build_config_sub(p, temp_pool, cfp, l,
+       errmsg = ap_build_config_sub(p, temp_pool, l, parms,
                                     &current, &curr_parent);
        if (errmsg != NULL)
            return errmsg;
@@ -1064,6 +1116,55 @@ API_EXPORT(const char *) ap_server_root_relative(ap_pool_t *p, const char *file)
     return ap_make_full_path(p, ap_server_root, file);
 }
 
+API_EXPORT(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive)
+{
+    char l[MAX_STRING_LEN];
+    const char *args;
+    char *cmd_name;
+
+    while(!(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) {
+#if RESOLVE_ENV_PER_TOKEN
+        args = l;
+#else
+        args = ap_resolve_env(cmd->temp_pool, l);
+#endif
+        cmd_name = ap_getword_conf(cmd->pool, &args);
+        if (cmd_name[0] == '<') {
+            if (cmd_name[1] == '/') {
+                cmd_name[strlen(cmd_name) - 1] = '\0';
+                if (strcasecmp(cmd_name + 2, directive + 1) != 0) {
+                    return ap_pstrcat(cmd->pool, "Expected </",
+                                      directive + 1, "> but saw ",
+                                      cmd_name, ">", NULL);
+                }
+                break;
+            }
+            else {
+                ap_soak_end_container(cmd, cmd_name);
+            }
+        }
+    }
+    return NULL;
+}
+
+static const char *execute_now(char *cmd_line, const char *args, cmd_parms *parms, 
+                         ap_pool_t *p, ap_pool_t *ptemp, 
+                         ap_directive_t **sub_tree, ap_directive_t *parent)
+{
+    module *mod = top_module;
+    const command_rec *cmd;
+
+    if (!(cmd = ap_find_command_in_modules(cmd_line, &mod))) {
+        return ap_pstrcat(parms->pool, "Invalid command '", 
+                          cmd_line,
+                          "', perhaps mis-spelled or defined by a module "
+                          "not included in the server configuration",
+                          NULL);
+    }
+    else {
+        return invoke_cmd(cmd, parms, sub_tree, args);
+    }
+}
 
 /* This structure and the following functions are needed for the
  * table-based config file reading. They are passed to the
@@ -1112,7 +1213,6 @@ 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;
@@ -1123,11 +1223,11 @@ static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_poo
     parms.server = s;
     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
 
-    cfp = ap_pcfg_open_custom(p, "-c/-C directives",
+    parms.config_file = 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);
+    errmsg = ap_build_config(&parms, p, ptemp, &conftree);
     if (errmsg == NULL)
        errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults);
     if (errmsg) {
@@ -1136,7 +1236,7 @@ static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_poo
         exit(1);
     }
 
-    ap_cfg_closefile(cfp);
+    ap_cfg_closefile(parms.config_file);
 }
 
 void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p, ap_pool_t *ptemp)
@@ -1171,7 +1271,8 @@ void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p,
        exit(1);
     }
 
-    errmsg = ap_build_config(cfp, p, ptemp, &conftree);
+    parms.config_file = cfp;
+    errmsg = ap_build_config(&parms, p, ptemp, &conftree);
     if (errmsg == NULL)
        errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults);
 
@@ -1228,7 +1329,8 @@ int ap_parse_htaccess(void **result, request_rec *r, int override,
 
             dc = ap_create_per_dir_config(r->pool);
 
-            errmsg = ap_build_config(f, r->pool, r->pool, &conftree);
+            parms.config_file = f;
+            errmsg = ap_build_config(&parms, r->pool, r->pool, &conftree);
            if (errmsg == NULL)
                errmsg = ap_walk_config(conftree, &parms, dc);