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