Configuration File Parser. More...
#include "asterisk.h"#include "asterisk/paths.h"#include "asterisk/network.h"#include <time.h>#include <sys/stat.h>#include <math.h>#include "asterisk/config.h"#include "asterisk/cli.h"#include "asterisk/lock.h"#include "asterisk/utils.h"#include "asterisk/channel.h"#include "asterisk/app.h"#include "asterisk/astobj2.h"#include "asterisk/strings.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_category |
| struct | ast_category_template_instance |
| struct | ast_comment |
| Structure to keep comments for rewriting configuration files. More... | |
| struct | ast_config |
| struct | ast_config_include |
| struct | ast_config_map |
| struct | cache_file_include |
| Hold the mtime for config files, so if we don't need to reread our config, don't. More... | |
| struct | cache_file_mtime |
| struct | cfmtime_head |
| struct | inclfile |
| struct | includes |
| struct | template_instance_list |
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 |
Enumerations | |
| enum | config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0, ATTRIBUTE_EXEC = 1 } |
Functions | |
| static void | __init_appendbuf (void) |
| static struct ast_comment * | ALLOC_COMMENT (struct ast_str *buffer) |
| static int | append_mapping (const char *name, const char *driver, const char *database, const char *table) |
| void | ast_category_append (struct ast_config *config, struct ast_category *category) |
| char * | ast_category_browse (struct ast_config *config, const char *prev) |
| Goes through categories. | |
| int | ast_category_delete (struct ast_config *cfg, const char *category) |
| void | ast_category_destroy (struct ast_category *cat) |
| struct ast_variable * | ast_category_detach_variables (struct ast_category *cat) |
| int | ast_category_empty (struct ast_config *cfg, const char *category) |
| Removes and destroys all variables within a category. | |
| int | ast_category_exist (const struct ast_config *config, const char *category_name) |
| Check for category duplicates. | |
| struct ast_variable * | ast_category_first (struct ast_category *cat) |
| given a pointer to a category, return the root variable. This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get()) | |
| struct ast_category * | ast_category_get (const struct ast_config *config, const char *category_name) |
| Retrieve a category if it exists. | |
| void | ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match) |
| Inserts new category. | |
| struct ast_category * | ast_category_new (const char *name, const char *in_file, int lineno) |
| Create a category structure. | |
| void | ast_category_rename (struct ast_category *cat, const char *name) |
| struct ast_variable * | ast_category_root (struct ast_config *config, char *cat) |
| returns the root ast_variable of a config | |
| int | ast_check_realtime (const char *family) |
| Check if realtime engine is configured for family. | |
| static void | ast_comment_destroy (struct ast_comment **comment) |
| void | ast_config_destroy (struct ast_config *cfg) |
| Destroys a config. | |
| int | ast_config_engine_deregister (struct ast_config_engine *del) |
| Deregister config engine. | |
| int | ast_config_engine_register (struct ast_config_engine *new) |
| Register config engine. | |
| struct ast_category * | ast_config_get_current_category (const struct ast_config *cfg) |
| Retrieve the current category name being built. API for backend configuration engines while building a configuration set. | |
| struct ast_config * | ast_config_internal_load (const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) |
| struct ast_config * | ast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags) |
| Load a config file. | |
| struct ast_config * | ast_config_new (void) |
| Create a new base configuration structure. | |
| const char * | ast_config_option (struct ast_config *cfg, const char *cat, const char *var) |
Retrieve a configuration variable within the configuration set. 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. | |
| int | ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator) |
| int | ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...) |
| Destroy realtime configuration. | |
| static void | ast_destroy_template_list (struct ast_category *cat) |
| struct ast_config_include * | ast_include_find (struct ast_config *conf, const char *included_file) |
| struct ast_config_include * | ast_include_new (struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size) |
| void | ast_include_rename (struct ast_config *conf, const char *from_file, const char *to_file) |
| static void | ast_includes_destroy (struct ast_config_include *incls) |
| struct ast_variable * | ast_load_realtime (const char *family,...) |
| Retrieve realtime configuration. | |
| struct ast_variable * | ast_load_realtime_all (const char *family,...) |
| static struct ast_variable * | ast_load_realtime_helper (const char *family, va_list ap) |
| struct ast_config * | ast_load_realtime_multientry (const char *family,...) |
| Retrieve realtime configuration. | |
| int | ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *p_result,...) |
| Helper function to parse arguments See documentation in config.h. | |
| 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_update2_realtime (const char *family,...) |
| Update realtime configuration. | |
| int | ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...) |
| Update realtime configuration. | |
| void | ast_variable_append (struct ast_category *category, struct ast_variable *variable) |
| struct ast_variable * | ast_variable_browse (const struct ast_config *config, const char *category) |
| Goes through variables 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) |
| struct ast_variable * | ast_variable_new (const char *name, const char *value, const char *filename) |
| const char * | ast_variable_retrieve (const struct ast_config *config, const char *category, const char *variable) |
| Gets a variable. | |
| int | ast_variable_update (struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object) |
| Update variable value within a config. | |
| void | ast_variables_destroy (struct ast_variable *v) |
| Free variable list. | |
| 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 |
Configuration File Parser.
Includes the Asterisk Realtime API - ARA See doc/realtime.txt and doc/extconfig.txt
Definition in file config.c.
| #define CB_SIZE 250 |
Definition at line 93 of file config.c.
Referenced by config_text_file_load().
| #define COMMENT_META ';' |
Definition at line 54 of file config.c.
Referenced by config_text_file_load().
| #define COMMENT_TAG '-' |
Definition at line 55 of file config.c.
Referenced by config_text_file_load().
| #define MAX_INCLUDE_LEVEL 10 |
Definition at line 175 of file config.c.
Referenced by ast_config_new().
| #define MAX_NESTED_COMMENTS 128 |
Definition at line 51 of file config.c.
Referenced by config_text_file_load().
Definition at line 856 of file config.c.
00856 { 00857 ATTRIBUTE_INCLUDE = 0, 00858 ATTRIBUTE_EXEC = 1, 00859 };
| static struct ast_comment* ALLOC_COMMENT | ( | struct ast_str * | buffer | ) | [static, read] |
Definition at line 117 of file config.c.
References ast_calloc, ast_str_buffer(), ast_str_strlen(), and ast_comment::cmt.
Referenced by config_text_file_load(), and process_text_line().
00118 { 00119 struct ast_comment *x = NULL; 00120 if (!buffer || !ast_str_strlen(buffer)) { 00121 return NULL; 00122 } 00123 if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) { 00124 strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */ 00125 } 00126 return x; 00127 }
| static int append_mapping | ( | const char * | name, | |
| const char * | driver, | |||
| const char * | database, | |||
| const char * | table | |||
| ) | [static] |
Definition at line 1846 of file config.c.
References ast_calloc, ast_verb, config_maps, ast_config_map::database, ast_config_map::driver, map, ast_config_map::name, ast_config_map::next, ast_config_map::stuff, and ast_config_map::table.
Referenced by read_config_maps().
01847 { 01848 struct ast_config_map *map; 01849 int length; 01850 01851 length = sizeof(*map); 01852 length += strlen(name) + 1; 01853 length += strlen(driver) + 1; 01854 length += strlen(database) + 1; 01855 if (table) 01856 length += strlen(table) + 1; 01857 01858 if (!(map = ast_calloc(1, length))) 01859 return -1; 01860 01861 map->name = map->stuff; 01862 strcpy(map->name, name); 01863 map->driver = map->name + strlen(map->name) + 1; 01864 strcpy(map->driver, driver); 01865 map->database = map->driver + strlen(map->driver) + 1; 01866 strcpy(map->database, database); 01867 if (table) { 01868 map->table = map->database + strlen(map->database) + 1; 01869 strcpy(map->table, table); 01870 } 01871 map->next = config_maps; 01872 01873 ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name); 01874 01875 config_maps = map; 01876 return 0; 01877 }
| void ast_category_append | ( | struct ast_config * | config, | |
| struct ast_category * | category | |||
| ) |
Definition at line 522 of file config.c.
References ast_config::current, ast_config::include_level, ast_category::include_level, ast_config::last, ast_category::next, and ast_config::root.
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().
00523 { 00524 if (config->last) 00525 config->last->next = category; 00526 else 00527 config->root = category; 00528 category->include_level = config->include_level; 00529 config->last = category; 00530 config->current = category; 00531 }
| 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 613 of file config.c.
References ast_config::last_browse, ast_category::name, ast_category::next, next_available_category(), and ast_config::root.
Referenced by __init_manager(), __queues_show(), action_getconfig(), action_getconfigjson(), action_listcategories(), aji_load_config(), ast_cli_perms_init(), complete_sipnotify(), config_load(), find_queue_by_name_rt(), find_realtime(), get_insecure_variable_from_config(), gtalk_load_config(), iax_provision_reload(), jingle_load_config(), load_config(), load_indications(), 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(), search_directory_sub(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().
00614 { 00615 struct ast_category *cat = NULL; 00616 00617 if (prev && config->last_browse && (config->last_browse->name == prev)) 00618 cat = config->last_browse->next; 00619 else if (!prev && config->root) 00620 cat = config->root; 00621 else if (prev) { 00622 for (cat = config->root; cat; cat = cat->next) { 00623 if (cat->name == prev) { 00624 cat = cat->next; 00625 break; 00626 } 00627 } 00628 if (!cat) { 00629 for (cat = config->root; cat; cat = cat->next) { 00630 if (!strcasecmp(cat->name, prev)) { 00631 cat = cat->next; 00632 break; 00633 } 00634 } 00635 } 00636 } 00637 00638 if (cat) 00639 cat = next_available_category(cat); 00640 00641 config->last_browse = cat; 00642 return (cat) ? cat->name : NULL; 00643 }
| int ast_category_delete | ( | struct ast_config * | cfg, | |
| const char * | category | |||
| ) |
Definition at line 766 of file config.c.
References ast_category_destroy(), ast_config::last, ast_category::next, and ast_config::root.
Referenced by handle_updates().
00767 { 00768 struct ast_category *prev=NULL, *cat; 00769 00770 cat = cfg->root; 00771 while (cat) { 00772 if (cat->name == category) { 00773 if (prev) { 00774 prev->next = cat->next; 00775 if (cat == cfg->last) 00776 cfg->last = prev; 00777 } else { 00778 cfg->root = cat->next; 00779 if (cat == cfg->last) 00780 cfg->last = NULL; 00781 } 00782 ast_category_destroy(cat); 00783 return 0; 00784 } 00785 prev = cat; 00786 cat = cat->next; 00787 } 00788 00789 prev = NULL; 00790 cat = cfg->root; 00791 while (cat) { 00792 if (!strcasecmp(cat->name, category)) { 00793 if (prev) { 00794 prev->next = cat->next; 00795 if (cat == cfg->last) 00796 cfg->last = prev; 00797 } else { 00798 cfg->root = cat->next; 00799 if (cat == cfg->last) 00800 cfg->last = NULL; 00801 } 00802 ast_category_destroy(cat); 00803 return 0; 00804 } 00805 prev = cat; 00806 cat = cat->next; 00807 } 00808 return -1; 00809 }
| void ast_category_destroy | ( | struct ast_category * | cat | ) |
Definition at line 561 of file config.c.
References ast_comment_destroy(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, free, ast_category::precomments, ast_category::root, ast_category::sameline, and ast_category::trailing.
Referenced by add_cfg_entry(), ast_category_delete(), ast_config_destroy(), process_text_line(), and realtime_multi_odbc().
00562 { 00563 ast_variables_destroy(cat->root); 00564 if (cat->file) { 00565 free(cat->file); 00566 cat->file = 0; 00567 } 00568 ast_comment_destroy(&cat->precomments); 00569 ast_comment_destroy(&cat->sameline); 00570 ast_comment_destroy(&cat->trailing); 00571 ast_destroy_template_list(cat); 00572 ast_free(cat); 00573 }
| struct ast_variable* ast_category_detach_variables | ( | struct ast_category * | cat | ) | [read] |
Definition at line 645 of file config.c.
References ast_category::last, and ast_category::root.
Referenced by realtime_switch_common().
00646 { 00647 struct ast_variable *v; 00648 00649 v = cat->root; 00650 cat->root = NULL; 00651 cat->last = NULL; 00652 00653 return v; 00654 }
| 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 811 of file config.c.
References ast_variables_destroy(), ast_category::last, ast_category::name, ast_category::next, ast_category::root, and ast_config::root.
Referenced by handle_updates().
00812 { 00813 struct ast_category *cat; 00814 00815 for (cat = cfg->root; cat; cat = cat->next) { 00816 if (!strcasecmp(cat->name, category)) 00817 continue; 00818 ast_variables_destroy(cat->root); 00819 cat->root = NULL; 00820 cat->last = NULL; 00821 return 0; 00822 } 00823 00824 return -1; 00825 }
| 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 517 of file config.c.
References ast_category_get().
00518 { 00519 return !!ast_category_get(config, category_name); 00520 }
| struct ast_variable* ast_category_first | ( | struct ast_category * | cat | ) | [read] |
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 599 of file config.c.
References ast_category::root.
Referenced by process_text_line().
00600 { 00601 return (cat) ? cat->root : NULL; 00602 }
| struct ast_category* ast_category_get | ( | const struct ast_config * | config, | |
| const char * | category_name | |||
| ) | [read] |
Retrieve a category if it exists.
| config | which config to use | |
| category_name | name of the category you're looking for This will search through the categories within a given config file for a match. |
| pointer | to category if found | |
| NULL | if not. |
Definition at line 512 of file config.c.
References category_get().
Referenced by ast_category_exist(), ast_category_root(), ast_variable_browse(), handle_updates(), realtime_directory(), realtime_switch_common(), vm_change_password(), and vm_forwardoptions().
00513 { 00514 return category_get(config, category_name, 0); 00515 }
| 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 533 of file config.c.
References ast_category::name, ast_category::next, and ast_config::root.
Referenced by handle_updates().
00534 { 00535 struct ast_category *cur_category; 00536 00537 if (!cat || !match) 00538 return; 00539 if (!strcasecmp(config->root->name, match)) { 00540 cat->next = config->root; 00541 config->root = cat; 00542 return; 00543 } 00544 for (cur_category = config->root; cur_category; cur_category = cur_category->next) { 00545 if (!strcasecmp(cur_category->next->name, match)) { 00546 cat->next = cur_category->next; 00547 cur_category->next = cat; 00548 break; 00549 } 00550 } 00551 }
| struct ast_category* ast_category_new | ( | const char * | name, | |
| const char * | in_file, | |||
| int | lineno | |||
| ) | [read] |
Create a category structure.
Definition at line 483 of file config.c.
References ast_calloc, ast_copy_string(), ast_category::file, ast_category::lineno, ast_category::name, 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().
00484 { 00485 struct ast_category *category; 00486 00487 if ((category = ast_calloc(1, sizeof(*category)))) 00488 ast_copy_string(category->name, name, sizeof(category->name)); 00489 category->file = strdup(in_file); 00490 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */ 00491 return category; 00492 }
| void ast_category_rename | ( | struct ast_category * | cat, | |
| const char * | name | |||
| ) |
Definition at line 656 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().
00657 { 00658 ast_copy_string(cat->name, name, sizeof(cat->name)); 00659 }
| struct ast_variable* ast_category_root | ( | struct ast_config * | config, | |
| char * | cat | |||
| ) | [read] |
returns the root ast_variable of a config
| config | pointer to an ast_config data structure | |
| cat | name of the category for which you want the root |
Returns the category specified
Definition at line 604 of file config.c.
References ast_category_get(), and ast_category::root.
Referenced by get_insecure_variable_from_config().
00605 { 00606 struct ast_category *category = ast_category_get(config, cat); 00607 00608 if (category) 00609 return category->root; 00610 return NULL; 00611 }
| 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 2147 of file config.c.
References ast_realtime_enabled(), and find_engine().
Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_queue_log(), close_mailbox(), 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().
02148 { 02149 struct ast_config_engine *eng; 02150 if (!ast_realtime_enabled()) { 02151 return 0; /* There are no engines at all so fail early */ 02152 } 02153 02154 eng = find_engine(family, NULL, 0, NULL, 0); 02155 if (eng) 02156 return 1; 02157 return 0; 02158 }
| static void ast_comment_destroy | ( | struct ast_comment ** | comment | ) | [static] |
Definition at line 385 of file config.c.
References ast_free, and ast_comment::next.
Referenced by ast_category_destroy(), and ast_variables_destroy().
00386 { 00387 struct ast_comment *n, *p; 00388 00389 for (p = *comment; p; p = n) { 00390 n = p->next; 00391 ast_free(p); 00392 } 00393 00394 *comment = NULL; 00395 }
| 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 827 of file config.c.
References ast_category_destroy(), ast_free, ast_includes_destroy(), ast_config::includes, ast_category::next, and ast_config::root.
Referenced by __ast_http_load(), __ast_http_post_load(), __ast_rtp_reload(), __ast_udptl_reload(), __init_manager(), __queues_show(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), aji_load_config(), ast_cli_perms_init(), ast_config_load2(), ast_readconfig(), ast_xmldoc_load_documentation(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_realtime(), handle_cli_dialplan_save(), iax_provision_reload(), init_logger_chain(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_realtime_queue(), load_rpt_vars(), make_email_file(), misdn_cfg_init(), 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(), read_config_maps(), realtime_directory(), realtime_multi_handler(), realtime_peer(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), run_startup_commands(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), smdi_load(), store_config(), tds_load_module(), unload_module(), update_realtime_members(), and vm_forwardoptions().
00828 { 00829 struct ast_category *cat, *catn; 00830 00831 if (!cfg) 00832 return; 00833 00834 ast_includes_destroy(cfg->includes); 00835 00836 cat = cfg->root; 00837 while (cat) { 00838 catn = cat; 00839 cat = cat->next; 00840 ast_category_destroy(catn); 00841 } 00842 ast_free(cfg); 00843 }
| int ast_config_engine_deregister | ( | struct ast_config_engine * | del | ) |
Deregister config engine.
| 0 | Always |
Definition at line 1969 of file config.c.
References ast_mutex_lock(), ast_mutex_unlock(), config_lock, last, and ast_config_engine::next.
Referenced by unload_module().
01970 { 01971 struct ast_config_engine *ptr, *last=NULL; 01972 01973 ast_mutex_lock(&config_lock); 01974 01975 for (ptr = config_engine_list; ptr; ptr=ptr->next) { 01976 if (ptr == del) { 01977 if (last) 01978 last->next = ptr->next; 01979 else 01980 config_engine_list = ptr->next; 01981 break; 01982 } 01983 last = ptr; 01984 } 01985 01986 ast_mutex_unlock(&config_lock); 01987 01988 return 0; 01989 }
| int ast_config_engine_register | ( | struct ast_config_engine * | newconfig | ) |
Register config engine.
| 1 | Always |
Definition at line 1950 of file config.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), config_lock, LOG_NOTICE, and ast_config_engine::next.
Referenced by load_module().
01951 { 01952 struct ast_config_engine *ptr; 01953 01954 ast_mutex_lock(&config_lock); 01955 01956 if (!config_engine_list) { 01957 config_engine_list = new; 01958 } else { 01959 for (ptr = config_engine_list; ptr->next; ptr=ptr->next); 01960 ptr->next = new; 01961 } 01962 01963 ast_mutex_unlock(&config_lock); 01964 ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name); 01965 01966 return 1; 01967 }
| struct ast_category* ast_config_get_current_category | ( | const struct ast_config * | cfg | ) | [read] |
Retrieve the current category name being built. API for backend configuration engines while building a configuration set.
Definition at line 845 of file config.c.
References ast_config::current.
Referenced by config_curl(), config_odbc(), and config_text_file_load().
00846 { 00847 return cfg->current; 00848 }
| struct ast_config* ast_config_internal_load | ( | const char * | filename, | |
| struct ast_config * | cfg, | |||
| struct ast_flags | flags, | |||
| const char * | suggested_include_file, | |||
| const char * | who_asked | |||
| ) | [read] |
Definition at line 2031 of file config.c.
References ast_log(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, db, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, and table.
Referenced by add_cfg_entry(), ast_config_load2(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), process_text_line(), and read_config_maps().
02032 { 02033 char db[256]; 02034 char table[256]; 02035 struct ast_config_engine *loader = &text_file_engine; 02036 struct ast_config *result; 02037 02038 /* The config file itself bumps include_level by 1 */ 02039 if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) { 02040 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level); 02041 return NULL; 02042 } 02043 02044 cfg->include_level++; 02045 02046 if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) { 02047 struct ast_config_engine *eng; 02048 02049 eng = find_engine(filename, db, sizeof(db), table, sizeof(table)); 02050 02051 02052 if (eng && eng->load_func) { 02053 loader = eng; 02054 } else { 02055 eng = find_engine("global", db, sizeof(db), table, sizeof(table)); 02056 if (eng && eng->load_func) 02057 loader = eng; 02058 } 02059 } 02060 02061 result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked); 02062 02063 if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED) 02064 result->include_level--; 02065 else if (result != CONFIG_STATUS_FILEINVALID) 02066 cfg->include_level--; 02067 02068 return result; 02069 }
| struct ast_config* ast_config_load2 | ( | const char * | filename, | |
| const char * | who_asked, | |||
| struct ast_flags | flags | |||
| ) | [read] |
Load a config file.
| filename | path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR 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 2071 of file config.c.
References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), CONFIG_STATUS_FILEINVALID, and CONFIG_STATUS_FILEUNCHANGED.
Referenced by __ast_http_load(), __ast_http_post_load(), __ast_rtp_reload(), __ast_udptl_reload(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_cli_perms_init(), ast_readconfig(), ast_xmldoc_load_documentation(), do_reload(), iax_provision_reload(), init_logger_chain(), load_config(), load_indications(), load_modules(), misdn_cfg_init(), private_enum_init(), and run_startup_commands().
02072 { 02073 struct ast_config *cfg; 02074 struct ast_config *result; 02075 02076 cfg = ast_config_new(); 02077 if (!cfg) 02078 return NULL; 02079 02080 result = ast_config_internal_load(filename, cfg, flags, "", who_asked); 02081 if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID) 02082 ast_config_destroy(cfg); 02083 02084 return result; 02085 }
| struct ast_config* ast_config_new | ( | void | ) | [read] |
Create a new base configuration structure.
Definition at line 673 of file config.c.
References ast_calloc, config, MAX_INCLUDE_LEVEL, and ast_config::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().
00674 { 00675 struct ast_config *config; 00676 00677 if ((config = ast_calloc(1, sizeof(*config)))) 00678 config->max_include_level = MAX_INCLUDE_LEVEL; 00679 return config; 00680 }
| 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 424 of file config.c.
References ast_variable_retrieve().
Referenced by load_config(), pbx_load_users(), and search_directory_sub().
00425 { 00426 const char *tmp; 00427 tmp = ast_variable_retrieve(cfg, cat, var); 00428 if (!tmp) { 00429 tmp = ast_variable_retrieve(cfg, "general", var); 00430 } 00431 return tmp; 00432 }
| 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 850 of file config.c.
References ast_config::current.
00851 { 00852 /* cast below is just to silence compiler warning about dropping "const" */ 00853 cfg->current = (struct ast_category *) cat; 00854 }
| int ast_config_text_file_save | ( | const char * | configfile, | |
| const struct ast_config * | cfg, | |||
| const char * | generator | |||
| ) |
Definition at line 1591 of file config.c.
References ao2_container_alloc, ao2_ref, ast_debug, AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_verb, ast_variable::blanklines, ast_comment::cmt, errno, ast_config_include::exec, ast_config_include::exec_file, f, ast_variable::file, ast_category::file, gen_header(), hash_string(), hashtab_compare_strings(), ast_category::ignored, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config::includes, insert_leading_blank_lines(), ast_category_template_instance::inst, ast_variable::lineno, ast_category::lineno, ast_variable::name, ast_category_template_instance::name, ast_category::name, ast_category::next, ast_variable::next, ast_comment::next, ast_config_include::next, ast_variable::object, option_debug, ast_config_include::output, ast_variable::precomments, ast_category::precomments, ast_category::root, ast_config::root, ast_variable::sameline, ast_category::sameline, set_fn(), ast_category::template_instances, ast_variable::trailing, ast_category::trailing, ast_variable::value, and var.
Referenced by action_updateconfig(), config_text_file_save(), vm_change_password(), and vm_forwardoptions().
01592 { 01593 FILE *f; 01594 char fn[256]; 01595 struct ast_variable *var; 01596 struct ast_category *cat; 01597 struct ast_comment *cmt; 01598 struct ast_config_include *incl; 01599 int blanklines = 0; 01600 struct ao2_container *fileset = ao2_container_alloc(180000, hash_string, hashtab_compare_strings); 01601 struct inclfile *fi = 0; 01602 01603 /* reset all the output flags, in case this isn't our first time saving this data */ 01604 01605 for (incl=cfg->includes; incl; incl = incl->next) 01606 incl->output = 0; 01607 01608 /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions) 01609 are all truncated to zero bytes and have that nice header*/ 01610 01611 for (incl=cfg->includes; incl; incl = incl->next) 01612 { 01613 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*/ 01614 FILE *f1; 01615 01616 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 */ 01617 f1 = fopen(fn,"w"); 01618 if (f1) { 01619 gen_header(f1, configfile, fn, generator); 01620 fclose(f1); /* this should zero out the file */ 01621 } else { 01622 ast_debug(1, "Unable to open for writing: %s\n", fn); 01623 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01624 } 01625 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01626 fi = 0; 01627 } 01628 } 01629 01630 set_fn(fn, sizeof(fn), 0, configfile, fileset, &fi); /* just set fn to absolute ver of configfile */ 01631 #ifdef __CYGWIN__ 01632 if ((f = fopen(fn, "w+"))) { 01633 #else 01634 if ((f = fopen(fn, "w"))) { 01635 #endif 01636 ast_verb(2, "Saving '%s': ", fn); 01637 gen_header(f, configfile, fn, generator); 01638 cat = cfg->root; 01639 fclose(f); 01640 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01641 01642 /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */ 01643 /* since each var, cat, and associated comments can come from any file, we have to be 01644 mobile, and open each file, print, and close it on an entry-by-entry basis */ 01645 01646 while (cat) { 01647 set_fn(fn, sizeof(fn), cat->file, configfile, fileset, &fi); 01648 f = fopen(fn, "a"); 01649 if (!f) 01650 { 01651 ast_debug(1, "Unable to open for writing: %s\n", fn); 01652 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01653 ao2_ref(fileset, -1); 01654 return -1; 01655 } 01656 01657 /* dump any includes that happen before this category header */ 01658 for (incl=cfg->includes; incl; incl = incl->next) { 01659 if (strcmp(incl->include_location_file, cat->file) == 0){ 01660 if (cat->lineno > incl->include_location_lineno && !incl->output) { 01661 if (incl->exec) 01662 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01663 else 01664 fprintf(f,"#include \"%s\"\n", incl->included_file); 01665 incl->output = 1; 01666 } 01667 } 01668 } 01669 01670 insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno); 01671 /* Dump section with any appropriate comment */ 01672 for (cmt = cat->precomments; cmt; cmt=cmt->next) { 01673 char *cmtp = cmt->cmt; 01674 while (*cmtp == ';' && *(cmtp+1) == '!') { 01675 char *cmtp2 = strchr(cmtp+1, '\n'); 01676 if (cmtp2) 01677 cmtp = cmtp2+1; 01678 else cmtp = 0; 01679 } 01680 if (cmtp) 01681 fprintf(f,"%s", cmtp); 01682 } 01683 fprintf(f, "[%s]", cat->name); 01684 if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) { 01685 fprintf(f, "("); 01686 if (cat->ignored) { 01687 fprintf(f, "!"); 01688 } 01689 if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) { 01690 fprintf(f, ","); 01691 } 01692 if (!AST_LIST_EMPTY(&cat->template_instances)) { 01693 struct ast_category_template_instance *x; 01694 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01695 fprintf(f,"%s",x->name); 01696 if (x != AST_LIST_LAST(&cat->template_instances)) 01697 fprintf(f,","); 01698 } 01699 } 01700 fprintf(f, ")"); 01701 } 01702 for(cmt = cat->sameline; cmt; cmt=cmt->next) 01703 { 01704 fprintf(f,"%s", cmt->cmt); 01705 } 01706 if (!cat->sameline) 01707 fprintf(f,"\n"); 01708 for (cmt = cat->trailing; cmt; cmt=cmt->next) { 01709 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01710 fprintf(f,"%s", cmt->cmt); 01711 } 01712 fclose(f); 01713 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01714 fi = 0; 01715 01716 var = cat->root; 01717 while (var) { 01718 struct ast_category_template_instance *x; 01719 int found = 0; 01720 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01721 struct ast_variable *v; 01722 for (v = x->inst->root; v; v = v->next) { 01723 if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) { 01724 found = 1; 01725 break; 01726 } 01727 } 01728 if (found) 01729 break; 01730 } 01731 if (found) { 01732 var = var->next; 01733 continue; 01734 } 01735 set_fn(fn, sizeof(fn), var->file, configfile, fileset, &fi); 01736 f = fopen(fn, "a"); 01737 if (!f) 01738 { 01739 ast_debug(1, "Unable to open for writing: %s\n", fn); 01740 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01741 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01742 fi = 0; 01743 ao2_ref(fileset, -1); 01744 return -1; 01745 } 01746 01747 /* dump any includes that happen before this category header */ 01748 for (incl=cfg->includes; incl; incl = incl->next) { 01749 if (strcmp(incl->include_location_file, var->file) == 0){ 01750 if (var->lineno > incl->include_location_lineno && !incl->output) { 01751 if (incl->exec) 01752 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01753 else 01754 fprintf(f,"#include \"%s\"\n", incl->included_file); 01755 incl->output = 1; 01756 } 01757 } 01758 } 01759 01760 insert_leading_blank_lines(f, fi, var->precomments, var->lineno); 01761 for (cmt = var->precomments; cmt; cmt=cmt->next) { 01762 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01763 fprintf(f,"%s", cmt->cmt); 01764 } 01765 if (var->sameline) 01766 fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt); 01767 else 01768 fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value); 01769 for (cmt = var->trailing; cmt; cmt=cmt->next) { 01770 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01771 fprintf(f,"%s", cmt->cmt); 01772 } 01773 if (var->blanklines) { 01774 blanklines = var->blanklines; 01775 while (blanklines--) 01776 fprintf(f, "\n"); 01777 } 01778 01779 fclose(f); 01780 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01781 fi = 0; 01782 01783 var = var->next; 01784 } 01785 cat = cat->next; 01786 } 01787 if (!option_debug) 01788 ast_verb(2, "Saved\n"); 01789 } else { 01790 ast_debug(1, "Unable to open for writing: %s\n", fn); 01791 ast_verb(2, "Unable to write (%s)", strerror(errno)); 01792 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01793 ao2_ref(fileset, -1); 01794 return -1; 01795 } 01796 01797 /* Now, for files with trailing #include/#exec statements, 01798 we have to make sure every entry is output */ 01799 01800 for (incl=cfg->includes; incl; incl = incl->next) { 01801 if (!incl->output) { 01802 /* open the respective file */ 01803 set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset, &fi); 01804 f = fopen(fn, "a"); 01805 if (!f) 01806 { 01807 ast_debug(1, "Unable to open for writing: %s\n", fn); 01808 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01809 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01810 fi = 0; 01811 ao2_ref(fileset, -1); 01812 return -1; 01813 } 01814 01815 /* output the respective include */ 01816 if (incl->exec) 01817 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01818 else 01819 fprintf(f,"#include \"%s\"\n", incl->included_file); 01820 fclose(f); 01821 incl->output = 1; 01822 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01823 fi = 0; 01824 } 01825 } 01826 ao2_ref(fileset, -1); /* this should destroy the hash container */ 01827 01828 return 0; 01829 }
| 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. |
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2266 of file config.c.
References db, ast_config_engine::destroy_func, find_engine(), and table.
Referenced by cli_realtime_destroy(), function_realtime_readdestroy(), leave_voicemail(), and vm_delete().
02267 { 02268 struct ast_config_engine *eng; 02269 int res = -1; 02270 char db[256]; 02271 char table[256]; 02272 va_list ap; 02273 02274 va_start(ap, lookup); 02275 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02276 if (eng && eng->destroy_func) 02277 res = eng->destroy_func(db, table, keyfield, lookup, ap); 02278 va_end(ap); 02279 02280 return res; 02281 }
| static void ast_destroy_template_list | ( | struct ast_category * | cat | ) | [static] |
Definition at line 553 of file config.c.
References AST_LIST_REMOVE_HEAD, free, and ast_category::template_instances.
Referenced by ast_category_destroy().
00554 { 00555 struct ast_category_template_instance *x; 00556 00557 while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next))) 00558 free(x); 00559 }
| struct ast_config_include* ast_include_find | ( | struct ast_config * | conf, | |
| const char * | included_file | |||
| ) | [read] |
Definition at line 337 of file config.c.
References ast_config_include::included_file, ast_config::includes, and ast_config_include::next.
Referenced by ast_include_new().
00338 { 00339 struct ast_config_include *x; 00340 for (x=conf->includes;x;x=x->next) { 00341 if (strcmp(x->included_file,included_file) == 0) 00342 return x; 00343 } 00344 return 0; 00345 }
| struct ast_config_include* ast_include_new | ( | struct ast_config * | conf, | |
| const char * | from_file, | |||
| const char * | included_file, | |||
| int | is_exec, | |||
| const char * | exec_file, | |||
| int | from_lineno, | |||
| char * | real_included_file_name, | |||
| int | real_included_file_name_size | |||
| ) | [read] |
Definition at line 246 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().
00247 { 00248 /* a file should be included ONCE. Otherwise, if one of the instances is changed, 00249 * then all be changed. -- how do we know to include it? -- Handling modified 00250 * instances is possible, I'd have 00251 * to create a new master for each instance. */ 00252 struct ast_config_include *inc; 00253 struct stat statbuf; 00254 00255 inc = ast_include_find(conf, included_file); 00256 if (inc) { 00257 do { 00258 inc->inclusion_count++; 00259 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count); 00260 } while (stat(real_included_file_name, &statbuf) == 0); 00261 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); 00262 } else 00263 *real_included_file_name = 0; 00264 00265 inc = ast_calloc(1,sizeof(struct ast_config_include)); 00266 inc->include_location_file = ast_strdup(from_file); 00267 inc->include_location_lineno = from_lineno; 00268 if (!ast_strlen_zero(real_included_file_name)) 00269 inc->included_file = ast_strdup(real_included_file_name); 00270 else 00271 inc->included_file = ast_strdup(included_file); 00272 00273 inc->exec = is_exec; 00274 if (is_exec) 00275 inc->exec_file = ast_strdup(exec_file); 00276 00277 /* attach this new struct to the conf struct */ 00278 inc->next = conf->includes; 00279 conf->includes = inc; 00280 00281 return inc; 00282 }
| void ast_include_rename | ( | struct ast_config * | conf, | |
| const char * | from_file, | |||
| const char * | to_file | |||
| ) |
Definition at line 284 of file config.c.
References ast_variable::file, ast_category::file, free, ast_config_include::include_location_file, ast_config::includes, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, ast_config::root, and strdup.
Referenced by action_updateconfig().
00285 { 00286 struct ast_config_include *incl; 00287 struct ast_category *cat; 00288 struct ast_variable *v; 00289 00290 int from_len = strlen(from_file); 00291 int to_len = strlen(to_file); 00292 00293 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */ 00294 return; 00295 00296 /* the manager code allows you to read in one config file, then 00297 * write it back out under a different name. But, the new arrangement 00298 * ties output lines to the file name. So, before you try to write 00299 * the config file to disk, better riffle thru the data and make sure 00300 * the file names are changed. 00301 */ 00302 /* file names are on categories, includes (of course), and on variables. So, 00303 * traverse all this and swap names */ 00304 00305 for (incl = conf->includes; incl; incl=incl->next) { 00306 if (strcmp(incl->include_location_file,from_file) == 0) { 00307 if (from_len >= to_len) 00308 strcpy(incl->include_location_file, to_file); 00309 else { 00310 free(incl->include_location_file); 00311 incl->include_location_file = strdup(to_file); 00312 } 00313 } 00314 } 00315 for (cat = conf->root; cat; cat = cat->next) { 00316 if (strcmp(cat->file,from_file) == 0) { 00317 if (from_len >= to_len) 00318 strcpy(cat->file, to_file); 00319 else { 00320 free(cat->file); 00321 cat->file = strdup(to_file); 00322 } 00323 } 00324 for (v = cat->root; v; v = v->next) { 00325 if (strcmp(v->file,from_file) == 0) { 00326 if (from_len >= to_len) 00327 strcpy(v->file, to_file); 00328 else { 00329 free(v->file); 00330 v->file = strdup(to_file); 00331 } 00332 } 00333 } 00334 } 00335 }
| static void ast_includes_destroy | ( | struct ast_config_include * | incls | ) | [static] |
Definition at line 575 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().
00576 { 00577 struct ast_config_include *incl,*inclnext; 00578 00579 for (incl=incls; incl; incl = inclnext) { 00580 inclnext = incl->next; 00581 if (incl->include_location_file) 00582 free(incl->include_location_file); 00583 if (incl->exec_file) 00584 free(incl->exec_file); 00585 if (incl->included_file) 00586 free(incl->included_file); 00587 free(incl); 00588 } 00589 }
| struct ast_variable* ast_load_realtime | ( | const char * | family, | |
| ... | ||||
| ) | [read] |
Retrieve realtime configuration.
| family | which family/config to lookup This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. 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. |
The difference between these two calls is that ast_load_realtime excludes fields whose values are NULL, while ast_load_realtime_all loads all columns.
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2113 of file config.c.
References ast_free, ast_load_realtime_helper(), ast_strlen_zero(), ast_variable::next, and ast_variable::value.
Referenced by conf_run(), copy_plain_file(), find_conf_realtime(), find_realtime(), find_user_realtime(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), queue_function_queuewaitingcount(), realtime_alias(), realtime_peer(), realtime_switch_common(), realtime_user(), and rt_extend_conf().
02114 { 02115 struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL; 02116 va_list ap; 02117 02118 va_start(ap, family); 02119 res = ast_load_realtime_helper(family, ap); 02120 va_end(ap); 02121 02122 /* Eliminate blank entries */ 02123 for (cur = res; cur; cur = cur->next) { 02124 if (freeme) { 02125 ast_free(freeme); 02126 freeme = NULL; 02127 } 02128 02129 if (ast_strlen_zero(cur->value)) { 02130 if (prev) 02131 prev->next = cur->next; 02132 else 02133 res = cur->next; 02134 freeme = cur; 02135 } else if (cur->value[0] == ' ' && cur->value[1] == '\0') { 02136 char *vptr = (char *) cur->value; 02137 vptr[0] = '\0'; 02138 prev = cur; 02139 } else { 02140 prev = cur; 02141 } 02142 } 02143 return res; 02144 }
| struct ast_variable* ast_load_realtime_all | ( | const char * | family, | |
| ... | ||||
| ) | [read] |
Definition at line 2101 of file config.c.
References ast_load_realtime_helper().
Referenced by cli_realtime_load(), function_realtime_read(), function_realtime_readdestroy(), and realtimefield_read().
02102 { 02103 struct ast_variable *res; 02104 va_list ap; 02105 02106 va_start(ap, family); 02107 res = ast_load_realtime_helper(family, ap); 02108 va_end(ap); 02109 02110 return res; 02111 }
| static struct ast_variable* ast_load_realtime_helper | ( | const char * | family, | |
| va_list | ap | |||
| ) | [static, read] |
Definition at line 2087 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().
02088 { 02089 struct ast_config_engine *eng; 02090 char db[256]; 02091 char table[256]; 02092 struct ast_variable *res=NULL; 02093 02094 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02095 if (eng && eng->realtime_func) 02096 res = eng->realtime_func(db, table, ap); 02097 02098 return res; 02099 }
| struct ast_config* ast_load_realtime_multientry | ( | const char * | family, | |
| ... | ||||
| ) | [read] |
Retrieve realtime configuration.
| family | which family/config to lookup |
This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. Unlike the ast_load_realtime, this function can return more than one entry and is thus stored inside a traditional ast_config structure rather than just returning a linked list of variables.
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2198 of file config.c.
References db, find_engine(), ast_config_engine::realtime_multi_func, and table.
Referenced by __queues_show(), find_realtime(), load_realtime_queue(), realtime_directory(), realtime_peer(), realtime_switch_common(), show_users_realtime(), and update_realtime_members().
02199 { 02200 struct ast_config_engine *eng; 02201 char db[256]; 02202 char table[256]; 02203 struct ast_config *res = NULL; 02204 va_list ap; 02205 02206 va_start(ap, family); 02207 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02208 if (eng && eng->realtime_multi_func) 02209 res = eng->realtime_multi_func(db, table, ap); 02210 va_end(ap); 02211 02212 return res; 02213 }
| int ast_parse_arg | ( | const char * | arg, | |
| enum ast_parse_flags | flags, | |||
| void * | p_result, | |||
| ... | ||||
| ) |
Helper function to parse arguments See documentation in config.h.
The argument parsing routine.
Definition at line 2286 of file config.c.
References ast_debug, ast_gethostbyname(), ast_inet_ntoa(), 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, and PARSE_UINT32.
Referenced by ast_sip_ouraddrfor(), check_via_response(), and reload_config().
02288 { 02289 va_list ap; 02290 int error = 0; 02291 02292 va_start(ap, p_result); 02293 switch (flags & PARSE_TYPE) { 02294 case PARSE_INT32: 02295 { 02296 int32_t *result = p_result; 02297 int32_t x, def = result ? *result : 0, 02298 high = (int32_t)0x7fffffff, 02299 low = (int32_t)0x80000000; 02300 /* optional argument: first default value, then range */ 02301 if (flags & PARSE_DEFAULT) 02302 def = va_arg(ap, int32_t); 02303 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02304 /* range requested, update bounds */ 02305 low = va_arg(ap, int32_t); 02306 high = va_arg(ap, int32_t); 02307 } 02308 x = strtol(arg, NULL, 0); 02309 error = (x < low) || (x > high); 02310 if (flags & PARSE_OUT_RANGE) 02311 error = !error; 02312 if (result) 02313 *result = error ? def : x; 02314 ast_debug(3, 02315 "extract int from [%s] in [%d, %d] gives [%d](%d)\n", 02316 arg, low, high, 02317 result ? *result : x, error); 02318 break; 02319 } 02320 02321 case PARSE_UINT32: 02322 { 02323 uint32_t *result = p_result; 02324 uint32_t x, def = result ? *result : 0, 02325 low = 0, high = (uint32_t)~0; 02326 /* optional argument: first default value, then range */ 02327 if (flags & PARSE_DEFAULT) 02328 def = va_arg(ap, uint32_t); 02329 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02330 /* range requested, update bounds */ 02331 low = va_arg(ap, uint32_t); 02332 high = va_arg(ap, uint32_t); 02333 } 02334 x = strtoul(arg, NULL, 0); 02335 error = (x < low) || (x > high); 02336 if (flags & PARSE_OUT_RANGE) 02337 error = !error; 02338 if (result) 02339 *result = error ? def : x; 02340 ast_debug(3, 02341 "extract uint from [%s] in [%u, %u] gives [%u](%d)\n", 02342 arg, low, high, 02343 result ? *result : x, error); 02344 break; 02345 } 02346 02347 case PARSE_DOUBLE: 02348 { 02349 double *result = p_result; 02350 double x, def = result ? *result : 0, 02351 low = -HUGE_VAL, high = HUGE_VAL; 02352 02353 /* optional argument: first default value, then range */ 02354 if (flags & PARSE_DEFAULT) 02355 def = va_arg(ap, double); 02356 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02357 /* range requested, update bounds */ 02358 low = va_arg(ap, double); 02359 high = va_arg(ap, double); 02360 } 02361 x = strtod(arg, NULL); 02362 error = (x < low) || (x > high); 02363 if (flags & PARSE_OUT_RANGE) 02364 error = !error; 02365 if (result) 02366 *result = error ? def : x; 02367 ast_debug(3, 02368 "extract double from [%s] in [%f, %f] gives [%f](%d)\n", 02369 arg, low, high, 02370 result ? *result : x, error); 02371 break; 02372 } 02373 case PARSE_INADDR: 02374 { 02375 char *port, *buf; 02376 struct sockaddr_in _sa_buf; /* buffer for the result */ 02377 struct sockaddr_in *sa = p_result ? 02378 (struct sockaddr_in *)p_result : &_sa_buf; 02379 /* default is either the supplied value or the result itself */ 02380 struct sockaddr_in *def = (flags & PARSE_DEFAULT) ? 02381 va_arg(ap, struct sockaddr_in *) : sa; 02382 struct hostent *hp; 02383 struct ast_hostent ahp; 02384 02385 memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */ 02386 /* duplicate the string to strip away the :port */ 02387 port = ast_strdupa(arg); 02388 buf = strsep(&port, ":"); 02389 sa->sin_family = AF_INET; /* assign family */ 02390 /* 02391 * honor the ports flag setting, assign default value 02392 * in case of errors or field unset. 02393 */ 02394 flags &= PARSE_PORT_MASK; /* the only flags left to process */ 02395 if (port) { 02396 if (flags == PARSE_PORT_FORBID) { 02397 error = 1; /* port was forbidden */ 02398 sa->sin_port = def->sin_port; 02399 } else if (flags == PARSE_PORT_IGNORE) 02400 sa->sin_port = def->sin_port; 02401 else /* accept or require */ 02402 sa->sin_port = htons(strtol(port, NULL, 0)); 02403 } else { 02404 sa->sin_port = def->sin_port; 02405 if (flags == PARSE_PORT_REQUIRE) 02406 error = 1; 02407 } 02408 /* Now deal with host part, even if we have errors before. */ 02409 hp = ast_gethostbyname(buf, &ahp); 02410 if (hp) /* resolved successfully */ 02411 memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr)); 02412 else { 02413 error = 1; 02414 sa->sin_addr = def->sin_addr; 02415 } 02416 ast_debug(3, 02417 "extract inaddr from [%s] gives [%s:%d](%d)\n", 02418 arg, ast_inet_ntoa(sa->sin_addr), 02419 ntohs(sa->sin_port), error); 02420 break; 02421 } 02422 } 02423 va_end(ap); 02424 return error; 02425 }
| int ast_realtime_enabled | ( | void | ) |
Check if there's any realtime engines loaded.
Definition at line 2161 of file config.c.
References config_maps.
Referenced by action_coresettings(), ast_check_realtime(), and handle_show_settings().
02162 { 02163 return config_maps ? 1 : 0; 02164 }
| int ast_realtime_require_field | ( | const char * | family, | |
| ... | ||||
| ) |
Inform realtime what fields that may be stored.
| family | which family/config is referenced This will inform builtin configuration backends that particular fields may be updated during the use of that configuration section. This is mainly to be used during startup routines, to ensure that various fields exist in the backend. The backends may take various actions, such as creating new fields in the data store or warning the administrator that new fields may need to be created, in order to ensure proper function. |
The arguments are specified in groups of 3: column name, column type, and column size. The column types are specified as integer constants, defined by the enum require_type. Note that the size is specified as the number of equivalent character fields that a field may take up, even if a field is otherwise specified as an integer type. This is due to the fact that some fields have historically been specified as character types, even if they contained integer values.
A family should always specify its fields to the minimum necessary requirements to fulfill all possible values (within reason; for example, a timeout value may reasonably be specified as an INTEGER2, with size 5. Even though values above 32767 seconds are possible, they are unlikely to be useful, and we should not complain about that size).
| 0 | Required fields met specified standards | |
| -1 | One or more fields was missing or insufficient |
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2166 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().
02167 { 02168 struct ast_config_engine *eng; 02169 char db[256]; 02170 char table[256]; 02171 va_list ap; 02172 int res = -1; 02173 02174 va_start(ap, family); 02175 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02176 if (eng && eng->require_func) { 02177 res = eng->require_func(db, table, ap); 02178 } 02179 va_end(ap); 02180 02181 return res; 02182 }
| 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. |
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2249 of file config.c.
References db, find_engine(), ast_config_engine::store_func, and table.
Referenced by ast_queue_log(), cli_realtime_store(), copy_plain_file(), function_realtime_store(), and leave_voicemail().
02250 { 02251 struct ast_config_engine *eng; 02252 int res = -1; 02253 char db[256]; 02254 char table[256]; 02255 va_list ap; 02256 02257 va_start(ap, family); 02258 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02259 if (eng && eng->store_func) 02260 res = eng->store_func(db, table, ap); 02261 va_end(ap); 02262 02263 return res; 02264 }
| 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 2184 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().
02185 { 02186 struct ast_config_engine *eng; 02187 char db[256]; 02188 char table[256]; 02189 int res = -1; 02190 02191 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02192 if (eng && eng->unload_func) { 02193 res = eng->unload_func(db, table); 02194 } 02195 return res; 02196 }
| int ast_update2_realtime | ( | const char * | family, | |
| ... | ||||
| ) |
Update realtime configuration.
| family | which family/config to be updated This function is used to update a parameter in realtime configuration space. It includes the ability to lookup a row based upon multiple key criteria. As a result, this function includes two sentinel values, one to terminate lookup values and the other to terminate the listing of fields to update. |
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2232 of file config.c.
References db, find_engine(), table, and ast_config_engine::update2_func.
Referenced by change_password_realtime(), and cli_realtime_update2().
02233 { 02234 struct ast_config_engine *eng; 02235 int res = -1; 02236 char db[256]; 02237 char table[256]; 02238 va_list ap; 02239 02240 va_start(ap, family); 02241 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02242 if (eng && eng->update2_func) 02243 res = eng->update2_func(db, table, ap); 02244 va_end(ap); 02245 02246 return res; 02247 }
| 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. |
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2215 of file config.c.
References db, find_engine(), table, and ast_config_engine::update_func.
Referenced by cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), handle_response_peerpoke(), leave_voicemail(), realtime_update_peer(), rename_file(), rt_extend_conf(), sip_poke_noanswer(), and update_realtime_member_field().
02216 { 02217 struct ast_config_engine *eng; 02218 int res = -1; 02219 char db[256]; 02220 char table[256]; 02221 va_list ap; 02222 02223 va_start(ap, lookup); 02224 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02225 if (eng && eng->update_func) 02226 res = eng->update_func(db, table, keyfield, lookup, ap); 02227 va_end(ap); 02228 02229 return res; 02230 }
| void ast_variable_append | ( | struct ast_category * | category, | |
| struct ast_variable * | variable | |||
| ) |
Definition at line 348 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().
| struct ast_variable* ast_variable_browse | ( | const struct ast_config * | config, | |
| const char * | category | |||
| ) | [read] |
Goes through variables Somewhat similar in intent as the ast_category_browse. List variables of config file category.
| ast_variable | list on success | |
| NULL | on failure |
Definition at line 411 of file config.c.
References ast_category_get(), ast_config::last_browse, ast_category::name, and ast_category::root.
Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), action_getconfig(), action_getconfigjson(), adsi_load(), aji_load_config(), ast_cli_perms_init(), ast_readconfig(), ast_variable_retrieve(), ast_xmldoc_load_documentation(), build_device(), build_event_channel(), check_tx_freq(), collect_function_digits(), conf_exec(), config_load(), config_module(), do_say(), do_scheduler(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_template_parse(), 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(), parse_tone_zone(), pbx_load_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_single_queue(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().
00412 { 00413 struct ast_category *cat = NULL; 00414 00415 if (category && config->last_browse && (config->last_browse->name == category)) { 00416 cat = config->last_browse; 00417 } else { 00418 cat = ast_category_get(config, category); 00419 } 00420 00421 return (cat) ? cat->root : NULL; 00422 }
| int ast_variable_delete | ( | struct ast_category * | category, | |
| const char * | variable, | |||
| const char * | match, | |||
| const char * | line | |||
| ) |
Definition at line 682 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().
00683 { 00684 struct ast_variable *cur, *prev=NULL, *curn; 00685 int res = -1; 00686 int lineno = 0; 00687 00688 cur = category->root; 00689 while (cur) { 00690 if (cur->name == variable) { 00691 if (prev) { 00692 prev->next = cur->next; 00693 if (cur == category->last) 00694 category->last = prev; 00695 } else { 00696 category->root = cur->next; 00697 if (cur == category->last) 00698 category->last = NULL; 00699 } 00700 cur->next = NULL; 00701 ast_variables_destroy(cur); 00702 return 0; 00703 } 00704 prev = cur; 00705 cur = cur->next; 00706 } 00707 00708 prev = NULL; 00709 cur = category->root; 00710 while (cur) { 00711 curn = cur->next; 00712 if ((!ast_strlen_zero(line) && lineno == atoi(line)) || (ast_strlen_zero(line) && !strcasecmp(cur->name, variable) && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) { 00713 if (prev) { 00714 prev->next = cur->next; 00715 if (cur == category->last) 00716 category->last = prev; 00717 } else { 00718 category->root = cur->next; 00719 if (cur == category->last) 00720 category->last = NULL; 00721 } 00722 cur->next = NULL; 00723 ast_variables_destroy(cur); 00724 res = 0; 00725 } else 00726 prev = cur; 00727 00728 cur = curn; 00729 lineno++; 00730 } 00731 return res; 00732 }
| void ast_variable_insert | ( | struct ast_category * | category, | |
| struct ast_variable * | variable, | |||
| const char * | line | |||
| ) |
Definition at line 361 of file config.c.
References ast_variable::next, and ast_category::root.
Referenced by handle_updates().
00362 { 00363 struct ast_variable *cur = category->root; 00364 int lineno; 00365 int insertline; 00366 00367 if (!variable || sscanf(line, "%30d", &insertline) != 1) { 00368 return; 00369 } 00370 if (!insertline) { 00371 variable->next = category->root; 00372 category->root = variable; 00373 } else { 00374 for (lineno = 1; lineno < insertline; lineno++) { 00375 cur = cur->next; 00376 if (!cur->next) { 00377 break; 00378 } 00379 } 00380 variable->next = cur->next; 00381 cur->next = variable; 00382 } 00383 }
| struct ast_variable* ast_variable_new | ( | const char * | name, | |
| const char * | value, | |||
| const char * | filename | |||
| ) | [read] |
Definition at line 223 of file config.c.
References __ast_calloc(), ast_calloc, ast_variable::file, ast_variable::name, ast_variable::stuff, and ast_variable::value.
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(), mkintf(), parkandannounce_exec(), parse_cookies(), process_dahdi(), process_text_line(), realtime_curl(), realtime_directory(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_multi_curl(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_odbc(), realtime_pgsql(), transmit_notify_custom(), variable_clone(), and vm_change_password().
00225 { 00226 struct ast_variable *variable; 00227 int name_len = strlen(name) + 1; 00228 int val_len = strlen(value) + 1; 00229 int fn_len = strlen(filename) + 1; 00230 00231 #ifdef MALLOC_DEBUG 00232 if ((variable = __ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable), file, lineno, func))) { 00233 #else 00234 if ((variable = ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable)))) { 00235 #endif 00236 char *dst = variable->stuff; /* writable space starts here */ 00237 variable->name = strcpy(dst, name); 00238 dst += name_len; 00239 variable->value = strcpy(dst, value); 00240 dst += val_len; 00241 variable->file = strcpy(dst, filename); 00242 } 00243 return variable; 00244 }
| 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 435 of file config.c.
References ast_variable_browse(), ast_variable::name, ast_category::next, ast_variable::next, ast_category::root, ast_config::root, and ast_variable::value.
Referenced by __ast_rtp_reload(), __ast_udptl_reload(), __init_manager(), _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(), find_queue_by_name_rt(), find_realtime(), function_macro(), get_insecure_variable_from_config(), get_wait_interval(), gtalk_load_config(), iax_template_parse(), init_acf_query(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), 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(), queue_set_global_params(), read_agent_config(), realtime_directory(), reload_config(), reload_followme(), reload_single_queue(), retreive_memory(), retrieve_astcfgint(), rpt(), rpt_master(), rpt_tele_thread(), rpt_telemetry(), saynode(), search_directory(), search_directory_sub(), 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().
00436 { 00437 struct ast_variable *v; 00438 00439 if (category) { 00440 for (v = ast_variable_browse(config, category); v; v = v->next) { 00441 if (!strcasecmp(variable, v->name)) { 00442 return v->value; 00443 } 00444 } 00445 } else { 00446 struct ast_category *cat; 00447 00448 for (cat = config->root; cat; cat = cat->next) { 00449 for (v = cat->root; v; v = v->next) { 00450 if (!strcasecmp(variable, v->name)) { 00451 return v->value; 00452 } 00453 } 00454 } 00455 } 00456 00457 return NULL; 00458 }
| 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 734 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().
00736 { 00737 struct ast_variable *cur, *prev=NULL, *newer=NULL; 00738 00739 for (cur = category->root; cur; prev = cur, cur = cur->next) { 00740 if (strcasecmp(cur->name, variable) || 00741 (!ast_strlen_zero(match) && strcasecmp(cur->value, match))) 00742 continue; 00743 00744 if (!(newer = ast_variable_new(variable, value, cur->file))) 00745 return -1; 00746 00747 newer->next = cur->next; 00748 newer->object = cur->object || object; 00749 if (prev) 00750 prev->next = newer; 00751 else 00752 category->root = newer; 00753 if (category->last == cur) 00754 category->last = newer; 00755 00756 cur->next = NULL; 00757 ast_variables_destroy(cur); 00758 00759 return 0; 00760 } 00761 00762 /* Could not find variable to update */ 00763 return -1; 00764 }
| 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 397 of file config.c.
References ast_comment_destroy(), ast_free, ast_variable::next, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.
Referenced by __sip_destroy(), ast_category_destroy(), ast_category_empty(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variable_delete(), ast_variable_update(), build_peer(), build_user(), cli_realtime_load(), conf_run(), copy_plain_file(), destroy_dahdi_pvt(), find_conf_realtime(), find_realtime(), find_user_realtime(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), 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_exec(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_user(), realtimefield_read(), rt_extend_conf(), sip_alloc(), sip_destroy_peer(), socket_process(), table_configs_free(), and user_destructor().
00398 { 00399 struct ast_variable *vn; 00400 00401 while (v) { 00402 vn = v; 00403 v = v->next; 00404 ast_comment_destroy(&vn->precomments); 00405 ast_comment_destroy(&vn->sameline); 00406 ast_comment_destroy(&vn->trailing); 00407 ast_free(vn); 00408 } 00409 }
| static struct ast_category* category_get | ( | const struct ast_config * | config, | |
| const char * | category_name, | |||
| int | ignored | |||
| ) | [static, read] |
Definition at line 494 of file config.c.
References ast_category::ignored, ast_category::name, ast_category::next, and ast_config::root.
Referenced by ast_category_get(), and process_text_line().
00495 { 00496 struct ast_category *cat; 00497 00498 /* try exact match first, then case-insensitive match */ 00499 for (cat = config->root; cat; cat = cat->next) { 00500 if (cat->name == category_name && (ignored || !cat->ignored)) 00501 return cat; 00502 } 00503 00504 for (cat = config->root; cat; cat = cat->next) { 00505 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored)) 00506 return cat; 00507 } 00508 00509 return NULL; 00510 }
| static void CB_ADD | ( | struct ast_str ** | cb, | |
| const char * | str | |||
| ) | [static] |
Definition at line 95 of file config.c.
References ast_str_append().
Referenced by config_text_file_load().
00096 { 00097 ast_str_append(cb, 0, "%s", str); 00098 }
| static void CB_ADD_LEN | ( | struct ast_str ** | cb, | |
| const char * | str, | |||
| int | len | |||
| ) | [static] |
Definition at line 100 of file config.c.
References ast_copy_string(), ast_str_append(), and s.
Referenced by config_text_file_load().
00101 { 00102 char *s = alloca(len + 1); 00103 ast_copy_string(s, str, len); 00104 ast_str_append(cb, 0, "%s", str); 00105 }
Definition at line 107 of file config.c.
References ast_str_reset().
Referenced by config_text_file_load(), and process_text_line().
00108 { 00109 if (cb) { 00110 ast_str_reset(cb); 00111 } 00112 if (llb) { 00113 ast_str_reset(llb); 00114 } 00115 }
| static void clear_config_maps | ( | void | ) | [static] |
Definition at line 1831 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().
01832 { 01833 struct ast_config_map *map; 01834 01835 ast_mutex_lock(&config_lock); 01836 01837 while (config_maps) { 01838 map = config_maps; 01839 config_maps = config_maps->next; 01840 ast_free(map); 01841 } 01842 01843 ast_mutex_unlock(&config_lock); 01844 }
| 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 861 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_mtime::mtime, and cache_file_mtime::who_asked.
Referenced by process_text_line().
00862 { 00863 struct cache_file_mtime *cfmtime; 00864 struct cache_file_include *cfinclude; 00865 struct stat statbuf = { 0, }; 00866 00867 /* Find our cached entry for this configuration file */ 00868 AST_LIST_LOCK(&cfmtime_head); 00869 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 00870 if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked)) 00871 break; 00872 } 00873 if (!cfmtime) { 00874 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1 + strlen(who_asked) + 1); 00875 if (!cfmtime) { 00876 AST_LIST_UNLOCK(&cfmtime_head); 00877 return; 00878 } 00879 AST_LIST_HEAD_INIT(&cfmtime->includes); 00880 strcpy(cfmtime->filename, configfile); 00881 cfmtime->who_asked = cfmtime->filename + strlen(configfile) + 1; 00882 strcpy(cfmtime->who_asked, who_asked); 00883 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 00884 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 00885 } 00886 00887 if (!stat(configfile, &statbuf)) 00888 cfmtime->mtime = 0; 00889 else 00890 cfmtime->mtime = statbuf.st_mtime; 00891 00892 switch (attrtype) { 00893 case ATTRIBUTE_INCLUDE: 00894 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 00895 if (!strcmp(cfinclude->include, filename)) { 00896 AST_LIST_UNLOCK(&cfmtime_head); 00897 return; 00898 } 00899 } 00900 cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1); 00901 if (!cfinclude) { 00902 AST_LIST_UNLOCK(&cfmtime_head); 00903 return; 00904 } 00905 strcpy(cfinclude->include, filename); 00906 AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list); 00907 break; 00908 case ATTRIBUTE_EXEC: 00909 cfmtime->has_exec = 1; 00910 break; 00911 } 00912 AST_LIST_UNLOCK(&cfmtime_head); 00913 }
| static struct ast_config* config_text_file_load | ( | const char * | database, | |
| const char * | table, | |||
| const char * | filename, | |||
| struct ast_config * | cfg, | |||
| struct ast_flags | flags, | |||
| const char * | suggested_include_file, | |||
| const char * | who_asked | |||
| ) | [static, read] |
Growable string buffer
< this will be a comment collector.
< A buffer for stuff behind the ;
Definition at line 1176 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_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, buf, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, comment, COMMENT_META, COMMENT_TAG, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, GLOB_ABORTED, cache_file_mtime::has_exec, cache_file_include::include, ast_config::include_level, cache_file_mtime::includes, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, cache_file_mtime::mtime, MY_GLOB_FLAGS, process_text_line(), ast_variable::trailing, ast_category::trailing, and cache_file_mtime::who_asked.
01177 { 01178 char fn[256]; 01179 #if defined(LOW_MEMORY) 01180 char buf[512]; 01181 #else 01182 char buf[8192]; 01183 #endif 01184 char *new_buf, *comment_p, *process_buf; 01185 FILE *f; 01186 int lineno=0; 01187 int comment = 0, nest[MAX_NESTED_COMMENTS]; 01188 struct ast_category *cat = NULL; 01189 int count = 0; 01190 struct stat statbuf; 01191 struct cache_file_mtime *cfmtime = NULL; 01192 struct cache_file_include *cfinclude; 01193 struct ast_variable *last_var = 0; 01194 struct ast_category *last_cat = 0; 01195 /*! Growable string buffer */ 01196 struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/ 01197 struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */ 01198 01199 if (cfg) 01200 cat = ast_config_get_current_category(cfg); 01201 01202 if (filename[0] == '/') { 01203 ast_copy_string(fn, filename, sizeof(fn)); 01204 } else { 01205 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 01206 } 01207 01208 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01209 comment_buffer = ast_str_create(CB_SIZE); 01210 if (comment_buffer) 01211 lline_buffer = ast_str_create(CB_SIZE); 01212 if (!lline_buffer) { 01213 if (comment_buffer) 01214 ast_free(comment_buffer); 01215 ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n"); 01216 return NULL; 01217 } 01218 } 01219 #ifdef AST_INCLUDE_GLOB 01220 { 01221 int glob_ret; 01222 glob_t globbuf; 01223 globbuf.gl_offs = 0; /* initialize it to silence gcc */ 01224 glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf); 01225 if (glob_ret == GLOB_NOSPACE) 01226 ast_log(LOG_WARNING, 01227 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn); 01228 else if (glob_ret == GLOB_ABORTED) 01229 ast_log(LOG_WARNING, 01230 "Glob Expansion of pattern '%s' failed: Read error\n", fn); 01231 else { 01232 /* loop over expanded files */ 01233 int i; 01234 for (i=0; i<globbuf.gl_pathc; i++) { 01235 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn)); 01236 #endif 01237 /* 01238 * The following is not a loop, but just a convenient way to define a block 01239 * (using do { } while(0) ), and be able to exit from it with 'continue' 01240 * or 'break' in case of errors. Nice trick. 01241 */ 01242 do { 01243 if (stat(fn, &statbuf)) 01244 continue; 01245 01246 if (!S_ISREG(statbuf.st_mode)) { 01247 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn); 01248 continue; 01249 } 01250 01251 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) { 01252 /* Find our cached entry for this configuration file */ 01253 AST_LIST_LOCK(&cfmtime_head); 01254 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 01255 if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) 01256 break; 01257 } 01258 if (!cfmtime) { 01259 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1 + strlen(who_asked) + 1); 01260 if (!cfmtime) 01261 continue; 01262 AST_LIST_HEAD_INIT(&cfmtime->includes); 01263 strcpy(cfmtime->filename, fn); 01264 cfmtime->who_asked = cfmtime->filename + strlen(fn) + 1; 01265 strcpy(cfmtime->who_asked, who_asked); 01266 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 01267 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 01268 } 01269 } 01270 01271 if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) { 01272 /* File is unchanged, what about the (cached) includes (if any)? */ 01273 int unchanged = 1; 01274 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 01275 /* We must glob here, because if we did not, then adding a file to globbed directory would 01276 * incorrectly cause no reload to be necessary. */ 01277 char fn2[256]; 01278 #ifdef AST_INCLUDE_GLOB 01279 int glob_return; 01280 glob_t glob_buf = { .gl_offs = 0 }; 01281 glob_return = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &glob_buf); 01282 /* On error, we reparse */ 01283 if (glob_return == GLOB_NOSPACE || glob_return == GLOB_ABORTED) 01284 unchanged = 0; 01285 else { 01286 /* loop over expanded files */ 01287 int j; 01288 for (j = 0; j < glob_buf.gl_pathc; j++) { 01289 ast_copy_string(fn2, glob_buf.gl_pathv[j], sizeof(fn2)); 01290 #else 01291 ast_copy_string(fn2, cfinclude->include); 01292 #endif 01293 if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) { 01294 /* that second-to-last field needs to be looked at in this case... TODO */ 01295 unchanged = 0; 01296 /* One change is enough to short-circuit and reload the whole shebang */ 01297 break; 01298 } 01299 #ifdef AST_INCLUDE_GLOB 01300 } 01301 } 01302 #endif 01303 } 01304 01305 if (unchanged) { 01306 AST_LIST_UNLOCK(&cfmtime_head); 01307 return CONFIG_STATUS_FILEUNCHANGED; 01308 } 01309 } 01310 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01311 AST_LIST_UNLOCK(&cfmtime_head); 01312 01313 /* If cfg is NULL, then we just want an answer */ 01314 if (cfg == NULL) 01315 return NULL; 01316 01317 if (cfmtime) 01318 cfmtime->mtime = statbuf.st_mtime; 01319 01320 ast_verb(2, "Parsing '%s': ", fn); 01321 fflush(stdout); 01322 if (!(f = fopen(fn, "r"))) { 01323 ast_debug(1, "No file to parse: %s\n", fn); 01324 ast_verb(2, "Not found (%s)\n", strerror(errno)); 01325 continue; 01326 } 01327 count++; 01328 /* If we get to this point, then we're loading regardless */ 01329 ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED); 01330 ast_debug(1, "Parsing %s\n", fn); 01331 ast_verb(2, "Found\n"); 01332 while (!feof(f)) { 01333 lineno++; 01334 if (fgets(buf, sizeof(buf), f)) { 01335 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && ast_str_strlen(lline_buffer)) { 01336 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01337 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01338 } 01339 01340 new_buf = buf; 01341 if (comment) 01342 process_buf = NULL; 01343 else 01344 process_buf = buf; 01345 01346 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer) && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) { 01347 /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */ 01348 CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */ 01349 continue; /* go get a new line, then */ 01350 } 01351 01352 while ((comment_p = strchr(new_buf, COMMENT_META))) { 01353 if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) { 01354 /* Escaped semicolons aren't comments. */ 01355 new_buf = comment_p + 1; 01356 } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { 01357 /* Meta-Comment start detected ";--" */ 01358 if (comment < MAX_NESTED_COMMENTS) { 01359 *comment_p = '\0'; 01360 new_buf = comment_p + 3; 01361 comment++; 01362 nest[comment-1] = lineno; 01363 } else { 01364 ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); 01365 } 01366 } else if ((comment_p >= new_buf + 2) && 01367 (*(comment_p - 1) == COMMENT_TAG) && 01368 (*(comment_p - 2) == COMMENT_TAG)) { 01369 /* Meta-Comment end detected */ 01370 comment--; 01371 new_buf = comment_p + 1; 01372 if (!comment) { 01373 /* Back to non-comment now */ 01374 if (process_buf) { 01375 /* Actually have to move what's left over the top, then continue */ 01376 char *oldptr; 01377 oldptr = process_buf + strlen(process_buf); 01378 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01379 CB_ADD(&comment_buffer, ";"); 01380 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1); 01381 } 01382 01383 memmove(oldptr, new_buf, strlen(new_buf) + 1); 01384 new_buf = oldptr; 01385 } else 01386 process_buf = new_buf; 01387 } 01388 } else { 01389 if (!comment) { 01390 /* If ; is found, and we are not nested in a comment, 01391 we immediately stop all comment processing */ 01392 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01393 CB_ADD(&lline_buffer, comment_p); 01394 } 01395 *comment_p = '\0'; 01396 new_buf = comment_p; 01397 } else 01398 new_buf = comment_p + 1; 01399 } 01400 } 01401 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) { 01402 CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */ 01403 } 01404 01405 if (process_buf) { 01406 char *buffer = ast_strip(process_buf); 01407 if (!ast_strlen_zero(buffer)) { 01408 if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) { 01409 cfg = CONFIG_STATUS_FILEINVALID; 01410 break; 01411 } 01412 } 01413 } 01414 } 01415 } 01416 /* end of file-- anything in a comment buffer? */ 01417 if (last_cat) { 01418 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01419 if (lline_buffer && ast_str_strlen(lline_buffer)) { 01420 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01421 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01422 } 01423 last_cat->trailing = ALLOC_COMMENT(comment_buffer); 01424 } 01425 } else if (last_var) { 01426 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01427 if (lline_buffer && ast_str_strlen(lline_buffer)) { 01428 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01429 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01430 } 01431 last_var->trailing = ALLOC_COMMENT(comment_buffer); 01432 } 01433 } else { 01434 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01435 ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer)); 01436 } 01437 } 01438 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01439 CB_RESET(comment_buffer, lline_buffer); 01440 01441 fclose(f); 01442 } while (0); 01443 if (comment) { 01444 ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]); 01445 } 01446 #ifdef AST_INCLUDE_GLOB 01447 if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { 01448 break; 01449 } 01450 } 01451 globfree(&globbuf); 01452 } 01453 } 01454 #endif 01455 01456 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01457 if (comment_buffer) 01458 ast_free(comment_buffer); 01459 if (lline_buffer) 01460 ast_free(lline_buffer); 01461 comment_buffer = NULL; 01462 lline_buffer = NULL; 01463 } 01464 01465 if (count == 0) 01466 return NULL; 01467 01468 return cfg; 01469 }
| int config_text_file_save | ( | const char * | configfile, | |
| const struct ast_config * | cfg, | |||
| const char * | generator | |||
| ) |
Definition at line 1586 of file config.c.
References ast_config_text_file_save().
01587 { 01588 return ast_config_text_file_save(configfile, cfg, generator); 01589 }
| static int count_linefeeds | ( | char * | str | ) | [static] |
| static int count_linefeeds_in_comments | ( | struct ast_comment * | x | ) | [static] |
Definition at line 1557 of file config.c.
References ast_comment::cmt, count_linefeeds(), and ast_comment::next.
Referenced by insert_leading_blank_lines().
01558 { 01559 int count = 0; 01560 01561 while (x) { 01562 count += count_linefeeds(x->cmt); 01563 x = x->next; 01564 } 01565 return count; 01566 }
| static struct ast_config_engine* find_engine | ( | const char * | family, | |
| char * | database, | |||
| int | dbsiz, | |||
| char * | table, | |||
| int | tabsiz | |||
| ) | [static, read] |
Find realtime engine for realtime family.
Definition at line 1992 of file config.c.
References ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), config_lock, config_maps, ast_config_map::database, ast_config_map::driver, LOG_WARNING, map, ast_config_map::name, ast_config_engine::next, ast_config_map::next, and ast_config_map::table.
Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_realtime_require_field(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), and ast_update_realtime().
01993 { 01994 struct ast_config_engine *eng, *ret = NULL; 01995 struct ast_config_map *map; 01996 01997 ast_mutex_lock(&config_lock); 01998 01999 for (map = config_maps; map; map = map->next) { 02000 if (!strcasecmp(family, map->name)) { 02001 if (database) 02002 ast_copy_string(database, map->database, dbsiz); 02003 if (table) 02004 ast_copy_string(table, map->table ? map->table : family, tabsiz); 02005 break; 02006 } 02007 } 02008 02009 /* Check if the required driver (engine) exist */ 02010 if (map) { 02011 for (eng = config_engine_list; !ret && eng; eng = eng->next) { 02012 if (!strcasecmp(eng->name, map->driver)) 02013 ret = eng; 02014 } 02015 } 02016 02017 ast_mutex_unlock(&config_lock); 02018 02019 /* if we found a mapping, but the engine is not available, then issue a warning */ 02020 if (map && !ret) 02021 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver); 02022 02023 return ret; 02024 }
| static void gen_header | ( | FILE * | f1, | |
| const char * | configfile, | |||
| const char * | fn, | |||
| const char * | generator | |||
| ) | [static] |
Definition at line 1492 of file config.c.
References ast_copy_string().
Referenced by ast_config_text_file_save().
01493 { 01494 char date[256]=""; 01495 time_t t; 01496 01497 time(&t); 01498 ast_copy_string(date, ctime(&t), sizeof(date)); 01499 01500 fprintf(f1, ";!\n"); 01501 fprintf(f1, ";! Automatically generated configuration file\n"); 01502 if (strcmp(configfile, fn)) 01503 fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn); 01504 else 01505 fprintf(f1, ";! Filename: %s\n", configfile); 01506 fprintf(f1, ";! Generator: %s\n", generator); 01507 fprintf(f1, ";! Creation Date: %s", date); 01508 fprintf(f1, ";!\n"); 01509 }
| static char* handle_cli_config_list | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2528 of file config.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.
02529 { 02530 struct cache_file_mtime *cfmtime; 02531 02532 switch (cmd) { 02533 case CLI_INIT: 02534 e->command = "config list"; 02535 e->usage = 02536 "Usage: config list\n" 02537 " Show all modules that have loaded a configuration file\n"; 02538 return NULL; 02539 case CLI_GENERATE: 02540 return NULL; 02541 } 02542 02543 AST_LIST_LOCK(&cfmtime_head); 02544 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02545 ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename); 02546 } 02547 AST_LIST_UNLOCK(&cfmtime_head); 02548 02549 return CLI_SUCCESS; 02550 }
| static char* handle_cli_config_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2466 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, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.
02467 { 02468 struct cache_file_mtime *cfmtime; 02469 char *prev = "", *completion_value = NULL; 02470 int wordlen, which = 0; 02471 02472 switch (cmd) { 02473 case CLI_INIT: 02474 e->command = "config reload"; 02475 e->usage = 02476 "Usage: config reload <filename.conf>\n" 02477 " Reloads all modules that reference <filename.conf>\n"; 02478 return NULL; 02479 case CLI_GENERATE: 02480 if (a->pos > 2) { 02481 return NULL; 02482 } 02483 02484 wordlen = strlen(a->word); 02485 02486 AST_LIST_LOCK(&cfmtime_head); 02487 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02488 /* Skip duplicates - this only works because the list is sorted by filename */ 02489 if (strcmp(cfmtime->filename, prev) == 0) { 02490 continue; 02491 } 02492 02493 /* Core configs cannot be reloaded */ 02494 if (ast_strlen_zero(cfmtime->who_asked)) { 02495 continue; 02496 } 02497 02498 if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) { 02499 completion_value = ast_strdup(cfmtime->filename); 02500 break; 02501 } 02502 02503 /* Otherwise save that we've seen this filename */ 02504 prev = cfmtime->filename; 02505 } 02506 AST_LIST_UNLOCK(&cfmtime_head); 02507 02508 return completion_value; 02509 } 02510 02511 if (a->argc != 3) { 02512 return CLI_SHOWUSAGE; 02513 } 02514 02515 AST_LIST_LOCK(&cfmtime_head); 02516 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02517 if (!strcmp(cfmtime->filename, a->argv[2])) { 02518 char *buf = alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1); 02519 sprintf(buf, "module reload %s", cfmtime->who_asked); 02520 ast_cli_command(a->fd, buf); 02521 } 02522 } 02523 AST_LIST_UNLOCK(&cfmtime_head); 02524 02525 return CLI_SUCCESS; 02526 }
| static char* handle_cli_core_show_config_mappings | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2427 of file config.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, ast_cli_args::fd, map, ast_config_map::name, ast_config_engine::name, ast_config_map::next, ast_config_engine::next, ast_config_map::table, and ast_cli_entry::usage.
02428 { 02429 struct ast_config_engine *eng; 02430 struct ast_config_map *map; 02431 02432 switch (cmd) { 02433 case CLI_INIT: 02434 e->command = "core show config mappings"; 02435 e->usage = 02436 "Usage: core show config mappings\n" 02437 " Shows the filenames to config engines.\n"; 02438 return NULL; 02439 case CLI_GENERATE: 02440 return NULL; 02441 } 02442 02443 ast_mutex_lock(&config_lock); 02444 02445 if (!config_engine_list) { 02446 ast_cli(a->fd, "No config mappings found.\n"); 02447 } else { 02448 ast_cli(a->fd, "\n\n"); 02449 for (eng = config_engine_list; eng; eng = eng->next) { 02450 ast_cli(a->fd, "\nConfig Engine: %s\n", eng->name); 02451 for (map = config_maps; map; map = map->next) { 02452 if (!strcasecmp(map->driver, eng->name)) { 02453 ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database, 02454 map->table ? map->table : map->name); 02455 } 02456 } 02457 } 02458 ast_cli(a->fd,"\n\n"); 02459 } 02460 02461 ast_mutex_unlock(&config_lock); 02462 02463 return CLI_SUCCESS; 02464 }
| static int hash_string | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 137 of file config.c.
Referenced by ast_config_text_file_save().
00138 { 00139 char *str = ((struct inclfile *) obj)->fname; 00140 int total; 00141 00142 for (total = 0; *str; str++) { 00143 unsigned int tmp = total; 00144 total <<= 1; /* multiply by 2 */ 00145 total += tmp; /* multiply by 3 */ 00146 total <<= 2; /* multiply by 12 */ 00147 total += tmp; /* multiply by 13 */ 00148 00149 total += ((unsigned int) (*str)); 00150 } 00151 if (total < 0) { 00152 total = -total; 00153 } 00154 return total; 00155 }
| static int hashtab_compare_strings | ( | void * | a, | |
| void * | b, | |||
| int | flags | |||
| ) | [static] |
Definition at line 157 of file config.c.
References CMP_MATCH, CMP_STOP, and inclfile::fname.
Referenced by ast_config_text_file_save().
| static void inclfile_destroy | ( | void * | obj | ) | [static] |
| static void inherit_category | ( | struct ast_category * | new, | |
| const struct ast_category * | base | |||
| ) | [static] |
Definition at line 661 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, ast_variable::next, ast_category::root, var, and variable_clone().
Referenced by process_text_line().
00662 { 00663 struct ast_variable *var; 00664 struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance)); 00665 00666 strcpy(x->name, base->name); 00667 x->inst = base; 00668 AST_LIST_INSERT_TAIL(&new->template_instances, x, next); 00669 for (var = base->root; var; var = var->next) 00670 ast_variable_append(new, variable_clone(var)); 00671 }
| static int init_appendbuf | ( | void * | data | ) | [static] |
Definition at line 83 of file config.c.
References ast_str_create(), and str.
00084 { 00085 struct ast_str **str = data; 00086 *str = ast_str_create(16); 00087 return *str ? 0 : -1; 00088 }
| static void insert_leading_blank_lines | ( | FILE * | fp, | |
| struct inclfile * | fi, | |||
| struct ast_comment * | precomments, | |||
| int | lineno | |||
| ) | [static] |
Definition at line 1568 of file config.c.
References count_linefeeds_in_comments(), and inclfile::lineno.
Referenced by ast_config_text_file_save().
01569 { 01570 int precomment_lines = count_linefeeds_in_comments(precomments); 01571 int i; 01572 01573 /* I don't have to worry about those ;! comments, they are 01574 stored in the precomments, but not printed back out. 01575 I did have to make sure that comments following 01576 the ;! header comments were not also deleted in the process */ 01577 if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */ 01578 return; 01579 } 01580 for (i=fi->lineno; i<lineno - precomment_lines; i++) { 01581 fprintf(fp,"\n"); 01582 } 01583 fi->lineno = lineno+1; /* Advance the file lineno */ 01584 }
| static void move_variables | ( | struct ast_category * | old, | |
| struct ast_category * | new | |||
| ) | [static] |
Definition at line 474 of file config.c.
References ast_variable_append(), ast_category::root, and var.
Referenced by process_text_line().
00475 { 00476 struct ast_variable *var = old->root; 00477 00478 old->root = NULL; 00479 /* we can just move the entire list in a single op */ 00480 ast_variable_append(new, var); 00481 }
| static struct ast_category* next_available_category | ( | struct ast_category * | cat | ) | [static, read] |
Definition at line 591 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 922 of file config.c.
References ALLOC_COMMENT(), appendbuf, ast_category_append(), ast_category_destroy(), ast_category_first(), ast_category_new(), ast_config_internal_load(), ast_include_new(), ast_log(), ast_opt_exec_includes, ast_safe_system(), ast_skip_blanks(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_trim_blanks(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_tvnow(), ast_variable_append(), ast_variable_new(), ast_variable_update(), ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, ast_variable::blanklines, category_get(), CB_RESET(), config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, ast_config::include_level, inherit_category(), ast_variable::lineno, LOG_ERROR, LOG_WARNING, move_variables(), ast_variable::name, ast_variable::next, ast_variable::object, ast_variable::precomments, ast_category::precomments, S_OR, ast_variable::sameline, ast_category::sameline, str, ast_variable::value, and var.
Referenced by config_text_file_load().
00928 { 00929 char *c; 00930 char *cur = buf; 00931 struct ast_variable *v; 00932 char cmd[512], exec_file[512]; 00933 00934 /* Actually parse the entry */ 00935 if (cur[0] == '[') { /* A category header */ 00936 /* format is one of the following: 00937 * [foo] define a new category named 'foo' 00938 * [foo](!) define a new template category named 'foo' 00939 * [foo](+) append to category 'foo', error if foo does not exist. 00940 * [foo](a) define a new category and inherit from template a. 00941 * You can put a comma-separated list of templates and '!' and '+' 00942 * between parentheses, with obvious meaning. 00943 */ 00944 struct ast_category *newcat = NULL; 00945 char *catname; 00946 00947 c = strchr(cur, ']'); 00948 if (!c) { 00949 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); 00950 return -1; 00951 } 00952 *c++ = '\0'; 00953 cur++; 00954 if (*c++ != '(') 00955 c = NULL; 00956 catname = cur; 00957 if (!(*cat = newcat = ast_category_new(catname, 00958 S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile), 00959 lineno))) { 00960 return -1; 00961 } 00962 (*cat)->lineno = lineno; 00963 *last_var = 0; 00964 *last_cat = newcat; 00965 00966 /* add comments */ 00967 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00968 newcat->precomments = ALLOC_COMMENT(comment_buffer); 00969 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00970 newcat->sameline = ALLOC_COMMENT(lline_buffer); 00971 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00972 CB_RESET(comment_buffer, lline_buffer); 00973 00974 /* If there are options or categories to inherit from, process them now */ 00975 if (c) { 00976 if (!(cur = strchr(c, ')'))) { 00977 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile); 00978 return -1; 00979 } 00980 *cur = '\0'; 00981 while ((cur = strsep(&c, ","))) { 00982 if (!strcasecmp(cur, "!")) { 00983 (*cat)->ignored = 1; 00984 } else if (!strcasecmp(cur, "+")) { 00985 *cat = category_get(cfg, catname, 1); 00986 if (!(*cat)) { 00987 if (newcat) 00988 ast_category_destroy(newcat); 00989 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile); 00990 return -1; 00991 } 00992 if (newcat) { 00993 move_variables(newcat, *cat); 00994 ast_category_destroy(newcat); 00995 newcat = NULL; 00996 } 00997 } else { 00998 struct ast_category *base; 00999 01000 base = category_get(cfg, cur, 1); 01001 if (!base) { 01002 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile); 01003 return -1; 01004 } 01005 inherit_category(*cat, base); 01006 } 01007 } 01008 } 01009 if (newcat) 01010 ast_category_append(cfg, *cat); 01011 } else if (cur[0] == '#') { /* A directive - #include or #exec */ 01012 char *cur2; 01013 char real_inclusion_name[256]; 01014 struct ast_config_include *inclu; 01015 int do_include = 0; /* otherwise, it is exec */ 01016 01017 cur++; 01018 c = cur; 01019 while (*c && (*c > 32)) { 01020 c++; 01021 } 01022 01023 if (*c) { 01024 *c = '\0'; 01025 /* Find real argument */ 01026 c = ast_skip_blanks(c + 1); 01027 if (!(*c)) { 01028 c = NULL; 01029 } 01030 } else 01031 c = NULL; 01032 if (!strcasecmp(cur, "include")) { 01033 do_include = 1; 01034 } else if (!strcasecmp(cur, "exec")) { 01035 if (!ast_opt_exec_includes) { 01036 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n"); 01037 return 0; /* XXX is this correct ? or we should return -1 ? */ 01038 } 01039 } else { 01040 ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile); 01041 return 0; /* XXX is this correct ? or we should return -1 ? */ 01042 } 01043 01044 if (c == NULL) { 01045 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 01046 do_include ? "include" : "exec", 01047 do_include ? "filename" : "/path/to/executable", 01048 lineno, 01049 configfile); 01050 return 0; /* XXX is this correct ? or we should return -1 ? */ 01051 } 01052 01053 cur = c; 01054 /* Strip off leading and trailing "'s and <>'s */ 01055 if (*c == '"') { 01056 /* Dequote */ 01057 while (*c) { 01058 if (*c == '"') { 01059 strcpy(c, c + 1); /* SAFE */ 01060 c--; 01061 } else if (*c == '\\') { 01062 strcpy(c, c + 1); /* SAFE */ 01063 } 01064 c++; 01065 } 01066 } else if (*c == '<') { 01067 /* C-style include */ 01068 if (*(c + strlen(c) - 1) == '>') { 01069 cur++; 01070 *(c + strlen(c) - 1) = '\0'; 01071 } 01072 } 01073 cur2 = cur; 01074 01075 /* #exec </path/to/executable> 01076 We create a tmp file, then we #include it, then we delete it. */ 01077 if (!do_include) { 01078 struct timeval now = ast_tvnow(); 01079 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01080 config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked); 01081 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self()); 01082 snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file); 01083 ast_safe_system(cmd); 01084 cur = exec_file; 01085 } else { 01086 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01087 config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked); 01088 exec_file[0] = '\0'; 01089 } 01090 /* A #include */ 01091 /* record this inclusion */ 01092 inclu = ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name)); 01093 01094 do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0; 01095 if (!ast_strlen_zero(exec_file)) 01096 unlink(exec_file); 01097 if (!do_include) { 01098 ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur); 01099 return -1; 01100 } 01101 /* XXX otherwise what ? the default return is 0 anyways */ 01102 01103 } else { 01104 /* Just a line (variable = value) */ 01105 int object = 0; 01106 if (!(*cat)) { 01107 ast_log(LOG_WARNING, 01108 "parse error: No category context for line %d of %s\n", lineno, configfile); 01109 return -1; 01110 } 01111 c = strchr(cur, '='); 01112 01113 if (c && c > cur && (*(c - 1) == '+')) { 01114 struct ast_variable *var, *replace = NULL; 01115 struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str)); 01116 01117 if (!str || !*str) { 01118 return -1; 01119 } 01120 01121 *(c - 1) = '\0'; 01122 c++; 01123 cur = ast_strip(cur); 01124 01125 /* Must iterate through category until we find last variable of same name (since there could be multiple) */ 01126 for (var = ast_category_first(*cat); var; var = var->next) { 01127 if (!strcmp(var->name, cur)) { 01128 replace = var; 01129 } 01130 } 01131 01132 if (!replace) { 01133 /* Nothing to replace; just set a variable normally. */ 01134 goto set_new_variable; 01135 } 01136 01137 ast_str_set(str, 0, "%s", replace->value); 01138 ast_str_append(str, 0, "%s", c); 01139 ast_str_trim_blanks(*str); 01140 ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object); 01141 } else if (c) { 01142 *c = 0; 01143 c++; 01144 /* Ignore > in => */ 01145 if (*c== '>') { 01146 object = 1; 01147 c++; 01148 } 01149 set_new_variable: 01150 if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) { 01151 v->lineno = lineno; 01152 v->object = object; 01153 *last_cat = 0; 01154 *last_var = v; 01155 /* Put and reset comments */ 01156 v->blanklines = 0; 01157 ast_variable_append(*cat, v); 01158 /* add comments */ 01159 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01160 v->precomments = ALLOC_COMMENT(comment_buffer); 01161 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01162 v->sameline = ALLOC_COMMENT(lline_buffer); 01163 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01164 CB_RESET(comment_buffer, lline_buffer); 01165 01166 } else { 01167 return -1; 01168 } 01169 } else { 01170 ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); 01171 } 01172 } 01173 return 0; 01174 }
| 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 1879 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, LOG_WARNING, ast_config::max_include_level, ast_variable::name, ast_variable::next, table, and ast_variable::value.
Referenced by main().
01880 { 01881 struct ast_config *config, *configtmp; 01882 struct ast_variable *v; 01883 char *driver, *table, *database, *stringp, *tmp; 01884 struct ast_flags flags = { 0 }; 01885 01886 clear_config_maps(); 01887 01888 configtmp = ast_config_new(); 01889 configtmp->max_include_level = 1; 01890 config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig"); 01891 if (!config) { 01892 ast_config_destroy(configtmp); 01893 return 0; 01894 } 01895 01896 for (v = ast_variable_browse(config, "settings"); v; v = v->next) { 01897 char buf[512]; 01898 ast_copy_string(buf, v->value, sizeof(buf)); 01899 stringp = buf; 01900 driver = strsep(&stringp, ","); 01901 01902 if ((tmp = strchr(stringp, '\"'))) 01903 stringp = tmp; 01904 01905 /* check if the database text starts with a double quote */ 01906 if (*stringp == '"') { 01907 stringp++; 01908 database = strsep(&stringp, "\""); 01909 strsep(&stringp, ","); 01910 } else { 01911 /* apparently this text has no quotes */ 01912 database = strsep(&stringp, ","); 01913 } 01914 01915 table = strsep(&stringp, ","); 01916 01917 if (!strcmp(v->name, extconfig_conf)) { 01918 ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf); 01919 continue; 01920 } 01921 01922 if (!strcmp(v->name, "asterisk.conf")) { 01923 ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n"); 01924 continue; 01925 } 01926 01927 if (!strcmp(v->name, "logger.conf")) { 01928 ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n"); 01929 continue; 01930 } 01931 01932 if (!driver || !database) 01933 continue; 01934 if (!strcasecmp(v->name, "sipfriends")) { 01935 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"); 01936 append_mapping("sipusers", driver, database, table ? table : "sipfriends"); 01937 append_mapping("sippeers", driver, database, table ? table : "sipfriends"); 01938 } else if (!strcasecmp(v->name, "iaxfriends")) { 01939 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"); 01940 append_mapping("iaxusers", driver, database, table ? table : "iaxfriends"); 01941 append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends"); 01942 } else 01943 append_mapping(v->name, driver, database, table); 01944 } 01945 01946 ast_config_destroy(config); 01947 return 0; 01948 }
| 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 2558 of file config.c.
References ARRAY_LEN, and ast_cli_register_multiple().
Referenced by main().
02559 { 02560 ast_cli_register_multiple(cli_config, ARRAY_LEN(cli_config)); 02561 return 0; 02562 }
| 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 1520 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 ast_config_text_file_save().
01521 { 01522 struct inclfile lookup; 01523 01524 if (!file || file[0] == 0) { 01525 if (configfile[0] == '/') 01526 ast_copy_string(fn, configfile, fn_size); 01527 else 01528 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile); 01529 } else if (file[0] == '/') 01530 ast_copy_string(fn, file, fn_size); 01531 else 01532 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file); 01533 lookup.fname = fn; 01534 *fi = ao2_find(fileset, &lookup, OBJ_POINTER); 01535 if (!(*fi)) { 01536 /* set up a file scratch pad */ 01537 struct inclfile *fx = ao2_alloc(sizeof(struct inclfile), inclfile_destroy); 01538 fx->fname = ast_strdup(fn); 01539 fx->lineno = 1; 01540 *fi = fx; 01541 ao2_link(fileset, fx); 01542 } 01543 }
| static struct ast_variable* variable_clone | ( | const struct ast_variable * | old | ) | [static, read] |
Definition at line 460 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().
00461 { 00462 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file); 00463 00464 if (new) { 00465 new->lineno = old->lineno; 00466 new->object = old->object; 00467 new->blanklines = old->blanklines; 00468 /* TODO: clone comments? */ 00469 } 00470 00471 return new; 00472 }
struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , } [static] |
Definition at line 90 of file config.c.
Referenced by process_text_line().
struct ast_cli_entry cli_config[] [static] |
{
AST_CLI_DEFINE(handle_cli_core_show_config_mappings, "Display config mappings (file names to config engines)"),
AST_CLI_DEFINE(handle_cli_config_reload, "Force a reload on modules using a particular configuration file"),
AST_CLI_DEFINE(handle_cli_config_list, "Show all files that have loaded a configuration file"),
}
struct ast_config_engine* config_engine_list [static] |
ast_mutex_t config_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 172 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] |
{
.name = "text",
.load_func = config_text_file_load,
}
1.6.2