Configuration File Parser. More...
#include "asterisk.h"#include "asterisk/paths.h"#include "asterisk/network.h"#include <time.h>#include <sys/stat.h>#include <math.h>#include "asterisk/config.h"#include "asterisk/cli.h"#include "asterisk/lock.h"#include "asterisk/utils.h"#include "asterisk/channel.h"#include "asterisk/app.h"#include "asterisk/astobj2.h"#include "asterisk/strings.h"#include "asterisk/netsock2.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_category |
| struct | ast_category_template_instance |
| struct | ast_comment |
| Structure to keep comments for rewriting configuration files. More... | |
| struct | ast_config |
| struct | ast_config_include |
| struct | ast_config_map |
| struct | cache_file_include |
| Hold the mtime for config files, so if we don't need to reread our config, don't. More... | |
| struct | cache_file_mtime |
| struct | cfg_hook |
| struct | cfmtime_head |
| struct | inclfile |
| struct | cache_file_mtime::includes |
| struct | ast_category::template_instance_list |
Defines | |
| #define | AST_INCLUDE_GLOB 1 |
| #define | CB_SIZE 250 /* initial size of comment buffers */ |
| #define | COMMENT_END "--;" |
| #define | COMMENT_META ';' |
| #define | COMMENT_START ";--" |
| #define | COMMENT_TAG '-' |
| #define | MAX_INCLUDE_LEVEL 10 |
| #define | MAX_NESTED_COMMENTS 128 |
| #define | MIN_VARIABLE_FNAME_SPACE 40 |
Enumerations | |
| enum | config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0, ATTRIBUTE_EXEC = 1 } |
Functions | |
| static void | __init_appendbuf (void) |
| static struct ast_comment * | ALLOC_COMMENT (struct ast_str *buffer) |
| static int | append_mapping (const char *name, const char *driver, const char *database, const char *table, int priority) |
| void | ast_category_append (struct ast_config *config, struct ast_category *category) |
| char * | ast_category_browse (struct ast_config *config, const char *prev) |
| Goes through categories. | |
| int | ast_category_delete (struct ast_config *cfg, const char *category) |
| void | ast_category_destroy (struct ast_category *cat) |
| struct ast_variable * | ast_category_detach_variables (struct ast_category *cat) |
| int | ast_category_empty (struct ast_config *cfg, const char *category) |
| Removes and destroys all variables within a category. | |
| int | ast_category_exist (const struct ast_config *config, const char *category_name) |
| Check for category duplicates. | |
| struct ast_variable * | ast_category_first (struct ast_category *cat) |
| given a pointer to a category, return the root variable. | |
| struct ast_category * | ast_category_get (const struct ast_config *config, const char *category_name) |
| Retrieve a category if it exists. | |
| void | ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match) |
| Inserts new category. | |
| struct ast_category * | ast_category_new (const char *name, const char *in_file, int lineno) |
| Create a category structure. | |
| void | ast_category_rename (struct ast_category *cat, const char *name) |
| struct ast_variable * | ast_category_root (struct ast_config *config, char *cat) |
| returns the root ast_variable of a config | |
| int | ast_check_realtime (const char *family) |
| Check if realtime engine is configured for family. | |
| static void | ast_comment_destroy (struct ast_comment **comment) |
| struct ast_config * | ast_config_copy (const struct ast_config *old) |
| Copies the contents of one ast_config into another. | |
| void | ast_config_destroy (struct ast_config *cfg) |
| Destroys a config. | |
| int | ast_config_engine_deregister (struct ast_config_engine *del) |
| Deregister config engine. | |
| int | ast_config_engine_register (struct ast_config_engine *new) |
| Register config engine. | |
| struct ast_category * | ast_config_get_current_category (const struct ast_config *cfg) |
| Retrieve the current category name being built. | |
| int | ast_config_hook_register (const char *name, const char *filename, const char *module, enum config_hook_flags flags, config_hook_cb hook_cb) |
| Register a config hook for a particular file and module. | |
| void | ast_config_hook_unregister (const char *name) |
| Unregister a config hook. | |
| 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) |
| struct ast_config * | ast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags) |
| Load a config file. | |
| struct ast_config * | ast_config_new (void) |
| Create a new base configuration structure. | |
| const char * | ast_config_option (struct ast_config *cfg, const char *cat, const char *var) |
| Retrieve a configuration variable within the configuration set. | |
| void | ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat) |
| Set the category within the configuration as being current. | |
| void | ast_config_sort_categories (struct ast_config *config, int descending, int(*comparator)(struct ast_category *p, struct ast_category *q)) |
| Sorts categories in a config in the order of a numerical value contained within them. | |
| int | ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator) |
| int | ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...) |
| Destroy realtime configuration. | |
| static void | ast_destroy_template_list (struct ast_category *cat) |
| struct ast_config_include * | ast_include_find (struct ast_config *conf, const char *included_file) |
| struct ast_config_include * | ast_include_new (struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size) |
| void | ast_include_rename (struct ast_config *conf, const char *from_file, const char *to_file) |
| static void | ast_includes_destroy (struct ast_config_include *incls) |
| struct ast_variable * | ast_load_realtime (const char *family,...) |
| Retrieve realtime configuration. | |
| struct ast_variable * | ast_load_realtime_all (const char *family,...) |
| static struct ast_variable * | ast_load_realtime_helper (const char *family, va_list ap) |
| struct ast_config * | ast_load_realtime_multientry (const char *family,...) |
| Retrieve realtime configuration. | |
| int | ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *p_result,...) |
| Helper function to parse arguments See documentation in config.h. | |
| char * | ast_realtime_decode_chunk (char *chunk) |
| Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values. | |
| int | ast_realtime_enabled (void) |
| Check if there's any realtime engines loaded. | |
| char * | ast_realtime_encode_chunk (struct ast_str **dest, ssize_t maxlen, const char *chunk) |
| Encodes a chunk of data for realtime. | |
| int | ast_realtime_is_mapping_defined (const char *family) |
| Determine if a mapping exists for a given family. | |
| int | ast_realtime_require_field (const char *family,...) |
| Inform realtime what fields that may be stored. | |
| int | ast_store_realtime (const char *family,...) |
| Create realtime configuration. | |
| int | ast_unload_realtime (const char *family) |
| Release any resources cached for a realtime family. | |
| int | ast_update2_realtime (const char *family,...) |
| Update realtime configuration. | |
| int | ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...) |
| Update realtime configuration. | |
| void | ast_variable_append (struct ast_category *category, struct ast_variable *variable) |
| struct ast_variable * | ast_variable_browse (const struct ast_config *config, const char *category) |
| Goes through variables. | |
| int | ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line) |
| static void | ast_variable_destroy (struct ast_variable *doomed) |
| void | ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line) |
| static void | ast_variable_move (struct ast_variable *dst_var, struct ast_variable *src_var) |
| struct ast_variable * | ast_variable_new (const char *name, const char *value, const char *filename) |
| const char * | ast_variable_retrieve (const struct ast_config *config, const char *category, const char *variable) |
| Gets a variable. | |
| int | ast_variable_update (struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object) |
| Update variable value within a config. | |
| void | ast_variables_destroy (struct ast_variable *v) |
| Free variable list. | |
| struct ast_variable * | ast_variables_dup (struct ast_variable *var) |
| Duplicate variable list. | |
| static struct ast_category * | category_get (const struct ast_config *config, const char *category_name, int ignored) |
| static void | CB_ADD (struct ast_str **cb, const char *str) |
| static void | CB_ADD_LEN (struct ast_str **cb, const char *str, int len) |
| static void | CB_RESET (struct ast_str *cb, struct ast_str *llb) |
| static void | cfmstat_clear (struct cache_file_mtime *cfmtime) |
| static int | cfmstat_cmp (struct cache_file_mtime *cfmtime, struct stat *statbuf) |
| static void | cfmstat_save (struct cache_file_mtime *cfmtime, struct stat *statbuf) |
| static struct cache_file_mtime * | cfmtime_new (const char *filename, const char *who_asked) |
| static void | clear_config_maps (void) |
| static void | config_cache_attribute (const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked) |
| static void | config_hook_exec (const char *filename, const char *module, struct ast_config *cfg) |
| static void | config_shutdown (void) |
| 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) |
| int | config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator) |
| static int | count_linefeeds (char *str) |
| static int | count_linefeeds_in_comments (struct ast_comment *x) |
| static struct ast_config_engine * | find_engine (const char *family, int priority, char *database, int dbsiz, char *table, int tabsiz) |
| Find realtime engine for realtime family. | |
| static void | gen_header (FILE *f1, const char *configfile, const char *fn, const char *generator) |
| static char * | handle_cli_config_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_config_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_core_show_config_mappings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static int | hash_string (const void *obj, const int flags) |
| static int | hashtab_compare_strings (void *a, void *b, int flags) |
| static int | hook_cmp (void *obj, void *arg, int flags) |
| static void | hook_destroy (void *obj) |
| static int | hook_hash (const void *obj, const int flags) |
| static void | inclfile_destroy (void *obj) |
| static void | inherit_category (struct ast_category *new, const struct ast_category *base) |
| static int | init_appendbuf (void *data) |
| static void | insert_leading_blank_lines (FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno) |
| static void | move_variables (struct ast_category *old, struct ast_category *new) |
| static struct ast_category * | next_available_category (struct ast_category *cat) |
| static int | process_text_line (struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, 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, const char *who_asked) |
| parse one line in the configuration. | |
| int | read_config_maps (void) |
| Exposed re-initialization method for core process. | |
| int | register_config_cli (void) |
| Exposed initialization method for core process. | |
| static struct inclfile * | set_fn (char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset) |
| static struct ast_variable * | variable_clone (const struct ast_variable *old) |
Variables | |
| static struct ast_threadstorage | appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , } |
| static struct ao2_container * | cfg_hooks |
| static struct cfmtime_head | cfmtime_head |
| static struct ast_cli_entry | cli_config [] |
| static struct ast_config_engine * | config_engine_list |
| static ast_mutex_t | config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
| static struct ast_config_map * | config_maps |
| static char * | extconfig_conf = "extconfig.conf" |
| static struct ast_config_engine | text_file_engine |
Configuration File Parser.
Includes the Asterisk Realtime API - ARA See http://wiki.asterisk.org
Definition in file config.c.
| #define AST_INCLUDE_GLOB 1 |
Definition at line 117 of file config.c.
Referenced by config_text_file_load().
| #define COMMENT_END "--;" |
| #define COMMENT_META ';' |
Definition at line 59 of file config.c.
Referenced by config_text_file_load().
| #define COMMENT_START ";--" |
| #define COMMENT_TAG '-' |
Definition at line 60 of file config.c.
Referenced by config_text_file_load().
| #define MAX_INCLUDE_LEVEL 10 |
Definition at line 205 of file config.c.
Referenced by ast_config_new().
| #define MAX_NESTED_COMMENTS 128 |
Definition at line 56 of file config.c.
Referenced by config_text_file_load().
| #define MIN_VARIABLE_FNAME_SPACE 40 |
Define the minimum filename space to reserve for each ast_variable in case the filename is renamed later by ast_include_rename().
Definition at line 67 of file config.c.
Referenced by ast_variable_new().
Definition at line 1183 of file config.c.
{
ATTRIBUTE_INCLUDE = 0,
ATTRIBUTE_EXEC = 1,
};
| static void __init_appendbuf | ( | void | ) | [static] |
| static struct ast_comment* ALLOC_COMMENT | ( | struct ast_str * | buffer | ) | [static, read] |
Definition at line 141 of file config.c.
References ast_calloc, ast_str_buffer(), ast_str_strlen(), and ast_comment::cmt.
Referenced by config_text_file_load(), and process_text_line().
{
struct ast_comment *x = NULL;
if (!buffer || !ast_str_strlen(buffer)) {
return NULL;
}
if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
}
return x;
}
| static int append_mapping | ( | const char * | name, |
| const char * | driver, | ||
| const char * | database, | ||
| const char * | table, | ||
| int | priority | ||
| ) | [static] |
Definition at line 2311 of file config.c.
References ast_calloc, ast_verb, config_maps, ast_config_map::database, ast_config_map::driver, map, ast_config_map::name, ast_config_map::next, ast_config_map::priority, ast_config_map::stuff, and ast_config_map::table.
Referenced by read_config_maps().
{
struct ast_config_map *map;
char *dst;
int length;
length = sizeof(*map);
length += strlen(name) + 1;
length += strlen(driver) + 1;
length += strlen(database) + 1;
if (table)
length += strlen(table) + 1;
if (!(map = ast_calloc(1, length)))
return -1;
dst = map->stuff; /* writable space starts here */
map->name = strcpy(dst, name);
dst += strlen(dst) + 1;
map->driver = strcpy(dst, driver);
dst += strlen(dst) + 1;
map->database = strcpy(dst, database);
if (table) {
dst += strlen(dst) + 1;
map->table = strcpy(dst, table);
}
map->priority = priority;
map->next = config_maps;
config_maps = map;
ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
return 0;
}
| void ast_category_append | ( | struct ast_config * | config, |
| struct ast_category * | category | ||
| ) |
Definition at line 694 of file config.c.
References ast_config::current, ast_category::include_level, ast_config::include_level, ast_config::last, ast_category::next, and ast_config::root.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), append_row_to_cfg(), ast_config_copy(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), static_realtime_cb(), and write_password_to_file().
{
if (config->last)
config->last->next = category;
else
config->root = category;
category->include_level = config->include_level;
config->last = category;
config->current = category;
}
| char* ast_category_browse | ( | struct ast_config * | config, |
| const char * | prev | ||
| ) |
Goes through categories.
| config | Which config structure you wish to "browse" |
| prev | A pointer to a previous category. |
This function is kind of non-intuitive in it's use. To begin, one passes NULL as the second argument. It will return a pointer to the string of the first category in the file. From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards.
| a | category on success |
| NULL | on failure/no-more-categories |
Definition at line 899 of file config.c.
References ast_config::last_browse, ast_category::name, ast_category::next, next_available_category(), and ast_config::root.
Referenced by __init_manager(), __queues_show(), action_getconfig(), action_getconfigjson(), action_listcategories(), actual_load_config(), aji_load_config(), ast_cli_perms_init(), complete_sip_notify(), conf_exec(), config_load(), find_queue_by_name_rt(), find_realtime(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), gtalk_load_config(), iax_provision_reload(), internal_process_ast_config(), jingle_load_config(), load_config(), load_format_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_tech_calendars(), misdn_cfg_init(), named_acl_find_realtime(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), process_config(), queues_data_provider_get(), read_agent_config(), realtime_directory(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), search_directory(), search_directory_sub(), set_config(), set_member_value(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().
{
struct ast_category *cat;
if (!prev) {
/* First time browse. */
cat = config->root;
} else if (config->last_browse && (config->last_browse->name == prev)) {
/* Simple last browse found. */
cat = config->last_browse->next;
} else {
/*
* Config changed since last browse.
*
* First try cheap last browse search. (Rebrowsing a different
* previous category?)
*/
for (cat = config->root; cat; cat = cat->next) {
if (cat->name == prev) {
/* Found it. */
cat = cat->next;
break;
}
}
if (!cat) {
/*
* Have to do it the hard way. (Last category was deleted and
* re-added?)
*/
for (cat = config->root; cat; cat = cat->next) {
if (!strcasecmp(cat->name, prev)) {
/* Found it. */
cat = cat->next;
break;
}
}
}
}
if (cat)
cat = next_available_category(cat);
config->last_browse = cat;
return (cat) ? cat->name : NULL;
}
| int ast_category_delete | ( | struct ast_config * | cfg, |
| const char * | category | ||
| ) |
Definition at line 1065 of file config.c.
References ast_category_destroy(), ast_config::last, ast_category::next, and ast_config::root.
Referenced by handle_updates().
{
struct ast_category *prev=NULL, *cat;
cat = cfg->root;
while (cat) {
if (cat->name == category) {
if (prev) {
prev->next = cat->next;
if (cat == cfg->last)
cfg->last = prev;
} else {
cfg->root = cat->next;
if (cat == cfg->last)
cfg->last = NULL;
}
ast_category_destroy(cat);
return 0;
}
prev = cat;
cat = cat->next;
}
prev = NULL;
cat = cfg->root;
while (cat) {
if (!strcasecmp(cat->name, category)) {
if (prev) {
prev->next = cat->next;
if (cat == cfg->last)
cfg->last = prev;
} else {
cfg->root = cat->next;
if (cat == cfg->last)
cfg->last = NULL;
}
ast_category_destroy(cat);
return 0;
}
prev = cat;
cat = cat->next;
}
return -1;
}
| void ast_category_destroy | ( | struct ast_category * | cat | ) |
Definition at line 733 of file config.c.
References ast_comment_destroy(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, ast_category::last, ast_category::precomments, ast_category::root, ast_category::sameline, and ast_category::trailing.
Referenced by add_cfg_entry(), ast_category_delete(), ast_category_new(), ast_config_destroy(), process_text_line(), realtime_multi_odbc(), static_realtime_cb(), and write_password_to_file().
{
ast_variables_destroy(cat->root);
cat->root = NULL;
cat->last = NULL;
ast_comment_destroy(&cat->precomments);
ast_comment_destroy(&cat->sameline);
ast_comment_destroy(&cat->trailing);
ast_destroy_template_list(cat);
ast_free(cat->file);
ast_free(cat);
}
| struct ast_variable* ast_category_detach_variables | ( | struct ast_category * | cat | ) | [read] |
Definition at line 945 of file config.c.
References ast_category::last, and ast_category::root.
Referenced by realtime_switch_common().
{
struct ast_variable *v;
v = cat->root;
cat->root = NULL;
cat->last = NULL;
return v;
}
| int ast_category_empty | ( | struct ast_config * | cfg, |
| const char * | category | ||
| ) |
Removes and destroys all variables within a category.
| 0 | if the category was found and emptied |
| -1 | if the category was not found |
Definition at line 1110 of file config.c.
References ast_variables_destroy(), ast_category::last, ast_category::name, ast_category::next, ast_category::root, and ast_config::root.
Referenced by handle_updates().
{
struct ast_category *cat;
for (cat = cfg->root; cat; cat = cat->next) {
if (!strcasecmp(cat->name, category))
continue;
ast_variables_destroy(cat->root);
cat->root = NULL;
cat->last = NULL;
return 0;
}
return -1;
}
| int ast_category_exist | ( | const struct ast_config * | config, |
| const char * | category_name | ||
| ) |
Check for category duplicates.
| config | which config to use |
| category_name | name of the category you're looking for |
This will search through the categories within a given config file for a match.
Definition at line 689 of file config.c.
References ast_category_get().
{
return !!ast_category_get(config, category_name);
}
| struct ast_variable* ast_category_first | ( | struct ast_category * | cat | ) | [read] |
given a pointer to a category, return the root variable.
return the first var of a category
Definition at line 767 of file config.c.
References ast_category::root.
Referenced by acl_order_comparator(), and process_text_line().
{
return (cat) ? cat->root : NULL;
}
| struct ast_category* ast_category_get | ( | const struct ast_config * | config, |
| const char * | category_name | ||
| ) | [read] |
Retrieve a category if it exists.
| config | which config to use |
| category_name | name of the category you're looking for |
This will search through the categories within a given config file for a match.
| pointer | to category if found |
| NULL | if not. |
Definition at line 684 of file config.c.
References category_get().
Referenced by add_message_id(), ast_category_exist(), ast_category_root(), ast_variable_browse(), handle_updates(), realtime_directory(), realtime_switch_common(), vm_change_password(), and vm_forwardoptions().
{
return category_get(config, category_name, 0);
}
| void ast_category_insert | ( | struct ast_config * | config, |
| struct ast_category * | cat, | ||
| const char * | match | ||
| ) |
Inserts new category.
| config | which config to use |
| cat | newly created category to insert |
| match | which category to insert above |
This function is used to insert a new category above another category matching the match parameter.
Definition at line 705 of file config.c.
References ast_category::name, ast_category::next, and ast_config::root.
Referenced by handle_updates().
{
struct ast_category *cur_category;
if (!cat || !match)
return;
if (!strcasecmp(config->root->name, match)) {
cat->next = config->root;
config->root = cat;
return;
}
for (cur_category = config->root; cur_category; cur_category = cur_category->next) {
if (!strcasecmp(cur_category->next->name, match)) {
cat->next = cur_category->next;
cur_category->next = cat;
break;
}
}
}
| struct ast_category* ast_category_new | ( | const char * | name, |
| const char * | in_file, | ||
| int | lineno | ||
| ) | [read] |
Create a category structure.
Definition at line 648 of file config.c.
References ast_calloc, ast_category_destroy(), ast_copy_string(), ast_strdup, ast_category::file, ast_category::lineno, and ast_category::name.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), append_row_to_cfg(), ast_config_copy(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), static_realtime_cb(), and write_password_to_file().
{
struct ast_category *category;
category = ast_calloc(1, sizeof(*category));
if (!category) {
return NULL;
}
category->file = ast_strdup(in_file);
if (!category->file) {
ast_category_destroy(category);
return NULL;
}
ast_copy_string(category->name, name, sizeof(category->name));
category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
return category;
}
| void ast_category_rename | ( | struct ast_category * | cat, |
| const char * | name | ||
| ) |
Definition at line 956 of file config.c.
References ast_copy_string(), and ast_category::name.
Referenced by handle_updates(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
{
ast_copy_string(cat->name, name, sizeof(cat->name));
}
| struct ast_variable* ast_category_root | ( | struct ast_config * | config, |
| char * | cat | ||
| ) | [read] |
returns the root ast_variable of a config
| config | pointer to an ast_config data structure |
| cat | name of the category for which you want the root |
Definition at line 772 of file config.c.
References ast_category_get(), and ast_category::root.
Referenced by get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), and register_realtime_peers_with_callbackextens().
{
struct ast_category *category = ast_category_get(config, cat);
if (category)
return category->root;
return NULL;
}
| int ast_check_realtime | ( | const char * | family | ) |
Check if realtime engine is configured for family.
| family | which family/config to be checked |
Definition at line 2687 of file config.c.
References ast_realtime_enabled(), and find_engine().
Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_named_acl_find(), ast_queue_log(), close_mailbox(), copy_plain_file(), destroy_association(), find_realtime_gw(), handle_response_peerpoke(), handle_voicemail_show_users(), leave_voicemail(), load_module(), load_moh_classes(), local_ast_moh_start(), logger_queue_rt_start(), msg_create_from_file(), realtime_peer(), realtime_update_peer(), register_realtime_peers_with_callbackextens(), rename_file(), set_member_value(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().
{
struct ast_config_engine *eng;
if (!ast_realtime_enabled()) {
return 0; /* There are no engines at all so fail early */
}
eng = find_engine(family, 1, NULL, 0, NULL, 0);
if (eng)
return 1;
return 0;
}
| static void ast_comment_destroy | ( | struct ast_comment ** | comment | ) | [static] |
Definition at line 519 of file config.c.
References ast_free, and ast_comment::next.
Referenced by ast_category_destroy(), and ast_variable_destroy().
{
struct ast_comment *n, *p;
for (p = *comment; p; p = n) {
n = p->next;
ast_free(p);
}
*comment = NULL;
}
| struct ast_config* ast_config_copy | ( | const struct ast_config * | orig | ) | [read] |
Copies the contents of one ast_config into another.
| orig | the config to copy |
Definition at line 2524 of file config.c.
References ast_category_append(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_variables_dup(), ast_category::file, ast_category::last, ast_category::lineno, ast_category::name, ast_category::next, ast_category::root, and ast_config::root.
Referenced by config_hook_exec().
{
struct ast_config *new_config = ast_config_new();
struct ast_category *cat_iter;
if (!new_config) {
return NULL;
}
for (cat_iter = old->root; cat_iter; cat_iter = cat_iter->next) {
struct ast_category *new_cat =
ast_category_new(cat_iter->name, cat_iter->file, cat_iter->lineno);
if (!new_cat) {
goto fail;
}
ast_category_append(new_config, new_cat);
if (cat_iter->root) {
new_cat->root = ast_variables_dup(cat_iter->root);
if (!new_cat->root) {
goto fail;
}
new_cat->last = cat_iter->last;
}
}
return new_config;
fail:
ast_config_destroy(new_config);
return NULL;
}
| void ast_config_destroy | ( | struct ast_config * | config | ) |
Destroys a config.
| config | pointer to config data structure |
Free memory associated with a given config
Definition at line 1126 of file config.c.
References ast_category_destroy(), ast_free, ast_includes_destroy(), ast_config::includes, ast_category::next, and ast_config::root.
Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), __queues_show(), _dsp_init(), aco_process_config(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), aji_load_config(), ast_cli_perms_init(), ast_config_copy(), ast_config_load2(), ast_load_realtime_multientry(), ast_plc_reload(), ast_readconfig(), ast_xmldoc_load_documentation(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_load_queue_rt_friendly(), find_realtime(), forward_message(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), gtalk_load_config(), handle_cli_dialplan_save(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), jingle_load_config(), load_config(), load_config_meetme(), load_format_config(), load_indications(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), make_email_file(), message_range_and_existence_check(), misdn_cfg_init(), named_acl_find_realtime(), notify_new_message(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queues_data_provider_get(), read_agent_config(), read_config_maps(), read_password_from_file(), realtime_directory(), realtime_multi_handler(), realtime_multi_pgsql(), realtime_sqlite3_multi(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), rtp_reload(), run_startup_commands(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), smdi_load(), tds_load_module(), unload_module(), update_realtime_members(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), vm_msg_snapshot_create(), and write_password_to_file().
{
struct ast_category *cat, *catn;
if (!cfg)
return;
ast_includes_destroy(cfg->includes);
cat = cfg->root;
while (cat) {
catn = cat;
cat = cat->next;
ast_category_destroy(catn);
}
ast_free(cfg);
}
| int ast_config_engine_deregister | ( | struct ast_config_engine * | del | ) |
Deregister config engine.
| 0 | Always |
Definition at line 2445 of file config.c.
References ast_mutex_lock, ast_mutex_unlock, config_lock, last, and ast_config_engine::next.
Referenced by unload_module().
{
struct ast_config_engine *ptr, *last=NULL;
ast_mutex_lock(&config_lock);
for (ptr = config_engine_list; ptr; ptr=ptr->next) {
if (ptr == del) {
if (last)
last->next = ptr->next;
else
config_engine_list = ptr->next;
break;
}
last = ptr;
}
ast_mutex_unlock(&config_lock);
return 0;
}
| int ast_config_engine_register | ( | struct ast_config_engine * | newconfig | ) |
Register config engine.
| 1 | Always |
Definition at line 2426 of file config.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, config_lock, LOG_NOTICE, and ast_config_engine::next.
Referenced by load_module().
{
struct ast_config_engine *ptr;
ast_mutex_lock(&config_lock);
if (!config_engine_list) {
config_engine_list = new;
} else {
for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
ptr->next = new;
}
ast_mutex_unlock(&config_lock);
ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name);
return 1;
}
| struct ast_category* ast_config_get_current_category | ( | const struct ast_config * | cfg | ) | [read] |
Retrieve the current category name being built.
API for backend configuration engines while building a configuration set.
Definition at line 1144 of file config.c.
References ast_config::current.
Referenced by config_curl(), config_odbc(), and config_text_file_load().
{
return cfg->current;
}
| int ast_config_hook_register | ( | const char * | name, |
| const char * | filename, | ||
| const char * | module, | ||
| enum config_hook_flags | flags, | ||
| config_hook_cb | hook | ||
| ) |
Register a config hook for a particular file and module.
| name | The name of the hook you are registering. |
| filename | The file whose config you wish to hook into. |
| module | The module that is reloading the config. This can be useful if multiple modules may possibly reload the same file, but you are only interested when a specific module reloads the file |
| flags | Flags that affect the way hooks work. |
| hook | The callback to be called when config is loaded. return 0 Success return -1 Unsuccess, also known as UTTER AND COMPLETE FAILURE |
Definition at line 3328 of file config.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ast_strdup, cfg_hook::filename, cfg_hook::hook_cb, hook_cmp(), hook_destroy(), hook_hash(), cfg_hook::module, and cfg_hook::name.
{
struct cfg_hook *hook;
if (!cfg_hooks && !(cfg_hooks = ao2_container_alloc(17, hook_hash, hook_cmp))) {
return -1;
}
if (!(hook = ao2_alloc(sizeof(*hook), hook_destroy))) {
return -1;
}
hook->hook_cb = hook_cb;
hook->filename = ast_strdup(filename);
hook->name = ast_strdup(name);
hook->module = ast_strdup(module);
ao2_link(cfg_hooks, hook);
return 0;
}
| void ast_config_hook_unregister | ( | const char * | name | ) |
Unregister a config hook.
| name | The name of the hook to unregister |
Definition at line 3300 of file config.c.
References ao2_find, cfg_hook::name, OBJ_NODATA, OBJ_POINTER, and OBJ_UNLINK.
{
struct cfg_hook tmp;
tmp.name = ast_strdupa(name);
ao2_find(cfg_hooks, &tmp, OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA);
}
| 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 | ||
| ) | [read] |
Definition at line 2557 of file config.c.
References ast_log(), ast_test_flag, CONFIG_FLAG_NOREALTIME, config_hook_exec(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, db, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, table, and text_file_engine.
Referenced by add_cfg_entry(), ast_config_load2(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), process_text_line(), read_config_maps(), and static_realtime_cb().
{
char db[256];
char table[256];
struct ast_config_engine *loader = &text_file_engine;
struct ast_config *result;
/* The config file itself bumps include_level by 1 */
if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
return NULL;
}
cfg->include_level++;
if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) {
struct ast_config_engine *eng;
eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
if (eng && eng->load_func) {
loader = eng;
} else {
eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
if (eng && eng->load_func)
loader = eng;
}
}
result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED) {
result->include_level--;
config_hook_exec(filename, who_asked, result);
} else if (result != CONFIG_STATUS_FILEINVALID) {
cfg->include_level--;
}
return result;
}
| struct ast_config* ast_config_load2 | ( | const char * | filename, |
| const char * | who_asked, | ||
| struct ast_flags | flags | ||
| ) | [read] |
Load a config file.
| filename | path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR |
| who_asked | The module which is making this request. |
| 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 CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files). |
Create a config structure from a given configuration file.
| NULL | on error |
Definition at line 2599 of file config.c.
References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), CONFIG_STATUS_FILEINVALID, and CONFIG_STATUS_FILEUNCHANGED.
Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_cli_perms_init(), ast_readconfig(), ast_xmldoc_load_documentation(), do_reload(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), load_config(), load_indications(), load_modules(), misdn_cfg_init(), private_enum_init(), rtp_reload(), run_startup_commands(), and set_config().
{
struct ast_config *cfg;
struct ast_config *result;
cfg = ast_config_new();
if (!cfg)
return NULL;
result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID)
ast_config_destroy(cfg);
return result;
}
| struct ast_config* ast_config_new | ( | void | ) | [read] |
Create a new base configuration structure.
Definition at line 977 of file config.c.
References ast_calloc, config, MAX_INCLUDE_LEVEL, and ast_config::max_include_level.
Referenced by ast_config_copy(), ast_config_load2(), find_load_queue_rt_friendly(), read_config_maps(), realtime_multi_curl(), realtime_multi_handler(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_sqlite3_multi(), setup_dahdi_int(), and write_password_to_file().
{
struct ast_config *config;
if ((config = ast_calloc(1, sizeof(*config))))
config->max_include_level = MAX_INCLUDE_LEVEL;
return config;
}
| const char* ast_config_option | ( | struct ast_config * | cfg, |
| const char * | cat, | ||
| const char * | var | ||
| ) |
Retrieve a configuration variable within the configuration set.
Retrieves the named variable var within category cat of configuration set cfg. If not found, attempts to retrieve the named variable var from within category general.
var, or NULL if not found. Definition at line 589 of file config.c.
References ast_variable_retrieve().
Referenced by actual_load_config(), pbx_load_users(), and search_directory_sub().
{
const char *tmp;
tmp = ast_variable_retrieve(cfg, cat, var);
if (!tmp) {
tmp = ast_variable_retrieve(cfg, "general", var);
}
return tmp;
}
| void ast_config_set_current_category | ( | struct ast_config * | cfg, |
| const struct ast_category * | cat | ||
| ) |
Set the category within the configuration as being current.
API for backend configuration engines while building a configuration set.
Definition at line 1149 of file config.c.
References ast_config::current.
{
/* cast below is just to silence compiler warning about dropping "const" */
cfg->current = (struct ast_category *) cat;
}
| void ast_config_sort_categories | ( | struct ast_config * | config, |
| int | descending, | ||
| int(*)(struct ast_category *p, struct ast_category *q) | comparator | ||
| ) |
Sorts categories in a config in the order of a numerical value contained within them.
| config | The config structure you wish to sort |
| variable | Which numerical value you wish to sort by |
| descending | If true, we sort highest to lowest instead of lowest to highest |
This function will assume a value of 0 for any non-numerical strings and NULL fields.
Definition at line 781 of file config.c.
References ast_category::next, and ast_config::root.
Referenced by named_acl_find_realtime().
{
/*
* The contents of this function are adapted from
* an example of linked list merge sorting
* copyright 2001 Simon Tatham.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
int insize = 1;
struct ast_category *p, *q, *e, *tail;
int nmerges, psize, qsize, i;
/* If the descending flag was sent, we'll apply inversion to the comparison function's return. */
if (descending) {
descending = -1;
} else {
descending = 1;
}
if (!config->root) {
return;
}
while (1) {
p = config->root;
config->root = NULL;
tail = NULL;
nmerges = 0; /* count number of merges we do in this pass */
while (p) {
nmerges++; /* there exists a merge to be done */
/* step `insize' places along from p */
q = p;
psize = 0;
for (i = 0; i < insize; i++) {
psize++;
q = q->next;
if (!q) {
break;
}
}
/* if q hasn't fallen off end, we have two lists to merge */
qsize = insize;
/* now we have two lists; merge them */
while (psize > 0 || (qsize > 0 && q)) {
/* decide whether next element of merge comes from p or q */
if (psize == 0) {
/* p is empty; e must come from q. */
e = q;
q = q->next;
qsize--;
} else if (qsize == 0 || !q) {
/* q is empty; e must come from p. */
e = p; p = p->next; psize--;
} else if ((comparator(p,q) * descending) <= 0) {
/* First element of p is lower (or same) e must come from p. */
e = p;
p = p->next;
psize--;
} else {
/* First element of q is lower; e must come from q. */
e = q;
q = q->next;
qsize--;
}
/* add the next element to the merged list */
if (tail) {
tail->next = e;
} else {
config->root = e;
}
tail = e;
}
/* now p has stepped `insize' places along, and q has too */
p = q;
}
tail->next = NULL;
/* If we have done only one merge, we're finished. */
if (nmerges <= 1) { /* allow for nmerges==0, the empty list case */
return;
}
/* Otherwise repeat, merging lists twice the size */
insize *= 2;
}
}
| int ast_config_text_file_save | ( | const char * | configfile, |
| const struct ast_config * | cfg, | ||
| const char * | generator | ||
| ) |
Definition at line 2040 of file config.c.
References ao2_container_alloc, ao2_ref, ast_debug, AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_verb, ast_variable::blanklines, ast_comment::cmt, errno, ast_config_include::exec, ast_config_include::exec_file, f, ast_variable::file, ast_category::file, gen_header(), hash_string(), hashtab_compare_strings(), ast_category::ignored, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config::includes, insert_leading_blank_lines(), ast_category_template_instance::inst, ast_variable::lineno, ast_category::lineno, ast_variable::name, ast_category_template_instance::name, ast_category::name, ast_comment::next, ast_variable::next, ast_category::next, ast_config_include::next, ast_variable::object, option_debug, ast_config_include::output, ast_variable::precomments, ast_category::precomments, ast_category::root, ast_config::root, ast_variable::sameline, ast_category::sameline, set_fn(), ast_category::template_instances, ast_variable::trailing, ast_category::trailing, ast_variable::value, and var.
Referenced by action_updateconfig(), add_message_id(), config_text_file_save(), vm_change_password(), vm_forwardoptions(), and write_password_to_file().
{
FILE *f;
char fn[PATH_MAX];
struct ast_variable *var;
struct ast_category *cat;
struct ast_comment *cmt;
struct ast_config_include *incl;
int blanklines = 0;
struct ao2_container *fileset;
struct inclfile *fi;
fileset = ao2_container_alloc(1023, hash_string, hashtab_compare_strings);
if (!fileset) {
/* Container creation failed. */
return -1;
}
/* reset all the output flags, in case this isn't our first time saving this data */
for (incl = cfg->includes; incl; incl = incl->next) {
incl->output = 0;
}
/* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
are all truncated to zero bytes and have that nice header*/
for (incl = cfg->includes; incl; incl = incl->next) {
if (!incl->exec) { /* leave the execs alone -- we'll write out the #exec directives, but won't zero out the include files or exec files*/
/* normally, fn is just set to incl->included_file, prepended with config dir if relative */
fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
f = fopen(fn, "w");
if (f) {
gen_header(f, configfile, fn, generator);
fclose(f); /* this should zero out the file */
} else {
ast_debug(1, "Unable to open for writing: %s\n", fn);
ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
}
if (fi) {
ao2_ref(fi, -1);
}
}
}
/* just set fn to absolute ver of configfile */
fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
if (
#ifdef __CYGWIN__
(f = fopen(fn, "w+"))
#else
(f = fopen(fn, "w"))
#endif
) {
ast_verb(2, "Saving '%s'\n", fn);
gen_header(f, configfile, fn, generator);
cat = cfg->root;
fclose(f);
if (fi) {
ao2_ref(fi, -1);
}
/* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
/* since each var, cat, and associated comments can come from any file, we have to be
mobile, and open each file, print, and close it on an entry-by-entry basis */
while (cat) {
fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
f = fopen(fn, "a");
if (!f) {
ast_debug(1, "Unable to open for writing: %s\n", fn);
ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
if (fi) {
ao2_ref(fi, -1);
}
ao2_ref(fileset, -1);
return -1;
}
/* dump any includes that happen before this category header */
for (incl=cfg->includes; incl; incl = incl->next) {
if (strcmp(incl->include_location_file, cat->file) == 0){
if (cat->lineno > incl->include_location_lineno && !incl->output) {
if (incl->exec)
fprintf(f,"#exec \"%s\"\n", incl->exec_file);
else
fprintf(f,"#include \"%s\"\n", incl->included_file);
incl->output = 1;
}
}
}
insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno);
/* Dump section with any appropriate comment */
for (cmt = cat->precomments; cmt; cmt=cmt->next) {
char *cmtp = cmt->cmt;
while (cmtp && *cmtp == ';' && *(cmtp+1) == '!') {
char *cmtp2 = strchr(cmtp+1, '\n');
if (cmtp2)
cmtp = cmtp2+1;
else cmtp = 0;
}
if (cmtp)
fprintf(f,"%s", cmtp);
}
fprintf(f, "[%s]", cat->name);
if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
fprintf(f, "(");
if (cat->ignored) {
fprintf(f, "!");
}
if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
fprintf(f, ",");
}
if (!AST_LIST_EMPTY(&cat->template_instances)) {
struct ast_category_template_instance *x;
AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
fprintf(f,"%s",x->name);
if (x != AST_LIST_LAST(&cat->template_instances))
fprintf(f,",");
}
}
fprintf(f, ")");
}
for(cmt = cat->sameline; cmt; cmt=cmt->next)
{
fprintf(f,"%s", cmt->cmt);
}
if (!cat->sameline)
fprintf(f,"\n");
for (cmt = cat->trailing; cmt; cmt=cmt->next) {
if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
fprintf(f,"%s", cmt->cmt);
}
fclose(f);
if (fi) {
ao2_ref(fi, -1);
}
var = cat->root;
while (var) {
struct ast_category_template_instance *x;
int found = 0;
AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
struct ast_variable *v;
for (v = x->inst->root; v; v = v->next) {
if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
found = 1;
break;
}
}
if (found)
break;
}
if (found) {
var = var->next;
continue;
}
fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
f = fopen(fn, "a");
if (!f) {
ast_debug(1, "Unable to open for writing: %s\n", fn);
ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
if (fi) {
ao2_ref(fi, -1);
}
ao2_ref(fileset, -1);
return -1;
}
/* dump any includes that happen before this category header */
for (incl=cfg->includes; incl; incl = incl->next) {
if (strcmp(incl->include_location_file, var->file) == 0){
if (var->lineno > incl->include_location_lineno && !incl->output) {
if (incl->exec)
fprintf(f,"#exec \"%s\"\n", incl->exec_file);
else
fprintf(f,"#include \"%s\"\n", incl->included_file);
incl->output = 1;
}
}
}
insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
for (cmt = var->precomments; cmt; cmt=cmt->next) {
if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
fprintf(f,"%s", cmt->cmt);
}
if (var->sameline)
fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
else
fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
for (cmt = var->trailing; cmt; cmt=cmt->next) {
if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
fprintf(f,"%s", cmt->cmt);
}
if (var->blanklines) {
blanklines = var->blanklines;
while (blanklines--)
fprintf(f, "\n");
}
fclose(f);
if (fi) {
ao2_ref(fi, -1);
}
var = var->next;
}
cat = cat->next;
}
if (!option_debug) {
ast_verb(2, "Saving '%s': saved\n", fn);
}
} else {
ast_debug(1, "Unable to open for writing: %s\n", fn);
ast_verb(2, "Unable to write '%s' (%s)\n", fn, strerror(errno));
if (fi) {
ao2_ref(fi, -1);
}
ao2_ref(fileset, -1);
return -1;
}
/* Now, for files with trailing #include/#exec statements,
we have to make sure every entry is output */
for (incl=cfg->includes; incl; incl = incl->next) {
if (!incl->output) {
/* open the respective file */
fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
f = fopen(fn, "a");
if (!f) {
ast_debug(1, "Unable to open for writing: %s\n", fn);
ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
if (fi) {
ao2_ref(fi, -1);
}
ao2_ref(fileset, -1);
return -1;
}
/* output the respective include */
if (incl->exec)
fprintf(f,"#exec \"%s\"\n", incl->exec_file);
else
fprintf(f,"#include \"%s\"\n", incl->included_file);
fclose(f);
incl->output = 1;
if (fi) {
ao2_ref(fi, -1);
}
}
}
ao2_ref(fileset, -1); /* this should destroy the hash container */
return 0;
}
| int ast_destroy_realtime | ( | const char * | family, |
| const char * | keyfield, | ||
| const char * | lookup, | ||
| ... | |||
| ) |
Destroy realtime configuration.
| family | which family/config to be destroyed |
| keyfield | which field to use as the key |
| lookup | which value to look for in the key field to match the entry. |
This function is used to destroy an entry in realtime configuration space. Additional params are used as keys.
Definition at line 2850 of file config.c.
References db, ast_config_engine::destroy_func, find_engine(), and table.
Referenced by cli_realtime_destroy(), function_realtime_readdestroy(), leave_voicemail(), msg_create_from_file(), and vm_delete().
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
va_list ap;
va_start(ap, lookup);
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, ap))) {
break;
}
} else {
break;
}
}
va_end(ap);
return res;
}
| static void ast_destroy_template_list | ( | struct ast_category * | cat | ) | [static] |
Definition at line 725 of file config.c.
References ast_free, AST_LIST_REMOVE_HEAD, and ast_category::template_instances.
Referenced by ast_category_destroy().
{
struct ast_category_template_instance *x;
while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
ast_free(x);
}
| struct ast_config_include* ast_include_find | ( | struct ast_config * | conf, |
| const char * | included_file | ||
| ) | [read] |
Definition at line 471 of file config.c.
References ast_config_include::included_file, ast_config::includes, and ast_config_include::next.
Referenced by ast_include_new().
{
struct ast_config_include *x;
for (x=conf->includes;x;x=x->next) {
if (strcmp(x->included_file,included_file) == 0)
return x;
}
return 0;
}
| struct ast_config_include* ast_include_new | ( | struct ast_config * | conf, |
| const char * | from_file, | ||
| const char * | included_file, | ||
| int | is_exec, | ||
| const char * | exec_file, | ||
| int | from_lineno, | ||
| char * | real_included_file_name, | ||
| int | real_included_file_name_size | ||
| ) | [read] |
Definition at line 331 of file config.c.
References ast_calloc, ast_include_find(), ast_includes_destroy(), ast_log(), ast_strdup, ast_strlen_zero(), ast_config::includes, and LOG_WARNING.
Referenced by process_text_line().
{
/* a file should be included ONCE. Otherwise, if one of the instances is changed,
* then all be changed. -- how do we know to include it? -- Handling modified
* instances is possible, I'd have
* to create a new master for each instance. */
struct ast_config_include *inc;
struct stat statbuf;
inc = ast_include_find(conf, included_file);
if (inc) {
do {
inc->inclusion_count++;
snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
} while (stat(real_included_file_name, &statbuf) == 0);
ast_log(LOG_WARNING,"'%s', line %d: Same File included more than once! This data will be saved in %s if saved back to disk.\n", from_file, from_lineno, real_included_file_name);
} else
*real_included_file_name = 0;
inc = ast_calloc(1,sizeof(struct ast_config_include));
if (!inc) {
return NULL;
}
inc->include_location_file = ast_strdup(from_file);
inc->include_location_lineno = from_lineno;
if (!ast_strlen_zero(real_included_file_name))
inc->included_file = ast_strdup(real_included_file_name);
else
inc->included_file = ast_strdup(included_file);
inc->exec = is_exec;
if (is_exec)
inc->exec_file = ast_strdup(exec_file);
if (!inc->include_location_file
|| !inc->included_file
|| (is_exec && !inc->exec_file)) {
ast_includes_destroy(inc);
return NULL;
}
/* attach this new struct to the conf struct */
inc->next = conf->includes;
conf->includes = inc;
return inc;
}
| void ast_include_rename | ( | struct ast_config * | conf, |
| const char * | from_file, | ||
| const char * | to_file | ||
| ) |
Definition at line 379 of file config.c.
References ast_free, ast_strdup, ast_variable_destroy(), ast_variable_move(), ast_variable_new(), ast_variable::file, ast_category::file, ast_config_include::include_location_file, ast_config::includes, ast_category::last, ast_variable::name, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, ast_config::root, str, and ast_variable::value.
Referenced by action_updateconfig().
{
struct ast_config_include *incl;
struct ast_category *cat;
char *str;
int from_len = strlen(from_file);
int to_len = strlen(to_file);
if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
return;
/* the manager code allows you to read in one config file, then
* write it back out under a different name. But, the new arrangement
* ties output lines to the file name. So, before you try to write
* the config file to disk, better riffle thru the data and make sure
* the file names are changed.
*/
/* file names are on categories, includes (of course), and on variables. So,
* traverse all this and swap names */
for (incl = conf->includes; incl; incl=incl->next) {
if (strcmp(incl->include_location_file,from_file) == 0) {
if (from_len >= to_len)
strcpy(incl->include_location_file, to_file);
else {
/* Keep the old filename if the allocation fails. */
str = ast_strdup(to_file);
if (str) {
ast_free(incl->include_location_file);
incl->include_location_file = str;
}
}
}
}
for (cat = conf->root; cat; cat = cat->next) {
struct ast_variable **prev;
struct ast_variable *v;
struct ast_variable *new_var;
if (strcmp(cat->file,from_file) == 0) {
if (from_len >= to_len)
strcpy(cat->file, to_file);
else {
/* Keep the old filename if the allocation fails. */
str = ast_strdup(to_file);
if (str) {
ast_free(cat->file);
cat->file = str;
}
}
}
for (prev = &cat->root, v = cat->root; v; prev = &v->next, v = v->next) {
if (strcmp(v->file, from_file)) {
continue;
}
/*
* Calculate actual space available. The file string is
* intentionally stuffed before the name string just so we can
* do this.
*/
if (to_len < v->name - v->file) {
/* The new name will fit in the available space. */
str = (char *) v->file;/* Stupid compiler complains about discarding qualifiers even though I used a cast. */
strcpy(str, to_file);/* SAFE */
continue;
}
/* Keep the old filename if the allocation fails. */
new_var = ast_variable_new(v->name, v->value, to_file);
if (!new_var) {
continue;
}
/* Move items from the old list node to the replacement node. */
ast_variable_move(new_var, v);
/* Replace the old node in the list with the new node. */
new_var->next = v->next;
if (cat->last == v) {
cat->last = new_var;
}
*prev = new_var;
ast_variable_destroy(v);
v = new_var;
}
}
}
| static void ast_includes_destroy | ( | struct ast_config_include * | incls | ) | [static] |
Definition at line 746 of file config.c.
References ast_free, ast_config_include::exec_file, ast_config_include::include_location_file, ast_config_include::included_file, and ast_config_include::next.
Referenced by ast_config_destroy(), and ast_include_new().
{
struct ast_config_include *incl,*inclnext;
for (incl=incls; incl; incl = inclnext) {
inclnext = incl->next;
ast_free(incl->include_location_file);
ast_free(incl->exec_file);
ast_free(incl->included_file);
ast_free(incl);
}
}
| struct ast_variable* ast_load_realtime | ( | const char * | family, |
| ... | |||
| ) | [read] |
Retrieve realtime configuration.
| family | which family/config to lookup |
This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters.
Definition at line 2648 of file config.c.
References ast_load_realtime_helper(), ast_strlen_zero(), ast_variable_destroy(), ast_variable::next, cache_file_include::next, and ast_variable::value.
Referenced by conf_run(), copy_plain_file(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_realtime_gw(), find_user_realtime(), leave_queue(), local_ast_moh_start(), queue_function_queuewaitingcount(), realtime_alias(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_switch_common(), realtime_user(), and rt_extend_conf().
{
struct ast_variable *res;
struct ast_variable *cur;
struct ast_variable **prev;
va_list ap;
va_start(ap, family);
res = ast_load_realtime_helper(family, ap);
va_end(ap);
/* Filter the list. */
prev = &res;
cur = res;
while (cur) {
if (ast_strlen_zero(cur->value)) {
/* Eliminate empty entries */
struct ast_variable *next;
next = cur->next;
*prev = next;
ast_variable_destroy(cur);
cur = next;
} else {
/* Make blank entries empty and keep them. */
if (cur->value[0] == ' ' && cur->value[1] == '\0') {
char *vptr = (char *) cur->value;
vptr[0] = '\0';
}
prev = &cur->next;
cur = cur->next;
}
}
return res;
}
| struct ast_variable* ast_load_realtime_all | ( | const char * | family, |
| ... | |||
| ) | [read] |
Definition at line 2636 of file config.c.
References ast_load_realtime_helper().
Referenced by cli_realtime_load(), function_realtime_read(), function_realtime_readdestroy(), and realtimefield_read().
{
struct ast_variable *res;
va_list ap;
va_start(ap, family);
res = ast_load_realtime_helper(family, ap);
va_end(ap);
return res;
}
| static struct ast_variable* ast_load_realtime_helper | ( | const char * | family, |
| va_list | ap | ||
| ) | [static, read] |
Definition at line 2615 of file config.c.
References db, find_engine(), ast_config_engine::realtime_func, and table.
Referenced by ast_load_realtime(), and ast_load_realtime_all().
{
struct ast_config_engine *eng;
char db[256];
char table[256];
struct ast_variable *res=NULL;
int i;
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
if (eng->realtime_func && (res = eng->realtime_func(db, table, ap))) {
return res;
}
} else {
return NULL;
}
}
return res;
}
| struct ast_config* ast_load_realtime_multientry | ( | const char * | family, |
| ... | |||
| ) | [read] |
Retrieve realtime configuration.
| family | which family/config to lookup |
This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. Unlike the ast_load_realtime, this function can return more than one entry and is thus stored inside a traditional ast_config structure rather than just returning a linked list of variables.
| NULL | Error or no results returned |
Definition at line 2750 of file config.c.
References ast_config_destroy(), db, find_engine(), ast_config_engine::realtime_multi_func, ast_config::root, and table.
Referenced by __queues_show(), conf_exec(), find_load_queue_rt_friendly(), find_realtime(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), load_module(), named_acl_find_realtime(), queues_data_provider_get(), realtime_directory(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), set_member_value(), show_users_realtime(), and update_realtime_members().
{
struct ast_config_engine *eng;
char db[256];
char table[256];
struct ast_config *res = NULL;
va_list ap;
int i;
va_start(ap, family);
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, ap))) {
/* If we were returned an empty cfg, destroy it and return NULL */
if (!res->root) {
ast_config_destroy(res);
res = NULL;
}
break;
}
} else {
break;
}
}
va_end(ap);
return res;
}
| int ast_parse_arg | ( | const char * | arg, |
| enum ast_parse_flags | flags, | ||
| void * | p_result, | ||
| ... | |||
| ) |
Helper function to parse arguments See documentation in config.h.
The argument parsing routine.
Definition at line 2905 of file config.c.
References ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_skip_blanks(), ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_strlen_zero(), errno, hp, INT32_MAX, INT32_MIN, PARSE_ADDR, PARSE_DEFAULT, PARSE_DOUBLE, PARSE_IN_RANGE, PARSE_INADDR, PARSE_INT32, PARSE_OUT_RANGE, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, PARSE_PORT_REQUIRE, PARSE_RANGE_DEFAULTS, PARSE_TYPE, PARSE_UINT32, and UINT32_MAX.
Referenced by __ast_http_load(), __init_manager(), app_exec(), ast_tls_read_conf(), double_handler_fn(), gtalk_load_config(), int_handler_fn(), reload_config(), rtp_reload(), sockaddr_handler_fn(), and uint_handler_fn().
{
va_list ap;
int error = 0;
va_start(ap, p_result);
switch (flags & PARSE_TYPE) {
case PARSE_INT32:
{
long int x = 0;
int32_t *result = p_result;
int32_t def = result ? *result : 0, high = INT32_MAX, low = INT32_MIN;
char *endptr = NULL;
/* optional arguments: default value and/or (low, high) */
if (flags & PARSE_DEFAULT) {
def = va_arg(ap, int32_t);
}
if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
low = va_arg(ap, int32_t);
high = va_arg(ap, int32_t);
}
if (ast_strlen_zero(arg)) {
error = 1;
goto int32_done;
}
errno = 0;
x = strtol(arg, &endptr, 0);
if (*endptr || errno || x < INT32_MIN || x > INT32_MAX) {
/* Parse error, or type out of int32_t bounds */
error = 1;
goto int32_done;
}
error = (x < low) || (x > high);
if (flags & PARSE_RANGE_DEFAULTS) {
if (x < low) {
def = low;
} else if (x > high) {
def = high;
}
}
if (flags & PARSE_OUT_RANGE) {
error = !error;
}
int32_done:
if (result) {
*result = error ? def : x;
}
ast_debug(3, "extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
arg, low, high, result ? *result : x, error);
break;
}
case PARSE_UINT32:
{
unsigned long int x = 0;
uint32_t *result = p_result;
uint32_t def = result ? *result : 0, low = 0, high = UINT32_MAX;
char *endptr = NULL;
/* optional argument: first default value, then range */
if (flags & PARSE_DEFAULT) {
def = va_arg(ap, uint32_t);
}
if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
/* range requested, update bounds */
low = va_arg(ap, uint32_t);
high = va_arg(ap, uint32_t);
}
if (ast_strlen_zero(arg)) {
error = 1;
goto uint32_done;
}
/* strtoul will happilly and silently negate negative numbers */
arg = ast_skip_blanks(arg);
if (*arg == '-') {
error = 1;
goto uint32_done;
}
errno = 0;
x = strtoul(arg, &endptr, 0);
if (*endptr || errno || x > UINT32_MAX) {
error = 1;
goto uint32_done;
}
error = (x < low) || (x > high);
if (flags & PARSE_RANGE_DEFAULTS) {
if (x < low) {
def = low;
} else if (x > high) {
def = high;
}
}
if (flags & PARSE_OUT_RANGE) {
error = !error;
}
uint32_done:
if (result) {
*result = error ? def : x;
}
ast_debug(3, "extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
arg, low, high, result ? *result : x, error);
break;
}
case PARSE_DOUBLE:
{
double *result = p_result;
double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
char *endptr = NULL;
/* optional argument: first default value, then range */
if (flags & PARSE_DEFAULT) {
def = va_arg(ap, double);
}
if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
/* range requested, update bounds */
low = va_arg(ap, double);
high = va_arg(ap, double);
}
if (ast_strlen_zero(arg)) {
error = 1;
goto double_done;
}
errno = 0;
x = strtod(arg, &endptr);
if (*endptr || errno == ERANGE) {
error = 1;
goto double_done;
}
error = (x < low) || (x > high);
if (flags & PARSE_OUT_RANGE) {
error = !error;
}
double_done:
if (result) {
*result = error ? def : x;
}
ast_debug(3, "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
arg, low, high, result ? *result : x, error);
break;
}
case PARSE_ADDR:
{
struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result;
if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) {
error = 1;
}
ast_debug(3, "extract addr from %s gives %s(%d)\n",
arg, ast_sockaddr_stringify(addr), error);
break;
}
case PARSE_INADDR: /* TODO Remove this (use PARSE_ADDR instead). */
{
char *port, *buf;
struct sockaddr_in _sa_buf; /* buffer for the result */
struct sockaddr_in *sa = p_result ?
(struct sockaddr_in *)p_result : &_sa_buf;
/* default is either the supplied value or the result itself */
struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
va_arg(ap, struct sockaddr_in *) : sa;
struct hostent *hp;
struct ast_hostent ahp;
memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
/* duplicate the string to strip away the :port */
port = ast_strdupa(arg);
buf = strsep(&port, ":");
sa->sin_family = AF_INET; /* assign family */
/*
* honor the ports flag setting, assign default value
* in case of errors or field unset.
*/
flags &= PARSE_PORT_MASK; /* the only flags left to process */
if (port) {
if (flags == PARSE_PORT_FORBID) {
error = 1; /* port was forbidden */
sa->sin_port = def->sin_port;
} else if (flags == PARSE_PORT_IGNORE)
sa->sin_port = def->sin_port;
else /* accept or require */
sa->sin_port = htons(strtol(port, NULL, 0));
} else {
sa->sin_port = def->sin_port;
if (flags == PARSE_PORT_REQUIRE)
error = 1;
}
/* Now deal with host part, even if we have errors before. */
hp = ast_gethostbyname(buf, &ahp);
if (hp) /* resolved successfully */
memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
else {
error = 1;
sa->sin_addr = def->sin_addr;
}
ast_debug(3,
"extract inaddr from [%s] gives [%s:%d](%d)\n",
arg, ast_inet_ntoa(sa->sin_addr),
ntohs(sa->sin_port), error);
break;
}
}
va_end(ap);
return error;
}
| char* ast_realtime_decode_chunk | ( | char * | chunk | ) |
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values.
| chunk | Data to be decoded |
Definition at line 2873 of file config.c.
Referenced by realtime_multi_pgsql(), and realtime_pgsql().
{
char *orig = chunk;
for (; *chunk; chunk++) {
if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
sscanf(chunk + 1, "%02hhX", chunk);
memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
}
}
return orig;
}
| int ast_realtime_enabled | ( | void | ) |
Check if there's any realtime engines loaded.
Definition at line 2701 of file config.c.
References config_maps.
Referenced by action_coresettings(), ast_check_realtime(), and handle_show_settings().
{
return config_maps ? 1 : 0;
}
| char* ast_realtime_encode_chunk | ( | struct ast_str ** | dest, |
| ssize_t | maxlen, | ||
| const char * | chunk | ||
| ) |
Encodes a chunk of data for realtime.
| dest | Destination buffer |
| maxlen | Length passed through to ast_str_* functions |
| chunk | Source data to be encoded |
Definition at line 2885 of file config.c.
References ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_set().
{
if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
ast_str_set(dest, maxlen, "%s", chunk);
} else {
ast_str_reset(*dest);
for (; *chunk; chunk++) {
if (strchr(";^", *chunk)) {
ast_str_append(dest, maxlen, "^%02hhX", *chunk);
} else {
ast_str_append(dest, maxlen, "%c", *chunk);
}
}
}
return ast_str_buffer(*dest);
}
| int ast_realtime_is_mapping_defined | ( | const char * | family | ) |
Determine if a mapping exists for a given family.
| family | which family you are looking to see if a mapping exists for |
| 1 | if it is mapped |
| 0 | if it is not |
Definition at line 2467 of file config.c.
References ast_mutex_lock, ast_mutex_unlock, config_lock, config_maps, map, ast_config_map::name, and ast_config_map::next.
Referenced by ast_named_acl_find().
{
struct ast_config_map *map;
ast_mutex_lock(&config_lock);
for (map = config_maps; map; map = map->next) {
if (!strcasecmp(family, map->name)) {
ast_mutex_unlock(&config_lock);
return 1;
}
}
ast_mutex_unlock(&config_lock);
return 0;
}
| int ast_realtime_require_field | ( | const char * | family, |
| ... | |||
| ) |
Inform realtime what fields that may be stored.
| family | which family/config is referenced |
This will inform builtin configuration backends that particular fields may be updated during the use of that configuration section. This is mainly to be used during startup routines, to ensure that various fields exist in the backend. The backends may take various actions, such as creating new fields in the data store or warning the administrator that new fields may need to be created, in order to ensure proper function.
The arguments are specified in groups of 3: column name, column type, and column size. The column types are specified as integer constants, defined by the enum require_type. Note that the size is specified as the number of equivalent character fields that a field may take up, even if a field is otherwise specified as an integer type. This is due to the fact that some fields have historically been specified as character types, even if they contained integer values.
A family should always specify its fields to the minimum necessary requirements to fulfill all possible values (within reason; for example, a timeout value may reasonably be specified as an INTEGER2, with size 5. Even though values above 32767 seconds are possible, they are unlikely to be useful, and we should not complain about that size).
| 0 | Required fields met specified standards |
| -1 | One or more fields was missing or insufficient |
Definition at line 2706 of file config.c.
References db, find_engine(), ast_config_engine::require_func, and table.
Referenced by ast_queue_log(), change_password_realtime(), conf_run(), load_module(), and logger_queue_rt_start().
{
struct ast_config_engine *eng;
char db[256];
char table[256];
va_list ap;
int res = -1, i;
va_start(ap, family);
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
/* If the require succeeds, it returns 0. */
if (eng->require_func && !(res = eng->require_func(db, table, ap))) {
break;
}
} else {
break;
}
}
va_end(ap);
return res;
}
| int ast_store_realtime | ( | const char * | family, |
| ... | |||
| ) |
Create realtime configuration.
| family | which family/config to be created |
This function is used to create a parameter in realtime configuration space.
Definition at line 2826 of file config.c.
References db, find_engine(), ast_config_engine::store_func, and table.
Referenced by ast_queue_log(), cli_realtime_store(), copy_plain_file(), function_realtime_store(), leave_voicemail(), and msg_create_from_file().
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
va_list ap;
va_start(ap, family);
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
/* If the store succeeds, it returns 0. */
if (eng->store_func && !(res = eng->store_func(db, table, ap))) {
break;
}
} else {
break;
}
}
va_end(ap);
return res;
}
| int ast_unload_realtime | ( | const char * | family | ) |
Release any resources cached for a realtime family.
| family | which family/config to destroy |
Various backends may cache attributes about a realtime data storage facility; on reload, a front end resource may request to purge that cache.
| 0 | If any cache was purged |
| -1 | If no cache was found |
Definition at line 2730 of file config.c.
References db, find_engine(), table, and ast_config_engine::unload_func.
Referenced by __unload_module(), load_config(), logger_queue_init(), reload(), reload_config(), reload_logger(), and unload_module().
{
struct ast_config_engine *eng;
char db[256];
char table[256];
int res = -1, i;
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
if (eng->unload_func) {
/* Do this for ALL engines */
res = eng->unload_func(db, table);
}
} else {
break;
}
}
return res;
}
| int ast_update2_realtime | ( | const char * | family, |
| ... | |||
| ) |
Update realtime configuration.
| family | which family/config to be updated |
This function is used to update a parameter in realtime configuration space. It includes the ability to lookup a row based upon multiple key criteria. As a result, this function includes two sentinel values, one to terminate lookup values and the other to terminate the listing of fields to update.
Definition at line 2803 of file config.c.
References db, find_engine(), table, and ast_config_engine::update2_func.
Referenced by change_password_realtime(), and cli_realtime_update2().
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
va_list ap;
va_start(ap, family);
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
if (eng->update2_func && !(res = eng->update2_func(db, table, ap))) {
break;
}
} else {
break;
}
}
va_end(ap);
return res;
}
| int ast_update_realtime | ( | const char * | family, |
| const char * | keyfield, | ||
| const char * | lookup, | ||
| ... | |||
| ) |
Update realtime configuration.
| family | which family/config to be updated |
| keyfield | which field to use as the key |
| lookup | which value to look for in the key field to match the entry. |
This function is used to update a parameter in realtime configuration space.
Definition at line 2779 of file config.c.
References db, find_engine(), table, and ast_config_engine::update_func.
Referenced by cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), handle_response_peerpoke(), leave_voicemail(), realtime_update_peer(), rename_file(), rt_extend_conf(), sip_poke_noanswer(), and update_realtime_member_field().
{
struct ast_config_engine *eng;
int res = -1, i;
char db[256];
char table[256];
va_list ap;
va_start(ap, lookup);
for (i = 1; ; i++) {
if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
/* If the update succeeds, it returns 0. */
if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, ap))) {
break;
}
} else {
break;
}
}
va_end(ap);
return res;
}
| void ast_variable_append | ( | struct ast_category * | category, |
| struct ast_variable * | variable | ||
| ) |
Definition at line 482 of file config.c.
References ast_category::last, ast_variable::next, and ast_category::root.
Referenced by add_cfg_entry(), add_message_id(), add_rt_multi_cfg_entry(), append_row_to_cfg(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), inherit_category(), move_variables(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), static_realtime_cb(), vm_change_password(), and write_password_to_file().
| struct ast_variable* ast_variable_browse | ( | const struct ast_config * | config, |
| const char * | category | ||
| ) | [read] |
Goes through variables.
Somewhat similar in intent as the ast_category_browse. List variables of config file category
| ast_variable | list on success |
| NULL | on failure |
Definition at line 572 of file config.c.
References ast_category_get(), ast_config::last_browse, ast_category::name, and ast_category::root.
Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), _dsp_init(), aco_process_category_options(), action_getconfig(), action_getconfigjson(), actual_load_config(), adsi_load(), aji_load_config(), ast_cli_perms_init(), ast_plc_reload(), ast_readconfig(), ast_variable_retrieve(), ast_xmldoc_load_documentation(), build_calendar(), build_device(), caldav_load_calendar(), conf_exec(), config_load(), config_module(), do_reload(), do_say(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), jingle_load_config(), load_config(), load_format_config(), load_general_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), misdn_cfg_init(), new_realtime_sqlite3_db(), odbc_load_module(), osp_create_provider(), parse_config(), parse_tone_zone(), pbx_load_config(), process_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_single_queue(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().
{
struct ast_category *cat = NULL;
if (!category) {
return NULL;
}
if (config->last_browse && (config->last_browse->name == category)) {
cat = config->last_browse;
} else {
cat = ast_category_get(config, category);
}
return (cat) ? cat->root : NULL;
}
| int ast_variable_delete | ( | struct ast_category * | category, |
| const char * | variable, | ||
| const char * | match, | ||
| const char * | line | ||
| ) |
Definition at line 986 of file config.c.
References ast_strlen_zero(), ast_variable_destroy(), ast_category::last, ast_variable::name, ast_variable::next, ast_category::root, and ast_variable::value.
Referenced by handle_updates().
{
struct ast_variable *cur, *prev=NULL, *curn;
int res = -1;
int num_item = 0;
int req_item;
req_item = -1;
if (!ast_strlen_zero(line)) {
/* Requesting to delete by item number. */
if (sscanf(line, "%30d", &req_item) != 1
|| req_item < 0) {
/* Invalid item number to delete. */
return -1;
}
}
prev = NULL;
cur = category->root;
while (cur) {
curn = cur->next;
/* Delete by item number or by variable name with optional value. */
if ((0 <= req_item && num_item == req_item)
|| (req_item < 0 && !strcasecmp(cur->name, variable)
&& (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
if (prev) {
prev->next = cur->next;
if (cur == category->last)
category->last = prev;
} else {
category->root = cur->next;
if (cur == category->last)
category->last = NULL;
}
ast_variable_destroy(cur);
res = 0;
} else
prev = cur;
cur = curn;
++num_item;
}
return res;
}
| static void ast_variable_destroy | ( | struct ast_variable * | doomed | ) | [static] |
Definition at line 531 of file config.c.
References ast_comment_destroy(), ast_free, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.
Referenced by ast_include_rename(), ast_load_realtime(), ast_variable_delete(), ast_variable_update(), and ast_variables_destroy().
{
ast_comment_destroy(&doomed->precomments);
ast_comment_destroy(&doomed->sameline);
ast_comment_destroy(&doomed->trailing);
ast_free(doomed);
}
| void ast_variable_insert | ( | struct ast_category * | category, |
| struct ast_variable * | variable, | ||
| const char * | line | ||
| ) |
Definition at line 495 of file config.c.
References ast_variable::lineno, ast_variable::next, and ast_category::root.
Referenced by handle_updates().
{
struct ast_variable *cur = category->root;
int lineno;
int insertline;
if (!variable || sscanf(line, "%30d", &insertline) != 1) {
return;
}
if (!insertline) {
variable->next = category->root;
category->root = variable;
} else {
for (lineno = 1; lineno < insertline; lineno++) {
cur = cur->next;
if (!cur->next) {
break;
}
}
variable->next = cur->next;
cur->next = variable;
}
}
| static void ast_variable_move | ( | struct ast_variable * | dst_var, |
| struct ast_variable * | src_var | ||
| ) | [static] |
Definition at line 318 of file config.c.
References ast_variable::blanklines, ast_variable::lineno, ast_variable::object, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.
Referenced by ast_include_rename(), and ast_variable_update().
{
dst_var->lineno = src_var->lineno;
dst_var->object = src_var->object;
dst_var->blanklines = src_var->blanklines;
dst_var->precomments = src_var->precomments;
src_var->precomments = NULL;
dst_var->sameline = src_var->sameline;
src_var->sameline = NULL;
dst_var->trailing = src_var->trailing;
src_var->trailing = NULL;
}
| struct ast_variable* ast_variable_new | ( | const char * | name, |
| const char * | value, | ||
| const char * | filename | ||
| ) | [read] |
Definition at line 277 of file config.c.
References __ast_calloc(), ast_calloc, ast_variable::file, MIN_VARIABLE_FNAME_SPACE, ast_variable::name, ast_variable::stuff, and ast_variable::value.
Referenced by __init_manager(), aco_set_defaults(), add_cfg_entry(), add_message_id(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), append_row_to_cfg(), apply_outgoing(), ast_channeltype_list(), ast_http_get_post_vars(), ast_include_rename(), ast_variable_update(), ast_variables_dup(), build_calendar(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), dup_vars(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), man_do_variable_value(), manager_sipnotify(), mkintf(), parkandannounce_exec(), parse_cookies(), process_dahdi(), process_text_line(), realtime_curl(), realtime_directory(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_multi_curl(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_odbc(), realtime_pgsql(), row_to_varlist(), sip_cli_notify(), static_realtime_cb(), variable_clone(), vm_change_password(), and write_password_to_file().
{
struct ast_variable *variable;
int name_len = strlen(name) + 1;
int val_len = strlen(value) + 1;
int fn_len = strlen(filename) + 1;
/* Ensure a minimum length in case the filename is changed later. */
if (fn_len < MIN_VARIABLE_FNAME_SPACE) {
fn_len = MIN_VARIABLE_FNAME_SPACE;
}
if (
#ifdef MALLOC_DEBUG
(variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable), file, lineno, func))
#else
(variable = ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable)))
#endif
) {
char *dst = variable->stuff; /* writable space starts here */
/* Put file first so ast_include_rename() can calculate space available. */
variable->file = strcpy(dst, filename);
dst += fn_len;
variable->name = strcpy(dst, name);
dst += name_len;
variable->value = strcpy(dst, value);
}
return variable;
}
| const char* ast_variable_retrieve | ( | const struct ast_config * | config, |
| const char * | category, | ||
| const char * | variable | ||
| ) |
Gets a variable.
| config | which (opened) config to use |
| category | category under which the variable lies |
| variable | which variable you wish to get the data for |
Goes through a given config file in the given category and searches for the given variable
| The | variable value on success |
| NULL | if unable to find it. |
Definition at line 600 of file config.c.
References ast_variable_browse(), ast_variable::name, ast_variable::next, ast_category::next, ast_category::root, ast_config::root, and ast_variable::value.
Referenced by __init_manager(), actual_load_config(), advanced_options(), aji_load_config(), ast_config_option(), build_extension(), conf_exec(), config_function_read(), config_module(), directory_exec(), do_reload(), festival_exec(), find_realtime(), forward_message(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), gtalk_load_config(), iax_template_parse(), init_acf_query(), init_logger_chain(), initialize_cc_devstate_map_helper(), initialize_cc_max_requests(), internal_aco_type_find(), jingle_load_config(), load_config(), load_config_meetme(), load_format_config(), load_indications(), load_module(), load_modules(), load_tech_calendars(), make_email_file(), message_range_and_existence_check(), named_acl_find_realtime(), notify_new_message(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queue_set_global_params(), read_agent_config(), read_password_from_file(), realtime_directory(), reload_config(), reload_followme(), reload_single_queue(), rt_handle_member_record(), rtp_reload(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), and vm_msg_snapshot_create().
{
struct ast_variable *v;
if (category) {
for (v = ast_variable_browse(config, category); v; v = v->next) {
if (!strcasecmp(variable, v->name)) {
return v->value;
}
}
} else {
struct ast_category *cat;
for (cat = config->root; cat; cat = cat->next) {
for (v = cat->root; v; v = v->next) {
if (!strcasecmp(variable, v->name)) {
return v->value;
}
}
}
}
return NULL;
}
| int ast_variable_update | ( | struct ast_category * | category, |
| const char * | variable, | ||
| const char * | value, | ||
| const char * | match, | ||
| unsigned int | object | ||
| ) |
Update variable value within a config.
| category | Category element within the config |
| variable | Name of the variable to change |
| value | New value of the variable |
| match | If set, previous value of the variable (if NULL or zero-length, no matching will be done) |
| object | Boolean of whether to make the new variable an object |
Definition at line 1031 of file config.c.
References ast_strlen_zero(), ast_variable_destroy(), ast_variable_move(), ast_variable_new(), ast_variable::file, ast_category::last, ast_variable::name, ast_variable::next, ast_variable::object, ast_category::root, and ast_variable::value.
Referenced by handle_updates(), process_text_line(), vm_change_password(), and vm_forwardoptions().
{
struct ast_variable *cur, *prev=NULL, *newer=NULL;
for (cur = category->root; cur; prev = cur, cur = cur->next) {
if (strcasecmp(cur->name, variable) ||
(!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
continue;
if (!(newer = ast_variable_new(variable, value, cur->file)))
return -1;
ast_variable_move(newer, cur);
newer->object = newer->object || object;
/* Replace the old node in the list with the new node. */
newer->next = cur->next;
if (prev)
prev->next = newer;
else
category->root = newer;
if (category->last == cur)
category->last = newer;
ast_variable_destroy(cur);
return 0;
}
/* Could not find variable to update */
return -1;
}
| void ast_variables_destroy | ( | struct ast_variable * | var | ) |
Free variable list.
| var | the linked list of variables to free |
This function frees a list of variables.
Definition at line 561 of file config.c.
References ast_variable_destroy(), and ast_variable::next.
Referenced by __init_manager(), __sip_destroy(), aco_set_defaults(), action_messagesend(), action_originate(), add_message_id(), ast_category_destroy(), ast_category_empty(), ast_http_get_cookies(), ast_http_manid_from_vars(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variables_dup(), auth_http_callback(), build_gateway(), build_peer(), build_user(), calendar_destructor(), check_peer_ok(), cli_realtime_load(), conf_run(), copy_plain_file(), destroy_dahdi_pvt(), destroy_endpoint(), destroy_fast_originate_helper(), dup_vars(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_realtime_gw(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), generic_http_callback(), get_insecure_variable_from_sipregs(), handle_uri(), http_post_callback(), httpd_helper_thread(), httpstatus_callback(), ldap_loadentry(), leave_queue(), local_ast_moh_start(), manager_free_user(), manager_sipnotify(), mkintf(), parkandannounce_exec(), process_dahdi(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_common(), realtime_exec(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_user(), realtimefield_read(), row_to_varlist(), rt_extend_conf(), session_destructor(), sip_destroy_peer(), socket_process_helper(), table_configs_free(), and user_destructor().
{
struct ast_variable *vn;
while (v) {
vn = v;
v = v->next;
ast_variable_destroy(vn);
}
}
| struct ast_variable* ast_variables_dup | ( | struct ast_variable * | var | ) | [read] |
Duplicate variable list.
| var | the linked list of variables to clone |
Definition at line 539 of file config.c.
References ast_variable_new(), ast_variables_destroy(), ast_variable::file, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by action_originate(), ast_config_copy(), authenticate(), get_insecure_variable_from_sippeers(), and get_insecure_variable_from_sipregs().
{
struct ast_variable *cloned;
struct ast_variable *tmp;
if (!(cloned = ast_variable_new(var->name, var->value, var->file))) {
return NULL;
}
tmp = cloned;
while ((var = var->next)) {
if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) {
ast_variables_destroy(cloned);
return NULL;
}
tmp = tmp->next;
}
return cloned;
}
| static struct ast_category* category_get | ( | const struct ast_config * | config, |
| const char * | category_name, | ||
| int | ignored | ||
| ) | [static, read] |
Definition at line 666 of file config.c.
References ast_category::ignored, ast_category::name, ast_category::next, and ast_config::root.
Referenced by ast_category_get(), and process_text_line().
{
struct ast_category *cat;
/* try exact match first, then case-insensitive match */
for (cat = config->root; cat; cat = cat->next) {
if (cat->name == category_name && (ignored || !cat->ignored))
return cat;
}
for (cat = config->root; cat; cat = cat->next) {
if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
return cat;
}
return NULL;
}
Definition at line 119 of file config.c.
References ast_str_append().
Referenced by config_text_file_load().
{
ast_str_append(cb, 0, "%s", str);
}
| static void CB_ADD_LEN | ( | struct ast_str ** | cb, |
| const char * | str, | ||
| int | len | ||
| ) | [static] |
Definition at line 124 of file config.c.
References ast_alloca, ast_copy_string(), and ast_str_append().
Referenced by config_text_file_load().
{
char *s = ast_alloca(len + 1);
ast_copy_string(s, str, len);
ast_str_append(cb, 0, "%s", str);
}
Definition at line 131 of file config.c.
References ast_str_reset().
Referenced by config_text_file_load(), and process_text_line().
{
if (cb) {
ast_str_reset(cb);
}
if (llb) {
ast_str_reset(llb);
}
}
| static void cfmstat_clear | ( | struct cache_file_mtime * | cfmtime | ) | [static] |
Definition at line 1196 of file config.c.
References cache_file_mtime::stat_mtime, cache_file_mtime::stat_mtime_nsec, and cache_file_mtime::stat_size.
Referenced by config_cache_attribute().
{
cfmtime->stat_size = 0;
cfmtime->stat_mtime_nsec = 0;
cfmtime->stat_mtime = 0;
}
| static int cfmstat_cmp | ( | struct cache_file_mtime * | cfmtime, |
| struct stat * | statbuf | ||
| ) | [static] |
Definition at line 1236 of file config.c.
References cfmstat_save(), cache_file_mtime::stat_mtime, cache_file_mtime::stat_mtime_nsec, and cache_file_mtime::stat_size.
Referenced by config_text_file_load().
{
struct cache_file_mtime cfm_buf;
cfmstat_save(&cfm_buf, statbuf);
return cfmtime->stat_size != cfm_buf.stat_size
|| cfmtime->stat_mtime != cfm_buf.stat_mtime
|| cfmtime->stat_mtime_nsec != cfm_buf.stat_mtime_nsec;
}
| static void cfmstat_save | ( | struct cache_file_mtime * | cfmtime, |
| struct stat * | statbuf | ||
| ) | [static] |
Definition at line 1212 of file config.c.
References cache_file_mtime::stat_mtime, cache_file_mtime::stat_mtime_nsec, and cache_file_mtime::stat_size.
Referenced by cfmstat_cmp(), config_cache_attribute(), and config_text_file_load().
{
cfmtime->stat_size = statbuf->st_size;
#if defined(HAVE_STRUCT_STAT_ST_MTIM)
cfmtime->stat_mtime_nsec = statbuf->st_mtim.tv_nsec;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
cfmtime->stat_mtime_nsec = statbuf->st_mtimensec;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
cfmtime->stat_mtime_nsec = statbuf->st_mtimespec.tv_nsec;
#else
cfmtime->stat_mtime_nsec = 0;
#endif
cfmtime->stat_mtime = statbuf->st_mtime;
}
| static struct cache_file_mtime* cfmtime_new | ( | const char * | filename, |
| const char * | who_asked | ||
| ) | [static, read] |
Definition at line 1165 of file config.c.
References ast_calloc, cache_file_mtime::filename, and cache_file_mtime::who_asked.
Referenced by config_cache_attribute(), and config_text_file_load().
{
struct cache_file_mtime *cfmtime;
char *dst;
cfmtime = ast_calloc(1,
sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
if (!cfmtime) {
return NULL;
}
dst = cfmtime->filename; /* writable space starts here */
strcpy(dst, filename);
dst += strlen(dst) + 1;
cfmtime->who_asked = strcpy(dst, who_asked);
return cfmtime;
}
| static void clear_config_maps | ( | void | ) | [static] |
Definition at line 2296 of file config.c.
References ast_free, ast_mutex_lock, ast_mutex_unlock, config_lock, config_maps, map, and ast_config_map::next.
Referenced by read_config_maps().
{
struct ast_config_map *map;
ast_mutex_lock(&config_lock);
while (config_maps) {
map = config_maps;
config_maps = config_maps->next;
ast_free(map);
}
ast_mutex_unlock(&config_lock);
}
| static void config_cache_attribute | ( | const char * | configfile, |
| enum config_cache_attribute_enum | attrtype, | ||
| const char * | filename, | ||
| const char * | who_asked | ||
| ) | [static] |
Definition at line 1247 of file config.c.
References ast_calloc, AST_LIST_INSERT_SORTALPHA, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, cfmstat_clear(), cfmstat_save(), cfmtime_new(), cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, and cache_file_mtime::who_asked.
Referenced by process_text_line().
{
struct cache_file_mtime *cfmtime;
struct cache_file_include *cfinclude;
struct stat statbuf = { 0, };
/* Find our cached entry for this configuration file */
AST_LIST_LOCK(&cfmtime_head);
AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
break;
}
if (!cfmtime) {
cfmtime = cfmtime_new(configfile, who_asked);
if (!cfmtime) {
AST_LIST_UNLOCK(&cfmtime_head);
return;
}
/* Note that the file mtime is initialized to 0, i.e. 1970 */
AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
}
if (stat(configfile, &statbuf)) {
cfmstat_clear(cfmtime);
} else {
cfmstat_save(cfmtime, &statbuf);
}
switch (attrtype) {
case ATTRIBUTE_INCLUDE:
AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
if (!strcmp(cfinclude->include, filename)) {
AST_LIST_UNLOCK(&cfmtime_head);
return;
}
}
cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
if (!cfinclude) {
AST_LIST_UNLOCK(&cfmtime_head);
return;
}
strcpy(cfinclude->include, filename);
AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
break;
case ATTRIBUTE_EXEC:
cfmtime->has_exec = 1;
break;
}
AST_LIST_UNLOCK(&cfmtime_head);
}
| static void config_hook_exec | ( | const char * | filename, |
| const char * | module, | ||
| struct ast_config * | cfg | ||
| ) | [static] |
Definition at line 3309 of file config.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_config_copy(), copy(), cfg_hook::filename, cfg_hook::hook_cb, and cfg_hook::module.
Referenced by ast_config_internal_load().
{
struct ao2_iterator it;
struct cfg_hook *hook;
if (!(cfg_hooks)) {
return;
}
it = ao2_iterator_init(cfg_hooks, 0);
while ((hook = ao2_iterator_next(&it))) {
if (!strcasecmp(hook->filename, filename) &&
!strcasecmp(hook->module, module)) {
struct ast_config *copy = ast_config_copy(cfg);
hook->hook_cb(copy);
}
ao2_ref(hook, -1);
}
ao2_iterator_destroy(&it);
}
| static void config_shutdown | ( | void | ) | [static] |
Definition at line 3246 of file config.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and cache_file_mtime::includes.
Referenced by register_config_cli().
{
struct cache_file_mtime *cfmtime;
AST_LIST_LOCK(&cfmtime_head);
while ((cfmtime = AST_LIST_REMOVE_HEAD(&cfmtime_head, list))) {
struct cache_file_include *cfinclude;
while ((cfinclude = AST_LIST_REMOVE_HEAD(&cfmtime->includes, list))) {
ast_free(cfinclude);
}
ast_free(cfmtime);
}
AST_LIST_UNLOCK(&cfmtime_head);
ast_cli_unregister_multiple(cli_config, ARRAY_LEN(cli_config));
}
| 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 | ||
| ) | [static, read] |
Growable string buffer
< this will be a comment collector.
< A buffer for stuff behind the ;
Definition at line 1572 of file config.c.
References ALLOC_COMMENT(), ast_clear_flag, ast_config_AST_CONFIG_DIR, ast_config_get_current_category(), ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_SORTALPHA, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, cfmstat_cmp(), cfmstat_save(), cfmtime_new(), comment, COMMENT_META, COMMENT_TAG, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, GLOB_ABORTED, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, process_text_line(), ast_variable::trailing, ast_category::trailing, and cache_file_mtime::who_asked.
{
char fn[256];
#if defined(LOW_MEMORY)
char buf[512];
#else
char buf[8192];
#endif
char *new_buf, *comment_p, *process_buf;
FILE *f;
int lineno=0;
int comment = 0, nest[MAX_NESTED_COMMENTS];
struct ast_category *cat = NULL;
int count = 0;
struct stat statbuf;
struct cache_file_mtime *cfmtime = NULL;
struct cache_file_include *cfinclude;
struct ast_variable *last_var = 0;
struct ast_category *last_cat = 0;
/*! Growable string buffer */
struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/
struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */
if (cfg)
cat = ast_config_get_current_category(cfg);
if (filename[0] == '/') {
ast_copy_string(fn, filename, sizeof(fn));
} else {
snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
}
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
comment_buffer = ast_str_create(CB_SIZE);
if (comment_buffer)
lline_buffer = ast_str_create(CB_SIZE);
if (!lline_buffer) {
ast_free(comment_buffer);
ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
return NULL;
}
}
#ifdef AST_INCLUDE_GLOB
{
int glob_ret;
glob_t globbuf;
globbuf.gl_offs = 0; /* initialize it to silence gcc */
glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf);
if (glob_ret == GLOB_NOSPACE)
ast_log(LOG_WARNING,
"Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
else if (glob_ret == GLOB_ABORTED)
ast_log(LOG_WARNING,
"Glob Expansion of pattern '%s' failed: Read error\n", fn);
else {
/* loop over expanded files */
int i;
for (i=0; i<globbuf.gl_pathc; i++) {
ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
#endif
/*
* The following is not a loop, but just a convenient way to define a block
* (using do { } while(0) ), and be able to exit from it with 'continue'
* or 'break' in case of errors. Nice trick.
*/
do {
if (stat(fn, &statbuf))
continue;
if (!S_ISREG(statbuf.st_mode)) {
ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
continue;
}
if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
/* 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) && !strcmp(cfmtime->who_asked, who_asked))
break;
}
if (!cfmtime) {
cfmtime = cfmtime_new(fn, who_asked);
if (!cfmtime) {
AST_LIST_UNLOCK(&cfmtime_head);
continue;
}
/* Note that the file mtime is initialized to 0, i.e. 1970 */
AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
}
}
if (cfmtime
&& !cfmtime->has_exec
&& !cfmstat_cmp(cfmtime, &statbuf)
&& ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) {
/* File is unchanged, what about the (cached) includes (if any)? */
int unchanged = 1;
AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
/* We must glob here, because if we did not, then adding a file to globbed directory would
* incorrectly cause no reload to be necessary. */
char fn2[256];
#ifdef AST_INCLUDE_GLOB
int glob_return;
glob_t glob_buf = { .gl_offs = 0 };
glob_return = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &glob_buf);
/* On error, we reparse */
if (glob_return == GLOB_NOSPACE || glob_return == GLOB_ABORTED)
unchanged = 0;
else {
/* loop over expanded files */
int j;
for (j = 0; j < glob_buf.gl_pathc; j++) {
ast_copy_string(fn2, glob_buf.gl_pathv[j], sizeof(fn2));
#else
ast_copy_string(fn2, cfinclude->include);
#endif
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;
}
#ifdef AST_INCLUDE_GLOB
}
}
#endif
}
if (unchanged) {
AST_LIST_UNLOCK(&cfmtime_head);
ast_free(comment_buffer);
ast_free(lline_buffer);
#ifdef AST_INCLUDE_GLOB
globfree(&globbuf);
#endif
return CONFIG_STATUS_FILEUNCHANGED;
}
}
if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
AST_LIST_UNLOCK(&cfmtime_head);
/* If cfg is NULL, then we just want an answer */
if (cfg == NULL) {
ast_free(comment_buffer);
ast_free(lline_buffer);
#ifdef AST_INCLUDE_GLOB
globfree(&globbuf);
#endif
return NULL;
}
if (cfmtime) {
cfmstat_save(cfmtime, &statbuf);
}
if (!(f = fopen(fn, "r"))) {
ast_debug(1, "No file to parse: %s\n", fn);
ast_verb(2, "Parsing '%s': Not found (%s)\n", fn, strerror(errno));
continue;
}
count++;
/* If we get to this point, then we're loading regardless */
ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED);
ast_debug(1, "Parsing %s\n", fn);
ast_verb(2, "Parsing '%s': Found\n", fn);
while (!feof(f)) {
lineno++;
if (fgets(buf, sizeof(buf), f)) {
/* Skip lines that are too long */
if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 1] != '\n') {
ast_log(LOG_WARNING, "Line %d too long, skipping. It begins with: %.32s...\n", lineno, buf);
while (fgets(buf, sizeof(buf), f)) {
if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 1] == '\n') {
break;
}
}
continue;
}
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && ast_str_strlen(lline_buffer)) {
CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
ast_str_reset(lline_buffer); /* erase the lline buffer */
}
new_buf = buf;
if (comment)
process_buf = NULL;
else
process_buf = buf;
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer) && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) {
/* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */
CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */
continue; /* go get a new line, then */
}
while ((comment_p = strchr(new_buf, COMMENT_META))) {
if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) {
/* Escaped semicolons aren't comments. */
new_buf = comment_p;
/* write over the \ and bring the null terminator with us */
memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
} else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
/* Meta-Comment start detected ";--" */
if (comment < MAX_NESTED_COMMENTS) {
*comment_p = '\0';
new_buf = comment_p + 3;
comment++;
nest[comment-1] = lineno;
} else {
ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
}
} else if ((comment_p >= new_buf + 2) &&
(*(comment_p - 1) == COMMENT_TAG) &&
(*(comment_p - 2) == COMMENT_TAG)) {
/* Meta-Comment end detected */
comment--;
new_buf = comment_p + 1;
if (!comment) {
/* Back to non-comment now */
if (process_buf) {
/* Actually have to move what's left over the top, then continue */
char *oldptr;
oldptr = process_buf + strlen(process_buf);
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
CB_ADD(&comment_buffer, ";");
CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
}
memmove(oldptr, new_buf, strlen(new_buf) + 1);
new_buf = oldptr;
} else
process_buf = new_buf;
}
} else {
if (!comment) {
/* If ; is found, and we are not nested in a comment,
we immediately stop all comment processing */
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
CB_ADD(&lline_buffer, comment_p);
}
*comment_p = '\0';
new_buf = comment_p;
} else
new_buf = comment_p + 1;
}
}
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) {
CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */
}
if (process_buf) {
char *buffer = ast_strip(process_buf);
if (!ast_strlen_zero(buffer)) {
if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) {
cfg = CONFIG_STATUS_FILEINVALID;
break;
}
}
}
}
}
/* end of file-- anything in a comment buffer? */
if (last_cat) {
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
if (lline_buffer && ast_str_strlen(lline_buffer)) {
CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
ast_str_reset(lline_buffer); /* erase the lline buffer */
}
last_cat->trailing = ALLOC_COMMENT(comment_buffer);
}
} else if (last_var) {
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
if (lline_buffer && ast_str_strlen(lline_buffer)) {
CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
ast_str_reset(lline_buffer); /* erase the lline buffer */
}
last_var->trailing = ALLOC_COMMENT(comment_buffer);
}
} else {
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer));
}
}
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
CB_RESET(comment_buffer, lline_buffer);
fclose(f);
} while (0);
if (comment) {
ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
}
#ifdef AST_INCLUDE_GLOB
if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
break;
}
}
globfree(&globbuf);
}
}
#endif
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
ast_free(comment_buffer);
ast_free(lline_buffer);
comment_buffer = NULL;
lline_buffer = NULL;
}
if (count == 0)
return NULL;
return cfg;
}
| int config_text_file_save | ( | const char * | configfile, |
| const struct ast_config * | cfg, | ||
| const char * | generator | ||
| ) |
Definition at line 2035 of file config.c.
References ast_config_text_file_save().
{
return ast_config_text_file_save(configfile, cfg, generator);
}
| static int count_linefeeds | ( | char * | str | ) | [static] |
| static int count_linefeeds_in_comments | ( | struct ast_comment * | x | ) | [static] |
Definition at line 1988 of file config.c.
References ast_comment::cmt, count_linefeeds(), and ast_comment::next.
Referenced by insert_leading_blank_lines().
{
int count = 0;
while (x) {
count += count_linefeeds(x->cmt);
x = x->next;
}
return count;
}
| static struct ast_config_engine* find_engine | ( | const char * | family, |
| int | priority, | ||
| char * | database, | ||
| int | dbsiz, | ||
| char * | table, | ||
| int | tabsiz | ||
| ) | [static, read] |
Find realtime engine for realtime family.
Definition at line 2485 of file config.c.
References ast_copy_string(), ast_log(), ast_mutex_lock, ast_mutex_unlock, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, LOG_WARNING, map, ast_config_map::name, ast_config_engine::next, ast_config_map::next, ast_config_map::priority, and ast_config_map::table.
Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_realtime_require_field(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), and ast_update_realtime().
{
struct ast_config_engine *eng, *ret = NULL;
struct ast_config_map *map;
ast_mutex_lock(&config_lock);
for (map = config_maps; map; map = map->next) {
if (!strcasecmp(family, map->name) && (priority == map->priority)) {
if (database)
ast_copy_string(database, map->database, dbsiz);
if (table)
ast_copy_string(table, map->table ? map->table : family, tabsiz);
break;
}
}
/* Check if the required driver (engine) exist */
if (map) {
for (eng = config_engine_list; !ret && eng; eng = eng->next) {
if (!strcasecmp(eng->name, map->driver))
ret = eng;
}
}
ast_mutex_unlock(&config_lock);
/* if we found a mapping, but the engine is not available, then issue a warning */
if (map && !ret)
ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
return ret;
}
| static void gen_header | ( | FILE * | f1, |
| const char * | configfile, | ||
| const char * | fn, | ||
| const char * | generator | ||
| ) | [static] |
Definition at line 1909 of file config.c.
References ast_copy_string().
Referenced by ast_config_text_file_save().
{
char date[256]="";
time_t t;
time(&t);
ast_copy_string(date, ctime(&t), sizeof(date));
fprintf(f1, ";!\n");
fprintf(f1, ";! Automatically generated configuration file\n");
if (strcmp(configfile, fn))
fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
else
fprintf(f1, ";! Filename: %s\n", configfile);
fprintf(f1, ";! Generator: %s\n", generator);
fprintf(f1, ";! Creation Date: %s", date);
fprintf(f1, ";!\n");
}
| static char* handle_cli_config_list | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 3216 of file config.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.
{
struct cache_file_mtime *cfmtime;
switch (cmd) {
case CLI_INIT:
e->command = "config list";
e->usage =
"Usage: config list\n"
" Show all modules that have loaded a configuration file\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
AST_LIST_LOCK(&cfmtime_head);
AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
}
AST_LIST_UNLOCK(&cfmtime_head);
return CLI_SUCCESS;
}
| static char* handle_cli_config_reload | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 3154 of file config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_alloca, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.
{
struct cache_file_mtime *cfmtime;
char *prev = "", *completion_value = NULL;
int wordlen, which = 0;
switch (cmd) {
case CLI_INIT:
e->command = "config reload";
e->usage =
"Usage: config reload <filename.conf>\n"
" Reloads all modules that reference <filename.conf>\n";
return NULL;
case CLI_GENERATE:
if (a->pos > 2) {
return NULL;
}
wordlen = strlen(a->word);
AST_LIST_LOCK(&cfmtime_head);
AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
/* Skip duplicates - this only works because the list is sorted by filename */
if (strcmp(cfmtime->filename, prev) == 0) {
continue;
}
/* Core configs cannot be reloaded */
if (ast_strlen_zero(cfmtime->who_asked)) {
continue;
}
if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) {
completion_value = ast_strdup(cfmtime->filename);
break;
}
/* Otherwise save that we've seen this filename */
prev = cfmtime->filename;
}
AST_LIST_UNLOCK(&cfmtime_head);
return completion_value;
}
if (a->argc != 3) {
return CLI_SHOWUSAGE;
}
AST_LIST_LOCK(&cfmtime_head);
AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
if (!strcmp(cfmtime->filename, a->argv[2])) {
char *buf = ast_alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
sprintf(buf, "module reload %s", cfmtime->who_asked);
ast_cli_command(a->fd, buf);
}
}
AST_LIST_UNLOCK(&cfmtime_head);
return CLI_SUCCESS;
}
| static char* handle_cli_core_show_config_mappings | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 3117 of file config.c.
References ast_cli(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, ast_cli_args::fd, map, ast_config_engine::name, ast_config_map::name, ast_config_engine::next, ast_config_map::next, ast_config_map::table, and ast_cli_entry::usage.
{
struct ast_config_engine *eng;
struct ast_config_map *map;
switch (cmd) {
case CLI_INIT:
e->command = "core show config mappings";
e->usage =
"Usage: core show config mappings\n"
" Shows the filenames to config engines.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_mutex_lock(&config_lock);
if (!config_engine_list) {
ast_cli(a->fd, "No config mappings found.\n");
} else {
for (eng = config_engine_list; eng; eng = eng->next) {
ast_cli(a->fd, "Config Engine: %s\n", eng->name);
for (map = config_maps; map; map = map->next) {
if (!strcasecmp(map->driver, eng->name)) {
ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
map->table ? map->table : map->name);
}
}
}
}
ast_mutex_unlock(&config_lock);
return CLI_SUCCESS;
}
| static int hash_string | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 161 of file config.c.
Referenced by ast_config_text_file_save().
{
char *str = ((struct inclfile *) obj)->fname;
int total;
for (total = 0; *str; str++) {
unsigned int tmp = total;
total <<= 1; /* multiply by 2 */
total += tmp; /* multiply by 3 */
total <<= 2; /* multiply by 12 */
total += tmp; /* multiply by 13 */
total += ((unsigned int) (*str));
}
if (total < 0) {
total = -total;
}
return total;
}
| static int hashtab_compare_strings | ( | void * | a, |
| void * | b, | ||
| int | flags | ||
| ) | [static] |
Definition at line 181 of file config.c.
References CMP_MATCH, CMP_STOP, and inclfile::fname.
Referenced by ast_config_text_file_save().
| static int hook_cmp | ( | void * | obj, |
| void * | arg, | ||
| int | flags | ||
| ) | [static] |
| static void hook_destroy | ( | void * | obj | ) | [static] |
Definition at line 3277 of file config.c.
References ast_free, cfg_hook::filename, cfg_hook::module, and cfg_hook::name.
Referenced by ast_config_hook_register().
| static int hook_hash | ( | const void * | obj, |
| const int | flags | ||
| ) | [static] |
Definition at line 3293 of file config.c.
References ast_str_hash(), and cfg_hook::name.
Referenced by ast_config_hook_register().
{
const struct cfg_hook *hook = obj;
return ast_str_hash(hook->name);
}
| static void inclfile_destroy | ( | void * | obj | ) | [static] |
| static void inherit_category | ( | struct ast_category * | new, |
| const struct ast_category * | base | ||
| ) | [static] |
Definition at line 961 of file config.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_variable_append(), ast_category_template_instance::inst, ast_category_template_instance::name, ast_category::name, ast_variable::next, ast_category::root, var, and variable_clone().
Referenced by process_text_line().
{
struct ast_variable *var;
struct ast_category_template_instance *x;
x = ast_calloc(1, sizeof(*x));
if (!x) {
return;
}
strcpy(x->name, base->name);
x->inst = base;
AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
for (var = base->root; var; var = var->next)
ast_variable_append(new, variable_clone(var));
}
| static int init_appendbuf | ( | void * | data | ) | [static] |
Definition at line 107 of file config.c.
References ast_str_create(), and str.
{
struct ast_str **str = data;
*str = ast_str_create(16);
return *str ? 0 : -1;
}
| static void insert_leading_blank_lines | ( | FILE * | fp, |
| struct inclfile * | fi, | ||
| struct ast_comment * | precomments, | ||
| int | lineno | ||
| ) | [static] |
Definition at line 1999 of file config.c.
References count_linefeeds_in_comments(), and inclfile::lineno.
Referenced by ast_config_text_file_save().
{
int precomment_lines;
int i;
if (!fi) {
/* No file scratch pad object so insert no blank lines. */
return;
}
precomment_lines = count_linefeeds_in_comments(precomments);
/* I don't have to worry about those ;! comments, they are
stored in the precomments, but not printed back out.
I did have to make sure that comments following
the ;! header comments were not also deleted in the process */
if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */
return;
} else if (lineno == 0) {
/* Line replacements also mess things up */
return;
} else if (lineno - precomment_lines - fi->lineno < 5) {
/* Only insert less than 5 blank lines; if anything more occurs,
* it's probably due to context deletion. */
for (i = fi->lineno; i < lineno - precomment_lines; i++) {
fprintf(fp, "\n");
}
} else {
/* Deletion occurred - insert a single blank line, for separation of
* contexts. */
fprintf(fp, "\n");
}
fi->lineno = lineno + 1; /* Advance the file lineno */
}
| static void move_variables | ( | struct ast_category * | old, |
| struct ast_category * | new | ||
| ) | [static] |
Definition at line 639 of file config.c.
References ast_variable_append(), ast_category::root, and var.
Referenced by process_text_line().
{
struct ast_variable *var = old->root;
old->root = NULL;
/* we can just move the entire list in a single op */
ast_variable_append(new, var);
}
| static struct ast_category* next_available_category | ( | struct ast_category * | cat | ) | [static, read] |
Definition at line 759 of file config.c.
References ast_category::ignored, and ast_category::next.
Referenced by ast_category_browse().
| static int process_text_line | ( | struct ast_config * | cfg, |
| struct ast_category ** | cat, | ||
| char * | buf, | ||
| int | lineno, | ||
| const char * | configfile, | ||
| struct ast_flags | flags, | ||
| 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, | ||
| const char * | who_asked | ||
| ) | [static] |
parse one line in the configuration.
* We can have a category header [foo](...) * a directive #include / #exec * or a regular line name = value *
Definition at line 1305 of file config.c.
References ALLOC_COMMENT(), appendbuf, ast_category_append(), ast_category_destroy(), ast_category_first(), ast_category_new(), ast_config_internal_load(), ast_include_new(), ast_log(), ast_opt_exec_includes, ast_safe_system(), ast_skip_blanks(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_trim_blanks(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_tvnow(), ast_variable_append(), ast_variable_new(), ast_variable_update(), ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, ast_variable::blanklines, category_get(), CB_RESET(), config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, ast_config::include_level, inherit_category(), ast_variable::lineno, ast_category::lineno, LOG_ERROR, LOG_WARNING, move_variables(), ast_variable::name, ast_variable::next, ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, ast_variable::value, and var.
Referenced by config_text_file_load().
{
char *c;
char *cur = buf;
struct ast_variable *v;
char cmd[512], exec_file[512];
/* Actually parse the entry */
if (cur[0] == '[') { /* A category header */
/* format is one of the following:
* [foo] define a new category named 'foo'
* [foo](!) define a new template category named 'foo'
* [foo](+) append to category 'foo', error if foo does not exist.
* [foo](a) define a new category and inherit from category or template a.
* You can put a comma-separated list of categories and templates
* and '!' and '+' between parentheses, with obvious meaning.
*/
struct ast_category *newcat = NULL;
char *catname;
c = strchr(cur, ']');
if (!c) {
ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
return -1;
}
*c++ = '\0';
cur++;
if (*c++ != '(')
c = NULL;
catname = cur;
if (!(*cat = newcat = ast_category_new(catname,
S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile),
lineno))) {
return -1;
}
(*cat)->lineno = lineno;
*last_var = 0;
*last_cat = newcat;
/* add comments */
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
newcat->precomments = ALLOC_COMMENT(comment_buffer);
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
newcat->sameline = ALLOC_COMMENT(lline_buffer);
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
CB_RESET(comment_buffer, lline_buffer);
/* If there are options or categories to inherit from, process them now */
if (c) {
if (!(cur = strchr(c, ')'))) {
ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
return -1;
}
*cur = '\0';
while ((cur = strsep(&c, ","))) {
if (!strcasecmp(cur, "!")) {
(*cat)->ignored = 1;
} else if (!strcasecmp(cur, "+")) {
*cat = category_get(cfg, catname, 1);
if (!(*cat)) {
if (newcat)
ast_category_destroy(newcat);
ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
return -1;
}
if (newcat) {
move_variables(newcat, *cat);
ast_category_destroy(newcat);
newcat = NULL;
}
} else {
struct ast_category *base;
base = category_get(cfg, cur, 1);
if (!base) {
ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
return -1;
}
inherit_category(*cat, base);
}
}
}
if (newcat)
ast_category_append(cfg, *cat);
} else if (cur[0] == '#') { /* A directive - #include or #exec */
char *cur2;
char real_inclusion_name[256];
int do_include = 0; /* otherwise, it is exec */
int try_include = 0;
cur++;
c = cur;
while (*c && (*c > 32)) {
c++;
}
if (*c) {
*c = '\0';
/* Find real argument */
c = ast_strip(c + 1);
if (!(*c)) {
c = NULL;
}
} else {
c = NULL;
}
if (!strcasecmp(cur, "include")) {
do_include = 1;
} else if (!strcasecmp(cur, "tryinclude")) {
do_include = 1;
try_include = 1;
} else if (!strcasecmp(cur, "exec")) {
if (!ast_opt_exec_includes) {
ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
return 0; /* XXX is this correct ? or we should return -1 ? */
}
} else {
ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
return 0; /* XXX is this correct ? or we should return -1 ? */
}
if (c == NULL) {
ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
do_include ? "include / tryinclude" : "exec",
do_include ? "filename" : "/path/to/executable",
lineno,
configfile);
return 0; /* XXX is this correct ? or we should return -1 ? */
}
cur = c;
/* Strip off leading and trailing "'s and <>'s */
/* Dequote */
if ((*c == '"') || (*c == '<')) {
char quote_char = *c;
if (quote_char == '<') {
quote_char = '>';
}
if (*(c + strlen(c) - 1) == quote_char) {
cur++;
*(c + strlen(c) - 1) = '\0';
}
}
cur2 = cur;
/* #exec </path/to/executable>
We create a tmp file, then we #include it, then we delete it. */
if (!do_include) {
struct timeval now = ast_tvnow();
if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked);
snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (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, who_asked);
exec_file[0] = '\0';
}
/* A #include */
/* record this inclusion */
ast_include_new(cfg, cfg->include_level == 1 ? "" : 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, who_asked) ? 1 : 0;
if (!ast_strlen_zero(exec_file))
unlink(exec_file);
if (!do_include && !try_include) {
ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur);
return -1;
}
/* XXX otherwise what ? the default return is 0 anyways */
} else {
/* Just a line (variable = value) */
int object = 0;
int is_escaped;
if (!(*cat)) {
ast_log(LOG_WARNING,
"parse error: No category context for line %d of %s\n", lineno, configfile);
return -1;
}
is_escaped = cur[0] == '\\';
if (is_escaped) {
/* First character is escaped. */
++cur;
if (cur[0] < 33) {
ast_log(LOG_ERROR, "Invalid escape in line %d of %s\n", lineno, configfile);
return -1;
}
}
c = strchr(cur + is_escaped, '=');
if (c && c > cur + is_escaped && (*(c - 1) == '+')) {
struct ast_variable *var, *replace = NULL;
struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str));
if (!str || !*str) {
return -1;
}
*(c - 1) = '\0';
c++;
cur = ast_strip(cur);
/* Must iterate through category until we find last variable of same name (since there could be multiple) */
for (var = ast_category_first(*cat); var; var = var->next) {
if (!strcmp(var->name, cur)) {
replace = var;
}
}
if (!replace) {
/* Nothing to replace; just set a variable normally. */
goto set_new_variable;
}
ast_str_set(str, 0, "%s", replace->value);
ast_str_append(str, 0, "%s", c);
ast_str_trim_blanks(*str);
ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object);
} else if (c) {
*c = 0;
c++;
/* Ignore > in => */
if (*c== '>') {
object = 1;
c++;
}
cur = ast_strip(cur);
set_new_variable:
if (ast_strlen_zero(cur)) {
ast_log(LOG_WARNING, "No variable name in line %d of %s\n", lineno, configfile);
} else if ((v = ast_variable_new(cur, ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) {
v->lineno = lineno;
v->object = object;
*last_cat = 0;
*last_var = v;
/* Put and reset comments */
v->blanklines = 0;
ast_variable_append(*cat, v);
/* add comments */
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
v->precomments = ALLOC_COMMENT(comment_buffer);
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
v->sameline = ALLOC_COMMENT(lline_buffer);
if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
CB_RESET(comment_buffer, lline_buffer);
} else {
return -1;
}
} else {
ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
}
}
return 0;
}
| int read_config_maps | ( | void | ) |
Exposed re-initialization method for core process.
This method is intended for use only with the core re-initialization and is not designed to be called from any user applications.
Definition at line 2346 of file config.c.
References append_mapping(), ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log(), ast_variable_browse(), clear_config_maps(), config, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, table, and ast_variable::value.
Referenced by main().
{
struct ast_config *config, *configtmp;
struct ast_variable *v;
char *driver, *table, *database, *textpri, *stringp, *tmp;
struct ast_flags flags = { CONFIG_FLAG_NOREALTIME };
int pri;
clear_config_maps();
configtmp = ast_config_new();
if (!configtmp) {
ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
return -1;
}
config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
if (config == CONFIG_STATUS_FILEINVALID) {
return -1;
} else if (!config) {
ast_config_destroy(configtmp);
return 0;
}
for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
char buf[512];
ast_copy_string(buf, v->value, sizeof(buf));
stringp = buf;
driver = strsep(&stringp, ",");
if ((tmp = strchr(stringp, '\"')))
stringp = tmp;
/* check if the database text starts with a double quote */
if (*stringp == '"') {
stringp++;
database = strsep(&stringp, "\"");
strsep(&stringp, ",");
} else {
/* apparently this text has no quotes */
database = strsep(&stringp, ",");
}
table = strsep(&stringp, ",");
textpri = strsep(&stringp, ",");
if (!textpri || !(pri = atoi(textpri))) {
pri = 1;
}
if (!strcmp(v->name, extconfig_conf)) {
ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
continue;
}
if (!strcmp(v->name, "asterisk.conf")) {
ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
continue;
}
if (!strcmp(v->name, "logger.conf")) {
ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
continue;
}
if (!driver || !database)
continue;
if (!strcasecmp(v->name, "sipfriends")) {
ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
} else if (!strcasecmp(v->name, "iaxfriends")) {
ast_log(LOG_WARNING, "The 'iaxfriends' table is obsolete, update your config to use iaxusers and iaxpeers, though they can point to the same table.\n");
append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
} else
append_mapping(v->name, driver, database, table, pri);
}
ast_config_destroy(config);
return 0;
}
| int register_config_cli | ( | void | ) |
Exposed initialization method for core process.
This method is intended for use only with the core initialization and is not designed to be called from any user applications.
Definition at line 3263 of file config.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), and config_shutdown().
Referenced by main().
{
ast_cli_register_multiple(cli_config, ARRAY_LEN(cli_config));
ast_register_atexit(config_shutdown);
return 0;
}
| static struct inclfile* set_fn | ( | char * | fn, |
| int | fn_size, | ||
| const char * | file, | ||
| const char * | configfile, | ||
| struct ao2_container * | fileset | ||
| ) | [static, read] |
Definition at line 1936 of file config.c.
References ao2_alloc, ao2_find, ao2_link, ao2_ref, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_strdup, ast_strlen_zero(), inclfile::fname, inclfile_destroy(), inclfile::lineno, and OBJ_POINTER.
Referenced by ast_config_text_file_save().
{
struct inclfile lookup;
struct inclfile *fi;
if (ast_strlen_zero(file)) {
if (configfile[0] == '/')
ast_copy_string(fn, configfile, fn_size);
else
snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
} else if (file[0] == '/')
ast_copy_string(fn, file, fn_size);
else
snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
lookup.fname = fn;
fi = ao2_find(fileset, &lookup, OBJ_POINTER);
if (fi) {
/* Found existing include file scratch pad. */
return fi;
}
/* set up a file scratch pad */
fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
if (!fi) {
/* Scratch pad creation failed. */
return NULL;
}
fi->fname = ast_strdup(fn);
if (!fi->fname) {
/* Scratch pad creation failed. */
ao2_ref(fi, -1);
return NULL;
}
fi->lineno = 1;
ao2_link(fileset, fi);
return fi;
}
| static struct ast_variable* variable_clone | ( | const struct ast_variable * | old | ) | [static, read] |
Definition at line 625 of file config.c.
References ast_variable_new(), ast_variable::blanklines, ast_variable::file, ast_variable::lineno, ast_variable::name, ast_variable::object, and ast_variable::value.
Referenced by inherit_category().
{
struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
if (new) {
new->lineno = old->lineno;
new->object = old->object;
new->blanklines = old->blanklines;
/* TODO: clone comments? */
}
return new;
}
struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , } [static] |
Definition at line 114 of file config.c.
Referenced by process_text_line().
struct ao2_container* cfg_hooks [static] |
struct cfmtime_head cfmtime_head [static] |
struct ast_cli_entry cli_config[] [static] |
{
AST_CLI_DEFINE(handle_cli_core_show_config_mappings, "Display config mappings (file names to config engines)"),
AST_CLI_DEFINE(handle_cli_config_reload, "Force a reload on modules using a particular configuration file"),
AST_CLI_DEFINE(handle_cli_config_list, "Show all files that have loaded a configuration file"),
}
struct ast_config_engine* config_engine_list [static] |
ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 202 of file config.c.
Referenced by ast_config_engine_deregister(), ast_config_engine_register(), ast_realtime_is_mapping_defined(), clear_config_maps(), find_engine(), and handle_cli_core_show_config_mappings().
struct ast_config_map * config_maps [static] |
char* extconfig_conf = "extconfig.conf" [static] |
struct ast_config_engine text_file_engine [static] |
{
.name = "text",
.load_func = config_text_file_load,
}
Definition at line 2519 of file config.c.
Referenced by ast_config_internal_load().