#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_list |
struct | ast_category_template_instance |
struct | ast_comment |
Structure to keep comments for rewriting configuration files. More... | |
struct | ast_config |
struct | ast_config_include |
struct | ast_config_map |
struct | cache_file_include |
Hold the mtime for config files, so if we don't need to reread our config, don't. More... | |
struct | cache_file_mtime |
struct | cache_file_mtime::includes |
struct | cfmtime_head |
struct | inclfile |
Defines | |
#define | AST_INCLUDE_GLOB 1 |
#define | CB_SIZE 250 |
#define | COMMENT_END "--;" |
#define | COMMENT_META ';' |
#define | COMMENT_START ";--" |
#define | COMMENT_TAG '-' |
#define | MAX_INCLUDE_LEVEL 10 |
#define | MAX_NESTED_COMMENTS 128 |
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) |
ast_variable * | ast_category_detach_variables (struct ast_category *cat) |
int | ast_category_empty (struct ast_config *cfg, const char *category) |
Removes and destroys all variables within a category. | |
int | ast_category_exist (const struct ast_config *config, const char *category_name) |
Check for category duplicates. | |
ast_variable * | ast_category_first (struct ast_category *cat) |
given a pointer to a category, return the root variable. This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get()) | |
ast_category * | ast_category_get (const struct ast_config *config, const char *category_name) |
Retrieve a category if it exists. | |
void | ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match) |
Inserts new category. | |
ast_category * | ast_category_new (const char *name, const char *in_file, int lineno) |
Create a category structure. | |
void | ast_category_rename (struct ast_category *cat, const char *name) |
ast_variable * | ast_category_root (struct ast_config *config, char *cat) |
returns the root ast_variable of a config | |
int | ast_check_realtime (const char *family) |
Check if realtime engine is configured for family. | |
void | ast_config_destroy (struct ast_config *cfg) |
Destroys a config. | |
int | ast_config_engine_deregister (struct ast_config_engine *del) |
Deregister config engine. | |
int | ast_config_engine_register (struct ast_config_engine *new) |
Register config engine. | |
ast_category * | ast_config_get_current_category (const struct ast_config *cfg) |
Retrieve the current category name being built. API for backend configuration engines while building a configuration set. | |
ast_config * | ast_config_internal_load (const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) |
ast_config * | ast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags) |
Load a config file. | |
ast_config * | ast_config_new (void) |
Create a new base configuration structure. | |
const char * | ast_config_option (struct ast_config *cfg, const char *cat, const char *var) |
Retrieve a configuration variable within the configuration set. Retrieves the named variable var within category cat of configuration set cfg . If not found, attempts to retrieve the named variable var from within category general. | |
void | ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat) |
Set the category within the configuration as being current. API for backend configuration engines while building a configuration set. | |
static void | ast_destroy_comments (struct ast_category *cat) |
int | ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...) |
Destroy realtime configuration. | |
static void | ast_destroy_template_list (struct ast_category *cat) |
ast_config_include * | ast_include_find (struct ast_config *conf, const char *included_file) |
ast_config_include * | ast_include_new (struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size) |
void | ast_include_rename (struct ast_config *conf, const char *from_file, const char *to_file) |
static void | ast_includes_destroy (struct ast_config_include *incls) |
ast_variable * | ast_load_realtime (const char *family,...) |
Retrieve realtime configuration. | |
ast_variable * | ast_load_realtime_all (const char *family,...) |
static struct ast_variable * | ast_load_realtime_helper (const char *family, va_list ap) |
ast_config * | ast_load_realtime_multientry (const char *family,...) |
Retrieve realtime configuration. | |
int | ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *p_result,...) |
The argument parsing routine. | |
int | ast_realtime_enabled () |
Check if there's any realtime engines loaded. | |
int | ast_store_realtime (const char *family,...) |
Create realtime configuration. | |
int | ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...) |
Update realtime configuration. | |
void | ast_variable_append (struct ast_category *category, struct ast_variable *variable) |
ast_variable * | ast_variable_browse (const struct ast_config *config, const char *category) |
Goes through variables Somewhat similar in intent as the ast_category_browse. List variables of config file category. | |
int | ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line) |
void | ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line) |
ast_variable * | ast_variable_new (const char *name, const char *value, const char *filename) |
const char * | ast_variable_retrieve (const struct ast_config *config, const char *category, const char *variable) |
Gets a variable. | |
int | ast_variable_update (struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object) |
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_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 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 ast_mutex_t | config_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static struct ast_config_map * | config_maps |
static char * | extconfig_conf = "extconfig.conf" |
static struct ast_config_engine | text_file_engine |
Definition in file config.c.
#define CB_SIZE 250 |
#define COMMENT_META ';' |
#define COMMENT_TAG '-' |
#define MAX_INCLUDE_LEVEL 10 |
#define MAX_NESTED_COMMENTS 128 |
Definition at line 843 of file config.c.
00843 { 00844 ATTRIBUTE_INCLUDE = 0, 00845 ATTRIBUTE_EXEC = 1, 00846 };
static struct ast_comment* ALLOC_COMMENT | ( | const struct ast_str * | buffer | ) | [static] |
Definition at line 107 of file config.c.
References ast_calloc, ast_str::str, and ast_str::used.
Referenced by config_text_file_load(), and process_text_line().
00108 { 00109 struct ast_comment *x = NULL; 00110 if (buffer && buffer->used) 00111 x = ast_calloc(1, sizeof(*x) + buffer->used + 1); 00112 if (x) 00113 strcpy(x->cmt, buffer->str); 00114 return x; 00115 }
static int append_mapping | ( | const char * | name, | |
const char * | driver, | |||
const char * | database, | |||
const char * | table | |||
) | [static] |
Definition at line 1795 of file config.c.
References ast_calloc, ast_verb, config_maps, and map.
Referenced by read_config_maps().
01796 { 01797 struct ast_config_map *map; 01798 int length; 01799 01800 length = sizeof(*map); 01801 length += strlen(name) + 1; 01802 length += strlen(driver) + 1; 01803 length += strlen(database) + 1; 01804 if (table) 01805 length += strlen(table) + 1; 01806 01807 if (!(map = ast_calloc(1, length))) 01808 return -1; 01809 01810 map->name = map->stuff; 01811 strcpy(map->name, name); 01812 map->driver = map->name + strlen(map->name) + 1; 01813 strcpy(map->driver, driver); 01814 map->database = map->driver + strlen(map->driver) + 1; 01815 strcpy(map->database, database); 01816 if (table) { 01817 map->table = map->database + strlen(map->database) + 1; 01818 strcpy(map->table, table); 01819 } 01820 map->next = config_maps; 01821 01822 ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name); 01823 01824 config_maps = map; 01825 return 0; 01826 }
void ast_category_append | ( | struct ast_config * | config, | |
struct ast_category * | category | |||
) |
Definition at line 478 of file config.c.
References config, and ast_category::include_level.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00479 { 00480 if (config->last) 00481 config->last->next = category; 00482 else 00483 config->root = category; 00484 category->include_level = config->include_level; 00485 config->last = category; 00486 config->current = category; 00487 }
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 588 of file config.c.
References config, ast_category::name, ast_category::next, and next_available_category().
Referenced by __queues_show(), action_getconfig(), action_getconfigjson(), action_listcategories(), aji_load_config(), complete_sipnotify(), get_insecure_variable_from_config(), gtalk_load_config(), iax_provision_reload(), ind_load_module(), jingle_load_config(), load_config(), load_module(), load_moh_classes(), load_odbc_config(), misdn_cfg_init(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), search_directory(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().
00589 { 00590 struct ast_category *cat = NULL; 00591 00592 if (prev && config->last_browse && (config->last_browse->name == prev)) 00593 cat = config->last_browse->next; 00594 else if (!prev && config->root) 00595 cat = config->root; 00596 else if (prev) { 00597 for (cat = config->root; cat; cat = cat->next) { 00598 if (cat->name == prev) { 00599 cat = cat->next; 00600 break; 00601 } 00602 } 00603 if (!cat) { 00604 for (cat = config->root; cat; cat = cat->next) { 00605 if (!strcasecmp(cat->name, prev)) { 00606 cat = cat->next; 00607 break; 00608 } 00609 } 00610 } 00611 } 00612 00613 if (cat) 00614 cat = next_available_category(cat); 00615 00616 config->last_browse = cat; 00617 return (cat) ? cat->name : NULL; 00618 }
int ast_category_delete | ( | struct ast_config * | cfg, | |
const char * | category | |||
) |
Definition at line 753 of file config.c.
References ast_category_destroy(), ast_config::last, ast_category::next, and ast_config::root.
Referenced by handle_updates().
00754 { 00755 struct ast_category *prev=NULL, *cat; 00756 00757 cat = cfg->root; 00758 while (cat) { 00759 if (cat->name == category) { 00760 if (prev) { 00761 prev->next = cat->next; 00762 if (cat == cfg->last) 00763 cfg->last = prev; 00764 } else { 00765 cfg->root = cat->next; 00766 if (cat == cfg->last) 00767 cfg->last = NULL; 00768 } 00769 ast_category_destroy(cat); 00770 return 0; 00771 } 00772 prev = cat; 00773 cat = cat->next; 00774 } 00775 00776 prev = NULL; 00777 cat = cfg->root; 00778 while (cat) { 00779 if (!strcasecmp(cat->name, category)) { 00780 if (prev) { 00781 prev->next = cat->next; 00782 if (cat == cfg->last) 00783 cfg->last = prev; 00784 } else { 00785 cfg->root = cat->next; 00786 if (cat == cfg->last) 00787 cfg->last = NULL; 00788 } 00789 ast_category_destroy(cat); 00790 return 0; 00791 } 00792 prev = cat; 00793 cat = cat->next; 00794 } 00795 return -1; 00796 }
void ast_category_destroy | ( | struct ast_category * | cat | ) |
Definition at line 538 of file config.c.
References ast_destroy_comments(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, free, and ast_category::root.
Referenced by add_cfg_entry(), ast_category_delete(), ast_config_destroy(), process_text_line(), and realtime_multi_odbc().
00539 { 00540 ast_variables_destroy(cat->root); 00541 if (cat->file) { 00542 free(cat->file); 00543 cat->file = 0; 00544 } 00545 ast_destroy_comments(cat); 00546 ast_destroy_template_list(cat); 00547 ast_free(cat); 00548 }
struct ast_variable* ast_category_detach_variables | ( | struct ast_category * | cat | ) |
Definition at line 620 of file config.c.
References ast_category::last, and ast_category::root.
Referenced by realtime_switch_common().
00621 { 00622 struct ast_variable *v; 00623 00624 v = cat->root; 00625 cat->root = NULL; 00626 cat->last = NULL; 00627 00628 return v; 00629 }
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 798 of file config.c.
References ast_variables_destroy(), ast_category::last, ast_category::name, ast_category::next, ast_config::root, and ast_category::root.
Referenced by handle_updates().
00799 { 00800 struct ast_category *cat; 00801 00802 for (cat = cfg->root; cat; cat = cat->next) { 00803 if (!strcasecmp(cat->name, category)) 00804 continue; 00805 ast_variables_destroy(cat->root); 00806 cat->root = NULL; 00807 cat->last = NULL; 00808 return 0; 00809 } 00810 00811 return -1; 00812 }
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 473 of file config.c.
References ast_category_get(), and config.
00474 { 00475 return !!ast_category_get(config, category_name); 00476 }
struct ast_variable* ast_category_first | ( | struct ast_category * | cat | ) |
given a pointer to a category, return the root variable. This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get())
return the first var of a category
Definition at line 574 of file config.c.
References ast_category::root.
struct ast_category* ast_category_get | ( | const struct ast_config * | config, | |
const char * | category_name | |||
) |
Retrieve a category if it exists.
config | which config to use | |
category_name | name of the category you're looking for This will search through the categories within a given config file for a match. |
pointer | to category if found | |
NULL | if not. |
Definition at line 468 of file config.c.
References category_get(), and config.
Referenced by ast_category_exist(), ast_category_root(), ast_variable_browse(), handle_updates(), realtime_directory(), realtime_switch_common(), vm_change_password(), and vm_forwardoptions().
00469 { 00470 return category_get(config, category_name, 0); 00471 }
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 489 of file config.c.
References config, ast_category::name, and ast_category::next.
Referenced by handle_updates().
00490 { 00491 struct ast_category *cur_category; 00492 00493 if (!cat || !match) 00494 return; 00495 if (!strcasecmp(config->root->name, match)) { 00496 cat->next = config->root; 00497 config->root = cat; 00498 return; 00499 } 00500 for (cur_category = config->root; cur_category; cur_category = cur_category->next) { 00501 if (!strcasecmp(cur_category->next->name, match)) { 00502 cat->next = cur_category->next; 00503 cur_category->next = cat; 00504 break; 00505 } 00506 } 00507 }
struct ast_category* ast_category_new | ( | const char * | name, | |
const char * | in_file, | |||
int | lineno | |||
) |
Create a category structure.
Definition at line 439 of file config.c.
References ast_calloc, ast_copy_string(), and strdup.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00440 { 00441 struct ast_category *category; 00442 00443 if ((category = ast_calloc(1, sizeof(*category)))) 00444 ast_copy_string(category->name, name, sizeof(category->name)); 00445 category->file = strdup(in_file); 00446 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */ 00447 return category; 00448 }
void ast_category_rename | ( | struct ast_category * | cat, | |
const char * | name | |||
) |
Definition at line 631 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().
00632 { 00633 ast_copy_string(cat->name, name, sizeof(cat->name)); 00634 }
struct ast_variable* ast_category_root | ( | struct ast_config * | config, | |
char * | cat | |||
) |
returns the root ast_variable of a config
config | pointer to an ast_config data structure | |
cat | name of the category for which you want the root |
Definition at line 579 of file config.c.
References ast_category_get(), config, and ast_category::root.
Referenced by get_insecure_variable_from_config().
00580 { 00581 struct ast_category *category = ast_category_get(config, cat); 00582 00583 if (category) 00584 return category->root; 00585 return NULL; 00586 }
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 2092 of file config.c.
References find_engine().
Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_queue_log(), copy_plain_file(), destroy_association(), handle_response_peerpoke(), handle_voicemail_show_users(), local_ast_moh_start(), realtime_peer(), realtime_update_peer(), rename_file(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().
02093 { 02094 struct ast_config_engine *eng; 02095 02096 eng = find_engine(family, NULL, 0, NULL, 0); 02097 if (eng) 02098 return 1; 02099 return 0; 02100 }
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 814 of file config.c.
References ast_category_destroy(), ast_free, ast_includes_destroy(), ast_config::includes, ast_category::next, and ast_config::root.
Referenced by __ast_rtp_reload(), __ast_udptl_reload(), __queues_show(), action_getconfig(), action_listcategories(), action_updateconfig(), advanced_options(), ast_config_load2(), conf_exec(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), handle_cli_dialplan_save(), iax_provision_reload(), ind_load_module(), init_logger_chain(), load_config(), load_config_meetme(), load_module(), load_realtime_queue(), load_rpt_vars(), make_email_file(), odbc_load_module(), osp_load(), parse_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), read_agent_config(), read_config_maps(), realtime_directory(), realtime_multi_handler(), realtime_switch_common(), reload(), reload_config(), reload_followme(), rpt_master(), run_startup_commands(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), store_config(), tds_load_module(), unload_module(), update_realtime_members(), and vm_forwardoptions().
00815 { 00816 struct ast_category *cat, *catn; 00817 00818 if (!cfg) 00819 return; 00820 00821 ast_includes_destroy(cfg->includes); 00822 00823 cat = cfg->root; 00824 while (cat) { 00825 catn = cat; 00826 cat = cat->next; 00827 ast_category_destroy(catn); 00828 } 00829 ast_free(cfg); 00830 }
int ast_config_engine_deregister | ( | struct ast_config_engine * | del | ) |
Deregister config engine.
0 | Always |
Definition at line 1918 of file config.c.
References ast_mutex_lock(), ast_mutex_unlock(), config_engine_list, config_lock, last, and ast_config_engine::next.
Referenced by unload_module().
01919 { 01920 struct ast_config_engine *ptr, *last=NULL; 01921 01922 ast_mutex_lock(&config_lock); 01923 01924 for (ptr = config_engine_list; ptr; ptr=ptr->next) { 01925 if (ptr == del) { 01926 if (last) 01927 last->next = ptr->next; 01928 else 01929 config_engine_list = ptr->next; 01930 break; 01931 } 01932 last = ptr; 01933 } 01934 01935 ast_mutex_unlock(&config_lock); 01936 01937 return 0; 01938 }
int ast_config_engine_register | ( | struct ast_config_engine * | newconfig | ) |
Register config engine.
1 | Always |
Definition at line 1899 of file config.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), config_engine_list, config_lock, LOG_NOTICE, ast_config_engine::name, and ast_config_engine::next.
Referenced by load_module().
01900 { 01901 struct ast_config_engine *ptr; 01902 01903 ast_mutex_lock(&config_lock); 01904 01905 if (!config_engine_list) { 01906 config_engine_list = new; 01907 } else { 01908 for (ptr = config_engine_list; ptr->next; ptr=ptr->next); 01909 ptr->next = new; 01910 } 01911 01912 ast_mutex_unlock(&config_lock); 01913 ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name); 01914 01915 return 1; 01916 }
struct ast_category* ast_config_get_current_category | ( | const struct ast_config * | cfg | ) |
Retrieve the current category name being built. API for backend configuration engines while building a configuration set.
Definition at line 832 of file config.c.
References ast_config::current.
Referenced by config_curl(), config_odbc(), and config_text_file_load().
00833 { 00834 return cfg->current; 00835 }
struct ast_config* ast_config_internal_load | ( | const char * | filename, | |
struct ast_config * | cfg, | |||
struct ast_flags | flags, | |||
const char * | suggested_include_file, | |||
const char * | who_asked | |||
) |
Definition at line 1980 of file config.c.
References ast_log(), config_engine_list, CONFIG_STATUS_FILEUNCHANGED, db, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, table, and text_file_engine.
Referenced by add_cfg_entry(), ast_config_load2(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), process_text_line(), and read_config_maps().
01981 { 01982 char db[256]; 01983 char table[256]; 01984 struct ast_config_engine *loader = &text_file_engine; 01985 struct ast_config *result; 01986 01987 /* The config file itself bumps include_level by 1 */ 01988 if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) { 01989 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level); 01990 return NULL; 01991 } 01992 01993 cfg->include_level++; 01994 01995 if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) { 01996 struct ast_config_engine *eng; 01997 01998 eng = find_engine(filename, db, sizeof(db), table, sizeof(table)); 01999 02000 02001 if (eng && eng->load_func) { 02002 loader = eng; 02003 } else { 02004 eng = find_engine("global", db, sizeof(db), table, sizeof(table)); 02005 if (eng && eng->load_func) 02006 loader = eng; 02007 } 02008 } 02009 02010 result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked); 02011 02012 if (result && result != CONFIG_STATUS_FILEUNCHANGED) 02013 result->include_level--; 02014 else 02015 cfg->include_level--; 02016 02017 return result; 02018 }
struct ast_config* ast_config_load2 | ( | const char * | filename, | |
const char * | who_asked, | |||
struct ast_flags | flags | |||
) |
Load a config file.
filename | path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR Create a config structure from a given configuration file. | |
who_asked | The module which is making this request. | |
flags | Optional flags: CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact; CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files). |
NULL | on error |
Definition at line 2020 of file config.c.
References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), and CONFIG_STATUS_FILEUNCHANGED.
02021 { 02022 struct ast_config *cfg; 02023 struct ast_config *result; 02024 02025 cfg = ast_config_new(); 02026 if (!cfg) 02027 return NULL; 02028 02029 result = ast_config_internal_load(filename, cfg, flags, "", who_asked); 02030 if (!result || result == CONFIG_STATUS_FILEUNCHANGED) 02031 ast_config_destroy(cfg); 02032 02033 return result; 02034 }
struct ast_config* ast_config_new | ( | void | ) |
Create a new base configuration structure.
Definition at line 648 of file config.c.
References ast_calloc, config, and MAX_INCLUDE_LEVEL.
Referenced by ast_config_load2(), read_config_maps(), realtime_multi_curl(), realtime_multi_handler(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00649 { 00650 struct ast_config *config; 00651 00652 if ((config = ast_calloc(1, sizeof(*config)))) 00653 config->max_include_level = MAX_INCLUDE_LEVEL; 00654 return config; 00655 }
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 385 of file config.c.
References ast_variable_retrieve().
Referenced by load_config(), pbx_load_users(), and search_directory().
00386 { 00387 const char *tmp; 00388 tmp = ast_variable_retrieve(cfg, cat, var); 00389 if (!tmp) 00390 tmp = ast_variable_retrieve(cfg, "general", var); 00391 return tmp; 00392 }
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 837 of file config.c.
References ast_config::current.
00838 { 00839 /* cast below is just to silence compiler warning about dropping "const" */ 00840 cfg->current = (struct ast_category *) cat; 00841 }
static void ast_destroy_comments | ( | struct ast_category * | cat | ) | [static] |
Definition at line 509 of file config.c.
References free, ast_comment::next, ast_category::precomments, ast_category::sameline, and ast_category::trailing.
Referenced by ast_category_destroy().
00510 { 00511 struct ast_comment *n, *p; 00512 00513 for (p=cat->precomments; p; p=n) { 00514 n = p->next; 00515 free(p); 00516 } 00517 for (p=cat->sameline; p; p=n) { 00518 n = p->next; 00519 free(p); 00520 } 00521 for (p=cat->trailing; p; p=n) { 00522 n = p->next; 00523 free(p); 00524 } 00525 cat->precomments = NULL; 00526 cat->sameline = NULL; 00527 cat->trailing = NULL; 00528 }
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 2158 of file config.c.
References db, ast_config_engine::destroy_func, find_engine(), and table.
Referenced by function_realtime_readdestroy(), and vm_delete().
02158 { 02159 struct ast_config_engine *eng; 02160 int res = -1; 02161 char db[256]=""; 02162 char table[256]=""; 02163 va_list ap; 02164 02165 va_start(ap, lookup); 02166 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02167 if (eng && eng->destroy_func) 02168 res = eng->destroy_func(db, table, keyfield, lookup, ap); 02169 va_end(ap); 02170 02171 return res; 02172 }
static void ast_destroy_template_list | ( | struct ast_category * | cat | ) | [static] |
Definition at line 530 of file config.c.
References AST_LIST_REMOVE_HEAD, free, cache_file_include::next, and ast_category::template_instances.
Referenced by ast_category_destroy().
00531 { 00532 struct ast_category_template_instance *x; 00533 00534 while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next))) 00535 free(x); 00536 }
struct ast_config_include* ast_include_find | ( | struct ast_config * | conf, | |
const char * | included_file | |||
) |
Definition at line 316 of file config.c.
References ast_config_include::included_file, ast_config::includes, and ast_config_include::next.
Referenced by ast_include_new().
00317 { 00318 struct ast_config_include *x; 00319 for (x=conf->includes;x;x=x->next) { 00320 if (strcmp(x->included_file,included_file) == 0) 00321 return x; 00322 } 00323 return 0; 00324 }
struct ast_config_include* ast_include_new | ( | struct ast_config * | conf, | |
const char * | from_file, | |||
const char * | included_file, | |||
int | is_exec, | |||
const char * | exec_file, | |||
int | from_lineno, | |||
char * | real_included_file_name, | |||
int | real_included_file_name_size | |||
) |
Definition at line 225 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().
00226 { 00227 /* a file should be included ONCE. Otherwise, if one of the instances is changed, 00228 * then all be changed. -- how do we know to include it? -- Handling modified 00229 * instances is possible, I'd have 00230 * to create a new master for each instance. */ 00231 struct ast_config_include *inc; 00232 struct stat statbuf; 00233 00234 inc = ast_include_find(conf, included_file); 00235 if (inc) { 00236 do { 00237 inc->inclusion_count++; 00238 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count); 00239 } while (stat(real_included_file_name, &statbuf) == 0); 00240 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); 00241 } else 00242 *real_included_file_name = 0; 00243 00244 inc = ast_calloc(1,sizeof(struct ast_config_include)); 00245 inc->include_location_file = ast_strdup(from_file); 00246 inc->include_location_lineno = from_lineno; 00247 if (!ast_strlen_zero(real_included_file_name)) 00248 inc->included_file = ast_strdup(real_included_file_name); 00249 else 00250 inc->included_file = ast_strdup(included_file); 00251 00252 inc->exec = is_exec; 00253 if (is_exec) 00254 inc->exec_file = ast_strdup(exec_file); 00255 00256 /* attach this new struct to the conf struct */ 00257 inc->next = conf->includes; 00258 conf->includes = inc; 00259 00260 return inc; 00261 }
void ast_include_rename | ( | struct ast_config * | conf, | |
const char * | from_file, | |||
const char * | to_file | |||
) |
Definition at line 263 of file config.c.
References ast_category::file, ast_variable::file, free, ast_config_include::include_location_file, ast_config::includes, ast_config_include::next, ast_category::next, ast_variable::next, ast_config::root, ast_category::root, and strdup.
Referenced by action_updateconfig().
00264 { 00265 struct ast_config_include *incl; 00266 struct ast_category *cat; 00267 struct ast_variable *v; 00268 00269 int from_len = strlen(from_file); 00270 int to_len = strlen(to_file); 00271 00272 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */ 00273 return; 00274 00275 /* the manager code allows you to read in one config file, then 00276 * write it back out under a different name. But, the new arrangement 00277 * ties output lines to the file name. So, before you try to write 00278 * the config file to disk, better riffle thru the data and make sure 00279 * the file names are changed. 00280 */ 00281 /* file names are on categories, includes (of course), and on variables. So, 00282 * traverse all this and swap names */ 00283 00284 for (incl = conf->includes; incl; incl=incl->next) { 00285 if (strcmp(incl->include_location_file,from_file) == 0) { 00286 if (from_len >= to_len) 00287 strcpy(incl->include_location_file, to_file); 00288 else { 00289 free(incl->include_location_file); 00290 incl->include_location_file = strdup(to_file); 00291 } 00292 } 00293 } 00294 for (cat = conf->root; cat; cat = cat->next) { 00295 if (strcmp(cat->file,from_file) == 0) { 00296 if (from_len >= to_len) 00297 strcpy(cat->file, to_file); 00298 else { 00299 free(cat->file); 00300 cat->file = strdup(to_file); 00301 } 00302 } 00303 for (v = cat->root; v; v = v->next) { 00304 if (strcmp(v->file,from_file) == 0) { 00305 if (from_len >= to_len) 00306 strcpy(v->file, to_file); 00307 else { 00308 free(v->file); 00309 v->file = strdup(to_file); 00310 } 00311 } 00312 } 00313 } 00314 }
static void ast_includes_destroy | ( | struct ast_config_include * | incls | ) | [static] |
Definition at line 550 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().
00551 { 00552 struct ast_config_include *incl,*inclnext; 00553 00554 for (incl=incls; incl; incl = inclnext) { 00555 inclnext = incl->next; 00556 if (incl->include_location_file) 00557 free(incl->include_location_file); 00558 if (incl->exec_file) 00559 free(incl->exec_file); 00560 if (incl->included_file) 00561 free(incl->included_file); 00562 free(incl); 00563 } 00564 }
struct ast_variable* ast_load_realtime | ( | const char * | family, | |
... | ||||
) |
Retrieve realtime configuration.
family | which family/config to lookup This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. Note that unlike the variables in ast_config, the resulting list of variables MUST be freed with ast_variables_destroy() as there is no container. |
Definition at line 2062 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(), realtime_user(), and update_realtime_member_field().
02063 { 02064 struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL; 02065 va_list ap; 02066 02067 va_start(ap, family); 02068 res = ast_load_realtime_helper(family, ap); 02069 va_end(ap); 02070 02071 /* Eliminate blank entries */ 02072 for (cur = res; cur; cur = cur->next) { 02073 if (freeme) { 02074 ast_free(freeme); 02075 freeme = NULL; 02076 } 02077 02078 if (ast_strlen_zero(cur->value)) { 02079 if (prev) 02080 prev->next = cur->next; 02081 else 02082 res = cur->next; 02083 freeme = cur; 02084 } else { 02085 prev = cur; 02086 } 02087 } 02088 return res; 02089 }
struct ast_variable* ast_load_realtime_all | ( | const char * | family, | |
... | ||||
) |
Definition at line 2050 of file config.c.
References ast_load_realtime_helper().
Referenced by cli_realtime_load(), function_realtime_read(), and function_realtime_readdestroy().
02051 { 02052 struct ast_variable *res; 02053 va_list ap; 02054 02055 va_start(ap, family); 02056 res = ast_load_realtime_helper(family, ap); 02057 va_end(ap); 02058 02059 return res; 02060 }
static struct ast_variable* ast_load_realtime_helper | ( | const char * | family, | |
va_list | ap | |||
) | [static] |
Definition at line 2036 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().
02037 { 02038 struct ast_config_engine *eng; 02039 char db[256]=""; 02040 char table[256]=""; 02041 struct ast_variable *res=NULL; 02042 02043 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02044 if (eng && eng->realtime_func) 02045 res = eng->realtime_func(db, table, ap); 02046 02047 return res; 02048 }
struct ast_config* ast_load_realtime_multientry | ( | const char * | family, | |
... | ||||
) |
Retrieve realtime configuration.
family | which family/config to lookup This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. Unlike the ast_load_realtime, this function can return more than one entry and is thus stored inside a taditional ast_config structure rather than just returning a linked list of variables. |
Definition at line 2108 of file config.c.
References db, find_engine(), ast_config_engine::realtime_multi_func, and table.
Referenced by __queues_show(), load_realtime_queue(), realtime_directory(), realtime_switch_common(), show_users_realtime(), and update_realtime_members().
02109 { 02110 struct ast_config_engine *eng; 02111 char db[256]=""; 02112 char table[256]=""; 02113 struct ast_config *res=NULL; 02114 va_list ap; 02115 02116 va_start(ap, family); 02117 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02118 if (eng && eng->realtime_multi_func) 02119 res = eng->realtime_multi_func(db, table, ap); 02120 va_end(ap); 02121 02122 return res; 02123 }
int ast_parse_arg | ( | const char * | arg, | |
enum ast_parse_flags | flags, | |||
void * | result, | |||
... | ||||
) |
The argument parsing routine.
arg | the string to parse. It is not modified. | |
flags | combination of ast_parse_flags to specify the return type and additional checks. | |
result | pointer to the result. NULL is valid here, and can be used to perform only the validity checks. | |
... | extra arguments are required according to flags. |
0 | in case of success, != 0 otherwise. | |
result | returns the parsed value in case of success, the default value in case of error, or it is left unchanged in case of error and no default specified. Note that in certain cases (e.g. sockaddr_in, with multi-field return values) some of the fields in result may be changed even if an error occurs. |
Definition at line 2177 of file config.c.
References ahp, ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_strdupa, buf, hp, PARSE_DEFAULT, PARSE_DOUBLE, PARSE_IN_RANGE, PARSE_INADDR, PARSE_INT32, PARSE_OUT_RANGE, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, PARSE_PORT_REQUIRE, PARSE_TYPE, PARSE_UINT32, and strsep().
Referenced by ast_sip_ouraddrfor(), and check_via_response().
02179 { 02180 va_list ap; 02181 int error = 0; 02182 02183 va_start(ap, p_result); 02184 switch (flags & PARSE_TYPE) { 02185 case PARSE_INT32: 02186 { 02187 int32_t *result = p_result; 02188 int32_t x, def = result ? *result : 0, 02189 high = (int32_t)0x7fffffff, 02190 low = (int32_t)0x80000000; 02191 /* optional argument: first default value, then range */ 02192 if (flags & PARSE_DEFAULT) 02193 def = va_arg(ap, int32_t); 02194 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02195 /* range requested, update bounds */ 02196 low = va_arg(ap, int32_t); 02197 high = va_arg(ap, int32_t); 02198 } 02199 x = strtol(arg, NULL, 0); 02200 error = (x < low) || (x > high); 02201 if (flags & PARSE_OUT_RANGE) 02202 error = !error; 02203 if (result) 02204 *result = error ? def : x; 02205 ast_debug(3, 02206 "extract int from [%s] in [%d, %d] gives [%d](%d)\n", 02207 arg, low, high, 02208 result ? *result : x, error); 02209 break; 02210 } 02211 02212 case PARSE_UINT32: 02213 { 02214 uint32_t *result = p_result; 02215 uint32_t x, def = result ? *result : 0, 02216 low = 0, high = (uint32_t)~0; 02217 /* optional argument: first default value, then range */ 02218 if (flags & PARSE_DEFAULT) 02219 def = va_arg(ap, uint32_t); 02220 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02221 /* range requested, update bounds */ 02222 low = va_arg(ap, uint32_t); 02223 high = va_arg(ap, uint32_t); 02224 } 02225 x = strtoul(arg, NULL, 0); 02226 error = (x < low) || (x > high); 02227 if (flags & PARSE_OUT_RANGE) 02228 error = !error; 02229 if (result) 02230 *result = error ? def : x; 02231 ast_debug(3, 02232 "extract uint from [%s] in [%u, %u] gives [%u](%d)\n", 02233 arg, low, high, 02234 result ? *result : x, error); 02235 break; 02236 } 02237 02238 case PARSE_DOUBLE: 02239 { 02240 double *result = p_result; 02241 double x, def = result ? *result : 0, 02242 low = -HUGE_VAL, high = HUGE_VAL; 02243 02244 /* optional argument: first default value, then range */ 02245 if (flags & PARSE_DEFAULT) 02246 def = va_arg(ap, double); 02247 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02248 /* range requested, update bounds */ 02249 low = va_arg(ap, double); 02250 high = va_arg(ap, double); 02251 } 02252 x = strtod(arg, NULL); 02253 error = (x < low) || (x > high); 02254 if (flags & PARSE_OUT_RANGE) 02255 error = !error; 02256 if (result) 02257 *result = error ? def : x; 02258 ast_debug(3, 02259 "extract double from [%s] in [%f, %f] gives [%f](%d)\n", 02260 arg, low, high, 02261 result ? *result : x, error); 02262 break; 02263 } 02264 case PARSE_INADDR: 02265 { 02266 char *port, *buf; 02267 struct sockaddr_in _sa_buf; /* buffer for the result */ 02268 struct sockaddr_in *sa = p_result ? 02269 (struct sockaddr_in *)p_result : &_sa_buf; 02270 /* default is either the supplied value or the result itself */ 02271 struct sockaddr_in *def = (flags & PARSE_DEFAULT) ? 02272 va_arg(ap, struct sockaddr_in *) : sa; 02273 struct hostent *hp; 02274 struct ast_hostent ahp; 02275 02276 memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */ 02277 /* duplicate the string to strip away the :port */ 02278 port = ast_strdupa(arg); 02279 buf = strsep(&port, ":"); 02280 sa->sin_family = AF_INET; /* assign family */ 02281 /* 02282 * honor the ports flag setting, assign default value 02283 * in case of errors or field unset. 02284 */ 02285 flags &= PARSE_PORT_MASK; /* the only flags left to process */ 02286 if (port) { 02287 if (flags == PARSE_PORT_FORBID) { 02288 error = 1; /* port was forbidden */ 02289 sa->sin_port = def->sin_port; 02290 } else if (flags == PARSE_PORT_IGNORE) 02291 sa->sin_port = def->sin_port; 02292 else /* accept or require */ 02293 sa->sin_port = htons(strtol(port, NULL, 0)); 02294 } else { 02295 sa->sin_port = def->sin_port; 02296 if (flags == PARSE_PORT_REQUIRE) 02297 error = 1; 02298 } 02299 /* Now deal with host part, even if we have errors before. */ 02300 hp = ast_gethostbyname(buf, &ahp); 02301 if (hp) /* resolved successfully */ 02302 memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr)); 02303 else { 02304 error = 1; 02305 sa->sin_addr = def->sin_addr; 02306 } 02307 ast_debug(3, 02308 "extract inaddr from [%s] gives [%s:%d](%d)\n", 02309 arg, ast_inet_ntoa(sa->sin_addr), 02310 ntohs(sa->sin_port), error); 02311 break; 02312 } 02313 } 02314 va_end(ap); 02315 return error; 02316 }
int ast_realtime_enabled | ( | void | ) |
Check if there's any realtime engines loaded.
Definition at line 2103 of file config.c.
References config_maps.
Referenced by action_coresettings(), and handle_show_settings().
02104 { 02105 return config_maps ? 1 : 0; 02106 }
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 2142 of file config.c.
References db, find_engine(), ast_config_engine::store_func, and table.
Referenced by ast_queue_log(), and function_realtime_store().
02142 { 02143 struct ast_config_engine *eng; 02144 int res = -1; 02145 char db[256]=""; 02146 char table[256]=""; 02147 va_list ap; 02148 02149 va_start(ap, family); 02150 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02151 if (eng && eng->store_func) 02152 res = eng->store_func(db, table, ap); 02153 va_end(ap); 02154 02155 return res; 02156 }
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 2125 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(), realtime_update_peer(), rename_file(), sip_poke_noanswer(), and update_realtime_member_field().
02126 { 02127 struct ast_config_engine *eng; 02128 int res = -1; 02129 char db[256]=""; 02130 char table[256]=""; 02131 va_list ap; 02132 02133 va_start(ap, lookup); 02134 eng = find_engine(family, db, sizeof(db), table, sizeof(table)); 02135 if (eng && eng->update_func) 02136 res = eng->update_func(db, table, keyfield, lookup, ap); 02137 va_end(ap); 02138 02139 return res; 02140 }
void ast_variable_append | ( | struct ast_category * | category, | |
struct ast_variable * | variable | |||
) |
Definition at line 327 of file config.c.
References ast_category::last, ast_variable::next, and ast_category::root.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), inherit_category(), move_variables(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), and vm_change_password().
00328 { 00329 if (!variable) 00330 return; 00331 if (category->last) 00332 category->last->next = variable; 00333 else 00334 category->root = variable; 00335 category->last = variable; 00336 while (category->last->next) 00337 category->last = category->last->next; 00338 }
struct ast_variable* ast_variable_browse | ( | const struct ast_config * | config, | |
const char * | category | |||
) |
Goes through variables Somewhat similar in intent as the ast_category_browse. List variables of config file category.
ast_variable | list on success | |
NULL | on failure |
Definition at line 373 of file config.c.
References ast_category_get(), config, and ast_category::root.
Referenced by __ast_http_load(), __init_manager(), action_getconfig(), action_getconfigjson(), adsi_load(), aji_load_config(), ast_readconfig(), ast_variable_retrieve(), build_device(), collect_function_digits(), conf_exec(), config_module(), do_say(), 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(), odbc_load_module(), osp_create_provider(), parse_config(), pbx_load_config(), private_enum_init(), 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_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().
00374 { 00375 struct ast_category *cat = NULL; 00376 00377 if (category && config->last_browse && (config->last_browse->name == category)) 00378 cat = config->last_browse; 00379 else 00380 cat = ast_category_get(config, category); 00381 00382 return (cat) ? cat->root : NULL; 00383 }
int ast_variable_delete | ( | struct ast_category * | category, | |
const char * | variable, | |||
const char * | match, | |||
const char * | line | |||
) |
Definition at line 657 of file config.c.
References ast_strlen_zero(), ast_variables_destroy(), ast_category::last, ast_variable::name, ast_variable::next, ast_category::root, and ast_variable::value.
Referenced by handle_updates().
00658 { 00659 struct ast_variable *cur, *prev=NULL, *curn; 00660 int res = -1; 00661 int lineno = 0; 00662 00663 cur = category->root; 00664 while (cur) { 00665 if (cur->name == variable) { 00666 if (prev) { 00667 prev->next = cur->next; 00668 if (cur == category->last) 00669 category->last = prev; 00670 } else { 00671 category->root = cur->next; 00672 if (cur == category->last) 00673 category->last = NULL; 00674 } 00675 cur->next = NULL; 00676 ast_variables_destroy(cur); 00677 return 0; 00678 } 00679 prev = cur; 00680 cur = cur->next; 00681 } 00682 00683 prev = NULL; 00684 cur = category->root; 00685 while (cur) { 00686 curn = cur->next; 00687 if ((!ast_strlen_zero(line) && lineno == atoi(line)) || (ast_strlen_zero(line) && !strcasecmp(cur->name, variable) && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) { 00688 if (prev) { 00689 prev->next = cur->next; 00690 if (cur == category->last) 00691 category->last = prev; 00692 } else { 00693 category->root = cur->next; 00694 if (cur == category->last) 00695 category->last = NULL; 00696 } 00697 cur->next = NULL; 00698 ast_variables_destroy(cur); 00699 res = 0; 00700 } else 00701 prev = cur; 00702 00703 cur = curn; 00704 lineno++; 00705 } 00706 return res; 00707 }
void ast_variable_insert | ( | struct ast_category * | category, | |
struct ast_variable * | variable, | |||
const char * | line | |||
) |
Definition at line 340 of file config.c.
References ast_variable::next, and ast_category::root.
Referenced by handle_updates().
00341 { 00342 struct ast_variable *cur = category->root; 00343 int lineno; 00344 int insertline; 00345 00346 if (!variable || sscanf(line, "%d", &insertline) != 1) 00347 return; 00348 if (!insertline) { 00349 variable->next = category->root; 00350 category->root = variable; 00351 } else { 00352 for (lineno = 1; lineno < insertline; lineno++) { 00353 cur = cur->next; 00354 if (!cur->next) 00355 break; 00356 } 00357 variable->next = cur->next; 00358 cur->next = variable; 00359 } 00360 }
struct ast_variable* ast_variable_new | ( | const char * | name, | |
const char * | value, | |||
const char * | filename | |||
) |
Definition at line 207 of file config.c.
References ast_calloc, and ast_variable::stuff.
Referenced by add_cfg_entry(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), apply_outgoing(), ast_channeltype_list(), ast_variable_update(), astman_get_variables(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), parkandannounce_exec(), parse_cookies(), process_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(), variable_clone(), and vm_change_password().
00208 { 00209 struct ast_variable *variable; 00210 int name_len = strlen(name) + 1; 00211 int val_len = strlen(value) + 1; 00212 int fn_len = strlen(filename) + 1; 00213 00214 if ((variable = ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable)))) { 00215 char *dst = variable->stuff; /* writable space starts here */ 00216 variable->name = strcpy(dst, name); 00217 dst += name_len; 00218 variable->value = strcpy(dst, value); 00219 dst += val_len; 00220 variable->file = strcpy(dst, filename); 00221 } 00222 return variable; 00223 }
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 395 of file config.c.
References ast_variable_browse(), config, ast_variable::name, ast_variable::next, ast_category::next, ast_category::root, and ast_variable::value.
Referenced by __ast_rtp_reload(), __ast_udptl_reload(), advanced_options(), aji_load_config(), ast_config_option(), attempt_reconnect(), build_user(), config_module(), directory_exec(), do_reload(), festival_exec(), function_gosub(), function_ilink(), function_macro(), function_remote(), 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(), make_email_file(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), read_agent_config(), realtime_directory(), reload_config(), reload_followme(), reload_queues(), retrieve_astcfgint(), rpt(), rpt_master(), rpt_tele_thread(), 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().
00396 { 00397 struct ast_variable *v; 00398 00399 if (category) { 00400 for (v = ast_variable_browse(config, category); v; v = v->next) { 00401 if (!strcasecmp(variable, v->name)) 00402 return v->value; 00403 } 00404 } else { 00405 struct ast_category *cat; 00406 00407 for (cat = config->root; cat; cat = cat->next) 00408 for (v = cat->root; v; v = v->next) 00409 if (!strcasecmp(variable, v->name)) 00410 return v->value; 00411 } 00412 00413 return NULL; 00414 }
int ast_variable_update | ( | struct ast_category * | category, | |
const char * | variable, | |||
const char * | value, | |||
const char * | match, | |||
unsigned int | object | |||
) |
Definition at line 709 of file config.c.
References ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), ast_variable::blanklines, ast_variable::file, ast_category::last, ast_variable::lineno, ast_variable::name, ast_variable::next, ast_variable::object, ast_variable::precomments, ast_category::root, ast_variable::sameline, ast_variable::trailing, and ast_variable::value.
Referenced by handle_updates(), vm_change_password(), and vm_forwardoptions().
00711 { 00712 struct ast_variable *cur, *prev=NULL, *newer=NULL; 00713 00714 for (cur = category->root; cur; prev = cur, cur = cur->next) { 00715 if (strcasecmp(cur->name, variable) || 00716 (!ast_strlen_zero(match) && strcasecmp(cur->value, match))) 00717 continue; 00718 00719 if (!(newer = ast_variable_new(variable, value, cur->file))) 00720 return -1; 00721 00722 newer->next = cur->next; 00723 newer->object = cur->object || object; 00724 00725 /* Preserve everything */ 00726 newer->lineno = cur->lineno; 00727 newer->blanklines = cur->blanklines; 00728 newer->precomments = cur->precomments; cur->precomments = NULL; 00729 newer->sameline = cur->sameline; cur->sameline = NULL; 00730 newer->trailing = cur->trailing; cur->trailing = NULL; 00731 00732 if (prev) 00733 prev->next = newer; 00734 else 00735 category->root = newer; 00736 if (category->last == cur) 00737 category->last = newer; 00738 00739 cur->next = NULL; 00740 ast_variables_destroy(cur); 00741 00742 return 0; 00743 } 00744 00745 if (prev) 00746 prev->next = newer; 00747 else 00748 category->root = newer; 00749 00750 return 0; 00751 }
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 362 of file config.c.
References ast_free, and ast_variable::next.
Referenced by ast_category_destroy(), ast_category_empty(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_variable_delete(), ast_variable_update(), build_peer(), build_user(), cli_realtime_load(), destroy_dahdi_pvt(), find_conf_realtime(), find_user_realtime(), free_user(), handle_uri(), httpd_helper_thread(), ldap_loadentry(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_user(), sip_alloc(), sip_destroy_peer(), sip_destroy_user(), socket_process(), table_configs_free(), update_realtime_member_field(), and user_destructor().
00363 { 00364 struct ast_variable *vn; 00365 00366 while (v) { 00367 vn = v; 00368 v = v->next; 00369 ast_free(vn); 00370 } 00371 }
static struct ast_category* category_get | ( | const struct ast_config * | config, | |
const char * | category_name, | |||
int | ignored | |||
) | [static] |
Definition at line 450 of file config.c.
References config, ast_category::ignored, ast_category::name, and ast_category::next.
Referenced by ast_category_get(), and process_text_line().
00451 { 00452 struct ast_category *cat; 00453 00454 /* try exact match first, then case-insensitive match */ 00455 for (cat = config->root; cat; cat = cat->next) { 00456 if (cat->name == category_name && (ignored || !cat->ignored)) 00457 return cat; 00458 } 00459 00460 for (cat = config->root; cat; cat = cat->next) { 00461 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored)) 00462 return cat; 00463 } 00464 00465 return NULL; 00466 }
static void CB_ADD | ( | struct ast_str ** | cb, | |
const char * | str | |||
) | [static] |
Definition at line 87 of file config.c.
References ast_str_append().
Referenced by config_text_file_load().
00088 { 00089 ast_str_append(cb, 0, "%s", str); 00090 }
static void CB_ADD_LEN | ( | struct ast_str ** | cb, | |
const char * | str, | |||
int | len | |||
) | [static] |
Definition at line 92 of file config.c.
References ast_copy_string(), ast_str_append(), and s.
Referenced by config_text_file_load().
00093 { 00094 char *s = alloca(len + 1); 00095 ast_copy_string(s, str, len); 00096 ast_str_append(cb, 0, "%s", str); 00097 }
Definition at line 99 of file config.c.
References ast_str::used.
Referenced by config_text_file_load(), and process_text_line().
00100 { 00101 if (cb) 00102 cb->used = 0; 00103 if (llb) 00104 llb->used = 0; 00105 }
static void clear_config_maps | ( | void | ) | [static] |
Definition at line 1780 of file config.c.
References ast_free, ast_mutex_lock(), ast_mutex_unlock(), config_lock, config_maps, map, and ast_config_map::next.
Referenced by read_config_maps().
01781 { 01782 struct ast_config_map *map; 01783 01784 ast_mutex_lock(&config_lock); 01785 01786 while (config_maps) { 01787 map = config_maps; 01788 config_maps = config_maps->next; 01789 ast_free(map); 01790 } 01791 01792 ast_mutex_unlock(&config_lock); 01793 }
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 848 of file config.c.
References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, cache_file_include::list, cache_file_mtime::mtime, and cache_file_mtime::who_asked.
Referenced by process_text_line().
00849 { 00850 struct cache_file_mtime *cfmtime; 00851 struct cache_file_include *cfinclude; 00852 struct stat statbuf = { 0, }; 00853 00854 /* Find our cached entry for this configuration file */ 00855 AST_LIST_LOCK(&cfmtime_head); 00856 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 00857 if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked)) 00858 break; 00859 } 00860 if (!cfmtime) { 00861 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1 + strlen(who_asked) + 1); 00862 if (!cfmtime) { 00863 AST_LIST_UNLOCK(&cfmtime_head); 00864 return; 00865 } 00866 AST_LIST_HEAD_INIT(&cfmtime->includes); 00867 strcpy(cfmtime->filename, configfile); 00868 cfmtime->who_asked = cfmtime->filename + strlen(configfile) + 1; 00869 strcpy(cfmtime->who_asked, who_asked); 00870 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 00871 AST_LIST_INSERT_TAIL(&cfmtime_head, cfmtime, list); 00872 } 00873 00874 if (!stat(configfile, &statbuf)) 00875 cfmtime->mtime = 0; 00876 else 00877 cfmtime->mtime = statbuf.st_mtime; 00878 00879 switch (attrtype) { 00880 case ATTRIBUTE_INCLUDE: 00881 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 00882 if (!strcmp(cfinclude->include, filename)) { 00883 AST_LIST_UNLOCK(&cfmtime_head); 00884 return; 00885 } 00886 } 00887 cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1); 00888 if (!cfinclude) { 00889 AST_LIST_UNLOCK(&cfmtime_head); 00890 return; 00891 } 00892 strcpy(cfinclude->include, filename); 00893 AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list); 00894 break; 00895 case ATTRIBUTE_EXEC: 00896 cfmtime->has_exec = 1; 00897 break; 00898 } 00899 AST_LIST_UNLOCK(&cfmtime_head); 00900 }
static struct ast_config* config_text_file_load | ( | const char * | database, | |
const char * | table, | |||
const char * | filename, | |||
struct ast_config * | cfg, | |||
struct ast_flags | flags, | |||
const char * | suggested_include_file, | |||
const char * | who_asked | |||
) | [static] |
Definition at line 1120 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_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_str_create(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, buf, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, COMMENT_META, COMMENT_TAG, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, cache_file_include::list, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, cache_file_mtime::mtime, MY_GLOB_FLAGS, process_text_line(), ast_str::str, ast_variable::trailing, ast_category::trailing, ast_str::used, and cache_file_mtime::who_asked.
01121 { 01122 char fn[256]; 01123 #if defined(LOW_MEMORY) 01124 char buf[512]; 01125 #else 01126 char buf[8192]; 01127 #endif 01128 char *new_buf, *comment_p, *process_buf; 01129 FILE *f; 01130 int lineno=0; 01131 int comment = 0, nest[MAX_NESTED_COMMENTS]; 01132 struct ast_category *cat = NULL; 01133 int count = 0; 01134 struct stat statbuf; 01135 struct cache_file_mtime *cfmtime = NULL; 01136 struct cache_file_include *cfinclude; 01137 struct ast_variable *last_var = 0; 01138 struct ast_category *last_cat = 0; 01139 /*! Growable string buffer */ 01140 struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/ 01141 struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */ 01142 01143 if (cfg) 01144 cat = ast_config_get_current_category(cfg); 01145 01146 if (filename[0] == '/') { 01147 ast_copy_string(fn, filename, sizeof(fn)); 01148 } else { 01149 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 01150 } 01151 01152 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01153 comment_buffer = ast_str_create(CB_SIZE); 01154 if (comment_buffer) 01155 lline_buffer = ast_str_create(CB_SIZE); 01156 if (!lline_buffer) { 01157 if (comment_buffer) 01158 ast_free(comment_buffer); 01159 ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n"); 01160 return NULL; 01161 } 01162 } 01163 #ifdef AST_INCLUDE_GLOB 01164 { 01165 int glob_ret; 01166 glob_t globbuf; 01167 globbuf.gl_offs = 0; /* initialize it to silence gcc */ 01168 glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf); 01169 if (glob_ret == GLOB_NOSPACE) 01170 ast_log(LOG_WARNING, 01171 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn); 01172 else if (glob_ret == GLOB_ABORTED) 01173 ast_log(LOG_WARNING, 01174 "Glob Expansion of pattern '%s' failed: Read error\n", fn); 01175 else { 01176 /* loop over expanded files */ 01177 int i; 01178 for (i=0; i<globbuf.gl_pathc; i++) { 01179 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn)); 01180 #endif 01181 /* 01182 * The following is not a loop, but just a convenient way to define a block 01183 * (using do { } while(0) ), and be able to exit from it with 'continue' 01184 * or 'break' in case of errors. Nice trick. 01185 */ 01186 do { 01187 if (stat(fn, &statbuf)) 01188 continue; 01189 01190 if (!S_ISREG(statbuf.st_mode)) { 01191 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn); 01192 continue; 01193 } 01194 01195 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) { 01196 /* Find our cached entry for this configuration file */ 01197 AST_LIST_LOCK(&cfmtime_head); 01198 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 01199 if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) 01200 break; 01201 } 01202 if (!cfmtime) { 01203 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1 + strlen(who_asked) + 1); 01204 if (!cfmtime) 01205 continue; 01206 AST_LIST_HEAD_INIT(&cfmtime->includes); 01207 strcpy(cfmtime->filename, fn); 01208 cfmtime->who_asked = cfmtime->filename + strlen(fn) + 1; 01209 strcpy(cfmtime->who_asked, who_asked); 01210 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 01211 AST_LIST_INSERT_TAIL(&cfmtime_head, cfmtime, list); 01212 } 01213 } 01214 01215 if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) { 01216 /* File is unchanged, what about the (cached) includes (if any)? */ 01217 int unchanged = 1; 01218 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 01219 /* We must glob here, because if we did not, then adding a file to globbed directory would 01220 * incorrectly cause no reload to be necessary. */ 01221 char fn2[256]; 01222 #ifdef AST_INCLUDE_GLOB 01223 int glob_ret; 01224 glob_t globbuf = { .gl_offs = 0 }; 01225 glob_ret = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &globbuf); 01226 /* On error, we reparse */ 01227 if (glob_ret == GLOB_NOSPACE || glob_ret == GLOB_ABORTED) 01228 unchanged = 0; 01229 else { 01230 /* loop over expanded files */ 01231 int j; 01232 for (j = 0; j < globbuf.gl_pathc; j++) { 01233 ast_copy_string(fn2, globbuf.gl_pathv[j], sizeof(fn2)); 01234 #else 01235 ast_copy_string(fn2, cfinclude->include); 01236 #endif 01237 if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) { 01238 /* that second-to-last field needs to be looked at in this case... TODO */ 01239 unchanged = 0; 01240 /* One change is enough to short-circuit and reload the whole shebang */ 01241 break; 01242 } 01243 #ifdef AST_INCLUDE_GLOB 01244 } 01245 } 01246 #endif 01247 } 01248 01249 if (unchanged) { 01250 AST_LIST_UNLOCK(&cfmtime_head); 01251 return CONFIG_STATUS_FILEUNCHANGED; 01252 } 01253 } 01254 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01255 AST_LIST_UNLOCK(&cfmtime_head); 01256 01257 /* If cfg is NULL, then we just want an answer */ 01258 if (cfg == NULL) 01259 return NULL; 01260 01261 if (cfmtime) 01262 cfmtime->mtime = statbuf.st_mtime; 01263 01264 ast_verb(2, "Parsing '%s': ", fn); 01265 fflush(stdout); 01266 if (!(f = fopen(fn, "r"))) { 01267 ast_debug(1, "No file to parse: %s\n", fn); 01268 ast_verb(2, "Not found (%s)\n", strerror(errno)); 01269 continue; 01270 } 01271 count++; 01272 /* If we get to this point, then we're loading regardless */ 01273 ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED); 01274 ast_debug(1, "Parsing %s\n", fn); 01275 ast_verb(2, "Found\n"); 01276 while (!feof(f)) { 01277 lineno++; 01278 if (fgets(buf, sizeof(buf), f)) { 01279 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && lline_buffer->used) { 01280 CB_ADD(&comment_buffer, lline_buffer->str); /* add the current lline buffer to the comment buffer */ 01281 lline_buffer->used = 0; /* erase the lline buffer */ 01282 } 01283 01284 new_buf = buf; 01285 if (comment) 01286 process_buf = NULL; 01287 else 01288 process_buf = buf; 01289 01290 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) { 01291 /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */ 01292 CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */ 01293 continue; /* go get a new line, then */ 01294 } 01295 01296 while ((comment_p = strchr(new_buf, COMMENT_META))) { 01297 if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) { 01298 /* Escaped semicolons aren't comments. */ 01299 new_buf = comment_p + 1; 01300 } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { 01301 /* Meta-Comment start detected ";--" */ 01302 if (comment < MAX_NESTED_COMMENTS) { 01303 *comment_p = '\0'; 01304 new_buf = comment_p + 3; 01305 comment++; 01306 nest[comment-1] = lineno; 01307 } else { 01308 ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); 01309 } 01310 } else if ((comment_p >= new_buf + 2) && 01311 (*(comment_p - 1) == COMMENT_TAG) && 01312 (*(comment_p - 2) == COMMENT_TAG)) { 01313 /* Meta-Comment end detected */ 01314 comment--; 01315 new_buf = comment_p + 1; 01316 if (!comment) { 01317 /* Back to non-comment now */ 01318 if (process_buf) { 01319 /* Actually have to move what's left over the top, then continue */ 01320 char *oldptr; 01321 oldptr = process_buf + strlen(process_buf); 01322 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01323 CB_ADD(&comment_buffer, ";"); 01324 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1); 01325 } 01326 01327 memmove(oldptr, new_buf, strlen(new_buf) + 1); 01328 new_buf = oldptr; 01329 } else 01330 process_buf = new_buf; 01331 } 01332 } else { 01333 if (!comment) { 01334 /* If ; is found, and we are not nested in a comment, 01335 we immediately stop all comment processing */ 01336 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01337 CB_ADD(&lline_buffer, comment_p); 01338 } 01339 *comment_p = '\0'; 01340 new_buf = comment_p; 01341 } else 01342 new_buf = comment_p + 1; 01343 } 01344 } 01345 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) { 01346 CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */ 01347 } 01348 01349 if (process_buf) { 01350 char *buf = ast_strip(process_buf); 01351 if (!ast_strlen_zero(buf)) { 01352 if (process_text_line(cfg, &cat, buf, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) { 01353 cfg = NULL; 01354 break; 01355 } 01356 } 01357 } 01358 } 01359 } 01360 /* end of file-- anything in a comment buffer? */ 01361 if (last_cat) { 01362 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used ) { 01363 if (lline_buffer && lline_buffer->used) { 01364 CB_ADD(&comment_buffer, lline_buffer->str); /* add the current lline buffer to the comment buffer */ 01365 lline_buffer->used = 0; /* erase the lline buffer */ 01366 } 01367 last_cat->trailing = ALLOC_COMMENT(comment_buffer); 01368 } 01369 } else if (last_var) { 01370 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used ) { 01371 if (lline_buffer && lline_buffer->used) { 01372 CB_ADD(&comment_buffer, lline_buffer->str); /* add the current lline buffer to the comment buffer */ 01373 lline_buffer->used = 0; /* erase the lline buffer */ 01374 } 01375 last_var->trailing = ALLOC_COMMENT(comment_buffer); 01376 } 01377 } else { 01378 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && comment_buffer->used) { 01379 ast_debug(1, "Nothing to attach comments to, discarded: %s\n", comment_buffer->str); 01380 } 01381 } 01382 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01383 CB_RESET(comment_buffer, lline_buffer); 01384 01385 fclose(f); 01386 } while (0); 01387 if (comment) { 01388 ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]); 01389 } 01390 #ifdef AST_INCLUDE_GLOB 01391 if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED) 01392 break; 01393 } 01394 globfree(&globbuf); 01395 } 01396 } 01397 #endif 01398 01399 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01400 if (comment_buffer) 01401 ast_free(comment_buffer); 01402 if (lline_buffer) 01403 ast_free(lline_buffer); 01404 comment_buffer = NULL; 01405 lline_buffer = NULL; 01406 } 01407 01408 if (count == 0) 01409 return NULL; 01410 01411 return cfg; 01412 }
int config_text_file_save | ( | const char * | configfile, | |
const struct ast_config * | cfg, | |||
const char * | generator | |||
) |
Definition at line 1540 of file config.c.
References ao2_container_alloc(), ao2_ref(), ast_debug, AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_verb, ast_comment::cmt, errno, ast_config_include::exec, ast_config_include::exec_file, f, ast_category::file, gen_header(), hash_string(), hashtab_compare_strings(), ast_category::ignored, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config::includes, insert_leading_blank_lines(), ast_category_template_instance::inst, ast_category::lineno, ast_category::name, ast_category_template_instance::name, ast_variable::name, ast_config_include::next, ast_comment::next, cache_file_include::next, ast_variable::next, ast_category::next, option_debug, ast_config_include::output, ast_category::precomments, ast_config::root, ast_category::root, ast_category::sameline, set_fn(), ast_category::template_instances, ast_category::trailing, ast_variable::value, and var.
Referenced by action_updateconfig(), vm_change_password(), and vm_forwardoptions().
01541 { 01542 FILE *f; 01543 char fn[256]; 01544 struct ast_variable *var; 01545 struct ast_category *cat; 01546 struct ast_comment *cmt; 01547 struct ast_config_include *incl; 01548 int blanklines = 0; 01549 struct ao2_container *fileset = ao2_container_alloc(180000, hash_string, hashtab_compare_strings); 01550 struct inclfile *fi = 0; 01551 01552 /* reset all the output flags, in case this isn't our first time saving this data */ 01553 01554 for (incl=cfg->includes; incl; incl = incl->next) 01555 incl->output = 0; 01556 01557 /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions) 01558 are all truncated to zero bytes and have that nice header*/ 01559 01560 for (incl=cfg->includes; incl; incl = incl->next) 01561 { 01562 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*/ 01563 FILE *f1; 01564 01565 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 */ 01566 f1 = fopen(fn,"w"); 01567 if (f1) { 01568 gen_header(f1, configfile, fn, generator); 01569 fclose(f1); /* this should zero out the file */ 01570 } else { 01571 ast_debug(1, "Unable to open for writing: %s\n", fn); 01572 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01573 } 01574 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01575 fi = 0; 01576 } 01577 } 01578 01579 set_fn(fn, sizeof(fn), 0, configfile, fileset, &fi); /* just set fn to absolute ver of configfile */ 01580 #ifdef __CYGWIN__ 01581 if ((f = fopen(fn, "w+"))) { 01582 #else 01583 if ((f = fopen(fn, "w"))) { 01584 #endif 01585 ast_verb(2, "Saving '%s': ", fn); 01586 gen_header(f, configfile, fn, generator); 01587 cat = cfg->root; 01588 fclose(f); 01589 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01590 01591 /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */ 01592 /* since each var, cat, and associated comments can come from any file, we have to be 01593 mobile, and open each file, print, and close it on an entry-by-entry basis */ 01594 01595 while (cat) { 01596 set_fn(fn, sizeof(fn), cat->file, configfile, fileset, &fi); 01597 f = fopen(fn, "a"); 01598 if (!f) 01599 { 01600 ast_debug(1, "Unable to open for writing: %s\n", fn); 01601 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01602 ao2_ref(fileset, -1); 01603 return -1; 01604 } 01605 01606 /* dump any includes that happen before this category header */ 01607 for (incl=cfg->includes; incl; incl = incl->next) { 01608 if (strcmp(incl->include_location_file, cat->file) == 0){ 01609 if (cat->lineno > incl->include_location_lineno && !incl->output) { 01610 if (incl->exec) 01611 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01612 else 01613 fprintf(f,"#include \"%s\"\n", incl->included_file); 01614 incl->output = 1; 01615 } 01616 } 01617 } 01618 01619 insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno); 01620 /* Dump section with any appropriate comment */ 01621 for (cmt = cat->precomments; cmt; cmt=cmt->next) { 01622 char *cmtp = cmt->cmt; 01623 while (*cmtp == ';' && *(cmtp+1) == '!') { 01624 char *cmtp2 = strchr(cmtp+1, '\n'); 01625 if (cmtp2) 01626 cmtp = cmtp2+1; 01627 else cmtp = 0; 01628 } 01629 if (cmtp) 01630 fprintf(f,"%s", cmtp); 01631 } 01632 fprintf(f, "[%s]", cat->name); 01633 if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) { 01634 fprintf(f, "("); 01635 if (cat->ignored) { 01636 fprintf(f, "!"); 01637 } 01638 if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) { 01639 fprintf(f, ","); 01640 } 01641 if (!AST_LIST_EMPTY(&cat->template_instances)) { 01642 struct ast_category_template_instance *x; 01643 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01644 fprintf(f,"%s",x->name); 01645 if (x != AST_LIST_LAST(&cat->template_instances)) 01646 fprintf(f,","); 01647 } 01648 } 01649 fprintf(f, ")"); 01650 } 01651 for(cmt = cat->sameline; cmt; cmt=cmt->next) 01652 { 01653 fprintf(f,"%s", cmt->cmt); 01654 } 01655 if (!cat->sameline) 01656 fprintf(f,"\n"); 01657 for (cmt = cat->trailing; cmt; cmt=cmt->next) { 01658 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01659 fprintf(f,"%s", cmt->cmt); 01660 } 01661 fclose(f); 01662 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01663 fi = 0; 01664 01665 var = cat->root; 01666 while (var) { 01667 struct ast_category_template_instance *x; 01668 int found = 0; 01669 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01670 struct ast_variable *v; 01671 for (v = x->inst->root; v; v = v->next) { 01672 if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) { 01673 found = 1; 01674 break; 01675 } 01676 } 01677 if (found) 01678 break; 01679 } 01680 if (found) { 01681 var = var->next; 01682 continue; 01683 } 01684 set_fn(fn, sizeof(fn), var->file, configfile, fileset, &fi); 01685 f = fopen(fn, "a"); 01686 if (!f) 01687 { 01688 ast_debug(1, "Unable to open for writing: %s\n", fn); 01689 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01690 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01691 fi = 0; 01692 ao2_ref(fileset, -1); 01693 return -1; 01694 } 01695 01696 /* dump any includes that happen before this category header */ 01697 for (incl=cfg->includes; incl; incl = incl->next) { 01698 if (strcmp(incl->include_location_file, var->file) == 0){ 01699 if (var->lineno > incl->include_location_lineno && !incl->output) { 01700 if (incl->exec) 01701 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01702 else 01703 fprintf(f,"#include \"%s\"\n", incl->included_file); 01704 incl->output = 1; 01705 } 01706 } 01707 } 01708 01709 insert_leading_blank_lines(f, fi, var->precomments, var->lineno); 01710 for (cmt = var->precomments; cmt; cmt=cmt->next) { 01711 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01712 fprintf(f,"%s", cmt->cmt); 01713 } 01714 if (var->sameline) 01715 fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt); 01716 else 01717 fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value); 01718 for (cmt = var->trailing; cmt; cmt=cmt->next) { 01719 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01720 fprintf(f,"%s", cmt->cmt); 01721 } 01722 if (var->blanklines) { 01723 blanklines = var->blanklines; 01724 while (blanklines--) 01725 fprintf(f, "\n"); 01726 } 01727 01728 fclose(f); 01729 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01730 fi = 0; 01731 01732 var = var->next; 01733 } 01734 cat = cat->next; 01735 } 01736 if (!option_debug) 01737 ast_verb(2, "Saved\n"); 01738 } else { 01739 ast_debug(1, "Unable to open for writing: %s\n", fn); 01740 ast_verb(2, "Unable to write (%s)", strerror(errno)); 01741 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01742 ao2_ref(fileset, -1); 01743 return -1; 01744 } 01745 01746 /* Now, for files with trailing #include/#exec statements, 01747 we have to make sure every entry is output */ 01748 01749 for (incl=cfg->includes; incl; incl = incl->next) { 01750 if (!incl->output) { 01751 /* open the respective file */ 01752 set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset, &fi); 01753 f = fopen(fn, "a"); 01754 if (!f) 01755 { 01756 ast_debug(1, "Unable to open for writing: %s\n", fn); 01757 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01758 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01759 fi = 0; 01760 ao2_ref(fileset, -1); 01761 return -1; 01762 } 01763 01764 /* output the respective include */ 01765 if (incl->exec) 01766 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01767 else 01768 fprintf(f,"#include \"%s\"\n", incl->included_file); 01769 fclose(f); 01770 incl->output = 1; 01771 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01772 fi = 0; 01773 } 01774 } 01775 ao2_ref(fileset, -1); /* this should destroy the hash container */ 01776 01777 return 0; 01778 }
static int count_linefeeds | ( | char * | str | ) | [static] |
static int count_linefeeds_in_comments | ( | struct ast_comment * | x | ) | [static] |
Definition at line 1500 of file config.c.
References ast_comment::cmt, count_linefeeds(), and ast_comment::next.
Referenced by insert_leading_blank_lines().
01501 { 01502 int count = 0; 01503 01504 while (x) { 01505 count += count_linefeeds(x->cmt); 01506 x = x->next; 01507 } 01508 return count; 01509 }
static struct ast_config_engine* find_engine | ( | const char * | family, | |
char * | database, | |||
int | dbsiz, | |||
char * | table, | |||
int | tabsiz | |||
) | [static] |
Find realtime engine for realtime family.
Definition at line 1941 of file config.c.
References ast_copy_string(), ast_mutex_lock(), config_lock, config_maps, and map.
Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_speech_new(), ast_speech_register(), ast_store_realtime(), and ast_update_realtime().
01942 { 01943 struct ast_config_engine *eng, *ret = NULL; 01944 struct ast_config_map *map; 01945 01946 ast_mutex_lock(&config_lock); 01947 01948 for (map = config_maps; map; map = map->next) { 01949 if (!strcasecmp(family, map->name)) { 01950 if (database) 01951 ast_copy_string(database, map->database, dbsiz); 01952 if (table) 01953 ast_copy_string(table, map->table ? map->table : family, tabsiz); 01954 break; 01955 } 01956 } 01957 01958 /* Check if the required driver (engine) exist */ 01959 if (map) { 01960 for (eng = config_engine_list; !ret && eng; eng = eng->next) { 01961 if (!strcasecmp(eng->name, map->driver)) 01962 ret = eng; 01963 } 01964 } 01965 01966 ast_mutex_unlock(&config_lock); 01967 01968 /* if we found a mapping, but the engine is not available, then issue a warning */ 01969 if (map && !ret) 01970 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver); 01971 01972 return ret; 01973 }
static void gen_header | ( | FILE * | f1, | |
const char * | configfile, | |||
const char * | fn, | |||
const char * | generator | |||
) | [static] |
Definition at line 1435 of file config.c.
References ast_copy_string().
Referenced by config_text_file_save().
01436 { 01437 char date[256]=""; 01438 time_t t; 01439 01440 time(&t); 01441 ast_copy_string(date, ctime(&t), sizeof(date)); 01442 01443 fprintf(f1, ";!\n"); 01444 fprintf(f1, ";! Automatically generated configuration file\n"); 01445 if (strcmp(configfile, fn)) 01446 fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn); 01447 else 01448 fprintf(f1, ";! Filename: %s\n", configfile); 01449 fprintf(f1, ";! Generator: %s\n", generator); 01450 fprintf(f1, ";! Creation Date: %s", date); 01451 fprintf(f1, ";!\n"); 01452 }
static char* handle_cli_core_show_config_mappings | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2318 of file config.c.
References ast_cli(), ast_mutex_lock(), CLI_GENERATE, CLI_INIT, ast_cli_entry::command, config_engine_list, config_lock, config_maps, ast_cli_args::fd, map, ast_config_engine::name, ast_config_engine::next, and ast_cli_entry::usage.
02319 { 02320 struct ast_config_engine *eng; 02321 struct ast_config_map *map; 02322 02323 switch (cmd) { 02324 case CLI_INIT: 02325 e->command = "core show config mappings"; 02326 e->usage = 02327 "Usage: core show config mappings\n" 02328 " Shows the filenames to config engines.\n"; 02329 return NULL; 02330 case CLI_GENERATE: 02331 return NULL; 02332 } 02333 02334 ast_mutex_lock(&config_lock); 02335 02336 if (!config_engine_list) { 02337 ast_cli(a->fd, "No config mappings found.\n"); 02338 } else { 02339 ast_cli(a->fd, "\n\n"); 02340 for (eng = config_engine_list; eng; eng = eng->next) { 02341 ast_cli(a->fd, "\nConfig Engine: %s\n", eng->name); 02342 for (map = config_maps; map; map = map->next) { 02343 if (!strcasecmp(map->driver, eng->name)) { 02344 ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database, 02345 map->table ? map->table : map->name); 02346 } 02347 } 02348 } 02349 ast_cli(a->fd,"\n\n"); 02350 } 02351 02352 ast_mutex_unlock(&config_lock); 02353 02354 return CLI_SUCCESS; 02355 }
static int hash_string | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 125 of file config.c.
Referenced by config_text_file_save().
00126 { 00127 char *str = ((struct inclfile*)obj)->fname; 00128 int total; 00129 00130 for (total=0; *str; str++) { 00131 unsigned int tmp = total; 00132 total <<= 1; /* multiply by 2 */ 00133 total += tmp; /* multiply by 3 */ 00134 total <<= 2; /* multiply by 12 */ 00135 total += tmp; /* multiply by 13 */ 00136 00137 total += ((unsigned int)(*str)); 00138 } 00139 if (total < 0) 00140 total = -total; 00141 return total; 00142 }
static int hashtab_compare_strings | ( | void * | a, | |
void * | b, | |||
int | flags | |||
) | [static] |
Definition at line 144 of file config.c.
References CMP_MATCH, and inclfile::fname.
Referenced by config_text_file_save().
00145 { 00146 const struct inclfile *ae = a, *be = b; 00147 return !strcmp(ae->fname, be->fname) ? CMP_MATCH : 0; 00148 }
static void inclfile_destroy | ( | void * | obj | ) | [static] |
static void inherit_category | ( | struct ast_category * | new, | |
const struct ast_category * | base | |||
) | [static] |
Definition at line 636 of file config.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_variable_append(), ast_category_template_instance::inst, ast_category::name, ast_category_template_instance::name, cache_file_include::next, ast_category::root, ast_category::template_instances, var, and variable_clone().
Referenced by process_text_line().
00637 { 00638 struct ast_variable *var; 00639 struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance)); 00640 00641 strcpy(x->name, base->name); 00642 x->inst = base; 00643 AST_LIST_INSERT_TAIL(&new->template_instances, x, next); 00644 for (var = base->root; var; var = var->next) 00645 ast_variable_append(new, variable_clone(var)); 00646 }
static void insert_leading_blank_lines | ( | FILE * | fp, | |
struct inclfile * | fi, | |||
struct ast_comment * | precomments, | |||
int | lineno | |||
) | [static] |
Definition at line 1511 of file config.c.
References count_linefeeds_in_comments(), and inclfile::lineno.
Referenced by config_text_file_save().
01512 { 01513 int precomment_lines = count_linefeeds_in_comments(precomments); 01514 int i; 01515 01516 /* I don't have to worry about those ;! comments, they are 01517 stored in the precomments, but not printed back out. 01518 I did have to make sure that comments following 01519 the ;! header comments were not also deleted in the process */ 01520 if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */ 01521 return; 01522 } else if (lineno == 0) { 01523 /* Line replacements also mess things up */ 01524 return; 01525 } else if (lineno - precomment_lines - fi->lineno < 5) { 01526 /* Only insert less than 5 blank lines; if anything more occurs, 01527 * it's probably due to context deletion. */ 01528 for (i = fi->lineno; i < lineno - precomment_lines; i++) { 01529 fprintf(fp, "\n"); 01530 } 01531 } else { 01532 /* Deletion occurred - insert a single blank line, for separation of 01533 * contexts. */ 01534 fprintf(fp, "\n"); 01535 } 01536 01537 fi->lineno = lineno + 1; /* Advance the file lineno */ 01538 }
static void move_variables | ( | struct ast_category * | old, | |
struct ast_category * | new | |||
) | [static] |
Definition at line 430 of file config.c.
References ast_variable_append(), ast_category::root, and var.
Referenced by process_text_line().
00431 { 00432 struct ast_variable *var = old->root; 00433 00434 old->root = NULL; 00435 /* we can just move the entire list in a single op */ 00436 ast_variable_append(new, var); 00437 }
static struct ast_category* next_available_category | ( | struct ast_category * | cat | ) | [static] |
Definition at line 566 of file config.c.
References ast_category::ignored, and ast_category::next.
Referenced by ast_category_browse().
static int process_text_line | ( | struct ast_config * | cfg, | |
struct ast_category ** | cat, | |||
char * | buf, | |||
int | lineno, | |||
const char * | configfile, | |||
struct ast_flags | flags, | |||
struct ast_str * | comment_buffer, | |||
struct ast_str * | lline_buffer, | |||
const char * | suggested_include_file, | |||
struct ast_category ** | last_cat, | |||
struct ast_variable ** | last_var, | |||
const char * | who_asked | |||
) | [static] |
parse one line in the configuration.
* We can have a category header [foo](...) * a directive #include / #exec * or a regular line name = value *
Definition at line 909 of file config.c.
References ALLOC_COMMENT(), ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_internal_load(), ast_include_new(), ast_log(), ast_opt_exec_includes, ast_safe_system(), ast_skip_blanks(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_variable_append(), ast_variable_new(), 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::object, ast_variable::precomments, ast_category::precomments, S_OR, ast_variable::sameline, ast_category::sameline, and strsep().
Referenced by config_text_file_load().
00915 { 00916 char *c; 00917 char *cur = buf; 00918 struct ast_variable *v; 00919 char cmd[512], exec_file[512]; 00920 00921 /* Actually parse the entry */ 00922 if (cur[0] == '[') { /* A category header */ 00923 /* format is one of the following: 00924 * [foo] define a new category named 'foo' 00925 * [foo](!) define a new template category named 'foo' 00926 * [foo](+) append to category 'foo', error if foo does not exist. 00927 * [foo](a) define a new category and inherit from template a. 00928 * You can put a comma-separated list of templates and '!' and '+' 00929 * between parentheses, with obvious meaning. 00930 */ 00931 struct ast_category *newcat = NULL; 00932 char *catname; 00933 00934 c = strchr(cur, ']'); 00935 if (!c) { 00936 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); 00937 return -1; 00938 } 00939 *c++ = '\0'; 00940 cur++; 00941 if (*c++ != '(') 00942 c = NULL; 00943 catname = cur; 00944 if (!(*cat = newcat = ast_category_new(catname, 00945 S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile), 00946 lineno))) { 00947 return -1; 00948 } 00949 (*cat)->lineno = lineno; 00950 *last_var = 0; 00951 *last_cat = newcat; 00952 00953 /* add comments */ 00954 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00955 newcat->precomments = ALLOC_COMMENT(comment_buffer); 00956 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00957 newcat->sameline = ALLOC_COMMENT(lline_buffer); 00958 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00959 CB_RESET(comment_buffer, lline_buffer); 00960 00961 /* If there are options or categories to inherit from, process them now */ 00962 if (c) { 00963 if (!(cur = strchr(c, ')'))) { 00964 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile); 00965 return -1; 00966 } 00967 *cur = '\0'; 00968 while ((cur = strsep(&c, ","))) { 00969 if (!strcasecmp(cur, "!")) { 00970 (*cat)->ignored = 1; 00971 } else if (!strcasecmp(cur, "+")) { 00972 *cat = category_get(cfg, catname, 1); 00973 if (!(*cat)) { 00974 if (newcat) 00975 ast_category_destroy(newcat); 00976 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile); 00977 return -1; 00978 } 00979 if (newcat) { 00980 move_variables(newcat, *cat); 00981 ast_category_destroy(newcat); 00982 newcat = NULL; 00983 } 00984 } else { 00985 struct ast_category *base; 00986 00987 base = category_get(cfg, cur, 1); 00988 if (!base) { 00989 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile); 00990 return -1; 00991 } 00992 inherit_category(*cat, base); 00993 } 00994 } 00995 } 00996 if (newcat) 00997 ast_category_append(cfg, *cat); 00998 } else if (cur[0] == '#') { /* A directive - #include or #exec */ 00999 char *cur2; 01000 char real_inclusion_name[256]; 01001 struct ast_config_include *inclu; 01002 int do_include = 0; /* otherwise, it is exec */ 01003 01004 cur++; 01005 c = cur; 01006 while (*c && (*c > 32)) c++; 01007 if (*c) { 01008 *c = '\0'; 01009 /* Find real argument */ 01010 c = ast_skip_blanks(c + 1); 01011 if (!(*c)) 01012 c = NULL; 01013 } else 01014 c = NULL; 01015 if (!strcasecmp(cur, "include")) { 01016 do_include = 1; 01017 } else if (!strcasecmp(cur, "exec")) { 01018 if (!ast_opt_exec_includes) { 01019 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n"); 01020 return 0; /* XXX is this correct ? or we should return -1 ? */ 01021 } 01022 } else { 01023 ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile); 01024 return 0; /* XXX is this correct ? or we should return -1 ? */ 01025 } 01026 01027 if (c == NULL) { 01028 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 01029 do_include ? "include" : "exec", 01030 do_include ? "filename" : "/path/to/executable", 01031 lineno, 01032 configfile); 01033 return 0; /* XXX is this correct ? or we should return -1 ? */ 01034 } 01035 01036 /* Strip off leading and trailing "'s and <>'s */ 01037 while ((*c == '<') || (*c == '>') || (*c == '\"')) c++; 01038 /* Get rid of leading mess */ 01039 cur = c; 01040 cur2 = cur; 01041 while (!ast_strlen_zero(cur)) { 01042 c = cur + strlen(cur) - 1; 01043 if ((*c == '>') || (*c == '<') || (*c == '\"')) 01044 *c = '\0'; 01045 else 01046 break; 01047 } 01048 /* #exec </path/to/executable> 01049 We create a tmp file, then we #include it, then we delete it. */ 01050 if (!do_include) { 01051 struct timeval tv = ast_tvnow(); 01052 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01053 config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked); 01054 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)tv.tv_sec, (int)tv.tv_usec, (long)pthread_self()); 01055 snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file); 01056 ast_safe_system(cmd); 01057 cur = exec_file; 01058 } else { 01059 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01060 config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked); 01061 exec_file[0] = '\0'; 01062 } 01063 /* A #include */ 01064 /* record this inclusion */ 01065 inclu = ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name)); 01066 01067 do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0; 01068 if (!ast_strlen_zero(exec_file)) 01069 unlink(exec_file); 01070 if (!do_include) { 01071 ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur); 01072 return -1; 01073 } 01074 /* XXX otherwise what ? the default return is 0 anyways */ 01075 01076 } else { 01077 /* Just a line (variable = value) */ 01078 if (!(*cat)) { 01079 ast_log(LOG_WARNING, 01080 "parse error: No category context for line %d of %s\n", lineno, configfile); 01081 return -1; 01082 } 01083 c = strchr(cur, '='); 01084 if (c) { 01085 int object; 01086 *c = 0; 01087 c++; 01088 /* Ignore > in => */ 01089 if (*c== '>') { 01090 object = 1; 01091 c++; 01092 } else 01093 object = 0; 01094 if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) { 01095 v->lineno = lineno; 01096 v->object = object; 01097 *last_cat = 0; 01098 *last_var = v; 01099 /* Put and reset comments */ 01100 v->blanklines = 0; 01101 ast_variable_append(*cat, v); 01102 /* add comments */ 01103 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01104 v->precomments = ALLOC_COMMENT(comment_buffer); 01105 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01106 v->sameline = ALLOC_COMMENT(lline_buffer); 01107 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01108 CB_RESET(comment_buffer, lline_buffer); 01109 01110 } else { 01111 return -1; 01112 } 01113 } else { 01114 ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); 01115 } 01116 } 01117 return 0; 01118 }
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 1828 of file config.c.
References append_mapping(), ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log(), ast_variable_browse(), buf, clear_config_maps(), config, ast_flags::flags, LOG_WARNING, ast_config::max_include_level, ast_variable::name, ast_variable::next, strsep(), table, and ast_variable::value.
Referenced by main().
01829 { 01830 struct ast_config *config, *configtmp; 01831 struct ast_variable *v; 01832 char *driver, *table, *database, *stringp, *tmp; 01833 struct ast_flags flags = { 0 }; 01834 01835 clear_config_maps(); 01836 01837 configtmp = ast_config_new(); 01838 configtmp->max_include_level = 1; 01839 config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "config.c"); 01840 if (!config) { 01841 ast_config_destroy(configtmp); 01842 return 0; 01843 } 01844 01845 for (v = ast_variable_browse(config, "settings"); v; v = v->next) { 01846 char buf[512]; 01847 ast_copy_string(buf, v->value, sizeof(buf)); 01848 stringp = buf; 01849 driver = strsep(&stringp, ","); 01850 01851 if ((tmp = strchr(stringp, '\"'))) 01852 stringp = tmp; 01853 01854 /* check if the database text starts with a double quote */ 01855 if (*stringp == '"') { 01856 stringp++; 01857 database = strsep(&stringp, "\""); 01858 strsep(&stringp, ","); 01859 } else { 01860 /* apparently this text has no quotes */ 01861 database = strsep(&stringp, ","); 01862 } 01863 01864 table = strsep(&stringp, ","); 01865 01866 if (!strcmp(v->name, extconfig_conf)) { 01867 ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf); 01868 continue; 01869 } 01870 01871 if (!strcmp(v->name, "asterisk.conf")) { 01872 ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n"); 01873 continue; 01874 } 01875 01876 if (!strcmp(v->name, "logger.conf")) { 01877 ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n"); 01878 continue; 01879 } 01880 01881 if (!driver || !database) 01882 continue; 01883 if (!strcasecmp(v->name, "sipfriends")) { 01884 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"); 01885 append_mapping("sipusers", driver, database, table ? table : "sipfriends"); 01886 append_mapping("sippeers", driver, database, table ? table : "sipfriends"); 01887 } else if (!strcasecmp(v->name, "iaxfriends")) { 01888 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"); 01889 append_mapping("iaxusers", driver, database, table ? table : "iaxfriends"); 01890 append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends"); 01891 } else 01892 append_mapping(v->name, driver, database, table); 01893 } 01894 01895 ast_config_destroy(config); 01896 return 0; 01897 }
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 2361 of file config.c.
References ast_cli_register_multiple(), and cli_config.
Referenced by main().
02362 { 02363 ast_cli_register_multiple(cli_config, sizeof(cli_config) / sizeof(struct ast_cli_entry)); 02364 return 0; 02365 }
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 1463 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().
01464 { 01465 struct inclfile lookup; 01466 01467 if (!file || file[0] == 0) { 01468 if (configfile[0] == '/') 01469 ast_copy_string(fn, configfile, fn_size); 01470 else 01471 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile); 01472 } else if (file[0] == '/') 01473 ast_copy_string(fn, file, fn_size); 01474 else 01475 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file); 01476 lookup.fname = fn; 01477 *fi = ao2_find(fileset, &lookup, OBJ_POINTER); 01478 if (!(*fi)) { 01479 /* set up a file scratch pad */ 01480 struct inclfile *fx = ao2_alloc(sizeof(struct inclfile), inclfile_destroy); 01481 fx->fname = ast_strdup(fn); 01482 fx->lineno = 1; 01483 *fi = fx; 01484 ao2_link(fileset, fx); 01485 } 01486 }
static struct ast_variable* variable_clone | ( | const struct ast_variable * | old | ) | [static] |
Definition at line 416 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().
00417 { 00418 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file); 00419 00420 if (new) { 00421 new->lineno = old->lineno; 00422 new->object = old->object; 00423 new->blanklines = old->blanklines; 00424 /* TODO: clone comments? */ 00425 } 00426 00427 return new; 00428 }
struct ast_cli_entry cli_config[] [static] |
Initial value:
{ { .handler = handle_cli_core_show_config_mappings , .summary = "Display config mappings (file names to config engines)" ,__VA_ARGS__ }, }
Definition at line 2357 of file config.c.
Referenced by register_config_cli().
struct ast_config_engine* config_engine_list [static] |
Definition at line 160 of file config.c.
Referenced by ast_config_engine_deregister(), ast_config_engine_register(), ast_config_internal_load(), and handle_cli_core_show_config_mappings().
ast_mutex_t config_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 159 of file config.c.
Referenced by ast_config_engine_deregister(), ast_config_engine_register(), clear_config_maps(), find_engine(), and handle_cli_core_show_config_mappings().
struct ast_config_map * config_maps [static] |
Referenced by append_mapping(), ast_realtime_enabled(), clear_config_maps(), find_engine(), and handle_cli_core_show_config_mappings().
char* extconfig_conf = "extconfig.conf" [static] |
struct ast_config_engine text_file_engine [static] |
Initial value:
{ .name = "text", .load_func = config_text_file_load, }
Definition at line 1975 of file config.c.
Referenced by ast_config_internal_load().