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