#include "asterisk.h"
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include <time.h>
#include <sys/stat.h>
#include <math.h>
#include <glob.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"
Go to the source code of this file.
Data Structures | |
struct | ast_category |
struct | ast_category::template_instance_list |
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 | cache_file_mtime::includes |
struct | cfmtime_head |
struct | inclfile |
Defines | |
#define | AST_INCLUDE_GLOB 1 |
#define | CB_SIZE 250 |
#define | COMMENT_END "--;" |
#define | COMMENT_META ';' |
#define | COMMENT_START ";--" |
#define | COMMENT_TAG '-' |
#define | MAX_INCLUDE_LEVEL 10 |
#define | MAX_NESTED_COMMENTS 128 |
#define | MY_GLOB_FLAGS (GLOB_NOMAGIC|GLOB_BRACE) |
Enumerations | |
enum | config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0, ATTRIBUTE_EXEC = 1 } |
Functions | |
static void | __init_appendbuf (void) |
static struct ast_comment * | ALLOC_COMMENT (const struct ast_str *buffer) |
static int | append_mapping (const char *name, const char *driver, const char *database, const char *table) |
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) |
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. | |
ast_variable * | ast_category_first (struct ast_category *cat) |
given a pointer to a category, return the root variable. This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get()) | |
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. | |
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) |
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. | |
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. | |
ast_category * | ast_config_get_current_category (const struct ast_config *cfg) |
Retrieve the current category name being built. API for backend configuration engines while building a configuration set. | |
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) |
ast_config * | ast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags) |
Load a config file. | |
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. 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. | |
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. | |
static void | ast_destroy_comments (struct ast_category *cat) |
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) |
ast_config_include * | ast_include_find (struct ast_config *conf, const char *included_file) |
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) |
ast_variable * | ast_load_realtime (const char *family,...) |
Retrieve realtime configuration. | |
ast_variable * | ast_load_realtime_all (const char *family,...) |
static struct ast_variable * | ast_load_realtime_helper (const char *family, va_list ap) |
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,...) |
The argument parsing routine. | |
int | ast_realtime_enabled () |
Check if there's any realtime engines loaded. | |
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_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) |
ast_variable * | ast_variable_browse (const struct ast_config *config, const char *category) |
Goes through variables Somewhat similar in intent as the ast_category_browse. List variables of config file category. | |
int | ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line) |
void | ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line) |
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. | |
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 | 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 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, 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 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 This method is intended for use only with the core re-initialization and is not designed to be called from any user applications. | |
int | register_config_cli () |
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. | |
static void | set_fn (char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset, struct inclfile **fi) |
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 ast_cli_entry | cli_config [] |
static struct ast_config_engine * | config_engine_list |
static ast_mutex_t | config_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static struct ast_config_map * | config_maps |
static char * | extconfig_conf = "extconfig.conf" |
static struct ast_config_engine | text_file_engine |
Definition in file config.c.
#define CB_SIZE 250 |
#define COMMENT_META ';' |
#define COMMENT_TAG '-' |
#define MAX_INCLUDE_LEVEL 10 |
#define MAX_NESTED_COMMENTS 128 |
#define MY_GLOB_FLAGS (GLOB_NOMAGIC|GLOB_BRACE) |
Definition at line 865 of file config.c.
00865 { 00866 ATTRIBUTE_INCLUDE = 0, 00867 ATTRIBUTE_EXEC = 1, 00868 };
static struct ast_comment* ALLOC_COMMENT | ( | const struct ast_str * | buffer | ) | [static] |
Definition at line 133 of file config.c.
References ast_calloc, ast_str::str, and ast_str::used.
Referenced by config_text_file_load(), and process_text_line().
00134 { 00135 struct ast_comment *x = NULL; 00136 if (buffer && buffer->used) 00137 x = ast_calloc(1, sizeof(*x) + buffer->used + 1); 00138 if (x) 00139 strcpy(x->cmt, buffer->str); 00140 return x; 00141 }
static int append_mapping | ( | const char * | name, | |
const char * | driver, | |||
const char * | database, | |||
const char * | table | |||
) | [static] |
Definition at line 1834 of file config.c.
References ast_calloc, ast_verb, config_maps, and map.
Referenced by read_config_maps().
01835 { 01836 struct ast_config_map *map; 01837 int length; 01838 01839 length = sizeof(*map); 01840 length += strlen(name) + 1; 01841 length += strlen(driver) + 1; 01842 length += strlen(database) + 1; 01843 if (table) 01844 length += strlen(table) + 1; 01845 01846 if (!(map = ast_calloc(1, length))) 01847 return -1; 01848 01849 map->name = map->stuff; 01850 strcpy(map->name, name); 01851 map->driver = map->name + strlen(map->name) + 1; 01852 strcpy(map->driver, driver); 01853 map->database = map->driver + strlen(map->driver) + 1; 01854 strcpy(map->database, database); 01855 if (table) { 01856 map->table = map->database + strlen(map->database) + 1; 01857 strcpy(map->table, table); 01858 } 01859 map->next = config_maps; 01860 01861 ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name); 01862 01863 config_maps = map; 01864 return 0; 01865 }
void ast_category_append | ( | struct ast_config * | config, | |
struct ast_category * | category | |||
) |
Definition at line 512 of file config.c.
References config, and ast_category::include_level.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00513 { 00514 if (config->last) 00515 config->last->next = category; 00516 else 00517 config->root = category; 00518 category->include_level = config->include_level; 00519 config->last = category; 00520 config->current = category; 00521 }
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 622 of file config.c.
References config, ast_category::name, ast_category::next, and next_available_category().
Referenced by __queues_show(), action_getconfig(), action_getconfigjson(), action_listcategories(), aji_load_config(), complete_sipnotify(), get_insecure_variable_from_config(), gtalk_load_config(), iax_provision_reload(), ind_load_module(), jingle_load_config(), load_config(), load_module(), load_moh_classes(), load_odbc_config(), misdn_cfg_init(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), search_directory(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().
00623 { 00624 struct ast_category *cat = NULL; 00625 00626 if (prev && config->last_browse && (config->last_browse->name == prev)) 00627 cat = config->last_browse->next; 00628 else if (!prev && config->root) 00629 cat = config->root; 00630 else if (prev) { 00631 for (cat = config->root; cat; cat = cat->next) { 00632 if (cat->name == prev) { 00633 cat = cat->next; 00634 break; 00635 } 00636 } 00637 if (!cat) { 00638 for (cat = config->root; cat; cat = cat->next) { 00639 if (!strcasecmp(cat->name, prev)) { 00640 cat = cat->next; 00641 break; 00642 } 00643 } 00644 } 00645 } 00646 00647 if (cat) 00648 cat = next_available_category(cat); 00649 00650 config->last_browse = cat; 00651 return (cat) ? cat->name : NULL; 00652 }
int ast_category_delete | ( | struct ast_config * | cfg, | |
const char * | category | |||
) |
Definition at line 775 of file config.c.
References ast_category_destroy(), ast_config::last, ast_category::next, and ast_config::root.
Referenced by handle_updates().
00776 { 00777 struct ast_category *prev=NULL, *cat; 00778 00779 cat = cfg->root; 00780 while (cat) { 00781 if (cat->name == category) { 00782 if (prev) { 00783 prev->next = cat->next; 00784 if (cat == cfg->last) 00785 cfg->last = prev; 00786 } else { 00787 cfg->root = cat->next; 00788 if (cat == cfg->last) 00789 cfg->last = NULL; 00790 } 00791 ast_category_destroy(cat); 00792 return 0; 00793 } 00794 prev = cat; 00795 cat = cat->next; 00796 } 00797 00798 prev = NULL; 00799 cat = cfg->root; 00800 while (cat) { 00801 if (!strcasecmp(cat->name, category)) { 00802 if (prev) { 00803 prev->next = cat->next; 00804 if (cat == cfg->last) 00805 cfg->last = prev; 00806 } else { 00807 cfg->root = cat->next; 00808 if (cat == cfg->last) 00809 cfg->last = NULL; 00810 } 00811 ast_category_destroy(cat); 00812 return 0; 00813 } 00814 prev = cat; 00815 cat = cat->next; 00816 } 00817 return -1; 00818 }
void ast_category_destroy | ( | struct ast_category * | cat | ) |
Definition at line 572 of file config.c.
References ast_destroy_comments(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, free, and ast_category::root.
Referenced by add_cfg_entry(), ast_category_delete(), ast_config_destroy(), process_text_line(), and realtime_multi_odbc().
00573 { 00574 ast_variables_destroy(cat->root); 00575 if (cat->file) { 00576 free(cat->file); 00577 cat->file = 0; 00578 } 00579 ast_destroy_comments(cat); 00580 ast_destroy_template_list(cat); 00581 ast_free(cat); 00582 }
struct ast_variable* ast_category_detach_variables | ( | struct ast_category * | cat | ) |
Definition at line 654 of file config.c.
References ast_category::last, and ast_category::root.
Referenced by realtime_switch_common().
00655 { 00656 struct ast_variable *v; 00657 00658 v = cat->root; 00659 cat->root = NULL; 00660 cat->last = NULL; 00661 00662 return v; 00663 }
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 820 of file config.c.
References ast_variables_destroy(), ast_category::last, ast_category::name, ast_category::next, ast_config::root, and ast_category::root.
Referenced by handle_updates().
00821 { 00822 struct ast_category *cat; 00823 00824 for (cat = cfg->root; cat; cat = cat->next) { 00825 if (!strcasecmp(cat->name, category)) 00826 continue; 00827 ast_variables_destroy(cat->root); 00828 cat->root = NULL; 00829 cat->last = NULL; 00830 return 0; 00831 } 00832 00833 return -1; 00834 }
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 507 of file config.c.
References ast_category_get(), and config.
00508 { 00509 return !!ast_category_get(config, category_name); 00510 }
struct ast_variable* ast_category_first | ( | struct ast_category * | cat | ) |
given a pointer to a category, return the root variable. This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get())
return the first var of a category
Definition at line 608 of file config.c.
References ast_category::root.
Referenced by process_text_line().
struct ast_category* ast_category_get | ( | const struct ast_config * | config, | |
const char * | category_name | |||
) |
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 502 of file config.c.
References category_get(), and config.
Referenced by ast_category_exist(), ast_category_root(), ast_variable_browse(), handle_updates(), realtime_directory(), realtime_switch_common(), vm_change_password(), and vm_forwardoptions().
00503 { 00504 return category_get(config, category_name, 0); 00505 }
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 523 of file config.c.
References config, ast_category::name, and ast_category::next.
Referenced by handle_updates().
00524 { 00525 struct ast_category *cur_category; 00526 00527 if (!cat || !match) 00528 return; 00529 if (!strcasecmp(config->root->name, match)) { 00530 cat->next = config->root; 00531 config->root = cat; 00532 return; 00533 } 00534 for (cur_category = config->root; cur_category; cur_category = cur_category->next) { 00535 if (!strcasecmp(cur_category->next->name, match)) { 00536 cat->next = cur_category->next; 00537 cur_category->next = cat; 00538 break; 00539 } 00540 } 00541 }
struct ast_category* ast_category_new | ( | const char * | name, | |
const char * | in_file, | |||
int | lineno | |||
) |
Create a category structure.
Definition at line 473 of file config.c.
References ast_calloc, ast_copy_string(), and strdup.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00474 { 00475 struct ast_category *category; 00476 00477 if ((category = ast_calloc(1, sizeof(*category)))) 00478 ast_copy_string(category->name, name, sizeof(category->name)); 00479 category->file = strdup(in_file); 00480 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */ 00481 return category; 00482 }
void ast_category_rename | ( | struct ast_category * | cat, | |
const char * | name | |||
) |
Definition at line 665 of file config.c.
References ast_copy_string(), and ast_category::name.
Referenced by handle_updates(), realtime_multi_curl(), realtime_multi_odbc(), and realtime_multi_pgsql().
00666 { 00667 ast_copy_string(cat->name, name, sizeof(cat->name)); 00668 }
struct ast_variable* ast_category_root | ( | struct ast_config * | config, | |
char * | cat | |||
) |
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 613 of file config.c.
References ast_category_get(), config, and ast_category::root.
Referenced by get_insecure_variable_from_config().
00614 { 00615 struct ast_category *category = ast_category_get(config, cat); 00616 00617 if (category) 00618 return category->root; 00619 return NULL; 00620 }
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 2131 of file config.c.
References find_engine().
Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_queue_log(), copy_plain_file(), destroy_association(), handle_response_peerpoke(), handle_voicemail_show_users(), leave_voicemail(), load_module(), local_ast_moh_start(), realtime_peer(), realtime_update_peer(), rename_file(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().
02132 { 02133 struct ast_config_engine *eng; 02134 02135 eng = find_engine(family, NULL, 0, NULL, 0); 02136 if (eng) 02137 return 1; 02138 return 0; 02139 }
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 836 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_post_load(), __ast_rtp_reload(), __ast_udptl_reload(), __queues_show(), _dsp_init(), action_getconfig(), action_listcategories(), action_updateconfig(), advanced_options(), aji_load_config(), ast_config_load2(), conf_exec(), config_function_read(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), handle_cli_dialplan_save(), iax_provision_reload(), ind_load_module(), init_logger_chain(), load_config(), load_config_meetme(), load_module(), load_realtime_queue(), load_rpt_vars(), make_email_file(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), read_agent_config(), read_config_maps(), realtime_directory(), realtime_multi_handler(), realtime_switch_common(), reload(), reload_config(), reload_followme(), rpt_master(), run_startup_commands(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), store_config(), tds_load_module(), unload_module(), update_realtime_members(), and vm_forwardoptions().
00837 { 00838 struct ast_category *cat, *catn; 00839 00840 if (!cfg) 00841 return; 00842 00843 ast_includes_destroy(cfg->includes); 00844 00845 cat = cfg->root; 00846 while (cat) { 00847 catn = cat; 00848 cat = cat->next; 00849 ast_category_destroy(catn); 00850 } 00851 ast_free(cfg); 00852 }
int ast_config_engine_deregister | ( | struct ast_config_engine * | del | ) |
Deregister config engine.
0 | Always |
Definition at line 1957 of file config.c.
References ast_mutex_lock(), ast_mutex_unlock(), config_engine_list, config_lock, last, and ast_config_engine::next.
Referenced by unload_module().
01958 { 01959 struct ast_config_engine *ptr, *last=NULL; 01960 01961 ast_mutex_lock(&config_lock); 01962 01963 for (ptr = config_engine_list; ptr; ptr=ptr->next) { 01964 if (ptr == del) { 01965 if (last) 01966 last->next = ptr->next; 01967 else 01968 config_engine_list = ptr->next; 01969 break; 01970 } 01971 last = ptr; 01972 } 01973 01974 ast_mutex_unlock(&config_lock); 01975 01976 return 0; 01977 }
int ast_config_engine_register | ( | struct ast_config_engine * | newconfig | ) |
Register config engine.
1 | Always |
Definition at line 1938 of file config.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), config_engine_list, config_lock, LOG_NOTICE, ast_config_engine::name, and ast_config_engine::next.
Referenced by load_module().
01939 { 01940 struct ast_config_engine *ptr; 01941 01942 ast_mutex_lock(&config_lock); 01943 01944 if (!config_engine_list) { 01945 config_engine_list = new; 01946 } else { 01947 for (ptr = config_engine_list; ptr->next; ptr=ptr->next); 01948 ptr->next = new; 01949 } 01950 01951 ast_mutex_unlock(&config_lock); 01952 ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name); 01953 01954 return 1; 01955 }
struct ast_category* ast_config_get_current_category | ( | const struct ast_config * | cfg | ) |
Retrieve the current category name being built. API for backend configuration engines while building a configuration set.
Definition at line 854 of file config.c.
References ast_config::current.
Referenced by config_curl(), config_odbc(), and config_text_file_load().
00855 { 00856 return cfg->current; 00857 }
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 | |||
) |
Definition at line 2019 of file config.c.
References ast_log(), config_engine_list, 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(), and read_config_maps().
02020 { 02021 char db[256]; 02022 char table[256]; 02023 struct ast_config_engine *loader = &text_file_engine; 02024 struct ast_config *result; 02025 02026 /* The config file itself bumps include_level by 1 */ 02027 if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) { 02028 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level); 02029 return NULL; 02030 } 02031 02032 cfg->include_level++; 02033 02034 if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) { 02035 struct ast_config_engine *eng; 02036 02037 eng = find_engine(filename, db, sizeof(db), table, sizeof(table)); 02038 02039 02040 if (eng && eng->load_func) { 02041 loader = eng; 02042 } else { 02043 eng = find_engine("global", db, sizeof(db), table, sizeof(table)); 02044 if (eng && eng->load_func) 02045 loader = eng; 02046 } 02047 } 02048 02049 result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked); 02050 02051 if (result && result != CONFIG_STATUS_FILEUNCHANGED) 02052 result->include_level--; 02053 else 02054 cfg->include_level--; 02055 02056 return result; 02057 }
struct ast_config* ast_config_load2 | ( | const char * | filename, | |
const char * | who_asked, | |||
struct ast_flags | flags | |||
) |
Load a config file.
filename | path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR Create a config structure from a given configuration file. | |
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). |
NULL | on error |
Definition at line 2059 of file config.c.
References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), and CONFIG_STATUS_FILEUNCHANGED.
Referenced by __ast_http_load(), __ast_http_post_load(), __ast_rtp_reload(), __ast_udptl_reload(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_readconfig(), do_reload(), iax_provision_reload(), init_logger_chain(), load_config(), load_modules(), misdn_cfg_init(), private_enum_init(), and run_startup_commands().
02060 { 02061 struct ast_config *cfg; 02062 struct ast_config *result; 02063 02064 cfg = ast_config_new(); 02065 if (!cfg) 02066 return NULL; 02067 02068 result = ast_config_internal_load(filename, cfg, flags, "", who_asked); 02069 if (!result || result == CONFIG_STATUS_FILEUNCHANGED) 02070 ast_config_destroy(cfg); 02071 02072 return result; 02073 }
struct ast_config* ast_config_new | ( | void | ) |
Create a new base configuration structure.
Definition at line 682 of file config.c.
References ast_calloc, config, and MAX_INCLUDE_LEVEL.
Referenced by ast_config_load2(), read_config_maps(), realtime_multi_curl(), realtime_multi_handler(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00683 { 00684 struct ast_config *config; 00685 00686 if ((config = ast_calloc(1, sizeof(*config)))) 00687 config->max_include_level = MAX_INCLUDE_LEVEL; 00688 return config; 00689 }
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 419 of file config.c.
References ast_variable_retrieve().
Referenced by load_config(), pbx_load_users(), and search_directory().
00420 { 00421 const char *tmp; 00422 tmp = ast_variable_retrieve(cfg, cat, var); 00423 if (!tmp) 00424 tmp = ast_variable_retrieve(cfg, "general", var); 00425 return tmp; 00426 }
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 859 of file config.c.
References ast_config::current.
00860 { 00861 /* cast below is just to silence compiler warning about dropping "const" */ 00862 cfg->current = (struct ast_category *) cat; 00863 }
static void ast_destroy_comments | ( | struct ast_category * | cat | ) | [static] |
Definition at line 543 of file config.c.
References free, ast_comment::next, ast_category::precomments, ast_category::sameline, and ast_category::trailing.
Referenced by ast_category_destroy().
00544 { 00545 struct ast_comment *n, *p; 00546 00547 for (p=cat->precomments; p; p=n) { 00548 n = p->next; 00549 free(p); 00550 } 00551 for (p=cat->sameline; p; p=n) { 00552 n = p->next; 00553 free(p); 00554 } 00555 for (p=cat->trailing; p; p=n) { 00556 n = p->next; 00557 free(p); 00558 } 00559 cat->precomments = NULL; 00560 cat->sameline = NULL; 00561 cat->trailing = NULL; 00562 }
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 2230 of file config.c.
References db, ast_config_engine::destroy_func, find_engine(), and table.
Referenced by function_realtime_readdestroy(), leave_voicemail(), and vm_delete().
02231 { 02232 struct ast_config_engine *eng; 02233 int res = -1; 02234 char db[256]=""; 02235 char table[256]=""; 02236 va_list ap; 02237 02238 va_start(ap, lookup); 02239 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02240 if (eng && eng->destroy_func) 02241 res = eng->destroy_func(db, table, keyfield, lookup, ap); 02242 va_end(ap); 02243 02244 return res; 02245 }
static void ast_destroy_template_list | ( | struct ast_category * | cat | ) | [static] |
Definition at line 564 of file config.c.
References AST_LIST_REMOVE_HEAD, free, cache_file_include::next, and ast_category::template_instances.
Referenced by ast_category_destroy().
00565 { 00566 struct ast_category_template_instance *x; 00567 00568 while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next))) 00569 free(x); 00570 }
struct ast_config_include* ast_include_find | ( | struct ast_config * | conf, | |
const char * | included_file | |||
) |
Definition at line 350 of file config.c.
References ast_config_include::included_file, ast_config::includes, and ast_config_include::next.
Referenced by ast_include_new().
00351 { 00352 struct ast_config_include *x; 00353 for (x=conf->includes;x;x=x->next) { 00354 if (strcmp(x->included_file,included_file) == 0) 00355 return x; 00356 } 00357 return 0; 00358 }
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 | |||
) |
Definition at line 259 of file config.c.
References ast_calloc, ast_include_find(), ast_log(), ast_strdup, ast_strlen_zero(), ast_config::includes, and LOG_WARNING.
Referenced by process_text_line().
00260 { 00261 /* a file should be included ONCE. Otherwise, if one of the instances is changed, 00262 * then all be changed. -- how do we know to include it? -- Handling modified 00263 * instances is possible, I'd have 00264 * to create a new master for each instance. */ 00265 struct ast_config_include *inc; 00266 struct stat statbuf; 00267 00268 inc = ast_include_find(conf, included_file); 00269 if (inc) { 00270 do { 00271 inc->inclusion_count++; 00272 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count); 00273 } while (stat(real_included_file_name, &statbuf) == 0); 00274 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); 00275 } else 00276 *real_included_file_name = 0; 00277 00278 inc = ast_calloc(1,sizeof(struct ast_config_include)); 00279 inc->include_location_file = ast_strdup(from_file); 00280 inc->include_location_lineno = from_lineno; 00281 if (!ast_strlen_zero(real_included_file_name)) 00282 inc->included_file = ast_strdup(real_included_file_name); 00283 else 00284 inc->included_file = ast_strdup(included_file); 00285 00286 inc->exec = is_exec; 00287 if (is_exec) 00288 inc->exec_file = ast_strdup(exec_file); 00289 00290 /* attach this new struct to the conf struct */ 00291 inc->next = conf->includes; 00292 conf->includes = inc; 00293 00294 return inc; 00295 }
void ast_include_rename | ( | struct ast_config * | conf, | |
const char * | from_file, | |||
const char * | to_file | |||
) |
Definition at line 297 of file config.c.
References ast_category::file, ast_variable::file, free, ast_config_include::include_location_file, ast_config::includes, ast_config_include::next, ast_category::next, ast_variable::next, ast_config::root, ast_category::root, and strdup.
Referenced by action_updateconfig().
00298 { 00299 struct ast_config_include *incl; 00300 struct ast_category *cat; 00301 struct ast_variable *v; 00302 00303 int from_len = strlen(from_file); 00304 int to_len = strlen(to_file); 00305 00306 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */ 00307 return; 00308 00309 /* the manager code allows you to read in one config file, then 00310 * write it back out under a different name. But, the new arrangement 00311 * ties output lines to the file name. So, before you try to write 00312 * the config file to disk, better riffle thru the data and make sure 00313 * the file names are changed. 00314 */ 00315 /* file names are on categories, includes (of course), and on variables. So, 00316 * traverse all this and swap names */ 00317 00318 for (incl = conf->includes; incl; incl=incl->next) { 00319 if (strcmp(incl->include_location_file,from_file) == 0) { 00320 if (from_len >= to_len) 00321 strcpy(incl->include_location_file, to_file); 00322 else { 00323 free(incl->include_location_file); 00324 incl->include_location_file = strdup(to_file); 00325 } 00326 } 00327 } 00328 for (cat = conf->root; cat; cat = cat->next) { 00329 if (strcmp(cat->file,from_file) == 0) { 00330 if (from_len >= to_len) 00331 strcpy(cat->file, to_file); 00332 else { 00333 free(cat->file); 00334 cat->file = strdup(to_file); 00335 } 00336 } 00337 for (v = cat->root; v; v = v->next) { 00338 if (strcmp(v->file,from_file) == 0) { 00339 if (from_len >= to_len) 00340 strcpy(v->file, to_file); 00341 else { 00342 free(v->file); 00343 v->file = strdup(to_file); 00344 } 00345 } 00346 } 00347 } 00348 }
static void ast_includes_destroy | ( | struct ast_config_include * | incls | ) | [static] |
Definition at line 584 of file config.c.
References ast_config_include::exec_file, free, ast_config_include::include_location_file, ast_config_include::included_file, and ast_config_include::next.
Referenced by ast_config_destroy().
00585 { 00586 struct ast_config_include *incl,*inclnext; 00587 00588 for (incl=incls; incl; incl = inclnext) { 00589 inclnext = incl->next; 00590 if (incl->include_location_file) 00591 free(incl->include_location_file); 00592 if (incl->exec_file) 00593 free(incl->exec_file); 00594 if (incl->included_file) 00595 free(incl->included_file); 00596 free(incl); 00597 } 00598 }
struct ast_variable* ast_load_realtime | ( | const char * | family, | |
... | ||||
) |
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. Note that unlike the variables in ast_config, the resulting list of variables MUST be freed with ast_variables_destroy() as there is no container. |
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2101 of file config.c.
References ast_free, ast_load_realtime_helper(), ast_strlen_zero(), ast_variable::next, and ast_variable::value.
Referenced by copy_plain_file(), find_conf_realtime(), find_user_realtime(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), queue_function_queuewaitingcount(), realtime_alias(), realtime_peer(), realtime_switch_common(), and realtime_user().
02102 { 02103 struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL; 02104 va_list ap; 02105 02106 va_start(ap, family); 02107 res = ast_load_realtime_helper(family, ap); 02108 va_end(ap); 02109 02110 /* Eliminate blank entries */ 02111 for (cur = res; cur; cur = cur->next) { 02112 if (freeme) { 02113 ast_free(freeme); 02114 freeme = NULL; 02115 } 02116 02117 if (ast_strlen_zero(cur->value)) { 02118 if (prev) 02119 prev->next = cur->next; 02120 else 02121 res = cur->next; 02122 freeme = cur; 02123 } else { 02124 prev = cur; 02125 } 02126 } 02127 return res; 02128 }
struct ast_variable* ast_load_realtime_all | ( | const char * | family, | |
... | ||||
) |
Definition at line 2089 of file config.c.
References ast_load_realtime_helper().
Referenced by cli_realtime_load(), function_realtime_read(), and function_realtime_readdestroy().
02090 { 02091 struct ast_variable *res; 02092 va_list ap; 02093 02094 va_start(ap, family); 02095 res = ast_load_realtime_helper(family, ap); 02096 va_end(ap); 02097 02098 return res; 02099 }
static struct ast_variable* ast_load_realtime_helper | ( | const char * | family, | |
va_list | ap | |||
) | [static] |
Definition at line 2075 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().
02076 { 02077 struct ast_config_engine *eng; 02078 char db[256]=""; 02079 char table[256]=""; 02080 struct ast_variable *res=NULL; 02081 02082 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02083 if (eng && eng->realtime_func) 02084 res = eng->realtime_func(db, table, ap); 02085 02086 return res; 02087 }
struct ast_config* ast_load_realtime_multientry | ( | const char * | family, | |
... | ||||
) |
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. |
Definition at line 2179 of file config.c.
References db, find_engine(), ast_config_engine::realtime_multi_func, and table.
Referenced by __queues_show(), load_realtime_queue(), realtime_directory(), realtime_switch_common(), show_users_realtime(), and update_realtime_members().
02180 { 02181 struct ast_config_engine *eng; 02182 char db[256]=""; 02183 char table[256]=""; 02184 struct ast_config *res=NULL; 02185 va_list ap; 02186 02187 va_start(ap, family); 02188 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02189 if (eng && eng->realtime_multi_func) 02190 res = eng->realtime_multi_func(db, table, ap); 02191 va_end(ap); 02192 02193 return res; 02194 }
int ast_parse_arg | ( | const char * | arg, | |
enum ast_parse_flags | flags, | |||
void * | result, | |||
... | ||||
) |
The argument parsing routine.
arg | the string to parse. It is not modified. | |
flags | combination of ast_parse_flags to specify the return type and additional checks. | |
result | pointer to the result. NULL is valid here, and can be used to perform only the validity checks. | |
... | extra arguments are required according to flags. |
0 | in case of success, != 0 otherwise. | |
result | returns the parsed value in case of success, the default value in case of error, or it is left unchanged in case of error and no default specified. Note that in certain cases (e.g. sockaddr_in, with multi-field return values) some of the fields in result may be changed even if an error occurs. |
Definition at line 2250 of file config.c.
References ahp, ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_strdupa, buf, hp, 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_TYPE, PARSE_UINT32, and strsep().
Referenced by ast_sip_ouraddrfor(), and check_via_response().
02252 { 02253 va_list ap; 02254 int error = 0; 02255 02256 va_start(ap, p_result); 02257 switch (flags & PARSE_TYPE) { 02258 case PARSE_INT32: 02259 { 02260 int32_t *result = p_result; 02261 int32_t x, def = result ? *result : 0, 02262 high = (int32_t)0x7fffffff, 02263 low = (int32_t)0x80000000; 02264 /* optional argument: first default value, then range */ 02265 if (flags & PARSE_DEFAULT) 02266 def = va_arg(ap, int32_t); 02267 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02268 /* range requested, update bounds */ 02269 low = va_arg(ap, int32_t); 02270 high = va_arg(ap, int32_t); 02271 } 02272 x = strtol(arg, NULL, 0); 02273 error = (x < low) || (x > high); 02274 if (flags & PARSE_OUT_RANGE) 02275 error = !error; 02276 if (result) 02277 *result = error ? def : x; 02278 ast_debug(3, 02279 "extract int from [%s] in [%d, %d] gives [%d](%d)\n", 02280 arg, low, high, 02281 result ? *result : x, error); 02282 break; 02283 } 02284 02285 case PARSE_UINT32: 02286 { 02287 uint32_t *result = p_result; 02288 uint32_t x, def = result ? *result : 0, 02289 low = 0, high = (uint32_t)~0; 02290 /* optional argument: first default value, then range */ 02291 if (flags & PARSE_DEFAULT) 02292 def = va_arg(ap, uint32_t); 02293 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02294 /* range requested, update bounds */ 02295 low = va_arg(ap, uint32_t); 02296 high = va_arg(ap, uint32_t); 02297 } 02298 x = strtoul(arg, NULL, 0); 02299 error = (x < low) || (x > high); 02300 if (flags & PARSE_OUT_RANGE) 02301 error = !error; 02302 if (result) 02303 *result = error ? def : x; 02304 ast_debug(3, 02305 "extract uint from [%s] in [%u, %u] gives [%u](%d)\n", 02306 arg, low, high, 02307 result ? *result : x, error); 02308 break; 02309 } 02310 02311 case PARSE_DOUBLE: 02312 { 02313 double *result = p_result; 02314 double x, def = result ? *result : 0, 02315 low = -HUGE_VAL, high = HUGE_VAL; 02316 02317 /* optional argument: first default value, then range */ 02318 if (flags & PARSE_DEFAULT) 02319 def = va_arg(ap, double); 02320 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02321 /* range requested, update bounds */ 02322 low = va_arg(ap, double); 02323 high = va_arg(ap, double); 02324 } 02325 x = strtod(arg, NULL); 02326 error = (x < low) || (x > high); 02327 if (flags & PARSE_OUT_RANGE) 02328 error = !error; 02329 if (result) 02330 *result = error ? def : x; 02331 ast_debug(3, 02332 "extract double from [%s] in [%f, %f] gives [%f](%d)\n", 02333 arg, low, high, 02334 result ? *result : x, error); 02335 break; 02336 } 02337 case PARSE_INADDR: 02338 { 02339 char *port, *buf; 02340 struct sockaddr_in _sa_buf; /* buffer for the result */ 02341 struct sockaddr_in *sa = p_result ? 02342 (struct sockaddr_in *)p_result : &_sa_buf; 02343 /* default is either the supplied value or the result itself */ 02344 struct sockaddr_in *def = (flags & PARSE_DEFAULT) ? 02345 va_arg(ap, struct sockaddr_in *) : sa; 02346 struct hostent *hp; 02347 struct ast_hostent ahp; 02348 02349 memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */ 02350 /* duplicate the string to strip away the :port */ 02351 port = ast_strdupa(arg); 02352 buf = strsep(&port, ":"); 02353 sa->sin_family = AF_INET; /* assign family */ 02354 /* 02355 * honor the ports flag setting, assign default value 02356 * in case of errors or field unset. 02357 */ 02358 flags &= PARSE_PORT_MASK; /* the only flags left to process */ 02359 if (port) { 02360 if (flags == PARSE_PORT_FORBID) { 02361 error = 1; /* port was forbidden */ 02362 sa->sin_port = def->sin_port; 02363 } else if (flags == PARSE_PORT_IGNORE) 02364 sa->sin_port = def->sin_port; 02365 else /* accept or require */ 02366 sa->sin_port = htons(strtol(port, NULL, 0)); 02367 } else { 02368 sa->sin_port = def->sin_port; 02369 if (flags == PARSE_PORT_REQUIRE) 02370 error = 1; 02371 } 02372 /* Now deal with host part, even if we have errors before. */ 02373 hp = ast_gethostbyname(buf, &ahp); 02374 if (hp) /* resolved successfully */ 02375 memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr)); 02376 else { 02377 error = 1; 02378 sa->sin_addr = def->sin_addr; 02379 } 02380 ast_debug(3, 02381 "extract inaddr from [%s] gives [%s:%d](%d)\n", 02382 arg, ast_inet_ntoa(sa->sin_addr), 02383 ntohs(sa->sin_port), error); 02384 break; 02385 } 02386 } 02387 va_end(ap); 02388 return error; 02389 }
int ast_realtime_enabled | ( | void | ) |
Check if there's any realtime engines loaded.
Definition at line 2142 of file config.c.
References config_maps.
Referenced by action_coresettings(), and handle_show_settings().
02143 { 02144 return config_maps ? 1 : 0; 02145 }
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. |
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 2147 of file config.c.
References db, find_engine(), ast_config_engine::require_func, and table.
Referenced by change_password_realtime(), conf_run(), and load_module().
02148 { 02149 struct ast_config_engine *eng; 02150 char db[256] = ""; 02151 char table[256] = ""; 02152 va_list ap; 02153 int res = -1; 02154 02155 va_start(ap, family); 02156 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02157 if (eng && eng->require_func) { 02158 res = eng->require_func(db, table, ap); 02159 } 02160 va_end(ap); 02161 02162 return res; 02163 }
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 2213 of file config.c.
References db, find_engine(), ast_config_engine::store_func, and table.
Referenced by ast_queue_log(), function_realtime_store(), and leave_voicemail().
02214 { 02215 struct ast_config_engine *eng; 02216 int res = -1; 02217 char db[256]=""; 02218 char table[256]=""; 02219 va_list ap; 02220 02221 va_start(ap, family); 02222 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02223 if (eng && eng->store_func) 02224 res = eng->store_func(db, table, ap); 02225 va_end(ap); 02226 02227 return res; 02228 }
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 2165 of file config.c.
References db, find_engine(), table, and ast_config_engine::unload_func.
Referenced by __unload_module(), load_config(), reload(), reload_config(), and unload_module().
02166 { 02167 struct ast_config_engine *eng; 02168 char db[256] = ""; 02169 char table[256] = ""; 02170 int res = -1; 02171 02172 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02173 if (eng && eng->unload_func) { 02174 res = eng->unload_func(db, table); 02175 } 02176 return res; 02177 }
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 2196 of file config.c.
References db, find_engine(), table, and ast_config_engine::update_func.
Referenced by change_password_realtime(), cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), handle_response_peerpoke(), leave_voicemail(), realtime_update_peer(), rename_file(), sip_poke_noanswer(), and update_realtime_member_field().
02197 { 02198 struct ast_config_engine *eng; 02199 int res = -1; 02200 char db[256]=""; 02201 char table[256]=""; 02202 va_list ap; 02203 02204 va_start(ap, lookup); 02205 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02206 if (eng && eng->update_func) 02207 res = eng->update_func(db, table, keyfield, lookup, ap); 02208 va_end(ap); 02209 02210 return res; 02211 }
void ast_variable_append | ( | struct ast_category * | category, | |
struct ast_variable * | variable | |||
) |
Definition at line 361 of file config.c.
References ast_category::last, ast_variable::next, and ast_category::root.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), 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(), and vm_change_password().
00362 { 00363 if (!variable) 00364 return; 00365 if (category->last) 00366 category->last->next = variable; 00367 else 00368 category->root = variable; 00369 category->last = variable; 00370 while (category->last->next) 00371 category->last = category->last->next; 00372 }
struct ast_variable* ast_variable_browse | ( | const struct ast_config * | config, | |
const char * | category | |||
) |
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 407 of file config.c.
References ast_category_get(), config, and ast_category::root.
Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), action_getconfig(), action_getconfigjson(), adsi_load(), aji_load_config(), ast_readconfig(), ast_variable_retrieve(), build_device(), check_tx_freq(), collect_function_digits(), conf_exec(), config_module(), do_say(), do_scheduler(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_template_parse(), ind_load_module(), init_logger_chain(), jingle_load_config(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_rpt_vars(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_create_provider(), parse_config(), pbx_load_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), run_startup_commands(), search_directory(), set_config(), setup_dahdi(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().
00408 { 00409 struct ast_category *cat = NULL; 00410 00411 if (category && config->last_browse && (config->last_browse->name == category)) 00412 cat = config->last_browse; 00413 else 00414 cat = ast_category_get(config, category); 00415 00416 return (cat) ? cat->root : NULL; 00417 }
int ast_variable_delete | ( | struct ast_category * | category, | |
const char * | variable, | |||
const char * | match, | |||
const char * | line | |||
) |
Definition at line 691 of file config.c.
References ast_strlen_zero(), ast_variables_destroy(), ast_category::last, ast_variable::name, ast_variable::next, ast_category::root, and ast_variable::value.
Referenced by handle_updates().
00692 { 00693 struct ast_variable *cur, *prev=NULL, *curn; 00694 int res = -1; 00695 int lineno = 0; 00696 00697 cur = category->root; 00698 while (cur) { 00699 if (cur->name == variable) { 00700 if (prev) { 00701 prev->next = cur->next; 00702 if (cur == category->last) 00703 category->last = prev; 00704 } else { 00705 category->root = cur->next; 00706 if (cur == category->last) 00707 category->last = NULL; 00708 } 00709 cur->next = NULL; 00710 ast_variables_destroy(cur); 00711 return 0; 00712 } 00713 prev = cur; 00714 cur = cur->next; 00715 } 00716 00717 prev = NULL; 00718 cur = category->root; 00719 while (cur) { 00720 curn = cur->next; 00721 if ((!ast_strlen_zero(line) && lineno == atoi(line)) || (ast_strlen_zero(line) && !strcasecmp(cur->name, variable) && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) { 00722 if (prev) { 00723 prev->next = cur->next; 00724 if (cur == category->last) 00725 category->last = prev; 00726 } else { 00727 category->root = cur->next; 00728 if (cur == category->last) 00729 category->last = NULL; 00730 } 00731 cur->next = NULL; 00732 ast_variables_destroy(cur); 00733 res = 0; 00734 } else 00735 prev = cur; 00736 00737 cur = curn; 00738 lineno++; 00739 } 00740 return res; 00741 }
void ast_variable_insert | ( | struct ast_category * | category, | |
struct ast_variable * | variable, | |||
const char * | line | |||
) |
Definition at line 374 of file config.c.
References ast_variable::next, and ast_category::root.
Referenced by handle_updates().
00375 { 00376 struct ast_variable *cur = category->root; 00377 int lineno; 00378 int insertline; 00379 00380 if (!variable || sscanf(line, "%d", &insertline) != 1) 00381 return; 00382 if (!insertline) { 00383 variable->next = category->root; 00384 category->root = variable; 00385 } else { 00386 for (lineno = 1; lineno < insertline; lineno++) { 00387 cur = cur->next; 00388 if (!cur->next) 00389 break; 00390 } 00391 variable->next = cur->next; 00392 cur->next = variable; 00393 } 00394 }
struct ast_variable* ast_variable_new | ( | const char * | name, | |
const char * | value, | |||
const char * | filename | |||
) |
Definition at line 236 of file config.c.
References __ast_calloc(), ast_calloc, and ast_variable::stuff.
Referenced by add_cfg_entry(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), apply_outgoing(), ast_channeltype_list(), ast_variable_update(), astman_get_variables(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), parkandannounce_exec(), parse_cookies(), 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(), transmit_notify_custom(), variable_clone(), and vm_change_password().
00238 { 00239 struct ast_variable *variable; 00240 int name_len = strlen(name) + 1; 00241 int val_len = strlen(value) + 1; 00242 int fn_len = strlen(filename) + 1; 00243 00244 #ifdef MALLOC_DEBUG 00245 if ((variable = __ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable), file, lineno, func))) { 00246 #else 00247 if ((variable = ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable)))) { 00248 #endif 00249 char *dst = variable->stuff; /* writable space starts here */ 00250 variable->name = strcpy(dst, name); 00251 dst += name_len; 00252 variable->value = strcpy(dst, value); 00253 dst += val_len; 00254 variable->file = strcpy(dst, filename); 00255 } 00256 return variable; 00257 }
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 429 of file config.c.
References ast_variable_browse(), config, ast_variable::name, ast_variable::next, ast_category::next, ast_category::root, and ast_variable::value.
Referenced by __ast_rtp_reload(), __ast_udptl_reload(), _dsp_init(), advanced_options(), aji_load_config(), ast_config_option(), build_extension(), config_function_read(), config_module(), directory_exec(), do_reload(), do_scheduler(), festival_exec(), function_macro(), get_insecure_variable_from_config(), get_wait_interval(), gtalk_load_config(), iax_template_parse(), ind_load_module(), init_acf_query(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_module(), load_rpt_vars(), make_email_file(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), read_agent_config(), realtime_directory(), reload_config(), reload_followme(), reload_queues(), retreive_memory(), retrieve_astcfgint(), rpt(), rpt_master(), rpt_tele_thread(), rpt_telemetry(), saynode(), search_directory(), set_config(), setup_dahdi(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), telem_lookup(), update_realtime_members(), vm_change_password(), and vm_forwardoptions().
00430 { 00431 struct ast_variable *v; 00432 00433 if (category) { 00434 for (v = ast_variable_browse(config, category); v; v = v->next) { 00435 if (!strcasecmp(variable, v->name)) 00436 return v->value; 00437 } 00438 } else { 00439 struct ast_category *cat; 00440 00441 for (cat = config->root; cat; cat = cat->next) 00442 for (v = cat->root; v; v = v->next) 00443 if (!strcasecmp(variable, v->name)) 00444 return v->value; 00445 } 00446 00447 return NULL; 00448 }
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 743 of file config.c.
References ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), 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().
00745 { 00746 struct ast_variable *cur, *prev=NULL, *newer=NULL; 00747 00748 for (cur = category->root; cur; prev = cur, cur = cur->next) { 00749 if (strcasecmp(cur->name, variable) || 00750 (!ast_strlen_zero(match) && strcasecmp(cur->value, match))) 00751 continue; 00752 00753 if (!(newer = ast_variable_new(variable, value, cur->file))) 00754 return -1; 00755 00756 newer->next = cur->next; 00757 newer->object = cur->object || object; 00758 if (prev) 00759 prev->next = newer; 00760 else 00761 category->root = newer; 00762 if (category->last == cur) 00763 category->last = newer; 00764 00765 cur->next = NULL; 00766 ast_variables_destroy(cur); 00767 00768 return 0; 00769 } 00770 00771 /* Could not find variable to update */ 00772 return -1; 00773 }
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 396 of file config.c.
References ast_free, and ast_variable::next.
Referenced by __sip_destroy(), ast_category_destroy(), ast_category_empty(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_variable_delete(), ast_variable_update(), build_peer(), build_user(), cli_realtime_load(), destroy_dahdi_pvt(), find_conf_realtime(), find_user_realtime(), free_outgoing(), free_user(), handle_uri(), httpd_helper_thread(), ldap_loadentry(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), manager_sipnotify(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_user(), sip_alloc(), sip_destroy_peer(), socket_process(), table_configs_free(), and user_destructor().
00397 { 00398 struct ast_variable *vn; 00399 00400 while (v) { 00401 vn = v; 00402 v = v->next; 00403 ast_free(vn); 00404 } 00405 }
static struct ast_category* category_get | ( | const struct ast_config * | config, | |
const char * | category_name, | |||
int | ignored | |||
) | [static] |
Definition at line 484 of file config.c.
References config, ast_category::ignored, ast_category::name, and ast_category::next.
Referenced by ast_category_get(), and process_text_line().
00485 { 00486 struct ast_category *cat; 00487 00488 /* try exact match first, then case-insensitive match */ 00489 for (cat = config->root; cat; cat = cat->next) { 00490 if (cat->name == category_name && (ignored || !cat->ignored)) 00491 return cat; 00492 } 00493 00494 for (cat = config->root; cat; cat = cat->next) { 00495 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored)) 00496 return cat; 00497 } 00498 00499 return NULL; 00500 }
static void CB_ADD | ( | struct ast_str ** | cb, | |
const char * | str | |||
) | [static] |
Definition at line 113 of file config.c.
References ast_str_append().
Referenced by config_text_file_load().
00114 { 00115 ast_str_append(cb, 0, "%s", str); 00116 }
static void CB_ADD_LEN | ( | struct ast_str ** | cb, | |
const char * | str, | |||
int | len | |||
) | [static] |
Definition at line 118 of file config.c.
References ast_copy_string(), ast_str_append(), and s.
Referenced by config_text_file_load().
00119 { 00120 char *s = alloca(len + 1); 00121 ast_copy_string(s, str, len); 00122 ast_str_append(cb, 0, "%s", str); 00123 }
Definition at line 125 of file config.c.
References ast_str::used.
Referenced by config_text_file_load(), and process_text_line().
00126 { 00127 if (cb) 00128 cb->used = 0; 00129 if (llb) 00130 llb->used = 0; 00131 }
static void clear_config_maps | ( | void | ) | [static] |
Definition at line 1819 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().
01820 { 01821 struct ast_config_map *map; 01822 01823 ast_mutex_lock(&config_lock); 01824 01825 while (config_maps) { 01826 map = config_maps; 01827 config_maps = config_maps->next; 01828 ast_free(map); 01829 } 01830 01831 ast_mutex_unlock(&config_lock); 01832 }
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 870 of file config.c.
References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_SORTALPHA, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, cache_file_include::list, cache_file_mtime::mtime, and cache_file_mtime::who_asked.
Referenced by process_text_line().
00871 { 00872 struct cache_file_mtime *cfmtime; 00873 struct cache_file_include *cfinclude; 00874 struct stat statbuf = { 0, }; 00875 00876 /* Find our cached entry for this configuration file */ 00877 AST_LIST_LOCK(&cfmtime_head); 00878 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 00879 if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked)) 00880 break; 00881 } 00882 if (!cfmtime) { 00883 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1 + strlen(who_asked) + 1); 00884 if (!cfmtime) { 00885 AST_LIST_UNLOCK(&cfmtime_head); 00886 return; 00887 } 00888 AST_LIST_HEAD_INIT(&cfmtime->includes); 00889 strcpy(cfmtime->filename, configfile); 00890 cfmtime->who_asked = cfmtime->filename + strlen(configfile) + 1; 00891 strcpy(cfmtime->who_asked, who_asked); 00892 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 00893 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 00894 } 00895 00896 if (!stat(configfile, &statbuf)) 00897 cfmtime->mtime = 0; 00898 else 00899 cfmtime->mtime = statbuf.st_mtime; 00900 00901 switch (attrtype) { 00902 case ATTRIBUTE_INCLUDE: 00903 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 00904 if (!strcmp(cfinclude->include, filename)) { 00905 AST_LIST_UNLOCK(&cfmtime_head); 00906 return; 00907 } 00908 } 00909 cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1); 00910 if (!cfinclude) { 00911 AST_LIST_UNLOCK(&cfmtime_head); 00912 return; 00913 } 00914 strcpy(cfinclude->include, filename); 00915 AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list); 00916 break; 00917 case ATTRIBUTE_EXEC: 00918 cfmtime->has_exec = 1; 00919 break; 00920 } 00921 AST_LIST_UNLOCK(&cfmtime_head); 00922 }
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] |
Definition at line 1170 of file config.c.
References ALLOC_COMMENT(), ast_calloc, ast_clear_flag, ast_config_AST_CONFIG_DIR, ast_config_get_current_category(), ast_copy_string(), ast_debug, ast_free, AST_LIST_HEAD_INIT, AST_LIST_INSERT_SORTALPHA, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_str_create(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, buf, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, COMMENT_META, COMMENT_TAG, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, cache_file_include::list, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, cache_file_mtime::mtime, MY_GLOB_FLAGS, process_text_line(), ast_str::str, ast_variable::trailing, ast_category::trailing, ast_str::used, and cache_file_mtime::who_asked.
01171 { 01172 char fn[256]; 01173 #if defined(LOW_MEMORY) 01174 char buf[512]; 01175 #else 01176 char buf[8192]; 01177 #endif 01178 char *new_buf, *comment_p, *process_buf; 01179 FILE *f; 01180 int lineno=0; 01181 int comment = 0, nest[MAX_NESTED_COMMENTS]; 01182 struct ast_category *cat = NULL; 01183 int count = 0; 01184 struct stat statbuf; 01185 struct cache_file_mtime *cfmtime = NULL; 01186 struct cache_file_include *cfinclude; 01187 struct ast_variable *last_var = 0; 01188 struct ast_category *last_cat = 0; 01189 /*! Growable string buffer */ 01190 struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/ 01191 struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */ 01192 01193 if (cfg) 01194 cat = ast_config_get_current_category(cfg); 01195 01196 if (filename[0] == '/') { 01197 ast_copy_string(fn, filename, sizeof(fn)); 01198 } else { 01199 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 01200 } 01201 01202 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01203 comment_buffer = ast_str_create(CB_SIZE); 01204 if (comment_buffer) 01205 lline_buffer = ast_str_create(CB_SIZE); 01206 if (!lline_buffer) { 01207 if (comment_buffer) 01208 ast_free(comment_buffer); 01209 ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n"); 01210 return NULL; 01211 } 01212 } 01213 #ifdef AST_INCLUDE_GLOB 01214 { 01215 int glob_ret; 01216 glob_t globbuf; 01217 globbuf.gl_offs = 0; /* initialize it to silence gcc */ 01218 glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf); 01219 if (glob_ret == GLOB_NOSPACE) 01220 ast_log(LOG_WARNING, 01221 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn); 01222 else if (glob_ret == GLOB_ABORTED) 01223 ast_log(LOG_WARNING, 01224 "Glob Expansion of pattern '%s' failed: Read error\n", fn); 01225 else { 01226 /* loop over expanded files */ 01227 int i; 01228 for (i=0; i<globbuf.gl_pathc; i++) { 01229 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn)); 01230 #endif 01231 /* 01232 * The following is not a loop, but just a convenient way to define a block 01233 * (using do { } while(0) ), and be able to exit from it with 'continue' 01234 * or 'break' in case of errors. Nice trick. 01235 */ 01236 do { 01237 if (stat(fn, &statbuf)) 01238 continue; 01239 01240 if (!S_ISREG(statbuf.st_mode)) { 01241 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn); 01242 continue; 01243 } 01244 01245 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) { 01246 /* Find our cached entry for this configuration file */ 01247 AST_LIST_LOCK(&cfmtime_head); 01248 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 01249 if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) 01250 break; 01251 } 01252 if (!cfmtime) { 01253 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1 + strlen(who_asked) + 1); 01254 if (!cfmtime) 01255 continue; 01256 AST_LIST_HEAD_INIT(&cfmtime->includes); 01257 strcpy(cfmtime->filename, fn); 01258 cfmtime->who_asked = cfmtime->filename + strlen(fn) + 1; 01259 strcpy(cfmtime->who_asked, who_asked); 01260 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 01261 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 01262 } 01263 } 01264 01265 if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) { 01266 /* File is unchanged, what about the (cached) includes (if any)? */ 01267 int unchanged = 1; 01268 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 01269 /* We must glob here, because if we did not, then adding a file to globbed directory would 01270 * incorrectly cause no reload to be necessary. */ 01271 char fn2[256]; 01272 #ifdef AST_INCLUDE_GLOB 01273 int glob_return; 01274 glob_t glob_buf = { .gl_offs = 0 }; 01275 glob_return = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &glob_buf); 01276 /* On error, we reparse */ 01277 if (glob_return == GLOB_NOSPACE || glob_return == GLOB_ABORTED) 01278 unchanged = 0; 01279 else { 01280 /* loop over expanded files */ 01281 int j; 01282 for (j = 0; j < glob_buf.gl_pathc; j++) { 01283 ast_copy_string(fn2, glob_buf.gl_pathv[j], sizeof(fn2)); 01284 #else 01285 ast_copy_string(fn2, cfinclude->include); 01286 #endif 01287 if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) { 01288 /* that second-to-last field needs to be looked at in this case... TODO */ 01289 unchanged = 0; 01290 /* One change is enough to short-circuit and reload the whole shebang */ 01291 break; 01292 } 01293 #ifdef AST_INCLUDE_GLOB 01294 } 01295 } 01296 #endif 01297 } 01298 01299 if (unchanged) { 01300 AST_LIST_UNLOCK(&cfmtime_head); 01301 return CONFIG_STATUS_FILEUNCHANGED; 01302 } 01303 } 01304 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01305 AST_LIST_UNLOCK(&cfmtime_head); 01306 01307 /* If cfg is NULL, then we just want an answer */ 01308 if (cfg == NULL) 01309 return NULL; 01310 01311 if (cfmtime) 01312 cfmtime->mtime = statbuf.st_mtime; 01313 01314 ast_verb(2, "Parsing '%s': ", fn); 01315 fflush(stdout); 01316 if (!(f = fopen(fn, "r"))) { 01317 ast_debug(1, "No file to parse: %s\n", fn); 01318 ast_verb(2, "Not found (%s)\n", strerror(errno)); 01319 continue; 01320 } 01321 count++; 01322 /* If we get to this point, then we're loading regardless */ 01323 ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED); 01324 ast_debug(1, "Parsing %s\n", fn); 01325 ast_verb(2, "Found\n"); 01326 while (!feof(f)) { 01327 lineno++; 01328 if (fgets(buf, sizeof(buf), f)) { 01329 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && lline_buffer->used) { 01330 CB_ADD(&comment_buffer, lline_buffer->str); /* add the current lline buffer to the comment buffer */ 01331 lline_buffer->used = 0; /* erase the lline buffer */ 01332 } 01333 01334 new_buf = buf; 01335 if (comment) 01336 process_buf = NULL; 01337 else 01338 process_buf = buf; 01339 01340 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) { 01341 /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */ 01342 CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */ 01343 continue; /* go get a new line, then */ 01344 } 01345 01346 while ((comment_p = strchr(new_buf, COMMENT_META))) { 01347 if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) { 01348 /* Escaped semicolons aren't comments. */ 01349 new_buf = comment_p + 1; 01350 } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { 01351 /* Meta-Comment start detected ";--" */ 01352 if (comment < MAX_NESTED_COMMENTS) { 01353 *comment_p = '\0'; 01354 new_buf = comment_p + 3; 01355 comment++; 01356 nest[comment-1] = lineno; 01357 } else { 01358 ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); 01359 } 01360 } else if ((comment_p >= new_buf + 2) && 01361 (*(comment_p - 1) == COMMENT_TAG) && 01362 (*(comment_p - 2) == COMMENT_TAG)) { 01363 /* Meta-Comment end detected */ 01364 comment--; 01365 new_buf = comment_p + 1; 01366 if (!comment) { 01367 /* Back to non-comment now */ 01368 if (process_buf) { 01369 /* Actually have to move what's left over the top, then continue */ 01370 char *oldptr; 01371 oldptr = process_buf + strlen(process_buf); 01372 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01373 CB_ADD(&comment_buffer, ";"); 01374 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1); 01375 } 01376 01377 memmove(oldptr, new_buf, strlen(new_buf) + 1); 01378 new_buf = oldptr; 01379 } else 01380 process_buf = new_buf; 01381 } 01382 } else { 01383 if (!comment) { 01384 /* If ; is found, and we are not nested in a comment, 01385 we immediately stop all comment processing */ 01386 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01387 CB_ADD(&lline_buffer, comment_p); 01388 } 01389 *comment_p = '\0'; 01390 new_buf = comment_p; 01391 } else 01392 new_buf = comment_p + 1; 01393 } 01394 } 01395 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) { 01396 CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */ 01397 } 01398 01399 if (process_buf) { 01400 char *buffer = ast_strip(process_buf); 01401 if (!ast_strlen_zero(buffer)) { 01402 if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) { 01403 cfg = NULL; 01404 break; 01405 } 01406 } 01407 } 01408 } 01409 } 01410 /* end of file-- anything in a comment buffer? */ 01411 if (last_cat) { 01412 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used ) { 01413 if (lline_buffer && lline_buffer->used) { 01414 CB_ADD(&comment_buffer, lline_buffer->str); /* add the current lline buffer to the comment buffer */ 01415 lline_buffer->used = 0; /* erase the lline buffer */ 01416 } 01417 last_cat->trailing = ALLOC_COMMENT(comment_buffer); 01418 } 01419 } else if (last_var) { 01420 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used ) { 01421 if (lline_buffer && lline_buffer->used) { 01422 CB_ADD(&comment_buffer, lline_buffer->str); /* add the current lline buffer to the comment buffer */ 01423 lline_buffer->used = 0; /* erase the lline buffer */ 01424 } 01425 last_var->trailing = ALLOC_COMMENT(comment_buffer); 01426 } 01427 } else { 01428 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used) { 01429 ast_debug(1, "Nothing to attach comments to, discarded: %s\n", comment_buffer->str); 01430 } 01431 } 01432 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01433 CB_RESET(comment_buffer, lline_buffer); 01434 01435 fclose(f); 01436 } while (0); 01437 if (comment) { 01438 ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]); 01439 } 01440 #ifdef AST_INCLUDE_GLOB 01441 if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED) 01442 break; 01443 } 01444 globfree(&globbuf); 01445 } 01446 } 01447 #endif 01448 01449 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01450 if (comment_buffer) 01451 ast_free(comment_buffer); 01452 if (lline_buffer) 01453 ast_free(lline_buffer); 01454 comment_buffer = NULL; 01455 lline_buffer = NULL; 01456 } 01457 01458 if (count == 0) 01459 return NULL; 01460 01461 return cfg; 01462 }
int config_text_file_save | ( | const char * | configfile, | |
const struct ast_config * | cfg, | |||
const char * | generator | |||
) |
Definition at line 1579 of file config.c.
References ao2_container_alloc, ao2_ref, ast_debug, AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_verb, ast_comment::cmt, errno, ast_config_include::exec, ast_config_include::exec_file, f, 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_category::lineno, ast_category::name, ast_category_template_instance::name, ast_variable::name, ast_config_include::next, ast_comment::next, cache_file_include::next, ast_variable::next, ast_category::next, option_debug, ast_config_include::output, ast_category::precomments, ast_config::root, ast_category::root, ast_category::sameline, set_fn(), ast_category::template_instances, ast_category::trailing, ast_variable::value, and var.
Referenced by action_updateconfig(), vm_change_password(), and vm_forwardoptions().
01580 { 01581 FILE *f; 01582 char fn[256]; 01583 struct ast_variable *var; 01584 struct ast_category *cat; 01585 struct ast_comment *cmt; 01586 struct ast_config_include *incl; 01587 int blanklines = 0; 01588 struct ao2_container *fileset = ao2_container_alloc(180000, hash_string, hashtab_compare_strings); 01589 struct inclfile *fi = 0; 01590 01591 /* reset all the output flags, in case this isn't our first time saving this data */ 01592 01593 for (incl=cfg->includes; incl; incl = incl->next) 01594 incl->output = 0; 01595 01596 /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions) 01597 are all truncated to zero bytes and have that nice header*/ 01598 01599 for (incl=cfg->includes; incl; incl = incl->next) 01600 { 01601 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*/ 01602 FILE *f1; 01603 01604 set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset, &fi); /* normally, fn is just set to incl->included_file, prepended with config dir if relative */ 01605 f1 = fopen(fn,"w"); 01606 if (f1) { 01607 gen_header(f1, configfile, fn, generator); 01608 fclose(f1); /* this should zero out the file */ 01609 } else { 01610 ast_debug(1, "Unable to open for writing: %s\n", fn); 01611 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01612 } 01613 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01614 fi = 0; 01615 } 01616 } 01617 01618 set_fn(fn, sizeof(fn), 0, configfile, fileset, &fi); /* just set fn to absolute ver of configfile */ 01619 #ifdef __CYGWIN__ 01620 if ((f = fopen(fn, "w+"))) { 01621 #else 01622 if ((f = fopen(fn, "w"))) { 01623 #endif 01624 ast_verb(2, "Saving '%s': ", fn); 01625 gen_header(f, configfile, fn, generator); 01626 cat = cfg->root; 01627 fclose(f); 01628 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01629 01630 /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */ 01631 /* since each var, cat, and associated comments can come from any file, we have to be 01632 mobile, and open each file, print, and close it on an entry-by-entry basis */ 01633 01634 while (cat) { 01635 set_fn(fn, sizeof(fn), cat->file, configfile, fileset, &fi); 01636 f = fopen(fn, "a"); 01637 if (!f) 01638 { 01639 ast_debug(1, "Unable to open for writing: %s\n", fn); 01640 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01641 ao2_ref(fileset, -1); 01642 return -1; 01643 } 01644 01645 /* dump any includes that happen before this category header */ 01646 for (incl=cfg->includes; incl; incl = incl->next) { 01647 if (strcmp(incl->include_location_file, cat->file) == 0){ 01648 if (cat->lineno > incl->include_location_lineno && !incl->output) { 01649 if (incl->exec) 01650 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01651 else 01652 fprintf(f,"#include \"%s\"\n", incl->included_file); 01653 incl->output = 1; 01654 } 01655 } 01656 } 01657 01658 insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno); 01659 /* Dump section with any appropriate comment */ 01660 for (cmt = cat->precomments; cmt; cmt=cmt->next) { 01661 char *cmtp = cmt->cmt; 01662 while (*cmtp == ';' && *(cmtp+1) == '!') { 01663 char *cmtp2 = strchr(cmtp+1, '\n'); 01664 if (cmtp2) 01665 cmtp = cmtp2+1; 01666 else cmtp = 0; 01667 } 01668 if (cmtp) 01669 fprintf(f,"%s", cmtp); 01670 } 01671 fprintf(f, "[%s]", cat->name); 01672 if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) { 01673 fprintf(f, "("); 01674 if (cat->ignored) { 01675 fprintf(f, "!"); 01676 } 01677 if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) { 01678 fprintf(f, ","); 01679 } 01680 if (!AST_LIST_EMPTY(&cat->template_instances)) { 01681 struct ast_category_template_instance *x; 01682 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01683 fprintf(f,"%s",x->name); 01684 if (x != AST_LIST_LAST(&cat->template_instances)) 01685 fprintf(f,","); 01686 } 01687 } 01688 fprintf(f, ")"); 01689 } 01690 for(cmt = cat->sameline; cmt; cmt=cmt->next) 01691 { 01692 fprintf(f,"%s", cmt->cmt); 01693 } 01694 if (!cat->sameline) 01695 fprintf(f,"\n"); 01696 for (cmt = cat->trailing; cmt; cmt=cmt->next) { 01697 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01698 fprintf(f,"%s", cmt->cmt); 01699 } 01700 fclose(f); 01701 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01702 fi = 0; 01703 01704 var = cat->root; 01705 while (var) { 01706 struct ast_category_template_instance *x; 01707 int found = 0; 01708 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01709 struct ast_variable *v; 01710 for (v = x->inst->root; v; v = v->next) { 01711 if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) { 01712 found = 1; 01713 break; 01714 } 01715 } 01716 if (found) 01717 break; 01718 } 01719 if (found) { 01720 var = var->next; 01721 continue; 01722 } 01723 set_fn(fn, sizeof(fn), var->file, configfile, fileset, &fi); 01724 f = fopen(fn, "a"); 01725 if (!f) 01726 { 01727 ast_debug(1, "Unable to open for writing: %s\n", fn); 01728 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01729 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01730 fi = 0; 01731 ao2_ref(fileset, -1); 01732 return -1; 01733 } 01734 01735 /* dump any includes that happen before this category header */ 01736 for (incl=cfg->includes; incl; incl = incl->next) { 01737 if (strcmp(incl->include_location_file, var->file) == 0){ 01738 if (var->lineno > incl->include_location_lineno && !incl->output) { 01739 if (incl->exec) 01740 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01741 else 01742 fprintf(f,"#include \"%s\"\n", incl->included_file); 01743 incl->output = 1; 01744 } 01745 } 01746 } 01747 01748 insert_leading_blank_lines(f, fi, var->precomments, var->lineno); 01749 for (cmt = var->precomments; cmt; cmt=cmt->next) { 01750 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01751 fprintf(f,"%s", cmt->cmt); 01752 } 01753 if (var->sameline) 01754 fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt); 01755 else 01756 fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value); 01757 for (cmt = var->trailing; cmt; cmt=cmt->next) { 01758 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01759 fprintf(f,"%s", cmt->cmt); 01760 } 01761 if (var->blanklines) { 01762 blanklines = var->blanklines; 01763 while (blanklines--) 01764 fprintf(f, "\n"); 01765 } 01766 01767 fclose(f); 01768 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01769 fi = 0; 01770 01771 var = var->next; 01772 } 01773 cat = cat->next; 01774 } 01775 if (!option_debug) 01776 ast_verb(2, "Saved\n"); 01777 } else { 01778 ast_debug(1, "Unable to open for writing: %s\n", fn); 01779 ast_verb(2, "Unable to write (%s)", strerror(errno)); 01780 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01781 ao2_ref(fileset, -1); 01782 return -1; 01783 } 01784 01785 /* Now, for files with trailing #include/#exec statements, 01786 we have to make sure every entry is output */ 01787 01788 for (incl=cfg->includes; incl; incl = incl->next) { 01789 if (!incl->output) { 01790 /* open the respective file */ 01791 set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset, &fi); 01792 f = fopen(fn, "a"); 01793 if (!f) 01794 { 01795 ast_debug(1, "Unable to open for writing: %s\n", fn); 01796 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01797 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01798 fi = 0; 01799 ao2_ref(fileset, -1); 01800 return -1; 01801 } 01802 01803 /* output the respective include */ 01804 if (incl->exec) 01805 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01806 else 01807 fprintf(f,"#include \"%s\"\n", incl->included_file); 01808 fclose(f); 01809 incl->output = 1; 01810 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01811 fi = 0; 01812 } 01813 } 01814 ao2_ref(fileset, -1); /* this should destroy the hash container */ 01815 01816 return 0; 01817 }
static int count_linefeeds | ( | char * | str | ) | [static] |
static int count_linefeeds_in_comments | ( | struct ast_comment * | x | ) | [static] |
Definition at line 1550 of file config.c.
References ast_comment::cmt, count_linefeeds(), and ast_comment::next.
Referenced by insert_leading_blank_lines().
01551 { 01552 int count = 0; 01553 01554 while (x) { 01555 count += count_linefeeds(x->cmt); 01556 x = x->next; 01557 } 01558 return count; 01559 }
static struct ast_config_engine* find_engine | ( | const char * | family, | |
char * | database, | |||
int | dbsiz, | |||
char * | table, | |||
int | tabsiz | |||
) | [static] |
Find realtime engine for realtime family.
Definition at line 1980 of file config.c.
References ast_copy_string(), ast_mutex_lock(), config_lock, config_maps, and map.
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_speech_new(), ast_speech_register(), ast_store_realtime(), ast_unload_realtime(), and ast_update_realtime().
01981 { 01982 struct ast_config_engine *eng, *ret = NULL; 01983 struct ast_config_map *map; 01984 01985 ast_mutex_lock(&config_lock); 01986 01987 for (map = config_maps; map; map = map->next) { 01988 if (!strcasecmp(family, map->name)) { 01989 if (database) 01990 ast_copy_string(database, map->database, dbsiz); 01991 if (table) 01992 ast_copy_string(table, map->table ? map->table : family, tabsiz); 01993 break; 01994 } 01995 } 01996 01997 /* Check if the required driver (engine) exist */ 01998 if (map) { 01999 for (eng = config_engine_list; !ret && eng; eng = eng->next) { 02000 if (!strcasecmp(eng->name, map->driver)) 02001 ret = eng; 02002 } 02003 } 02004 02005 ast_mutex_unlock(&config_lock); 02006 02007 /* if we found a mapping, but the engine is not available, then issue a warning */ 02008 if (map && !ret) 02009 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver); 02010 02011 return ret; 02012 }
static void gen_header | ( | FILE * | f1, | |
const char * | configfile, | |||
const char * | fn, | |||
const char * | generator | |||
) | [static] |
Definition at line 1485 of file config.c.
References ast_copy_string().
Referenced by config_text_file_save().
01486 { 01487 char date[256]=""; 01488 time_t t; 01489 01490 time(&t); 01491 ast_copy_string(date, ctime(&t), sizeof(date)); 01492 01493 fprintf(f1, ";!\n"); 01494 fprintf(f1, ";! Automatically generated configuration file\n"); 01495 if (strcmp(configfile, fn)) 01496 fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn); 01497 else 01498 fprintf(f1, ";! Filename: %s\n", configfile); 01499 fprintf(f1, ";! Generator: %s\n", generator); 01500 fprintf(f1, ";! Creation Date: %s", date); 01501 fprintf(f1, ";!\n"); 01502 }
static char* handle_cli_config_list | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2492 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, cache_file_mtime::list, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.
02493 { 02494 struct cache_file_mtime *cfmtime; 02495 02496 switch (cmd) { 02497 case CLI_INIT: 02498 e->command = "config list"; 02499 e->usage = 02500 "Usage: config list\n" 02501 " Show all modules that have loaded a configuration file\n"; 02502 return NULL; 02503 case CLI_GENERATE: 02504 return NULL; 02505 } 02506 02507 AST_LIST_LOCK(&cfmtime_head); 02508 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02509 ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename); 02510 } 02511 AST_LIST_UNLOCK(&cfmtime_head); 02512 02513 return CLI_SUCCESS; 02514 }
static char* handle_cli_config_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2430 of file config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli_command(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strlen_zero(), buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, cache_file_mtime::list, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.
02431 { 02432 struct cache_file_mtime *cfmtime; 02433 char *prev = "", *completion_value = NULL; 02434 int wordlen, which = 0; 02435 02436 switch (cmd) { 02437 case CLI_INIT: 02438 e->command = "config reload"; 02439 e->usage = 02440 "Usage: config reload <filename.conf>\n" 02441 " Reloads all modules that reference <filename.conf>\n"; 02442 return NULL; 02443 case CLI_GENERATE: 02444 if (a->pos > 2) { 02445 return NULL; 02446 } 02447 02448 wordlen = strlen(a->word); 02449 02450 AST_LIST_LOCK(&cfmtime_head); 02451 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02452 /* Skip duplicates - this only works because the list is sorted by filename */ 02453 if (strcmp(cfmtime->filename, prev) == 0) { 02454 continue; 02455 } 02456 02457 /* Core configs cannot be reloaded */ 02458 if (ast_strlen_zero(cfmtime->who_asked)) { 02459 continue; 02460 } 02461 02462 if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) { 02463 completion_value = ast_strdup(cfmtime->filename); 02464 break; 02465 } 02466 02467 /* Otherwise save that we've seen this filename */ 02468 prev = cfmtime->filename; 02469 } 02470 AST_LIST_UNLOCK(&cfmtime_head); 02471 02472 return completion_value; 02473 } 02474 02475 if (a->argc != 3) { 02476 return CLI_SHOWUSAGE; 02477 } 02478 02479 AST_LIST_LOCK(&cfmtime_head); 02480 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02481 if (!strcmp(cfmtime->filename, a->argv[2])) { 02482 char *buf = alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1); 02483 sprintf(buf, "module reload %s", cfmtime->who_asked); 02484 ast_cli_command(a->fd, buf); 02485 } 02486 } 02487 AST_LIST_UNLOCK(&cfmtime_head); 02488 02489 return CLI_SUCCESS; 02490 }
static char* handle_cli_core_show_config_mappings | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2391 of file config.c.
References ast_cli(), ast_mutex_lock(), CLI_GENERATE, CLI_INIT, ast_cli_entry::command, config_engine_list, config_lock, config_maps, ast_cli_args::fd, map, ast_config_engine::name, ast_config_engine::next, and ast_cli_entry::usage.
02392 { 02393 struct ast_config_engine *eng; 02394 struct ast_config_map *map; 02395 02396 switch (cmd) { 02397 case CLI_INIT: 02398 e->command = "core show config mappings"; 02399 e->usage = 02400 "Usage: core show config mappings\n" 02401 " Shows the filenames to config engines.\n"; 02402 return NULL; 02403 case CLI_GENERATE: 02404 return NULL; 02405 } 02406 02407 ast_mutex_lock(&config_lock); 02408 02409 if (!config_engine_list) { 02410 ast_cli(a->fd, "No config mappings found.\n"); 02411 } else { 02412 ast_cli(a->fd, "\n\n"); 02413 for (eng = config_engine_list; eng; eng = eng->next) { 02414 ast_cli(a->fd, "\nConfig Engine: %s\n", eng->name); 02415 for (map = config_maps; map; map = map->next) { 02416 if (!strcasecmp(map->driver, eng->name)) { 02417 ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database, 02418 map->table ? map->table : map->name); 02419 } 02420 } 02421 } 02422 ast_cli(a->fd,"\n\n"); 02423 } 02424 02425 ast_mutex_unlock(&config_lock); 02426 02427 return CLI_SUCCESS; 02428 }
static int hash_string | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 151 of file config.c.
Referenced by config_text_file_save().
00152 { 00153 char *str = ((struct inclfile*)obj)->fname; 00154 int total; 00155 00156 for (total=0; *str; str++) { 00157 unsigned int tmp = total; 00158 total <<= 1; /* multiply by 2 */ 00159 total += tmp; /* multiply by 3 */ 00160 total <<= 2; /* multiply by 12 */ 00161 total += tmp; /* multiply by 13 */ 00162 00163 total += ((unsigned int)(*str)); 00164 } 00165 if (total < 0) 00166 total = -total; 00167 return total; 00168 }
static int hashtab_compare_strings | ( | void * | a, | |
void * | b, | |||
int | flags | |||
) | [static] |
Definition at line 170 of file config.c.
References CMP_MATCH, CMP_STOP, and inclfile::fname.
Referenced by config_text_file_save().
00171 { 00172 const struct inclfile *ae = a, *be = b; 00173 return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0; 00174 }
static void inclfile_destroy | ( | void * | obj | ) | [static] |
static void inherit_category | ( | struct ast_category * | new, | |
const struct ast_category * | base | |||
) | [static] |
Definition at line 670 of file config.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_variable_append(), ast_category_template_instance::inst, ast_category::name, ast_category_template_instance::name, cache_file_include::next, ast_category::root, ast_category::template_instances, var, and variable_clone().
Referenced by process_text_line().
00671 { 00672 struct ast_variable *var; 00673 struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance)); 00674 00675 strcpy(x->name, base->name); 00676 x->inst = base; 00677 AST_LIST_INSERT_TAIL(&new->template_instances, x, next); 00678 for (var = base->root; var; var = var->next) 00679 ast_variable_append(new, variable_clone(var)); 00680 }
static int init_appendbuf | ( | void * | data | ) | [static] |
Definition at line 101 of file config.c.
References ast_str_create(), and str.
00102 { 00103 struct ast_str **str = data; 00104 *str = ast_str_create(16); 00105 return *str ? 0 : -1; 00106 }
static void insert_leading_blank_lines | ( | FILE * | fp, | |
struct inclfile * | fi, | |||
struct ast_comment * | precomments, | |||
int | lineno | |||
) | [static] |
Definition at line 1561 of file config.c.
References count_linefeeds_in_comments(), and inclfile::lineno.
Referenced by config_text_file_save().
01562 { 01563 int precomment_lines = count_linefeeds_in_comments(precomments); 01564 int i; 01565 01566 /* I don't have to worry about those ;! comments, they are 01567 stored in the precomments, but not printed back out. 01568 I did have to make sure that comments following 01569 the ;! header comments were not also deleted in the process */ 01570 if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */ 01571 return; 01572 } 01573 for (i=fi->lineno; i<lineno - precomment_lines; i++) { 01574 fprintf(fp,"\n"); 01575 } 01576 fi->lineno = lineno+1; /* Advance the file lineno */ 01577 }
static void move_variables | ( | struct ast_category * | old, | |
struct ast_category * | new | |||
) | [static] |
Definition at line 464 of file config.c.
References ast_variable_append(), ast_category::root, and var.
Referenced by process_text_line().
00465 { 00466 struct ast_variable *var = old->root; 00467 00468 old->root = NULL; 00469 /* we can just move the entire list in a single op */ 00470 ast_variable_append(new, var); 00471 }
static struct ast_category* next_available_category | ( | struct ast_category * | cat | ) | [static] |
Definition at line 600 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 931 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_set(), 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, LOG_ERROR, LOG_WARNING, move_variables(), ast_category::name, ast_variable::object, ast_variable::precomments, ast_category::precomments, S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), and var.
Referenced by config_text_file_load().
00937 { 00938 char *c; 00939 char *cur = buf; 00940 struct ast_variable *v; 00941 char cmd[512], exec_file[512]; 00942 00943 /* Actually parse the entry */ 00944 if (cur[0] == '[') { /* A category header */ 00945 /* format is one of the following: 00946 * [foo] define a new category named 'foo' 00947 * [foo](!) define a new template category named 'foo' 00948 * [foo](+) append to category 'foo', error if foo does not exist. 00949 * [foo](a) define a new category and inherit from template a. 00950 * You can put a comma-separated list of templates and '!' and '+' 00951 * between parentheses, with obvious meaning. 00952 */ 00953 struct ast_category *newcat = NULL; 00954 char *catname; 00955 00956 c = strchr(cur, ']'); 00957 if (!c) { 00958 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); 00959 return -1; 00960 } 00961 *c++ = '\0'; 00962 cur++; 00963 if (*c++ != '(') 00964 c = NULL; 00965 catname = cur; 00966 if (!(*cat = newcat = ast_category_new(catname, 00967 S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile), 00968 lineno))) { 00969 return -1; 00970 } 00971 (*cat)->lineno = lineno; 00972 *last_var = 0; 00973 *last_cat = newcat; 00974 00975 /* add comments */ 00976 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00977 newcat->precomments = ALLOC_COMMENT(comment_buffer); 00978 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00979 newcat->sameline = ALLOC_COMMENT(lline_buffer); 00980 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00981 CB_RESET(comment_buffer, lline_buffer); 00982 00983 /* If there are options or categories to inherit from, process them now */ 00984 if (c) { 00985 if (!(cur = strchr(c, ')'))) { 00986 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile); 00987 return -1; 00988 } 00989 *cur = '\0'; 00990 while ((cur = strsep(&c, ","))) { 00991 if (!strcasecmp(cur, "!")) { 00992 (*cat)->ignored = 1; 00993 } else if (!strcasecmp(cur, "+")) { 00994 *cat = category_get(cfg, catname, 1); 00995 if (!(*cat)) { 00996 if (newcat) 00997 ast_category_destroy(newcat); 00998 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile); 00999 return -1; 01000 } 01001 if (newcat) { 01002 move_variables(newcat, *cat); 01003 ast_category_destroy(newcat); 01004 newcat = NULL; 01005 } 01006 } else { 01007 struct ast_category *base; 01008 01009 base = category_get(cfg, cur, 1); 01010 if (!base) { 01011 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile); 01012 return -1; 01013 } 01014 inherit_category(*cat, base); 01015 } 01016 } 01017 } 01018 if (newcat) 01019 ast_category_append(cfg, *cat); 01020 } else if (cur[0] == '#') { /* A directive - #include or #exec */ 01021 char *cur2; 01022 char real_inclusion_name[256]; 01023 struct ast_config_include *inclu; 01024 int do_include = 0; /* otherwise, it is exec */ 01025 01026 cur++; 01027 c = cur; 01028 while (*c && (*c > 32)) c++; 01029 if (*c) { 01030 *c = '\0'; 01031 /* Find real argument */ 01032 c = ast_skip_blanks(c + 1); 01033 if (!(*c)) 01034 c = NULL; 01035 } else 01036 c = NULL; 01037 if (!strcasecmp(cur, "include")) { 01038 do_include = 1; 01039 } else if (!strcasecmp(cur, "exec")) { 01040 if (!ast_opt_exec_includes) { 01041 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n"); 01042 return 0; /* XXX is this correct ? or we should return -1 ? */ 01043 } 01044 } else { 01045 ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile); 01046 return 0; /* XXX is this correct ? or we should return -1 ? */ 01047 } 01048 01049 if (c == NULL) { 01050 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 01051 do_include ? "include" : "exec", 01052 do_include ? "filename" : "/path/to/executable", 01053 lineno, 01054 configfile); 01055 return 0; /* XXX is this correct ? or we should return -1 ? */ 01056 } 01057 01058 /* Strip off leading and trailing "'s and <>'s */ 01059 while ((*c == '<') || (*c == '>') || (*c == '\"')) c++; 01060 /* Get rid of leading mess */ 01061 cur = c; 01062 cur2 = cur; 01063 while (!ast_strlen_zero(cur)) { 01064 c = cur + strlen(cur) - 1; 01065 if ((*c == '>') || (*c == '<') || (*c == '\"')) 01066 *c = '\0'; 01067 else 01068 break; 01069 } 01070 /* #exec </path/to/executable> 01071 We create a tmp file, then we #include it, then we delete it. */ 01072 if (!do_include) { 01073 struct timeval now = ast_tvnow(); 01074 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01075 config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked); 01076 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self()); 01077 snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file); 01078 ast_safe_system(cmd); 01079 cur = exec_file; 01080 } else { 01081 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01082 config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked); 01083 exec_file[0] = '\0'; 01084 } 01085 /* A #include */ 01086 /* record this inclusion */ 01087 inclu = ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name)); 01088 01089 do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0; 01090 if (!ast_strlen_zero(exec_file)) 01091 unlink(exec_file); 01092 if (!do_include) { 01093 ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur); 01094 return -1; 01095 } 01096 /* XXX otherwise what ? the default return is 0 anyways */ 01097 01098 } else { 01099 /* Just a line (variable = value) */ 01100 int object = 0; 01101 if (!(*cat)) { 01102 ast_log(LOG_WARNING, 01103 "parse error: No category context for line %d of %s\n", lineno, configfile); 01104 return -1; 01105 } 01106 c = strchr(cur, '='); 01107 01108 if (c && c > cur && (*(c - 1) == '+')) { 01109 struct ast_variable *var, *replace = NULL; 01110 struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str)); 01111 01112 if (!str || !*str) { 01113 return -1; 01114 } 01115 01116 *(c - 1) = '\0'; 01117 c++; 01118 cur = ast_strip(cur); 01119 01120 /* Must iterate through category until we find last variable of same name (since there could be multiple) */ 01121 for (var = ast_category_first(*cat); var; var = var->next) { 01122 if (!strcmp(var->name, cur)) { 01123 replace = var; 01124 } 01125 } 01126 01127 if (!replace) { 01128 /* Nothing to replace; just set a variable normally. */ 01129 goto set_new_variable; 01130 } 01131 01132 ast_str_set(str, 0, "%s", replace->value); 01133 ast_str_append(str, 0, "%s", c); 01134 ast_variable_update(*cat, replace->name, ast_strip((*str)->str), replace->value, object); 01135 } else if (c) { 01136 *c = 0; 01137 c++; 01138 /* Ignore > in => */ 01139 if (*c== '>') { 01140 object = 1; 01141 c++; 01142 } 01143 set_new_variable: 01144 if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) { 01145 v->lineno = lineno; 01146 v->object = object; 01147 *last_cat = 0; 01148 *last_var = v; 01149 /* Put and reset comments */ 01150 v->blanklines = 0; 01151 ast_variable_append(*cat, v); 01152 /* add comments */ 01153 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01154 v->precomments = ALLOC_COMMENT(comment_buffer); 01155 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01156 v->sameline = ALLOC_COMMENT(lline_buffer); 01157 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01158 CB_RESET(comment_buffer, lline_buffer); 01159 01160 } else { 01161 return -1; 01162 } 01163 } else { 01164 ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); 01165 } 01166 } 01167 return 0; 01168 }
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 1867 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(), buf, clear_config_maps(), config, ast_flags::flags, LOG_WARNING, ast_config::max_include_level, ast_variable::name, ast_variable::next, strsep(), table, and ast_variable::value.
Referenced by main().
01868 { 01869 struct ast_config *config, *configtmp; 01870 struct ast_variable *v; 01871 char *driver, *table, *database, *stringp, *tmp; 01872 struct ast_flags flags = { 0 }; 01873 01874 clear_config_maps(); 01875 01876 configtmp = ast_config_new(); 01877 configtmp->max_include_level = 1; 01878 config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig"); 01879 if (!config) { 01880 ast_config_destroy(configtmp); 01881 return 0; 01882 } 01883 01884 for (v = ast_variable_browse(config, "settings"); v; v = v->next) { 01885 char buf[512]; 01886 ast_copy_string(buf, v->value, sizeof(buf)); 01887 stringp = buf; 01888 driver = strsep(&stringp, ","); 01889 01890 if ((tmp = strchr(stringp, '\"'))) 01891 stringp = tmp; 01892 01893 /* check if the database text starts with a double quote */ 01894 if (*stringp == '"') { 01895 stringp++; 01896 database = strsep(&stringp, "\""); 01897 strsep(&stringp, ","); 01898 } else { 01899 /* apparently this text has no quotes */ 01900 database = strsep(&stringp, ","); 01901 } 01902 01903 table = strsep(&stringp, ","); 01904 01905 if (!strcmp(v->name, extconfig_conf)) { 01906 ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf); 01907 continue; 01908 } 01909 01910 if (!strcmp(v->name, "asterisk.conf")) { 01911 ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n"); 01912 continue; 01913 } 01914 01915 if (!strcmp(v->name, "logger.conf")) { 01916 ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n"); 01917 continue; 01918 } 01919 01920 if (!driver || !database) 01921 continue; 01922 if (!strcasecmp(v->name, "sipfriends")) { 01923 ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sipusers and sippeers, though they can point to the same table.\n"); 01924 append_mapping("sipusers", driver, database, table ? table : "sipfriends"); 01925 append_mapping("sippeers", driver, database, table ? table : "sipfriends"); 01926 } else if (!strcasecmp(v->name, "iaxfriends")) { 01927 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"); 01928 append_mapping("iaxusers", driver, database, table ? table : "iaxfriends"); 01929 append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends"); 01930 } else 01931 append_mapping(v->name, driver, database, table); 01932 } 01933 01934 ast_config_destroy(config); 01935 return 0; 01936 }
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 2522 of file config.c.
References ast_cli_register_multiple(), and cli_config.
Referenced by main().
02523 { 02524 ast_cli_register_multiple(cli_config, sizeof(cli_config) / sizeof(struct ast_cli_entry)); 02525 return 0; 02526 }
static void set_fn | ( | char * | fn, | |
int | fn_size, | |||
const char * | file, | |||
const char * | configfile, | |||
struct ao2_container * | fileset, | |||
struct inclfile ** | fi | |||
) | [static] |
Definition at line 1513 of file config.c.
References ao2_alloc, ao2_find, ao2_link, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_strdup, inclfile::fname, inclfile_destroy(), inclfile::lineno, and OBJ_POINTER.
Referenced by config_text_file_save().
01514 { 01515 struct inclfile lookup; 01516 01517 if (!file || file[0] == 0) { 01518 if (configfile[0] == '/') 01519 ast_copy_string(fn, configfile, fn_size); 01520 else 01521 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile); 01522 } else if (file[0] == '/') 01523 ast_copy_string(fn, file, fn_size); 01524 else 01525 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file); 01526 lookup.fname = fn; 01527 *fi = ao2_find(fileset, &lookup, OBJ_POINTER); 01528 if (!(*fi)) { 01529 /* set up a file scratch pad */ 01530 struct inclfile *fx = ao2_alloc(sizeof(struct inclfile), inclfile_destroy); 01531 fx->fname = ast_strdup(fn); 01532 fx->lineno = 1; 01533 *fi = fx; 01534 ao2_link(fileset, fx); 01535 } 01536 }
static struct ast_variable* variable_clone | ( | const struct ast_variable * | old | ) | [static] |
Definition at line 450 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().
00451 { 00452 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file); 00453 00454 if (new) { 00455 new->lineno = old->lineno; 00456 new->object = old->object; 00457 new->blanklines = old->blanklines; 00458 /* TODO: clone comments? */ 00459 } 00460 00461 return new; 00462 }
struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_appendbuf , .custom_init = init_appendbuf , } [static] |
struct ast_cli_entry cli_config[] [static] |
Initial value:
{ { .handler = handle_cli_core_show_config_mappings , .summary = "Display config mappings (file names to config engines)" ,__VA_ARGS__ }, { .handler = handle_cli_config_reload , .summary = "Force a reload on modules using a particular configuration file" ,__VA_ARGS__ }, { .handler = handle_cli_config_list , .summary = "Show all files that have loaded a configuration file" ,__VA_ARGS__ }, }
Definition at line 2516 of file config.c.
Referenced by register_config_cli().
struct ast_config_engine* config_engine_list [static] |
Definition at line 186 of file config.c.
Referenced by ast_config_engine_deregister(), ast_config_engine_register(), ast_config_internal_load(), and handle_cli_core_show_config_mappings().
ast_mutex_t config_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 185 of file config.c.
Referenced by ast_config_engine_deregister(), ast_config_engine_register(), clear_config_maps(), find_engine(), and handle_cli_core_show_config_mappings().
struct ast_config_map * config_maps [static] |
Referenced by append_mapping(), ast_realtime_enabled(), clear_config_maps(), find_engine(), and handle_cli_core_show_config_mappings().
char* extconfig_conf = "extconfig.conf" [static] |
struct ast_config_engine text_file_engine [static] |
Initial value:
{ .name = "text", .load_func = config_text_file_load, }
Definition at line 2014 of file config.c.
Referenced by ast_config_internal_load().