#include "asterisk.h"
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include <time.h>
#include <sys/stat.h>
#include <math.h>
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/netsock2.h"
Go to the source code of this file.
Data Structures | |
struct | ast_category |
struct | ast_category::template_instance_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 void | __init_appendbuf (void) |
static struct ast_comment * | ALLOC_COMMENT (struct ast_str *buffer) |
static int | append_mapping (const char *name, const char *driver, const char *database, const char *table, int priority) |
void | ast_category_append (struct ast_config *config, struct ast_category *category) |
char * | ast_category_browse (struct ast_config *config, const char *prev) |
Goes through categories. | |
int | ast_category_delete (struct ast_config *cfg, const char *category) |
void | ast_category_destroy (struct ast_category *cat) |
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. | |
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. | |
static void | ast_comment_destroy (struct ast_comment **comment) |
void | ast_config_destroy (struct ast_config *cfg) |
Destroys a config. | |
int | ast_config_engine_deregister (struct ast_config_engine *del) |
Deregister config engine. | |
int | ast_config_engine_register (struct ast_config_engine *new) |
Register config engine. | |
ast_category * | ast_config_get_current_category (const struct ast_config *cfg) |
Retrieve the current category name being built. | |
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. | |
void | ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat) |
Set the category within the configuration as being current. | |
int | ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator) |
int | ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...) |
Destroy realtime configuration. | |
static void | ast_destroy_template_list (struct ast_category *cat) |
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. | |
char * | ast_realtime_decode_chunk (char *chunk) |
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values. | |
int | ast_realtime_enabled () |
Check if there's any realtime engines loaded. | |
char * | ast_realtime_encode_chunk (struct ast_str **dest, ssize_t maxlen, const char *chunk) |
Encodes a chunk of data for realtime. | |
int | ast_realtime_require_field (const char *family,...) |
Inform realtime what fields that may be stored. | |
int | ast_store_realtime (const char *family,...) |
Create realtime configuration. | |
int | ast_unload_realtime (const char *family) |
Release any resources cached for a realtime family. | |
int | ast_update2_realtime (const char *family,...) |
Update realtime configuration. | |
int | ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...) |
Update realtime configuration. | |
void | ast_variable_append (struct ast_category *category, struct ast_variable *variable) |
ast_variable * | ast_variable_browse (const struct ast_config *config, const char *category) |
Goes through variables. | |
int | ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line) |
void | ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line) |
ast_variable * | ast_variable_new (const char *name, const char *value, const char *filename) |
const char * | ast_variable_retrieve (const struct ast_config *config, const char *category, const char *variable) |
Gets a variable. | |
int | ast_variable_update (struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object) |
Update variable value within a config. | |
void | ast_variables_destroy (struct ast_variable *v) |
Free variable list. | |
static struct ast_category * | category_get (const struct ast_config *config, const char *category_name, int ignored) |
static void | CB_ADD (struct ast_str **cb, const char *str) |
static void | CB_ADD_LEN (struct ast_str **cb, const char *str, int len) |
static void | CB_RESET (struct ast_str *cb, struct ast_str *llb) |
static void | clear_config_maps (void) |
static void | config_cache_attribute (const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked) |
static struct ast_config * | config_text_file_load (const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) |
int | config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator) |
static int | count_linefeeds (char *str) |
static int | count_linefeeds_in_comments (struct ast_comment *x) |
static struct ast_config_engine * | find_engine (const char *family, int priority, char *database, int dbsiz, char *table, int tabsiz) |
Find realtime engine for realtime family. | |
static void | gen_header (FILE *f1, const char *configfile, const char *fn, const char *generator) |
static char * | handle_cli_config_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_config_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_core_show_config_mappings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | hash_string (const void *obj, const int flags) |
static int | hashtab_compare_strings (void *a, void *b, int flags) |
static void | inclfile_destroy (void *obj) |
static void | inherit_category (struct ast_category *new, const struct ast_category *base) |
static int | init_appendbuf (void *data) |
static void | insert_leading_blank_lines (FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno) |
static void | move_variables (struct ast_category *old, struct ast_category *new) |
static struct ast_category * | next_available_category (struct ast_category *cat) |
static int | process_text_line (struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked) |
parse one line in the configuration. | |
int | read_config_maps (void) |
Exposed re-initialization method for core process. | |
int | register_config_cli () |
Exposed initialization method for core process. | |
static void | set_fn (char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset, struct inclfile **fi) |
static struct ast_variable * | variable_clone (const struct ast_variable *old) |
Variables | |
static struct ast_threadstorage | appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , } |
static struct ast_cli_entry | cli_config [] |
static struct ast_config_engine * | config_engine_list |
static ast_mutex_t | config_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, 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 866 of file config.c.
00866 { 00867 ATTRIBUTE_INCLUDE = 0, 00868 ATTRIBUTE_EXEC = 1, 00869 };
static struct ast_comment* ALLOC_COMMENT | ( | struct ast_str * | buffer | ) | [static] |
Definition at line 118 of file config.c.
References ast_calloc, ast_str_buffer(), and ast_str_strlen().
Referenced by config_text_file_load(), and process_text_line().
00119 { 00120 struct ast_comment *x = NULL; 00121 if (!buffer || !ast_str_strlen(buffer)) { 00122 return NULL; 00123 } 00124 if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) { 00125 strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */ 00126 } 00127 return x; 00128 }
static int append_mapping | ( | const char * | name, | |
const char * | driver, | |||
const char * | database, | |||
const char * | table, | |||
int | priority | |||
) | [static] |
Definition at line 1862 of file config.c.
References ast_calloc, ast_verb, config_maps, and map.
Referenced by read_config_maps().
01863 { 01864 struct ast_config_map *map; 01865 int length; 01866 01867 length = sizeof(*map); 01868 length += strlen(name) + 1; 01869 length += strlen(driver) + 1; 01870 length += strlen(database) + 1; 01871 if (table) 01872 length += strlen(table) + 1; 01873 01874 if (!(map = ast_calloc(1, length))) 01875 return -1; 01876 01877 map->name = map->stuff; 01878 strcpy(map->name, name); 01879 map->driver = map->name + strlen(map->name) + 1; 01880 strcpy(map->driver, driver); 01881 map->database = map->driver + strlen(map->driver) + 1; 01882 strcpy(map->database, database); 01883 if (table) { 01884 map->table = map->database + strlen(map->database) + 1; 01885 strcpy(map->table, table); 01886 } 01887 map->priority = priority; 01888 map->next = config_maps; 01889 01890 ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name); 01891 01892 config_maps = map; 01893 return 0; 01894 }
void ast_category_append | ( | struct ast_config * | config, | |
struct ast_category * | category | |||
) |
Definition at line 524 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(), realtime_multi_pgsql(), and write_password_to_file().
00525 { 00526 if (config->last) 00527 config->last->next = category; 00528 else 00529 config->root = category; 00530 category->include_level = config->include_level; 00531 config->last = category; 00532 config->current = category; 00533 }
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. |
a | category on success | |
NULL | on failure/no-more-categories |
Definition at line 615 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(), ast_cli_perms_init(), complete_sipnotify(), conf_exec(), config_load(), get_insecure_variable_from_config(), gtalk_load_config(), iax_provision_reload(), jingle_load_config(), load_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_tech_calendars(), misdn_cfg_init(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), queues_data_provider_get(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().
00616 { 00617 struct ast_category *cat = NULL; 00618 00619 if (prev && config->last_browse && (config->last_browse->name == prev)) 00620 cat = config->last_browse->next; 00621 else if (!prev && config->root) 00622 cat = config->root; 00623 else if (prev) { 00624 for (cat = config->root; cat; cat = cat->next) { 00625 if (cat->name == prev) { 00626 cat = cat->next; 00627 break; 00628 } 00629 } 00630 if (!cat) { 00631 for (cat = config->root; cat; cat = cat->next) { 00632 if (!strcasecmp(cat->name, prev)) { 00633 cat = cat->next; 00634 break; 00635 } 00636 } 00637 } 00638 } 00639 00640 if (cat) 00641 cat = next_available_category(cat); 00642 00643 config->last_browse = cat; 00644 return (cat) ? cat->name : NULL; 00645 }
int ast_category_delete | ( | struct ast_config * | cfg, | |
const char * | category | |||
) |
Definition at line 776 of file config.c.
References ast_category_destroy(), ast_config::last, ast_category::next, and ast_config::root.
Referenced by handle_updates().
00777 { 00778 struct ast_category *prev=NULL, *cat; 00779 00780 cat = cfg->root; 00781 while (cat) { 00782 if (cat->name == category) { 00783 if (prev) { 00784 prev->next = cat->next; 00785 if (cat == cfg->last) 00786 cfg->last = prev; 00787 } else { 00788 cfg->root = cat->next; 00789 if (cat == cfg->last) 00790 cfg->last = NULL; 00791 } 00792 ast_category_destroy(cat); 00793 return 0; 00794 } 00795 prev = cat; 00796 cat = cat->next; 00797 } 00798 00799 prev = NULL; 00800 cat = cfg->root; 00801 while (cat) { 00802 if (!strcasecmp(cat->name, category)) { 00803 if (prev) { 00804 prev->next = cat->next; 00805 if (cat == cfg->last) 00806 cfg->last = prev; 00807 } else { 00808 cfg->root = cat->next; 00809 if (cat == cfg->last) 00810 cfg->last = NULL; 00811 } 00812 ast_category_destroy(cat); 00813 return 0; 00814 } 00815 prev = cat; 00816 cat = cat->next; 00817 } 00818 return -1; 00819 }
void ast_category_destroy | ( | struct ast_category * | cat | ) |
Definition at line 563 of file config.c.
References ast_comment_destroy(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, free, ast_category::precomments, ast_category::root, ast_category::sameline, and ast_category::trailing.
Referenced by add_cfg_entry(), ast_category_delete(), ast_config_destroy(), process_text_line(), and realtime_multi_odbc().
00564 { 00565 ast_variables_destroy(cat->root); 00566 if (cat->file) { 00567 free(cat->file); 00568 cat->file = 0; 00569 } 00570 ast_comment_destroy(&cat->precomments); 00571 ast_comment_destroy(&cat->sameline); 00572 ast_comment_destroy(&cat->trailing); 00573 ast_destroy_template_list(cat); 00574 ast_free(cat); 00575 }
struct ast_variable* ast_category_detach_variables | ( | struct ast_category * | cat | ) |
Definition at line 647 of file config.c.
References ast_category::last, and ast_category::root.
Referenced by realtime_switch_common().
00648 { 00649 struct ast_variable *v; 00650 00651 v = cat->root; 00652 cat->root = NULL; 00653 cat->last = NULL; 00654 00655 return v; 00656 }
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 821 of file config.c.
References ast_variables_destroy(), ast_category::last, ast_category::name, ast_category::next, ast_category::root, and ast_config::root.
Referenced by handle_updates().
00822 { 00823 struct ast_category *cat; 00824 00825 for (cat = cfg->root; cat; cat = cat->next) { 00826 if (!strcasecmp(cat->name, category)) 00827 continue; 00828 ast_variables_destroy(cat->root); 00829 cat->root = NULL; 00830 cat->last = NULL; 00831 return 0; 00832 } 00833 00834 return -1; 00835 }
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 |
Definition at line 519 of file config.c.
References ast_category_get(), and config.
00520 { 00521 return !!ast_category_get(config, category_name); 00522 }
struct ast_variable* ast_category_first | ( | struct ast_category * | cat | ) |
given a pointer to a category, return the root variable.
return the first var of a category
Definition at line 601 of file config.c.
References ast_category::root.
Referenced by process_text_line().
struct ast_category* ast_category_get | ( | const struct ast_config * | config, | |
const char * | category_name | |||
) |
Retrieve a category if it exists.
config | which config to use | |
category_name | name of the category you're looking for |
pointer | to category if found | |
NULL | if not. |
Definition at line 514 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().
00515 { 00516 return category_get(config, category_name, 0); 00517 }
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 |
Definition at line 535 of file config.c.
References config, ast_category::name, and ast_category::next.
Referenced by handle_updates().
00536 { 00537 struct ast_category *cur_category; 00538 00539 if (!cat || !match) 00540 return; 00541 if (!strcasecmp(config->root->name, match)) { 00542 cat->next = config->root; 00543 config->root = cat; 00544 return; 00545 } 00546 for (cur_category = config->root; cur_category; cur_category = cur_category->next) { 00547 if (!strcasecmp(cur_category->next->name, match)) { 00548 cat->next = cur_category->next; 00549 cur_category->next = cat; 00550 break; 00551 } 00552 } 00553 }
struct ast_category* ast_category_new | ( | const char * | name, | |
const char * | in_file, | |||
int | lineno | |||
) |
Create a category structure.
Definition at line 485 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(), realtime_multi_pgsql(), and write_password_to_file().
00486 { 00487 struct ast_category *category; 00488 00489 if ((category = ast_calloc(1, sizeof(*category)))) 00490 ast_copy_string(category->name, name, sizeof(category->name)); 00491 category->file = strdup(in_file); 00492 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */ 00493 return category; 00494 }
void ast_category_rename | ( | struct ast_category * | cat, | |
const char * | name | |||
) |
Definition at line 658 of file config.c.
References ast_copy_string(), and ast_category::name.
Referenced by handle_updates(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00659 { 00660 ast_copy_string(cat->name, name, sizeof(cat->name)); 00661 }
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 606 of file config.c.
References ast_category_get(), config, and ast_category::root.
Referenced by get_insecure_variable_from_config().
00607 { 00608 struct ast_category *category = ast_category_get(config, cat); 00609 00610 if (category) 00611 return category->root; 00612 return NULL; 00613 }
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 2178 of file config.c.
References ast_realtime_enabled(), and find_engine().
Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_queue_log(), close_mailbox(), copy_plain_file(), destroy_association(), find_realtime_gw(), handle_response_peerpoke(), handle_voicemail_show_users(), load_module(), load_moh_classes(), local_ast_moh_start(), logger_queue_init(), realtime_peer(), realtime_update_peer(), reload_logger(), rename_file(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().
02179 { 02180 struct ast_config_engine *eng; 02181 if (!ast_realtime_enabled()) { 02182 return 0; /* There are no engines at all so fail early */ 02183 } 02184 02185 eng = find_engine(family, 1, NULL, 0, NULL, 0); 02186 if (eng) 02187 return 1; 02188 return 0; 02189 }
static void ast_comment_destroy | ( | struct ast_comment ** | comment | ) | [static] |
Definition at line 387 of file config.c.
References ast_free, comment, and ast_comment::next.
Referenced by ast_category_destroy(), and ast_variables_destroy().
00388 { 00389 struct ast_comment *n, *p; 00390 00391 for (p = *comment; p; p = n) { 00392 n = p->next; 00393 ast_free(p); 00394 } 00395 00396 *comment = NULL; 00397 }
void ast_config_destroy | ( | struct ast_config * | config | ) |
Destroys a config.
config | pointer to config data structure |
Definition at line 837 of file config.c.
References ast_category_destroy(), ast_free, ast_includes_destroy(), ast_config::includes, ast_category::next, and ast_config::root.
Referenced by __ast_http_post_load(), __ast_udptl_reload(), __queues_show(), _dsp_init(), action_getconfig(), action_listcategories(), action_updateconfig(), advanced_options(), ast_config_load2(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), handle_cli_dialplan_save(), iax_provision_reload(), initialize_cc_max_requests(), load_config(), load_config_meetme(), load_indications(), load_module(), load_realtime_queue(), load_rpt_vars(), make_email_file(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queues_data_provider_get(), read_agent_config(), read_config_maps(), realtime_directory(), realtime_multi_handler(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), rpt_master(), rtp_reload(), run_startup_commands(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), store_config(), tds_load_module(), unload_module(), update_realtime_members(), and vm_forwardoptions().
00838 { 00839 struct ast_category *cat, *catn; 00840 00841 if (!cfg) 00842 return; 00843 00844 ast_includes_destroy(cfg->includes); 00845 00846 cat = cfg->root; 00847 while (cat) { 00848 catn = cat; 00849 cat = cat->next; 00850 ast_category_destroy(catn); 00851 } 00852 ast_free(cfg); 00853 }
int ast_config_engine_deregister | ( | struct ast_config_engine * | del | ) |
Deregister config engine.
0 | Always |
Definition at line 1993 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().
01994 { 01995 struct ast_config_engine *ptr, *last=NULL; 01996 01997 ast_mutex_lock(&config_lock); 01998 01999 for (ptr = config_engine_list; ptr; ptr=ptr->next) { 02000 if (ptr == del) { 02001 if (last) 02002 last->next = ptr->next; 02003 else 02004 config_engine_list = ptr->next; 02005 break; 02006 } 02007 last = ptr; 02008 } 02009 02010 ast_mutex_unlock(&config_lock); 02011 02012 return 0; 02013 }
int ast_config_engine_register | ( | struct ast_config_engine * | newconfig | ) |
Register config engine.
1 | Always |
Definition at line 1974 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().
01975 { 01976 struct ast_config_engine *ptr; 01977 01978 ast_mutex_lock(&config_lock); 01979 01980 if (!config_engine_list) { 01981 config_engine_list = new; 01982 } else { 01983 for (ptr = config_engine_list; ptr->next; ptr=ptr->next); 01984 ptr->next = new; 01985 } 01986 01987 ast_mutex_unlock(&config_lock); 01988 ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name); 01989 01990 return 1; 01991 }
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 855 of file config.c.
References ast_config::current.
Referenced by config_curl(), config_odbc(), and config_text_file_load().
00856 { 00857 return cfg->current; 00858 }
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 2055 of file config.c.
References ast_log(), ast_test_flag, config_engine_list, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, db, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, table, and text_file_engine.
Referenced by add_cfg_entry(), ast_config_load2(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), process_text_line(), and read_config_maps().
02056 { 02057 char db[256]; 02058 char table[256]; 02059 struct ast_config_engine *loader = &text_file_engine; 02060 struct ast_config *result; 02061 02062 /* The config file itself bumps include_level by 1 */ 02063 if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) { 02064 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level); 02065 return NULL; 02066 } 02067 02068 cfg->include_level++; 02069 02070 if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) { 02071 struct ast_config_engine *eng; 02072 02073 eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table)); 02074 02075 02076 if (eng && eng->load_func) { 02077 loader = eng; 02078 } else { 02079 eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table)); 02080 if (eng && eng->load_func) 02081 loader = eng; 02082 } 02083 } 02084 02085 result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked); 02086 02087 if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED) 02088 result->include_level--; 02089 else if (result != CONFIG_STATUS_FILEINVALID) 02090 cfg->include_level--; 02091 02092 return result; 02093 }
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 | |
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 2095 of file config.c.
References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), CONFIG_STATUS_FILEINVALID, and CONFIG_STATUS_FILEUNCHANGED.
Referenced by __ast_http_load(), __ast_http_post_load(), __ast_udptl_reload(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_cli_perms_init(), ast_readconfig(), do_reload(), iax_provision_reload(), init_logger_chain(), initialize_cc_max_requests(), load_config(), load_indications(), load_modules(), misdn_cfg_init(), private_enum_init(), rtp_reload(), run_startup_commands(), and set_config().
02096 { 02097 struct ast_config *cfg; 02098 struct ast_config *result; 02099 02100 cfg = ast_config_new(); 02101 if (!cfg) 02102 return NULL; 02103 02104 result = ast_config_internal_load(filename, cfg, flags, "", who_asked); 02105 if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID) 02106 ast_config_destroy(cfg); 02107 02108 return result; 02109 }
struct ast_config* ast_config_new | ( | void | ) |
Create a new base configuration structure.
Definition at line 675 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(), realtime_multi_pgsql(), and write_password_to_file().
00676 { 00677 struct ast_config *config; 00678 00679 if ((config = ast_calloc(1, sizeof(*config)))) 00680 config->max_include_level = MAX_INCLUDE_LEVEL; 00681 return config; 00682 }
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 426 of file config.c.
References ast_variable_retrieve().
Referenced by load_config(), pbx_load_users(), and search_directory_sub().
00427 { 00428 const char *tmp; 00429 tmp = ast_variable_retrieve(cfg, cat, var); 00430 if (!tmp) { 00431 tmp = ast_variable_retrieve(cfg, "general", var); 00432 } 00433 return tmp; 00434 }
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 860 of file config.c.
References ast_config::current.
00861 { 00862 /* cast below is just to silence compiler warning about dropping "const" */ 00863 cfg->current = (struct ast_category *) cat; 00864 }
int ast_config_text_file_save | ( | const char * | configfile, | |
const struct ast_config * | cfg, | |||
const char * | generator | |||
) |
Definition at line 1607 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_variable::name, ast_category_template_instance::name, ast_category::name, ast_category::next, ast_variable::next, ast_category_template_instance::next, ast_comment::next, ast_config_include::next, option_debug, ast_config_include::output, ast_category::precomments, ast_category::root, ast_config::root, ast_category::sameline, set_fn(), ast_category::template_instances, ast_category::trailing, ast_variable::value, and var.
Referenced by action_updateconfig(), config_text_file_save(), vm_change_password(), vm_forwardoptions(), and write_password_to_file().
01608 { 01609 FILE *f; 01610 char fn[256]; 01611 struct ast_variable *var; 01612 struct ast_category *cat; 01613 struct ast_comment *cmt; 01614 struct ast_config_include *incl; 01615 int blanklines = 0; 01616 struct ao2_container *fileset = ao2_container_alloc(180000, hash_string, hashtab_compare_strings); 01617 struct inclfile *fi = 0; 01618 01619 /* reset all the output flags, in case this isn't our first time saving this data */ 01620 01621 for (incl=cfg->includes; incl; incl = incl->next) 01622 incl->output = 0; 01623 01624 /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions) 01625 are all truncated to zero bytes and have that nice header*/ 01626 01627 for (incl=cfg->includes; incl; incl = incl->next) 01628 { 01629 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*/ 01630 FILE *f1; 01631 01632 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 */ 01633 f1 = fopen(fn,"w"); 01634 if (f1) { 01635 gen_header(f1, configfile, fn, generator); 01636 fclose(f1); /* this should zero out the file */ 01637 } else { 01638 ast_debug(1, "Unable to open for writing: %s\n", fn); 01639 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01640 } 01641 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01642 fi = 0; 01643 } 01644 } 01645 01646 set_fn(fn, sizeof(fn), 0, configfile, fileset, &fi); /* just set fn to absolute ver of configfile */ 01647 #ifdef __CYGWIN__ 01648 if ((f = fopen(fn, "w+"))) { 01649 #else 01650 if ((f = fopen(fn, "w"))) { 01651 #endif 01652 ast_verb(2, "Saving '%s': ", fn); 01653 gen_header(f, configfile, fn, generator); 01654 cat = cfg->root; 01655 fclose(f); 01656 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01657 01658 /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */ 01659 /* since each var, cat, and associated comments can come from any file, we have to be 01660 mobile, and open each file, print, and close it on an entry-by-entry basis */ 01661 01662 while (cat) { 01663 set_fn(fn, sizeof(fn), cat->file, configfile, fileset, &fi); 01664 f = fopen(fn, "a"); 01665 if (!f) 01666 { 01667 ast_debug(1, "Unable to open for writing: %s\n", fn); 01668 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01669 ao2_ref(fileset, -1); 01670 return -1; 01671 } 01672 01673 /* dump any includes that happen before this category header */ 01674 for (incl=cfg->includes; incl; incl = incl->next) { 01675 if (strcmp(incl->include_location_file, cat->file) == 0){ 01676 if (cat->lineno > incl->include_location_lineno && !incl->output) { 01677 if (incl->exec) 01678 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01679 else 01680 fprintf(f,"#include \"%s\"\n", incl->included_file); 01681 incl->output = 1; 01682 } 01683 } 01684 } 01685 01686 insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno); 01687 /* Dump section with any appropriate comment */ 01688 for (cmt = cat->precomments; cmt; cmt=cmt->next) { 01689 char *cmtp = cmt->cmt; 01690 while (*cmtp == ';' && *(cmtp+1) == '!') { 01691 char *cmtp2 = strchr(cmtp+1, '\n'); 01692 if (cmtp2) 01693 cmtp = cmtp2+1; 01694 else cmtp = 0; 01695 } 01696 if (cmtp) 01697 fprintf(f,"%s", cmtp); 01698 } 01699 fprintf(f, "[%s]", cat->name); 01700 if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) { 01701 fprintf(f, "("); 01702 if (cat->ignored) { 01703 fprintf(f, "!"); 01704 } 01705 if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) { 01706 fprintf(f, ","); 01707 } 01708 if (!AST_LIST_EMPTY(&cat->template_instances)) { 01709 struct ast_category_template_instance *x; 01710 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01711 fprintf(f,"%s",x->name); 01712 if (x != AST_LIST_LAST(&cat->template_instances)) 01713 fprintf(f,","); 01714 } 01715 } 01716 fprintf(f, ")"); 01717 } 01718 for(cmt = cat->sameline; cmt; cmt=cmt->next) 01719 { 01720 fprintf(f,"%s", cmt->cmt); 01721 } 01722 if (!cat->sameline) 01723 fprintf(f,"\n"); 01724 for (cmt = cat->trailing; cmt; cmt=cmt->next) { 01725 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01726 fprintf(f,"%s", cmt->cmt); 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 = cat->root; 01733 while (var) { 01734 struct ast_category_template_instance *x; 01735 int found = 0; 01736 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01737 struct ast_variable *v; 01738 for (v = x->inst->root; v; v = v->next) { 01739 if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) { 01740 found = 1; 01741 break; 01742 } 01743 } 01744 if (found) 01745 break; 01746 } 01747 if (found) { 01748 var = var->next; 01749 continue; 01750 } 01751 set_fn(fn, sizeof(fn), var->file, configfile, fileset, &fi); 01752 f = fopen(fn, "a"); 01753 if (!f) 01754 { 01755 ast_debug(1, "Unable to open for writing: %s\n", fn); 01756 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01757 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01758 fi = 0; 01759 ao2_ref(fileset, -1); 01760 return -1; 01761 } 01762 01763 /* dump any includes that happen before this category header */ 01764 for (incl=cfg->includes; incl; incl = incl->next) { 01765 if (strcmp(incl->include_location_file, var->file) == 0){ 01766 if (var->lineno > incl->include_location_lineno && !incl->output) { 01767 if (incl->exec) 01768 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01769 else 01770 fprintf(f,"#include \"%s\"\n", incl->included_file); 01771 incl->output = 1; 01772 } 01773 } 01774 } 01775 01776 insert_leading_blank_lines(f, fi, var->precomments, var->lineno); 01777 for (cmt = var->precomments; cmt; cmt=cmt->next) { 01778 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01779 fprintf(f,"%s", cmt->cmt); 01780 } 01781 if (var->sameline) 01782 fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt); 01783 else 01784 fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value); 01785 for (cmt = var->trailing; cmt; cmt=cmt->next) { 01786 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01787 fprintf(f,"%s", cmt->cmt); 01788 } 01789 if (var->blanklines) { 01790 blanklines = var->blanklines; 01791 while (blanklines--) 01792 fprintf(f, "\n"); 01793 } 01794 01795 fclose(f); 01796 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01797 fi = 0; 01798 01799 var = var->next; 01800 } 01801 cat = cat->next; 01802 } 01803 if (!option_debug) 01804 ast_verb(2, "Saved\n"); 01805 } else { 01806 ast_debug(1, "Unable to open for writing: %s\n", fn); 01807 ast_verb(2, "Unable to write (%s)", strerror(errno)); 01808 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01809 ao2_ref(fileset, -1); 01810 return -1; 01811 } 01812 01813 /* Now, for files with trailing #include/#exec statements, 01814 we have to make sure every entry is output */ 01815 01816 for (incl=cfg->includes; incl; incl = incl->next) { 01817 if (!incl->output) { 01818 /* open the respective file */ 01819 set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset, &fi); 01820 f = fopen(fn, "a"); 01821 if (!f) 01822 { 01823 ast_debug(1, "Unable to open for writing: %s\n", fn); 01824 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01825 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01826 fi = 0; 01827 ao2_ref(fileset, -1); 01828 return -1; 01829 } 01830 01831 /* output the respective include */ 01832 if (incl->exec) 01833 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01834 else 01835 fprintf(f,"#include \"%s\"\n", incl->included_file); 01836 fclose(f); 01837 incl->output = 1; 01838 ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */ 01839 fi = 0; 01840 } 01841 } 01842 ao2_ref(fileset, -1); /* this should destroy the hash container */ 01843 01844 return 0; 01845 }
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. |
Definition at line 2336 of file config.c.
References db, ast_config_engine::destroy_func, find_engine(), and table.
Referenced by cli_realtime_destroy(), function_realtime_readdestroy(), and vm_delete().
02337 { 02338 struct ast_config_engine *eng; 02339 int res = -1, i; 02340 char db[256]; 02341 char table[256]; 02342 va_list ap; 02343 02344 va_start(ap, lookup); 02345 for (i = 1; ; i++) { 02346 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02347 if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, ap))) { 02348 break; 02349 } 02350 } else { 02351 break; 02352 } 02353 } 02354 va_end(ap); 02355 02356 return res; 02357 }
static void ast_destroy_template_list | ( | struct ast_category * | cat | ) | [static] |
Definition at line 555 of file config.c.
References AST_LIST_REMOVE_HEAD, free, ast_category_template_instance::next, and ast_category::template_instances.
Referenced by ast_category_destroy().
00556 { 00557 struct ast_category_template_instance *x; 00558 00559 while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next))) 00560 free(x); 00561 }
struct ast_config_include* ast_include_find | ( | struct ast_config * | conf, | |
const char * | included_file | |||
) |
Definition at line 339 of file config.c.
References ast_config_include::included_file, ast_config::includes, and ast_config_include::next.
Referenced by ast_include_new().
00340 { 00341 struct ast_config_include *x; 00342 for (x=conf->includes;x;x=x->next) { 00343 if (strcmp(x->included_file,included_file) == 0) 00344 return x; 00345 } 00346 return 0; 00347 }
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 248 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().
00249 { 00250 /* a file should be included ONCE. Otherwise, if one of the instances is changed, 00251 * then all be changed. -- how do we know to include it? -- Handling modified 00252 * instances is possible, I'd have 00253 * to create a new master for each instance. */ 00254 struct ast_config_include *inc; 00255 struct stat statbuf; 00256 00257 inc = ast_include_find(conf, included_file); 00258 if (inc) { 00259 do { 00260 inc->inclusion_count++; 00261 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count); 00262 } while (stat(real_included_file_name, &statbuf) == 0); 00263 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); 00264 } else 00265 *real_included_file_name = 0; 00266 00267 inc = ast_calloc(1,sizeof(struct ast_config_include)); 00268 inc->include_location_file = ast_strdup(from_file); 00269 inc->include_location_lineno = from_lineno; 00270 if (!ast_strlen_zero(real_included_file_name)) 00271 inc->included_file = ast_strdup(real_included_file_name); 00272 else 00273 inc->included_file = ast_strdup(included_file); 00274 00275 inc->exec = is_exec; 00276 if (is_exec) 00277 inc->exec_file = ast_strdup(exec_file); 00278 00279 /* attach this new struct to the conf struct */ 00280 inc->next = conf->includes; 00281 conf->includes = inc; 00282 00283 return inc; 00284 }
void ast_include_rename | ( | struct ast_config * | conf, | |
const char * | from_file, | |||
const char * | to_file | |||
) |
Definition at line 286 of file config.c.
References ast_variable::file, ast_category::file, free, ast_config_include::include_location_file, ast_config::includes, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, ast_config::root, and strdup.
Referenced by action_updateconfig().
00287 { 00288 struct ast_config_include *incl; 00289 struct ast_category *cat; 00290 struct ast_variable *v; 00291 00292 int from_len = strlen(from_file); 00293 int to_len = strlen(to_file); 00294 00295 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */ 00296 return; 00297 00298 /* the manager code allows you to read in one config file, then 00299 * write it back out under a different name. But, the new arrangement 00300 * ties output lines to the file name. So, before you try to write 00301 * the config file to disk, better riffle thru the data and make sure 00302 * the file names are changed. 00303 */ 00304 /* file names are on categories, includes (of course), and on variables. So, 00305 * traverse all this and swap names */ 00306 00307 for (incl = conf->includes; incl; incl=incl->next) { 00308 if (strcmp(incl->include_location_file,from_file) == 0) { 00309 if (from_len >= to_len) 00310 strcpy(incl->include_location_file, to_file); 00311 else { 00312 free(incl->include_location_file); 00313 incl->include_location_file = strdup(to_file); 00314 } 00315 } 00316 } 00317 for (cat = conf->root; cat; cat = cat->next) { 00318 if (strcmp(cat->file,from_file) == 0) { 00319 if (from_len >= to_len) 00320 strcpy(cat->file, to_file); 00321 else { 00322 free(cat->file); 00323 cat->file = strdup(to_file); 00324 } 00325 } 00326 for (v = cat->root; v; v = v->next) { 00327 if (strcmp(v->file,from_file) == 0) { 00328 if (from_len >= to_len) 00329 strcpy(v->file, to_file); 00330 else { 00331 free(v->file); 00332 v->file = strdup(to_file); 00333 } 00334 } 00335 } 00336 } 00337 }
static void ast_includes_destroy | ( | struct ast_config_include * | incls | ) | [static] |
Definition at line 577 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().
00578 { 00579 struct ast_config_include *incl,*inclnext; 00580 00581 for (incl=incls; incl; incl = inclnext) { 00582 inclnext = incl->next; 00583 if (incl->include_location_file) 00584 free(incl->include_location_file); 00585 if (incl->exec_file) 00586 free(incl->exec_file); 00587 if (incl->included_file) 00588 free(incl->included_file); 00589 free(incl); 00590 } 00591 }
struct ast_variable* ast_load_realtime | ( | const char * | family, | |
... | ||||
) |
Retrieve realtime configuration.
family | which family/config to lookup |
The difference between these two calls is that ast_load_realtime excludes fields whose values are NULL, while ast_load_realtime_all loads all columns.
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2144 of file config.c.
References ast_free, ast_load_realtime_helper(), ast_strlen_zero(), ast_variable::next, and ast_variable::value.
Referenced by conf_run(), copy_plain_file(), find_conf_realtime(), find_realtime(), find_realtime_gw(), find_user_realtime(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), queue_function_queuewaitingcount(), realtime_alias(), realtime_peer(), realtime_switch_common(), realtime_user(), and rt_extend_conf().
02145 { 02146 struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL; 02147 va_list ap; 02148 02149 va_start(ap, family); 02150 res = ast_load_realtime_helper(family, ap); 02151 va_end(ap); 02152 02153 /* Eliminate blank entries */ 02154 for (cur = res; cur; cur = cur->next) { 02155 if (freeme) { 02156 ast_free(freeme); 02157 freeme = NULL; 02158 } 02159 02160 if (ast_strlen_zero(cur->value)) { 02161 if (prev) 02162 prev->next = cur->next; 02163 else 02164 res = cur->next; 02165 freeme = cur; 02166 } else if (cur->value[0] == ' ' && cur->value[1] == '\0') { 02167 char *vptr = (char *) cur->value; 02168 vptr[0] = '\0'; 02169 prev = cur; 02170 } else { 02171 prev = cur; 02172 } 02173 } 02174 return res; 02175 }
struct ast_variable* ast_load_realtime_all | ( | const char * | family, | |
... | ||||
) |
Definition at line 2132 of file config.c.
References ast_load_realtime_helper().
Referenced by cli_realtime_load(), function_realtime_read(), function_realtime_readdestroy(), and realtimefield_read().
02133 { 02134 struct ast_variable *res; 02135 va_list ap; 02136 02137 va_start(ap, family); 02138 res = ast_load_realtime_helper(family, ap); 02139 va_end(ap); 02140 02141 return res; 02142 }
static struct ast_variable* ast_load_realtime_helper | ( | const char * | family, | |
va_list | ap | |||
) | [static] |
Definition at line 2111 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().
02112 { 02113 struct ast_config_engine *eng; 02114 char db[256]; 02115 char table[256]; 02116 struct ast_variable *res=NULL; 02117 int i; 02118 02119 for (i = 1; ; i++) { 02120 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02121 if (eng->realtime_func && (res = eng->realtime_func(db, table, ap))) { 02122 return res; 02123 } 02124 } else { 02125 return NULL; 02126 } 02127 } 02128 02129 return res; 02130 }
struct ast_config* ast_load_realtime_multientry | ( | const char * | family, | |
... | ||||
) |
Retrieve realtime configuration.
family | which family/config to lookup |
Definition at line 2241 of file config.c.
References db, find_engine(), ast_config_engine::realtime_multi_func, and table.
Referenced by __queues_show(), conf_exec(), load_realtime_queue(), queues_data_provider_get(), realtime_directory(), realtime_switch_common(), show_users_realtime(), and update_realtime_members().
02242 { 02243 struct ast_config_engine *eng; 02244 char db[256]; 02245 char table[256]; 02246 struct ast_config *res = NULL; 02247 va_list ap; 02248 int i; 02249 02250 va_start(ap, family); 02251 for (i = 1; ; i++) { 02252 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02253 if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, ap))) { 02254 break; 02255 } 02256 } else { 02257 break; 02258 } 02259 } 02260 va_end(ap); 02261 02262 return res; 02263 }
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 2391 of file config.c.
References ahp, ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_strdupa, hp, PARSE_ADDR, PARSE_DEFAULT, PARSE_DOUBLE, PARSE_IN_RANGE, PARSE_INADDR, PARSE_INT32, PARSE_OUT_RANGE, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, PARSE_PORT_REQUIRE, PARSE_TYPE, PARSE_UINT32, and strsep().
Referenced by ast_tls_read_conf(), check_via_response(), and load_config().
02393 { 02394 va_list ap; 02395 int error = 0; 02396 02397 va_start(ap, p_result); 02398 switch (flags & PARSE_TYPE) { 02399 case PARSE_INT32: 02400 { 02401 int32_t *result = p_result; 02402 int32_t x, def = result ? *result : 0, 02403 high = (int32_t)0x7fffffff, 02404 low = (int32_t)0x80000000; 02405 /* optional argument: first default value, then range */ 02406 if (flags & PARSE_DEFAULT) 02407 def = va_arg(ap, int32_t); 02408 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02409 /* range requested, update bounds */ 02410 low = va_arg(ap, int32_t); 02411 high = va_arg(ap, int32_t); 02412 } 02413 x = strtol(arg, NULL, 0); 02414 error = (x < low) || (x > high); 02415 if (flags & PARSE_OUT_RANGE) 02416 error = !error; 02417 if (result) 02418 *result = error ? def : x; 02419 ast_debug(3, 02420 "extract int from [%s] in [%d, %d] gives [%d](%d)\n", 02421 arg, low, high, 02422 result ? *result : x, error); 02423 break; 02424 } 02425 02426 case PARSE_UINT32: 02427 { 02428 uint32_t *result = p_result; 02429 uint32_t x, def = result ? *result : 0, 02430 low = 0, high = (uint32_t)~0; 02431 /* optional argument: first default value, then range */ 02432 if (flags & PARSE_DEFAULT) 02433 def = va_arg(ap, uint32_t); 02434 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02435 /* range requested, update bounds */ 02436 low = va_arg(ap, uint32_t); 02437 high = va_arg(ap, uint32_t); 02438 } 02439 x = strtoul(arg, NULL, 0); 02440 error = (x < low) || (x > high); 02441 if (flags & PARSE_OUT_RANGE) 02442 error = !error; 02443 if (result) 02444 *result = error ? def : x; 02445 ast_debug(3, 02446 "extract uint from [%s] in [%u, %u] gives [%u](%d)\n", 02447 arg, low, high, 02448 result ? *result : x, error); 02449 break; 02450 } 02451 02452 case PARSE_DOUBLE: 02453 { 02454 double *result = p_result; 02455 double x, def = result ? *result : 0, 02456 low = -HUGE_VAL, high = HUGE_VAL; 02457 02458 /* optional argument: first default value, then range */ 02459 if (flags & PARSE_DEFAULT) 02460 def = va_arg(ap, double); 02461 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02462 /* range requested, update bounds */ 02463 low = va_arg(ap, double); 02464 high = va_arg(ap, double); 02465 } 02466 x = strtod(arg, NULL); 02467 error = (x < low) || (x > high); 02468 if (flags & PARSE_OUT_RANGE) 02469 error = !error; 02470 if (result) 02471 *result = error ? def : x; 02472 ast_debug(3, 02473 "extract double from [%s] in [%f, %f] gives [%f](%d)\n", 02474 arg, low, high, 02475 result ? *result : x, error); 02476 break; 02477 } 02478 case PARSE_ADDR: 02479 { 02480 struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result; 02481 02482 if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) { 02483 error = 1; 02484 } 02485 02486 ast_debug(3, "extract addr from %s gives %s(%d)\n", 02487 arg, ast_sockaddr_stringify(addr), error); 02488 02489 break; 02490 } 02491 case PARSE_INADDR: /* TODO Remove this (use PARSE_ADDR instead). */ 02492 { 02493 char *port, *buf; 02494 struct sockaddr_in _sa_buf; /* buffer for the result */ 02495 struct sockaddr_in *sa = p_result ? 02496 (struct sockaddr_in *)p_result : &_sa_buf; 02497 /* default is either the supplied value or the result itself */ 02498 struct sockaddr_in *def = (flags & PARSE_DEFAULT) ? 02499 va_arg(ap, struct sockaddr_in *) : sa; 02500 struct hostent *hp; 02501 struct ast_hostent ahp; 02502 02503 memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */ 02504 /* duplicate the string to strip away the :port */ 02505 port = ast_strdupa(arg); 02506 buf = strsep(&port, ":"); 02507 sa->sin_family = AF_INET; /* assign family */ 02508 /* 02509 * honor the ports flag setting, assign default value 02510 * in case of errors or field unset. 02511 */ 02512 flags &= PARSE_PORT_MASK; /* the only flags left to process */ 02513 if (port) { 02514 if (flags == PARSE_PORT_FORBID) { 02515 error = 1; /* port was forbidden */ 02516 sa->sin_port = def->sin_port; 02517 } else if (flags == PARSE_PORT_IGNORE) 02518 sa->sin_port = def->sin_port; 02519 else /* accept or require */ 02520 sa->sin_port = htons(strtol(port, NULL, 0)); 02521 } else { 02522 sa->sin_port = def->sin_port; 02523 if (flags == PARSE_PORT_REQUIRE) 02524 error = 1; 02525 } 02526 /* Now deal with host part, even if we have errors before. */ 02527 hp = ast_gethostbyname(buf, &ahp); 02528 if (hp) /* resolved successfully */ 02529 memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr)); 02530 else { 02531 error = 1; 02532 sa->sin_addr = def->sin_addr; 02533 } 02534 ast_debug(3, 02535 "extract inaddr from [%s] gives [%s:%d](%d)\n", 02536 arg, ast_inet_ntoa(sa->sin_addr), 02537 ntohs(sa->sin_port), error); 02538 break; 02539 } 02540 } 02541 va_end(ap); 02542 return error; 02543 }
char* ast_realtime_decode_chunk | ( | char * | chunk | ) |
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values.
chunk | Data to be decoded |
Definition at line 2359 of file config.c.
Referenced by realtime_multi_pgsql(), and realtime_pgsql().
02360 { 02361 char *orig = chunk; 02362 for (; *chunk; chunk++) { 02363 if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) { 02364 sscanf(chunk + 1, "%02hhX", chunk); 02365 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1); 02366 } 02367 } 02368 return orig; 02369 }
int ast_realtime_enabled | ( | void | ) |
Check if there's any realtime engines loaded.
Definition at line 2192 of file config.c.
References config_maps.
Referenced by action_coresettings(), ast_check_realtime(), and handle_show_settings().
02193 { 02194 return config_maps ? 1 : 0; 02195 }
char* ast_realtime_encode_chunk | ( | struct ast_str ** | dest, | |
ssize_t | maxlen, | |||
const char * | chunk | |||
) |
Encodes a chunk of data for realtime.
dest | Destination buffer | |
maxlen | Length passed through to ast_str_* functions | |
chunk | Source data to be encoded |
Definition at line 2371 of file config.c.
References ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_set().
02372 { 02373 if (!strchr(chunk, ';') && !strchr(chunk, '^')) { 02374 ast_str_set(dest, maxlen, "%s", chunk); 02375 } else { 02376 ast_str_reset(*dest); 02377 for (; *chunk; chunk++) { 02378 if (strchr(";^", *chunk)) { 02379 ast_str_append(dest, maxlen, "^%02hhX", *chunk); 02380 } else { 02381 ast_str_append(dest, maxlen, "%c", *chunk); 02382 } 02383 } 02384 } 02385 return ast_str_buffer(*dest); 02386 }
int ast_realtime_require_field | ( | const char * | family, | |
... | ||||
) |
Inform realtime what fields that may be stored.
family | which family/config is referenced |
The arguments are specified in groups of 3: column name, column type, and column size. The column types are specified as integer constants, defined by the enum require_type. Note that the size is specified as the number of equivalent character fields that a field may take up, even if a field is otherwise specified as an integer type. This is due to the fact that some fields have historically been specified as character types, even if they contained integer values.
A family should always specify its fields to the minimum necessary requirements to fulfill all possible values (within reason; for example, a timeout value may reasonably be specified as an INTEGER2, with size 5. Even though values above 32767 seconds are possible, they are unlikely to be useful, and we should not complain about that size).
0 | Required fields met specified standards | |
-1 | One or more fields was missing or insufficient |
Definition at line 2197 of file config.c.
References db, find_engine(), ast_config_engine::require_func, and table.
Referenced by ast_queue_log(), change_password_realtime(), conf_run(), load_module(), logger_queue_init(), and reload_logger().
02198 { 02199 struct ast_config_engine *eng; 02200 char db[256]; 02201 char table[256]; 02202 va_list ap; 02203 int res = -1, i; 02204 02205 va_start(ap, family); 02206 for (i = 1; ; i++) { 02207 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02208 /* If the require succeeds, it returns 0. */ 02209 if (eng->require_func && !(res = eng->require_func(db, table, ap))) { 02210 break; 02211 } 02212 } else { 02213 break; 02214 } 02215 } 02216 va_end(ap); 02217 02218 return res; 02219 }
int ast_store_realtime | ( | const char * | family, | |
... | ||||
) |
Create realtime configuration.
family | which family/config to be created |
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2312 of file config.c.
References db, find_engine(), ast_config_engine::store_func, and table.
Referenced by ast_queue_log(), cli_realtime_store(), and function_realtime_store().
02313 { 02314 struct ast_config_engine *eng; 02315 int res = -1, i; 02316 char db[256]; 02317 char table[256]; 02318 va_list ap; 02319 02320 va_start(ap, family); 02321 for (i = 1; ; i++) { 02322 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02323 /* If the store succeeds, it returns 0. */ 02324 if (eng->store_func && !(res = eng->store_func(db, table, ap))) { 02325 break; 02326 } 02327 } else { 02328 break; 02329 } 02330 } 02331 va_end(ap); 02332 02333 return res; 02334 }
int ast_unload_realtime | ( | const char * | family | ) |
Release any resources cached for a realtime family.
family | which family/config to destroy |
0 | If any cache was purged | |
-1 | If no cache was found |
Definition at line 2221 of file config.c.
References db, find_engine(), table, and ast_config_engine::unload_func.
Referenced by __unload_module(), load_config(), logger_queue_init(), reload(), reload_config(), reload_logger(), and unload_module().
02222 { 02223 struct ast_config_engine *eng; 02224 char db[256]; 02225 char table[256]; 02226 int res = -1, i; 02227 02228 for (i = 1; ; i++) { 02229 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02230 if (eng->unload_func) { 02231 /* Do this for ALL engines */ 02232 res = eng->unload_func(db, table); 02233 } 02234 } else { 02235 break; 02236 } 02237 } 02238 return res; 02239 }
int ast_update2_realtime | ( | const char * | family, | |
... | ||||
) |
Update realtime configuration.
family | which family/config to be updated |
Definition at line 2289 of file config.c.
References db, find_engine(), table, and ast_config_engine::update2_func.
Referenced by change_password_realtime(), and cli_realtime_update2().
02290 { 02291 struct ast_config_engine *eng; 02292 int res = -1, i; 02293 char db[256]; 02294 char table[256]; 02295 va_list ap; 02296 02297 va_start(ap, family); 02298 for (i = 1; ; i++) { 02299 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02300 if (eng->update2_func && !(res = eng->update2_func(db, table, ap))) { 02301 break; 02302 } 02303 } else { 02304 break; 02305 } 02306 } 02307 va_end(ap); 02308 02309 return res; 02310 }
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. |
Definition at line 2265 of file config.c.
References db, find_engine(), table, and ast_config_engine::update_func.
Referenced by cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), handle_response_peerpoke(), realtime_update_peer(), rename_file(), rt_extend_conf(), sip_poke_noanswer(), and update_realtime_member_field().
02266 { 02267 struct ast_config_engine *eng; 02268 int res = -1, i; 02269 char db[256]; 02270 char table[256]; 02271 va_list ap; 02272 02273 va_start(ap, lookup); 02274 for (i = 1; ; i++) { 02275 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02276 /* If the update succeeds, it returns 0. */ 02277 if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, ap))) { 02278 break; 02279 } 02280 } else { 02281 break; 02282 } 02283 } 02284 va_end(ap); 02285 02286 return res; 02287 }
void ast_variable_append | ( | struct ast_category * | category, | |
struct ast_variable * | variable | |||
) |
Definition at line 350 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(), vm_change_password(), and write_password_to_file().
00351 { 00352 if (!variable) 00353 return; 00354 if (category->last) 00355 category->last->next = variable; 00356 else 00357 category->root = variable; 00358 category->last = variable; 00359 while (category->last->next) 00360 category->last = category->last->next; 00361 }
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 413 of file config.c.
References ast_category_get(), config, and ast_category::root.
Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), action_getconfig(), action_getconfigjson(), adsi_load(), aji_load_config(), ast_cli_perms_init(), ast_plc_reload(), ast_readconfig(), ast_variable_retrieve(), build_calendar(), build_device(), build_event_channel(), caldav_load_calendar(), check_tx_freq(), collect_function_digits(), conf_exec(), config_load(), config_module(), do_say(), do_scheduler(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), jingle_load_config(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_rpt_vars(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_create_provider(), parse_config(), parse_tone_zone(), pbx_load_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_single_queue(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().
00414 { 00415 struct ast_category *cat = NULL; 00416 00417 if (category && config->last_browse && (config->last_browse->name == category)) { 00418 cat = config->last_browse; 00419 } else { 00420 cat = ast_category_get(config, category); 00421 } 00422 00423 return (cat) ? cat->root : NULL; 00424 }
int ast_variable_delete | ( | struct ast_category * | category, | |
const char * | variable, | |||
const char * | match, | |||
const char * | line | |||
) |
Definition at line 684 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().
00685 { 00686 struct ast_variable *cur, *prev=NULL, *curn; 00687 int res = -1; 00688 int lineno = 0; 00689 00690 cur = category->root; 00691 while (cur) { 00692 if (cur->name == variable) { 00693 if (prev) { 00694 prev->next = cur->next; 00695 if (cur == category->last) 00696 category->last = prev; 00697 } else { 00698 category->root = cur->next; 00699 if (cur == category->last) 00700 category->last = NULL; 00701 } 00702 cur->next = NULL; 00703 ast_variables_destroy(cur); 00704 return 0; 00705 } 00706 prev = cur; 00707 cur = cur->next; 00708 } 00709 00710 prev = NULL; 00711 cur = category->root; 00712 while (cur) { 00713 curn = cur->next; 00714 if ((!ast_strlen_zero(line) && lineno == atoi(line)) || (ast_strlen_zero(line) && !strcasecmp(cur->name, variable) && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) { 00715 if (prev) { 00716 prev->next = cur->next; 00717 if (cur == category->last) 00718 category->last = prev; 00719 } else { 00720 category->root = cur->next; 00721 if (cur == category->last) 00722 category->last = NULL; 00723 } 00724 cur->next = NULL; 00725 ast_variables_destroy(cur); 00726 res = 0; 00727 } else 00728 prev = cur; 00729 00730 cur = curn; 00731 lineno++; 00732 } 00733 return res; 00734 }
void ast_variable_insert | ( | struct ast_category * | category, | |
struct ast_variable * | variable, | |||
const char * | line | |||
) |
Definition at line 363 of file config.c.
References ast_variable::next, and ast_category::root.
Referenced by handle_updates().
00364 { 00365 struct ast_variable *cur = category->root; 00366 int lineno; 00367 int insertline; 00368 00369 if (!variable || sscanf(line, "%30d", &insertline) != 1) { 00370 return; 00371 } 00372 if (!insertline) { 00373 variable->next = category->root; 00374 category->root = variable; 00375 } else { 00376 for (lineno = 1; lineno < insertline; lineno++) { 00377 cur = cur->next; 00378 if (!cur->next) { 00379 break; 00380 } 00381 } 00382 variable->next = cur->next; 00383 cur->next = variable; 00384 } 00385 }
struct ast_variable* ast_variable_new | ( | const char * | name, | |
const char * | value, | |||
const char * | filename | |||
) |
Definition at line 225 of file config.c.
References __ast_calloc(), ast_calloc, and ast_variable::stuff.
Referenced by add_cfg_entry(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), apply_outgoing(), ast_channeltype_list(), ast_variable_update(), astman_get_variables(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), dup_vars(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), manager_sipnotify(), parkandannounce_exec(), parse_cookies(), process_text_line(), realtime_curl(), realtime_directory(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_multi_curl(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_odbc(), realtime_pgsql(), sip_cli_notify(), variable_clone(), vm_change_password(), and write_password_to_file().
00227 { 00228 struct ast_variable *variable; 00229 int name_len = strlen(name) + 1; 00230 int val_len = strlen(value) + 1; 00231 int fn_len = strlen(filename) + 1; 00232 00233 #ifdef MALLOC_DEBUG 00234 if ((variable = __ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable), file, lineno, func))) { 00235 #else 00236 if ((variable = ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable)))) { 00237 #endif 00238 char *dst = variable->stuff; /* writable space starts here */ 00239 variable->name = strcpy(dst, name); 00240 dst += name_len; 00241 variable->value = strcpy(dst, value); 00242 dst += val_len; 00243 variable->file = strcpy(dst, filename); 00244 } 00245 return variable; 00246 }
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 |
The | variable value on success | |
NULL | if unable to find it. |
Definition at line 437 of file config.c.
References ast_variable_browse(), config, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __ast_udptl_reload(), _dsp_init(), advanced_options(), aji_load_config(), ast_config_option(), build_extension(), conf_exec(), config_function_read(), config_module(), directory_exec(), do_reload(), do_scheduler(), festival_exec(), function_macro(), get_insecure_variable_from_config(), get_wait_interval(), gtalk_load_config(), iax_template_parse(), init_acf_query(), init_logger_chain(), initialize_cc_max_requests(), jingle_load_config(), load_config(), load_config_meetme(), load_indications(), load_module(), load_rpt_vars(), load_tech_calendars(), make_email_file(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queue_set_global_params(), read_agent_config(), read_password_from_file(), realtime_directory(), reload_config(), reload_followme(), reload_single_queue(), retreive_memory(), retrieve_astcfgint(), rpt(), rpt_master(), rpt_tele_thread(), rpt_telemetry(), rtp_reload(), saynode(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), telem_lookup(), update_realtime_members(), vm_change_password(), and vm_forwardoptions().
00438 { 00439 struct ast_variable *v; 00440 00441 if (category) { 00442 for (v = ast_variable_browse(config, category); v; v = v->next) { 00443 if (!strcasecmp(variable, v->name)) { 00444 return v->value; 00445 } 00446 } 00447 } else { 00448 struct ast_category *cat; 00449 00450 for (cat = config->root; cat; cat = cat->next) { 00451 for (v = cat->root; v; v = v->next) { 00452 if (!strcasecmp(variable, v->name)) { 00453 return v->value; 00454 } 00455 } 00456 } 00457 } 00458 00459 return NULL; 00460 }
int ast_variable_update | ( | struct ast_category * | category, | |
const char * | variable, | |||
const char * | value, | |||
const char * | match, | |||
unsigned int | object | |||
) |
Update variable value within a config.
category | Category element within the config | |
variable | Name of the variable to change | |
value | New value of the variable | |
match | If set, previous value of the variable (if NULL or zero-length, no matching will be done) | |
object | Boolean of whether to make the new variable an object |
Definition at line 736 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(), process_text_line(), vm_change_password(), and vm_forwardoptions().
00738 { 00739 struct ast_variable *cur, *prev=NULL, *newer=NULL; 00740 00741 for (cur = category->root; cur; prev = cur, cur = cur->next) { 00742 if (strcasecmp(cur->name, variable) || 00743 (!ast_strlen_zero(match) && strcasecmp(cur->value, match))) 00744 continue; 00745 00746 if (!(newer = ast_variable_new(variable, value, cur->file))) 00747 return -1; 00748 00749 newer->next = cur->next; 00750 newer->object = cur->object || object; 00751 00752 /* Preserve everything */ 00753 newer->lineno = cur->lineno; 00754 newer->blanklines = cur->blanklines; 00755 newer->precomments = cur->precomments; cur->precomments = NULL; 00756 newer->sameline = cur->sameline; cur->sameline = NULL; 00757 newer->trailing = cur->trailing; cur->trailing = NULL; 00758 00759 if (prev) 00760 prev->next = newer; 00761 else 00762 category->root = newer; 00763 if (category->last == cur) 00764 category->last = newer; 00765 00766 cur->next = NULL; 00767 ast_variables_destroy(cur); 00768 00769 return 0; 00770 } 00771 00772 /* Could not find variable to update */ 00773 return -1; 00774 }
void ast_variables_destroy | ( | struct ast_variable * | var | ) |
Free variable list.
var | the linked list of variables to free |
Definition at line 399 of file config.c.
References ast_comment_destroy(), ast_free, ast_variable::next, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.
Referenced by __sip_destroy(), action_originate(), ast_category_destroy(), ast_category_empty(), ast_http_get_cookies(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variable_delete(), ast_variable_update(), build_peer(), build_user(), cli_realtime_load(), conf_run(), destroy_dahdi_pvt(), dup_vars(), find_conf_realtime(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), handle_uri(), httpd_helper_thread(), httpstatus_callback(), ldap_loadentry(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_common(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_user(), rt_extend_conf(), sip_destroy_peer(), socket_process(), table_configs_free(), and user_destructor().
00400 { 00401 struct ast_variable *vn; 00402 00403 while (v) { 00404 vn = v; 00405 v = v->next; 00406 ast_comment_destroy(&vn->precomments); 00407 ast_comment_destroy(&vn->sameline); 00408 ast_comment_destroy(&vn->trailing); 00409 ast_free(vn); 00410 } 00411 }
static struct ast_category* category_get | ( | const struct ast_config * | config, | |
const char * | category_name, | |||
int | ignored | |||
) | [static] |
Definition at line 496 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().
00497 { 00498 struct ast_category *cat; 00499 00500 /* try exact match first, then case-insensitive match */ 00501 for (cat = config->root; cat; cat = cat->next) { 00502 if (cat->name == category_name && (ignored || !cat->ignored)) 00503 return cat; 00504 } 00505 00506 for (cat = config->root; cat; cat = cat->next) { 00507 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored)) 00508 return cat; 00509 } 00510 00511 return NULL; 00512 }
static void CB_ADD | ( | struct ast_str ** | cb, | |
const char * | str | |||
) | [static] |
Definition at line 96 of file config.c.
References ast_str_append().
Referenced by config_text_file_load().
00097 { 00098 ast_str_append(cb, 0, "%s", str); 00099 }
static void CB_ADD_LEN | ( | struct ast_str ** | cb, | |
const char * | str, | |||
int | len | |||
) | [static] |
Definition at line 101 of file config.c.
References ast_copy_string(), and ast_str_append().
Referenced by config_text_file_load().
00102 { 00103 char *s = alloca(len + 1); 00104 ast_copy_string(s, str, len); 00105 ast_str_append(cb, 0, "%s", str); 00106 }
Definition at line 108 of file config.c.
References ast_str_reset().
Referenced by config_text_file_load(), and process_text_line().
00109 { 00110 if (cb) { 00111 ast_str_reset(cb); 00112 } 00113 if (llb) { 00114 ast_str_reset(llb); 00115 } 00116 }
static void clear_config_maps | ( | void | ) | [static] |
Definition at line 1847 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().
01848 { 01849 struct ast_config_map *map; 01850 01851 ast_mutex_lock(&config_lock); 01852 01853 while (config_maps) { 01854 map = config_maps; 01855 config_maps = config_maps->next; 01856 ast_free(map); 01857 } 01858 01859 ast_mutex_unlock(&config_lock); 01860 }
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 871 of file config.c.
References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_SORTALPHA, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, cache_file_mtime::mtime, and cache_file_mtime::who_asked.
Referenced by process_text_line().
00872 { 00873 struct cache_file_mtime *cfmtime; 00874 struct cache_file_include *cfinclude; 00875 struct stat statbuf = { 0, }; 00876 00877 /* Find our cached entry for this configuration file */ 00878 AST_LIST_LOCK(&cfmtime_head); 00879 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 00880 if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked)) 00881 break; 00882 } 00883 if (!cfmtime) { 00884 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1 + strlen(who_asked) + 1); 00885 if (!cfmtime) { 00886 AST_LIST_UNLOCK(&cfmtime_head); 00887 return; 00888 } 00889 AST_LIST_HEAD_INIT(&cfmtime->includes); 00890 strcpy(cfmtime->filename, configfile); 00891 cfmtime->who_asked = cfmtime->filename + strlen(configfile) + 1; 00892 strcpy(cfmtime->who_asked, who_asked); 00893 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 00894 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 00895 } 00896 00897 if (!stat(configfile, &statbuf)) 00898 cfmtime->mtime = 0; 00899 else 00900 cfmtime->mtime = statbuf.st_mtime; 00901 00902 switch (attrtype) { 00903 case ATTRIBUTE_INCLUDE: 00904 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 00905 if (!strcmp(cfinclude->include, filename)) { 00906 AST_LIST_UNLOCK(&cfmtime_head); 00907 return; 00908 } 00909 } 00910 cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1); 00911 if (!cfinclude) { 00912 AST_LIST_UNLOCK(&cfmtime_head); 00913 return; 00914 } 00915 strcpy(cfinclude->include, filename); 00916 AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list); 00917 break; 00918 case ATTRIBUTE_EXEC: 00919 cfmtime->has_exec = 1; 00920 break; 00921 } 00922 AST_LIST_UNLOCK(&cfmtime_head); 00923 }
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 1181 of file config.c.
References ALLOC_COMMENT(), ast_calloc, ast_clear_flag, ast_config_AST_CONFIG_DIR, ast_config_get_current_category(), ast_copy_string(), ast_debug, ast_free, AST_LIST_HEAD_INIT, AST_LIST_INSERT_SORTALPHA, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, comment, COMMENT_META, COMMENT_TAG, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, GLOB_ABORTED, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, cache_file_mtime::mtime, MY_GLOB_FLAGS, process_text_line(), ast_variable::trailing, ast_category::trailing, and cache_file_mtime::who_asked.
01182 { 01183 char fn[256]; 01184 #if defined(LOW_MEMORY) 01185 char buf[512]; 01186 #else 01187 char buf[8192]; 01188 #endif 01189 char *new_buf, *comment_p, *process_buf; 01190 FILE *f; 01191 int lineno=0; 01192 int comment = 0, nest[MAX_NESTED_COMMENTS]; 01193 struct ast_category *cat = NULL; 01194 int count = 0; 01195 struct stat statbuf; 01196 struct cache_file_mtime *cfmtime = NULL; 01197 struct cache_file_include *cfinclude; 01198 struct ast_variable *last_var = 0; 01199 struct ast_category *last_cat = 0; 01200 /*! Growable string buffer */ 01201 struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/ 01202 struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */ 01203 01204 if (cfg) 01205 cat = ast_config_get_current_category(cfg); 01206 01207 if (filename[0] == '/') { 01208 ast_copy_string(fn, filename, sizeof(fn)); 01209 } else { 01210 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 01211 } 01212 01213 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01214 comment_buffer = ast_str_create(CB_SIZE); 01215 if (comment_buffer) 01216 lline_buffer = ast_str_create(CB_SIZE); 01217 if (!lline_buffer) { 01218 if (comment_buffer) 01219 ast_free(comment_buffer); 01220 ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n"); 01221 return NULL; 01222 } 01223 } 01224 #ifdef AST_INCLUDE_GLOB 01225 { 01226 int glob_ret; 01227 glob_t globbuf; 01228 globbuf.gl_offs = 0; /* initialize it to silence gcc */ 01229 glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf); 01230 if (glob_ret == GLOB_NOSPACE) 01231 ast_log(LOG_WARNING, 01232 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn); 01233 else if (glob_ret == GLOB_ABORTED) 01234 ast_log(LOG_WARNING, 01235 "Glob Expansion of pattern '%s' failed: Read error\n", fn); 01236 else { 01237 /* loop over expanded files */ 01238 int i; 01239 for (i=0; i<globbuf.gl_pathc; i++) { 01240 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn)); 01241 #endif 01242 /* 01243 * The following is not a loop, but just a convenient way to define a block 01244 * (using do { } while(0) ), and be able to exit from it with 'continue' 01245 * or 'break' in case of errors. Nice trick. 01246 */ 01247 do { 01248 if (stat(fn, &statbuf)) 01249 continue; 01250 01251 if (!S_ISREG(statbuf.st_mode)) { 01252 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn); 01253 continue; 01254 } 01255 01256 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) { 01257 /* Find our cached entry for this configuration file */ 01258 AST_LIST_LOCK(&cfmtime_head); 01259 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 01260 if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) 01261 break; 01262 } 01263 if (!cfmtime) { 01264 cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1 + strlen(who_asked) + 1); 01265 if (!cfmtime) 01266 continue; 01267 AST_LIST_HEAD_INIT(&cfmtime->includes); 01268 strcpy(cfmtime->filename, fn); 01269 cfmtime->who_asked = cfmtime->filename + strlen(fn) + 1; 01270 strcpy(cfmtime->who_asked, who_asked); 01271 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 01272 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 01273 } 01274 } 01275 01276 if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) { 01277 /* File is unchanged, what about the (cached) includes (if any)? */ 01278 int unchanged = 1; 01279 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 01280 /* We must glob here, because if we did not, then adding a file to globbed directory would 01281 * incorrectly cause no reload to be necessary. */ 01282 char fn2[256]; 01283 #ifdef AST_INCLUDE_GLOB 01284 int glob_return; 01285 glob_t glob_buf = { .gl_offs = 0 }; 01286 glob_return = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &glob_buf); 01287 /* On error, we reparse */ 01288 if (glob_return == GLOB_NOSPACE || glob_return == GLOB_ABORTED) 01289 unchanged = 0; 01290 else { 01291 /* loop over expanded files */ 01292 int j; 01293 for (j = 0; j < glob_buf.gl_pathc; j++) { 01294 ast_copy_string(fn2, glob_buf.gl_pathv[j], sizeof(fn2)); 01295 #else 01296 ast_copy_string(fn2, cfinclude->include); 01297 #endif 01298 if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) { 01299 /* that second-to-last field needs to be looked at in this case... TODO */ 01300 unchanged = 0; 01301 /* One change is enough to short-circuit and reload the whole shebang */ 01302 break; 01303 } 01304 #ifdef AST_INCLUDE_GLOB 01305 } 01306 } 01307 #endif 01308 } 01309 01310 if (unchanged) { 01311 AST_LIST_UNLOCK(&cfmtime_head); 01312 return CONFIG_STATUS_FILEUNCHANGED; 01313 } 01314 } 01315 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01316 AST_LIST_UNLOCK(&cfmtime_head); 01317 01318 /* If cfg is NULL, then we just want an answer */ 01319 if (cfg == NULL) 01320 return NULL; 01321 01322 if (cfmtime) 01323 cfmtime->mtime = statbuf.st_mtime; 01324 01325 ast_verb(2, "Parsing '%s': ", fn); 01326 fflush(stdout); 01327 if (!(f = fopen(fn, "r"))) { 01328 ast_debug(1, "No file to parse: %s\n", fn); 01329 ast_verb(2, "Not found (%s)\n", strerror(errno)); 01330 continue; 01331 } 01332 count++; 01333 /* If we get to this point, then we're loading regardless */ 01334 ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED); 01335 ast_debug(1, "Parsing %s\n", fn); 01336 ast_verb(2, "Found\n"); 01337 while (!feof(f)) { 01338 lineno++; 01339 if (fgets(buf, sizeof(buf), f)) { 01340 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && ast_str_strlen(lline_buffer)) { 01341 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01342 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01343 } 01344 01345 new_buf = buf; 01346 if (comment) 01347 process_buf = NULL; 01348 else 01349 process_buf = buf; 01350 01351 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer) && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) { 01352 /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */ 01353 CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */ 01354 continue; /* go get a new line, then */ 01355 } 01356 01357 while ((comment_p = strchr(new_buf, COMMENT_META))) { 01358 if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) { 01359 /* Escaped semicolons aren't comments. */ 01360 new_buf = comment_p + 1; 01361 } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { 01362 /* Meta-Comment start detected ";--" */ 01363 if (comment < MAX_NESTED_COMMENTS) { 01364 *comment_p = '\0'; 01365 new_buf = comment_p + 3; 01366 comment++; 01367 nest[comment-1] = lineno; 01368 } else { 01369 ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); 01370 } 01371 } else if ((comment_p >= new_buf + 2) && 01372 (*(comment_p - 1) == COMMENT_TAG) && 01373 (*(comment_p - 2) == COMMENT_TAG)) { 01374 /* Meta-Comment end detected */ 01375 comment--; 01376 new_buf = comment_p + 1; 01377 if (!comment) { 01378 /* Back to non-comment now */ 01379 if (process_buf) { 01380 /* Actually have to move what's left over the top, then continue */ 01381 char *oldptr; 01382 oldptr = process_buf + strlen(process_buf); 01383 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01384 CB_ADD(&comment_buffer, ";"); 01385 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1); 01386 } 01387 01388 memmove(oldptr, new_buf, strlen(new_buf) + 1); 01389 new_buf = oldptr; 01390 } else 01391 process_buf = new_buf; 01392 } 01393 } else { 01394 if (!comment) { 01395 /* If ; is found, and we are not nested in a comment, 01396 we immediately stop all comment processing */ 01397 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01398 CB_ADD(&lline_buffer, comment_p); 01399 } 01400 *comment_p = '\0'; 01401 new_buf = comment_p; 01402 } else 01403 new_buf = comment_p + 1; 01404 } 01405 } 01406 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) { 01407 CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */ 01408 } 01409 01410 if (process_buf) { 01411 char *buffer = ast_strip(process_buf); 01412 if (!ast_strlen_zero(buffer)) { 01413 if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) { 01414 cfg = CONFIG_STATUS_FILEINVALID; 01415 break; 01416 } 01417 } 01418 } 01419 } 01420 } 01421 /* end of file-- anything in a comment buffer? */ 01422 if (last_cat) { 01423 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01424 if (lline_buffer && ast_str_strlen(lline_buffer)) { 01425 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01426 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01427 } 01428 last_cat->trailing = ALLOC_COMMENT(comment_buffer); 01429 } 01430 } else if (last_var) { 01431 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01432 if (lline_buffer && ast_str_strlen(lline_buffer)) { 01433 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01434 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01435 } 01436 last_var->trailing = ALLOC_COMMENT(comment_buffer); 01437 } 01438 } else { 01439 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01440 ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer)); 01441 } 01442 } 01443 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01444 CB_RESET(comment_buffer, lline_buffer); 01445 01446 fclose(f); 01447 } while (0); 01448 if (comment) { 01449 ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]); 01450 } 01451 #ifdef AST_INCLUDE_GLOB 01452 if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { 01453 break; 01454 } 01455 } 01456 globfree(&globbuf); 01457 } 01458 } 01459 #endif 01460 01461 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01462 if (comment_buffer) 01463 ast_free(comment_buffer); 01464 if (lline_buffer) 01465 ast_free(lline_buffer); 01466 comment_buffer = NULL; 01467 lline_buffer = NULL; 01468 } 01469 01470 if (count == 0) 01471 return NULL; 01472 01473 return cfg; 01474 }
int config_text_file_save | ( | const char * | configfile, | |
const struct ast_config * | cfg, | |||
const char * | generator | |||
) |
Definition at line 1602 of file config.c.
References ast_config_text_file_save().
01603 { 01604 return ast_config_text_file_save(configfile, cfg, generator); 01605 }
static int count_linefeeds | ( | char * | str | ) | [static] |
static int count_linefeeds_in_comments | ( | struct ast_comment * | x | ) | [static] |
Definition at line 1562 of file config.c.
References ast_comment::cmt, count_linefeeds(), and ast_comment::next.
Referenced by insert_leading_blank_lines().
01563 { 01564 int count = 0; 01565 01566 while (x) { 01567 count += count_linefeeds(x->cmt); 01568 x = x->next; 01569 } 01570 return count; 01571 }
static struct ast_config_engine* find_engine | ( | const char * | family, | |
int | priority, | |||
char * | database, | |||
int | dbsiz, | |||
char * | table, | |||
int | tabsiz | |||
) | [static] |
Find realtime engine for realtime family.
Definition at line 2016 of file config.c.
References ast_copy_string(), ast_mutex_lock, config_lock, config_maps, and map.
Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_realtime_require_field(), ast_speech_new(), ast_speech_register(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), and ast_update_realtime().
02017 { 02018 struct ast_config_engine *eng, *ret = NULL; 02019 struct ast_config_map *map; 02020 02021 ast_mutex_lock(&config_lock); 02022 02023 for (map = config_maps; map; map = map->next) { 02024 if (!strcasecmp(family, map->name) && (priority == map->priority)) { 02025 if (database) 02026 ast_copy_string(database, map->database, dbsiz); 02027 if (table) 02028 ast_copy_string(table, map->table ? map->table : family, tabsiz); 02029 break; 02030 } 02031 } 02032 02033 /* Check if the required driver (engine) exist */ 02034 if (map) { 02035 for (eng = config_engine_list; !ret && eng; eng = eng->next) { 02036 if (!strcasecmp(eng->name, map->driver)) 02037 ret = eng; 02038 } 02039 } 02040 02041 ast_mutex_unlock(&config_lock); 02042 02043 /* if we found a mapping, but the engine is not available, then issue a warning */ 02044 if (map && !ret) 02045 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver); 02046 02047 return ret; 02048 }
static void gen_header | ( | FILE * | f1, | |
const char * | configfile, | |||
const char * | fn, | |||
const char * | generator | |||
) | [static] |
Definition at line 1497 of file config.c.
References ast_copy_string().
Referenced by ast_config_text_file_save().
01498 { 01499 char date[256]=""; 01500 time_t t; 01501 01502 time(&t); 01503 ast_copy_string(date, ctime(&t), sizeof(date)); 01504 01505 fprintf(f1, ";!\n"); 01506 fprintf(f1, ";! Automatically generated configuration file\n"); 01507 if (strcmp(configfile, fn)) 01508 fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn); 01509 else 01510 fprintf(f1, ";! Filename: %s\n", configfile); 01511 fprintf(f1, ";! Generator: %s\n", generator); 01512 fprintf(f1, ";! Creation Date: %s", date); 01513 fprintf(f1, ";!\n"); 01514 }
static char* handle_cli_config_list | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2644 of file config.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, cache_file_mtime::list, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.
02645 { 02646 struct cache_file_mtime *cfmtime; 02647 02648 switch (cmd) { 02649 case CLI_INIT: 02650 e->command = "config list"; 02651 e->usage = 02652 "Usage: config list\n" 02653 " Show all modules that have loaded a configuration file\n"; 02654 return NULL; 02655 case CLI_GENERATE: 02656 return NULL; 02657 } 02658 02659 AST_LIST_LOCK(&cfmtime_head); 02660 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02661 ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename); 02662 } 02663 AST_LIST_UNLOCK(&cfmtime_head); 02664 02665 return CLI_SUCCESS; 02666 }
static char* handle_cli_config_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2582 of file config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli_command, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, cache_file_mtime::list, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.
02583 { 02584 struct cache_file_mtime *cfmtime; 02585 char *prev = "", *completion_value = NULL; 02586 int wordlen, which = 0; 02587 02588 switch (cmd) { 02589 case CLI_INIT: 02590 e->command = "config reload"; 02591 e->usage = 02592 "Usage: config reload <filename.conf>\n" 02593 " Reloads all modules that reference <filename.conf>\n"; 02594 return NULL; 02595 case CLI_GENERATE: 02596 if (a->pos > 2) { 02597 return NULL; 02598 } 02599 02600 wordlen = strlen(a->word); 02601 02602 AST_LIST_LOCK(&cfmtime_head); 02603 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02604 /* Skip duplicates - this only works because the list is sorted by filename */ 02605 if (strcmp(cfmtime->filename, prev) == 0) { 02606 continue; 02607 } 02608 02609 /* Core configs cannot be reloaded */ 02610 if (ast_strlen_zero(cfmtime->who_asked)) { 02611 continue; 02612 } 02613 02614 if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) { 02615 completion_value = ast_strdup(cfmtime->filename); 02616 break; 02617 } 02618 02619 /* Otherwise save that we've seen this filename */ 02620 prev = cfmtime->filename; 02621 } 02622 AST_LIST_UNLOCK(&cfmtime_head); 02623 02624 return completion_value; 02625 } 02626 02627 if (a->argc != 3) { 02628 return CLI_SHOWUSAGE; 02629 } 02630 02631 AST_LIST_LOCK(&cfmtime_head); 02632 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02633 if (!strcmp(cfmtime->filename, a->argv[2])) { 02634 char *buf = alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1); 02635 sprintf(buf, "module reload %s", cfmtime->who_asked); 02636 ast_cli_command(a->fd, buf); 02637 } 02638 } 02639 AST_LIST_UNLOCK(&cfmtime_head); 02640 02641 return CLI_SUCCESS; 02642 }
static char* handle_cli_core_show_config_mappings | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2545 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.
02546 { 02547 struct ast_config_engine *eng; 02548 struct ast_config_map *map; 02549 02550 switch (cmd) { 02551 case CLI_INIT: 02552 e->command = "core show config mappings"; 02553 e->usage = 02554 "Usage: core show config mappings\n" 02555 " Shows the filenames to config engines.\n"; 02556 return NULL; 02557 case CLI_GENERATE: 02558 return NULL; 02559 } 02560 02561 ast_mutex_lock(&config_lock); 02562 02563 if (!config_engine_list) { 02564 ast_cli(a->fd, "No config mappings found.\n"); 02565 } else { 02566 for (eng = config_engine_list; eng; eng = eng->next) { 02567 ast_cli(a->fd, "Config Engine: %s\n", eng->name); 02568 for (map = config_maps; map; map = map->next) { 02569 if (!strcasecmp(map->driver, eng->name)) { 02570 ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database, 02571 map->table ? map->table : map->name); 02572 } 02573 } 02574 } 02575 } 02576 02577 ast_mutex_unlock(&config_lock); 02578 02579 return CLI_SUCCESS; 02580 }
static int hash_string | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 138 of file config.c.
Referenced by ast_config_text_file_save().
00139 { 00140 char *str = ((struct inclfile *) obj)->fname; 00141 int total; 00142 00143 for (total = 0; *str; str++) { 00144 unsigned int tmp = total; 00145 total <<= 1; /* multiply by 2 */ 00146 total += tmp; /* multiply by 3 */ 00147 total <<= 2; /* multiply by 12 */ 00148 total += tmp; /* multiply by 13 */ 00149 00150 total += ((unsigned int) (*str)); 00151 } 00152 if (total < 0) { 00153 total = -total; 00154 } 00155 return total; 00156 }
static int hashtab_compare_strings | ( | void * | a, | |
void * | b, | |||
int | flags | |||
) | [static] |
Definition at line 158 of file config.c.
References CMP_MATCH, CMP_STOP, and inclfile::fname.
Referenced by ast_config_text_file_save().
00159 { 00160 const struct inclfile *ae = a, *be = b; 00161 return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0; 00162 }
static void inclfile_destroy | ( | void * | obj | ) | [static] |
static void inherit_category | ( | struct ast_category * | new, | |
const struct ast_category * | base | |||
) | [static] |
Definition at line 663 of file config.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_variable_append(), ast_category_template_instance::inst, ast_category::name, ast_category_template_instance::name, ast_category_template_instance::next, ast_category::root, ast_category::template_instances, var, and variable_clone().
Referenced by process_text_line().
00664 { 00665 struct ast_variable *var; 00666 struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance)); 00667 00668 strcpy(x->name, base->name); 00669 x->inst = base; 00670 AST_LIST_INSERT_TAIL(&new->template_instances, x, next); 00671 for (var = base->root; var; var = var->next) 00672 ast_variable_append(new, variable_clone(var)); 00673 }
static int init_appendbuf | ( | void * | data | ) | [static] |
Definition at line 84 of file config.c.
References ast_str_create(), and str.
00085 { 00086 struct ast_str **str = data; 00087 *str = ast_str_create(16); 00088 return *str ? 0 : -1; 00089 }
static void insert_leading_blank_lines | ( | FILE * | fp, | |
struct inclfile * | fi, | |||
struct ast_comment * | precomments, | |||
int | lineno | |||
) | [static] |
Definition at line 1573 of file config.c.
References count_linefeeds_in_comments(), and inclfile::lineno.
Referenced by ast_config_text_file_save().
01574 { 01575 int precomment_lines = count_linefeeds_in_comments(precomments); 01576 int i; 01577 01578 /* I don't have to worry about those ;! comments, they are 01579 stored in the precomments, but not printed back out. 01580 I did have to make sure that comments following 01581 the ;! header comments were not also deleted in the process */ 01582 if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */ 01583 return; 01584 } else if (lineno == 0) { 01585 /* Line replacements also mess things up */ 01586 return; 01587 } else if (lineno - precomment_lines - fi->lineno < 5) { 01588 /* Only insert less than 5 blank lines; if anything more occurs, 01589 * it's probably due to context deletion. */ 01590 for (i = fi->lineno; i < lineno - precomment_lines; i++) { 01591 fprintf(fp, "\n"); 01592 } 01593 } else { 01594 /* Deletion occurred - insert a single blank line, for separation of 01595 * contexts. */ 01596 fprintf(fp, "\n"); 01597 } 01598 01599 fi->lineno = lineno + 1; /* Advance the file lineno */ 01600 }
static void move_variables | ( | struct ast_category * | old, | |
struct ast_category * | new | |||
) | [static] |
Definition at line 476 of file config.c.
References ast_variable_append(), ast_category::root, and var.
Referenced by process_text_line().
00477 { 00478 struct ast_variable *var = old->root; 00479 00480 old->root = NULL; 00481 /* we can just move the entire list in a single op */ 00482 ast_variable_append(new, var); 00483 }
static struct ast_category* next_available_category | ( | struct ast_category * | cat | ) | [static] |
Definition at line 593 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 932 of file config.c.
References ALLOC_COMMENT(), appendbuf, ast_category_append(), ast_category_destroy(), ast_category_first(), ast_category_new(), ast_config_internal_load(), ast_include_new(), ast_log(), ast_opt_exec_includes, ast_safe_system(), ast_skip_blanks(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_trim_blanks(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_tvnow(), ast_variable_append(), ast_variable_new(), ast_variable_update(), ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, ast_variable::blanklines, category_get(), CB_RESET(), config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, ast_config::include_level, inherit_category(), ast_variable::lineno, LOG_ERROR, LOG_WARNING, move_variables(), ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), and var.
Referenced by config_text_file_load().
00938 { 00939 char *c; 00940 char *cur = buf; 00941 struct ast_variable *v; 00942 char cmd[512], exec_file[512]; 00943 00944 /* Actually parse the entry */ 00945 if (cur[0] == '[') { /* A category header */ 00946 /* format is one of the following: 00947 * [foo] define a new category named 'foo' 00948 * [foo](!) define a new template category named 'foo' 00949 * [foo](+) append to category 'foo', error if foo does not exist. 00950 * [foo](a) define a new category and inherit from template a. 00951 * You can put a comma-separated list of templates and '!' and '+' 00952 * between parentheses, with obvious meaning. 00953 */ 00954 struct ast_category *newcat = NULL; 00955 char *catname; 00956 00957 c = strchr(cur, ']'); 00958 if (!c) { 00959 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); 00960 return -1; 00961 } 00962 *c++ = '\0'; 00963 cur++; 00964 if (*c++ != '(') 00965 c = NULL; 00966 catname = cur; 00967 if (!(*cat = newcat = ast_category_new(catname, 00968 S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile), 00969 lineno))) { 00970 return -1; 00971 } 00972 (*cat)->lineno = lineno; 00973 *last_var = 0; 00974 *last_cat = newcat; 00975 00976 /* add comments */ 00977 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00978 newcat->precomments = ALLOC_COMMENT(comment_buffer); 00979 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00980 newcat->sameline = ALLOC_COMMENT(lline_buffer); 00981 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 00982 CB_RESET(comment_buffer, lline_buffer); 00983 00984 /* If there are options or categories to inherit from, process them now */ 00985 if (c) { 00986 if (!(cur = strchr(c, ')'))) { 00987 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile); 00988 return -1; 00989 } 00990 *cur = '\0'; 00991 while ((cur = strsep(&c, ","))) { 00992 if (!strcasecmp(cur, "!")) { 00993 (*cat)->ignored = 1; 00994 } else if (!strcasecmp(cur, "+")) { 00995 *cat = category_get(cfg, catname, 1); 00996 if (!(*cat)) { 00997 if (newcat) 00998 ast_category_destroy(newcat); 00999 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile); 01000 return -1; 01001 } 01002 if (newcat) { 01003 move_variables(newcat, *cat); 01004 ast_category_destroy(newcat); 01005 newcat = NULL; 01006 } 01007 } else { 01008 struct ast_category *base; 01009 01010 base = category_get(cfg, cur, 1); 01011 if (!base) { 01012 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile); 01013 return -1; 01014 } 01015 inherit_category(*cat, base); 01016 } 01017 } 01018 } 01019 if (newcat) 01020 ast_category_append(cfg, *cat); 01021 } else if (cur[0] == '#') { /* A directive - #include or #exec */ 01022 char *cur2; 01023 char real_inclusion_name[256]; 01024 struct ast_config_include *inclu; 01025 int do_include = 0; /* otherwise, it is exec */ 01026 01027 cur++; 01028 c = cur; 01029 while (*c && (*c > 32)) { 01030 c++; 01031 } 01032 01033 if (*c) { 01034 *c = '\0'; 01035 /* Find real argument */ 01036 c = ast_strip(c + 1); 01037 if (!(*c)) { 01038 c = NULL; 01039 } 01040 } else { 01041 c = NULL; 01042 } 01043 if (!strcasecmp(cur, "include")) { 01044 do_include = 1; 01045 } else if (!strcasecmp(cur, "exec")) { 01046 if (!ast_opt_exec_includes) { 01047 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n"); 01048 return 0; /* XXX is this correct ? or we should return -1 ? */ 01049 } 01050 } else { 01051 ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile); 01052 return 0; /* XXX is this correct ? or we should return -1 ? */ 01053 } 01054 01055 if (c == NULL) { 01056 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 01057 do_include ? "include" : "exec", 01058 do_include ? "filename" : "/path/to/executable", 01059 lineno, 01060 configfile); 01061 return 0; /* XXX is this correct ? or we should return -1 ? */ 01062 } 01063 01064 cur = c; 01065 /* Strip off leading and trailing "'s and <>'s */ 01066 /* Dequote */ 01067 if ((*c == '"') || (*c == '<')) { 01068 char quote_char = *c; 01069 if (quote_char == '<') { 01070 quote_char = '>'; 01071 } 01072 01073 if (*(c + strlen(c) - 1) == quote_char) { 01074 cur++; 01075 *(c + strlen(c) - 1) = '\0'; 01076 } 01077 } 01078 cur2 = cur; 01079 01080 /* #exec </path/to/executable> 01081 We create a tmp file, then we #include it, then we delete it. */ 01082 if (!do_include) { 01083 struct timeval now = ast_tvnow(); 01084 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01085 config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked); 01086 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self()); 01087 snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file); 01088 ast_safe_system(cmd); 01089 cur = exec_file; 01090 } else { 01091 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01092 config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked); 01093 exec_file[0] = '\0'; 01094 } 01095 /* A #include */ 01096 /* record this inclusion */ 01097 inclu = ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name)); 01098 01099 do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0; 01100 if (!ast_strlen_zero(exec_file)) 01101 unlink(exec_file); 01102 if (!do_include) { 01103 ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur); 01104 return -1; 01105 } 01106 /* XXX otherwise what ? the default return is 0 anyways */ 01107 01108 } else { 01109 /* Just a line (variable = value) */ 01110 int object = 0; 01111 if (!(*cat)) { 01112 ast_log(LOG_WARNING, 01113 "parse error: No category context for line %d of %s\n", lineno, configfile); 01114 return -1; 01115 } 01116 c = strchr(cur, '='); 01117 01118 if (c && c > cur && (*(c - 1) == '+')) { 01119 struct ast_variable *var, *replace = NULL; 01120 struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str)); 01121 01122 if (!str || !*str) { 01123 return -1; 01124 } 01125 01126 *(c - 1) = '\0'; 01127 c++; 01128 cur = ast_strip(cur); 01129 01130 /* Must iterate through category until we find last variable of same name (since there could be multiple) */ 01131 for (var = ast_category_first(*cat); var; var = var->next) { 01132 if (!strcmp(var->name, cur)) { 01133 replace = var; 01134 } 01135 } 01136 01137 if (!replace) { 01138 /* Nothing to replace; just set a variable normally. */ 01139 goto set_new_variable; 01140 } 01141 01142 ast_str_set(str, 0, "%s", replace->value); 01143 ast_str_append(str, 0, "%s", c); 01144 ast_str_trim_blanks(*str); 01145 ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object); 01146 } else if (c) { 01147 *c = 0; 01148 c++; 01149 /* Ignore > in => */ 01150 if (*c== '>') { 01151 object = 1; 01152 c++; 01153 } 01154 set_new_variable: 01155 if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) { 01156 v->lineno = lineno; 01157 v->object = object; 01158 *last_cat = 0; 01159 *last_var = v; 01160 /* Put and reset comments */ 01161 v->blanklines = 0; 01162 ast_variable_append(*cat, v); 01163 /* add comments */ 01164 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01165 v->precomments = ALLOC_COMMENT(comment_buffer); 01166 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01167 v->sameline = ALLOC_COMMENT(lline_buffer); 01168 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01169 CB_RESET(comment_buffer, lline_buffer); 01170 01171 } else { 01172 return -1; 01173 } 01174 } else { 01175 ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); 01176 } 01177 } 01178 return 0; 01179 }
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 1896 of file config.c.
References append_mapping(), ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log(), ast_variable_browse(), clear_config_maps(), config, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, 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().
01897 { 01898 struct ast_config *config, *configtmp; 01899 struct ast_variable *v; 01900 char *driver, *table, *database, *textpri, *stringp, *tmp; 01901 struct ast_flags flags = { CONFIG_FLAG_NOREALTIME }; 01902 int pri; 01903 01904 clear_config_maps(); 01905 01906 configtmp = ast_config_new(); 01907 configtmp->max_include_level = 1; 01908 config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig"); 01909 if (config == CONFIG_STATUS_FILEINVALID) { 01910 return -1; 01911 } else if (!config) { 01912 ast_config_destroy(configtmp); 01913 return 0; 01914 } 01915 01916 for (v = ast_variable_browse(config, "settings"); v; v = v->next) { 01917 char buf[512]; 01918 ast_copy_string(buf, v->value, sizeof(buf)); 01919 stringp = buf; 01920 driver = strsep(&stringp, ","); 01921 01922 if ((tmp = strchr(stringp, '\"'))) 01923 stringp = tmp; 01924 01925 /* check if the database text starts with a double quote */ 01926 if (*stringp == '"') { 01927 stringp++; 01928 database = strsep(&stringp, "\""); 01929 strsep(&stringp, ","); 01930 } else { 01931 /* apparently this text has no quotes */ 01932 database = strsep(&stringp, ","); 01933 } 01934 01935 table = strsep(&stringp, ","); 01936 textpri = strsep(&stringp, ","); 01937 if (!textpri || !(pri = atoi(textpri))) { 01938 pri = 1; 01939 } 01940 01941 if (!strcmp(v->name, extconfig_conf)) { 01942 ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf); 01943 continue; 01944 } 01945 01946 if (!strcmp(v->name, "asterisk.conf")) { 01947 ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n"); 01948 continue; 01949 } 01950 01951 if (!strcmp(v->name, "logger.conf")) { 01952 ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n"); 01953 continue; 01954 } 01955 01956 if (!driver || !database) 01957 continue; 01958 if (!strcasecmp(v->name, "sipfriends")) { 01959 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"); 01960 append_mapping("sipusers", driver, database, table ? table : "sipfriends", pri); 01961 append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri); 01962 } else if (!strcasecmp(v->name, "iaxfriends")) { 01963 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"); 01964 append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri); 01965 append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri); 01966 } else 01967 append_mapping(v->name, driver, database, table, pri); 01968 } 01969 01970 ast_config_destroy(config); 01971 return 0; 01972 }
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 2674 of file config.c.
References ARRAY_LEN, ast_cli_register_multiple(), and cli_config.
Referenced by main().
02675 { 02676 ast_cli_register_multiple(cli_config, ARRAY_LEN(cli_config)); 02677 return 0; 02678 }
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 1525 of file config.c.
References ao2_alloc, ao2_find, ao2_link, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_strdup, inclfile::fname, inclfile_destroy(), inclfile::lineno, and OBJ_POINTER.
Referenced by ast_config_text_file_save().
01526 { 01527 struct inclfile lookup; 01528 01529 if (!file || file[0] == 0) { 01530 if (configfile[0] == '/') 01531 ast_copy_string(fn, configfile, fn_size); 01532 else 01533 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile); 01534 } else if (file[0] == '/') 01535 ast_copy_string(fn, file, fn_size); 01536 else 01537 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file); 01538 lookup.fname = fn; 01539 *fi = ao2_find(fileset, &lookup, OBJ_POINTER); 01540 if (!(*fi)) { 01541 /* set up a file scratch pad */ 01542 struct inclfile *fx = ao2_alloc(sizeof(struct inclfile), inclfile_destroy); 01543 fx->fname = ast_strdup(fn); 01544 fx->lineno = 1; 01545 *fi = fx; 01546 ao2_link(fileset, fx); 01547 } 01548 }
static struct ast_variable* variable_clone | ( | const struct ast_variable * | old | ) | [static] |
Definition at line 462 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().
00463 { 00464 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file); 00465 00466 if (new) { 00467 new->lineno = old->lineno; 00468 new->object = old->object; 00469 new->blanklines = old->blanklines; 00470 /* TODO: clone comments? */ 00471 } 00472 00473 return new; 00474 }
struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , } [static] |
struct ast_cli_entry cli_config[] [static] |
Initial value:
{ { .handler = handle_cli_core_show_config_mappings , .summary = "Display config mappings (file names to config engines)" ,__VA_ARGS__ }, { .handler = handle_cli_config_reload , .summary = "Force a reload on modules using a particular configuration file" ,__VA_ARGS__ }, { .handler = handle_cli_config_list , .summary = "Show all files that have loaded a configuration file" ,__VA_ARGS__ }, }
Definition at line 2668 of file config.c.
Referenced by register_config_cli().
struct ast_config_engine* config_engine_list [static] |
Definition at line 175 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 = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
Definition at line 174 of file config.c.
Referenced by ast_calendar_config_release(), ast_config_engine_deregister(), ast_config_engine_register(), clear_config_maps(), find_engine(), handle_cli_core_show_config_mappings(), load_config(), and load_tech_calendars().
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 2050 of file config.c.
Referenced by ast_config_internal_load().