diff --git a/include/asterisk/config.h b/include/asterisk/config.h index 4757d5126c..793bb89ffe 100644 --- a/include/asterisk/config.h +++ b/include/asterisk/config.h @@ -64,7 +64,7 @@ struct ast_variable { char stuff[0]; }; -typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file); +typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file, const char *who_asked); typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap); typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap); typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap); @@ -86,6 +86,7 @@ struct ast_config_engine { /*! \brief Load a config file * \param filename path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR * Create a config structure from a given configuration file. + * \param who_asked The module which is making this request. * \param flags Optional flags: * CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact; * CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or @@ -94,7 +95,9 @@ struct ast_config_engine { * \retval an ast_config data structure on success * \retval NULL on error */ -struct ast_config *ast_config_load(const char *filename, struct ast_flags flags); +struct ast_config *ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags); + +#define ast_config_load(filename, flags) ast_config_load2(filename, __FILE__, flags) /*! \brief Destroys a config * \param config pointer to config data structure @@ -282,7 +285,7 @@ int ast_variable_update(struct ast_category *category, const char *variable, int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator); -struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file); +struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked); /*! \brief Support code to parse config file arguments * diff --git a/main/config.c b/main/config.c index bb469e12bd..ebc75f29b6 100644 --- a/main/config.c +++ b/main/config.c @@ -92,6 +92,7 @@ struct cache_file_mtime { AST_LIST_HEAD(includes, cache_file_include) includes; unsigned int has_exec:1; time_t mtime; + char *who_asked; char filename[0]; }; @@ -854,7 +855,7 @@ enum config_cache_attribute_enum { ATTRIBUTE_EXEC = 1, }; -static void config_cache_attribute(const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename) +static void config_cache_attribute(const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked) { struct cache_file_mtime *cfmtime; struct cache_file_include *cfinclude; @@ -867,13 +868,15 @@ static void config_cache_attribute(const char *configfile, enum config_cache_att break; } if (!cfmtime) { - cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1); + cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1 + strlen(who_asked) + 1); if (!cfmtime) { AST_LIST_UNLOCK(&cfmtime_head); return; } AST_LIST_HEAD_INIT(&cfmtime->includes); strcpy(cfmtime->filename, configfile); + cfmtime->who_asked = cfmtime->filename + strlen(configfile) + 1; + strcpy(cfmtime->who_asked, who_asked); /* Note that the file mtime is initialized to 0, i.e. 1970 */ AST_LIST_INSERT_TAIL(&cfmtime_head, cfmtime, list); } @@ -918,7 +921,7 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, - struct ast_category **last_cat, struct ast_variable **last_var) + struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked) { char *c; char *cur = buf; @@ -1054,21 +1057,21 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, We create a tmp file, then we #include it, then we delete it. */ if (!do_include) { if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) - config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL); + config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked); snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self()); snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file); ast_safe_system(cmd); cur = exec_file; } else { if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) - config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur); + config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked); exec_file[0] = '\0'; } /* A #include */ /* record this inclusion */ inclu = ast_include_new(cfg, configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name)); - do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name) ? 1 : 0; + do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0; if (!ast_strlen_zero(exec_file)) unlink(exec_file); if (!do_include) { @@ -1121,7 +1124,7 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, return 0; } -static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file) +static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) { char fn[256]; char buf[8192]; @@ -1196,15 +1199,17 @@ static struct ast_config *config_text_file_load(const char *database, const char /* Find our cached entry for this configuration file */ AST_LIST_LOCK(&cfmtime_head); AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { - if (!strcmp(cfmtime->filename, fn)) + if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) break; } if (!cfmtime) { - cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1); + cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1 + strlen(who_asked) + 1); if (!cfmtime) continue; AST_LIST_HEAD_INIT(&cfmtime->includes); strcpy(cfmtime->filename, fn); + cfmtime->who_asked = cfmtime->filename + strlen(fn) + 1; + strcpy(cfmtime->who_asked, who_asked); /* Note that the file mtime is initialized to 0, i.e. 1970 */ AST_LIST_INSERT_TAIL(&cfmtime_head, cfmtime, list); } @@ -1232,7 +1237,8 @@ static struct ast_config *config_text_file_load(const char *database, const char #else ast_copy_string(fn2, cfinclude->include); #endif - if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "") == NULL) { /* that last field needs to be looked at in this case... TODO */ + if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) { + /* that second-to-last field needs to be looked at in this case... TODO */ unchanged = 0; /* One change is enough to short-circuit and reload the whole shebang */ break; @@ -1346,7 +1352,7 @@ static struct ast_config *config_text_file_load(const char *database, const char if (process_buf) { char *buf = ast_strip(process_buf); if (!ast_strlen_zero(buf)) { - if (process_text_line(cfg, &cat, buf, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var)) { + if (process_text_line(cfg, &cat, buf, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) { cfg = NULL; break; } @@ -1815,7 +1821,7 @@ int read_config_maps(void) configtmp = ast_config_new(); configtmp->max_include_level = 1; - config = ast_config_internal_load(extconfig_conf, configtmp, flags, ""); + config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "config.c"); if (!config) { ast_config_destroy(configtmp); return 0; @@ -1956,7 +1962,7 @@ static struct ast_config_engine text_file_engine = { .load_func = config_text_file_load, }; -struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file) +struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) { char db[256]; char table[256]; @@ -1986,7 +1992,7 @@ struct ast_config *ast_config_internal_load(const char *filename, struct ast_con } } - result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file); + result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked); if (result && result != CONFIG_STATUS_FILEUNCHANGED) result->include_level--; @@ -1996,7 +2002,7 @@ struct ast_config *ast_config_internal_load(const char *filename, struct ast_con return result; } -struct ast_config *ast_config_load(const char *filename, struct ast_flags flags) +struct ast_config *ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags) { struct ast_config *cfg; struct ast_config *result; @@ -2005,7 +2011,7 @@ struct ast_config *ast_config_load(const char *filename, struct ast_flags flags) if (!cfg) return NULL; - result = ast_config_internal_load(filename, cfg, flags, ""); + result = ast_config_internal_load(filename, cfg, flags, "", who_asked); if (!result || result == CONFIG_STATUS_FILEUNCHANGED) ast_config_destroy(cfg); diff --git a/res/res_config_curl.c b/res/res_config_curl.c index 7556a70661..f36a5f6a9d 100644 --- a/res/res_config_curl.c +++ b/res/res_config_curl.c @@ -407,7 +407,7 @@ static int destroy_curl(const char *url, const char *unused, const char *keyfiel } -static struct ast_config *config_curl(const char *url, const char *unused, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl) +static struct ast_config *config_curl(const char *url, const char *unused, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked) { struct ast_str *query; char buf1[200]; @@ -463,7 +463,7 @@ static struct ast_config *config_curl(const char *url, const char *unused, const } if (!strcmp(var_name, "#include")) { - if (!ast_config_internal_load(var_val, cfg, loader_flags, "")) + if (!ast_config_internal_load(var_val, cfg, loader_flags, "", who_asked)) return NULL; } diff --git a/res/res_config_ldap.c b/res/res_config_ldap.c index 56f95ac015..b76ad8ae7b 100644 --- a/res/res_config_ldap.c +++ b/res/res_config_ldap.c @@ -1006,7 +1006,7 @@ static int compare_categories(const void *a, const void *b) * called on a reload */ static struct ast_config *config_ldap(const char *basedn, const char *table_name, - const char *file, struct ast_config *cfg, struct ast_flags config_flags, const char *sugg_incl) + const char *file, struct ast_config *cfg, struct ast_flags config_flags, const char *sugg_incl, const char *who_asked) { unsigned int vars_count = 0; struct ast_variable **vars; @@ -1088,7 +1088,7 @@ static struct ast_config *config_ldap(const char *basedn, const char *table_name for (i = 0; i < vars_count; i++) { if (!strcmp(categories[i].variable_name, "#include")) { struct ast_flags config_flags = { 0 }; - if (!ast_config_internal_load(categories[i].variable_value, cfg, config_flags, "")) + if (!ast_config_internal_load(categories[i].variable_value, cfg, config_flags, "", who_asked)) break; continue; } diff --git a/res/res_config_odbc.c b/res/res_config_odbc.c index 57b1ba5284..8a28ddec84 100644 --- a/res/res_config_odbc.c +++ b/res/res_config_odbc.c @@ -625,7 +625,7 @@ static SQLHSTMT config_odbc_prepare(struct odbc_obj *obj, void *data) return sth; } -static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl) +static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked) { struct ast_variable *new_v; struct ast_category *cur_cat; @@ -682,7 +682,7 @@ static struct ast_config *config_odbc(const char *database, const char *table, c while ((res = SQLFetch(stmt)) != SQL_NO_DATA) { if (!strcmp (q.var_name, "#include")) { - if (!ast_config_internal_load(q.var_val, cfg, loader_flags, "")) { + if (!ast_config_internal_load(q.var_val, cfg, loader_flags, "", who_asked)) { SQLFreeHandle(SQL_HANDLE_STMT, stmt); ast_odbc_release_obj(obj); return NULL; diff --git a/res/res_config_pgsql.c b/res/res_config_pgsql.c index e0511bbc61..04e4f1409e 100644 --- a/res/res_config_pgsql.c +++ b/res/res_config_pgsql.c @@ -658,7 +658,7 @@ static int destroy_pgsql(const char *database, const char *table, const char *ke static struct ast_config *config_pgsql(const char *database, const char *table, const char *file, struct ast_config *cfg, - struct ast_flags flags, const char *suggested_incl) + struct ast_flags flags, const char *suggested_incl, const char *who_asked) { PGresult *result = NULL; long num_rows; @@ -723,7 +723,7 @@ static struct ast_config *config_pgsql(const char *database, const char *table, char *field_var_val = PQgetvalue(result, rowIndex, 2); char *field_cat_metric = PQgetvalue(result, rowIndex, 3); if (!strcmp(field_var_name, "#include")) { - if (!ast_config_internal_load(field_var_val, cfg, flags, "")) { + if (!ast_config_internal_load(field_var_val, cfg, flags, "", who_asked)) { PQclear(result); ast_mutex_unlock(&pgsql_lock); return NULL; diff --git a/res/res_config_sqlite.c b/res/res_config_sqlite.c index fb22009b24..7eea32af85 100644 --- a/res/res_config_sqlite.c +++ b/res/res_config_sqlite.c @@ -178,6 +178,7 @@ struct cfg_entry_args { struct ast_category *cat; char *cat_name; struct ast_flags flags; + const char *who_asked; }; /*! @@ -277,7 +278,7 @@ static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames); * \see add_cfg_entry() */ static struct ast_config * config_handler(const char *database, const char *table, const char *file, - struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl); + struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked); /*! * \brief Helper function to parse a va_list object into 2 dynamic arrays of @@ -710,7 +711,7 @@ static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames) char *val; val = argv[RES_CONFIG_SQLITE_CONFIG_VAR_VAL]; - cfg = ast_config_internal_load(val, args->cfg, args->flags, ""); + cfg = ast_config_internal_load(val, args->cfg, args->flags, "", args->who_asked); if (!cfg) { ast_log(LOG_WARNING, "Unable to include %s\n", val); @@ -753,7 +754,7 @@ static int add_cfg_entry(void *arg, int argc, char **argv, char **columnNames) } static struct ast_config *config_handler(const char *database, const char *table, const char *file, - struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl) + struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked) { struct cfg_entry_args args; char *query, *errormsg; @@ -779,6 +780,7 @@ static struct ast_config *config_handler(const char *database, const char *table args.cat = NULL; args.cat_name = NULL; args.flags = flags; + args.who_asked = who_asked; ast_mutex_lock(&mutex);