From: Ryan Bloom Date: Mon, 15 May 2000 19:21:40 +0000 (+0000) Subject: Commit the EXEC_ON_READ changes. This allows modules to hook into the X-Git-Tag: APACHE_2_0_ALPHA_4~152 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=66826a60abd6d3c2f5c95765db03cb6bf9cd82d8;p=apache Commit the EXEC_ON_READ changes. This allows modules to hook into the config file read phase. Full details are in the CHANGES file blurb. Examples to see how this should be used are provided for 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 --- diff --git a/include/http_config.h b/include/http_config.h index d2ef076e78..30a80cc0e2 100644 --- a/include/http_config.h +++ b/include/http_config.h @@ -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 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); diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 68550e4976..34e0f75c6b 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -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, + ¤t, &parent, "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, + ¤t, &parent, " 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[] = { { "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, ¤t, &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 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);