#include "asterisk.h"
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include <time.h>
#include <sys/stat.h>
#include <math.h>
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/netsock2.h"
Go to the source code of this file.
Data Structures | |
struct | ast_category |
struct | ast_category::template_instance_list |
struct | ast_category_template_instance |
struct | ast_comment |
Structure to keep comments for rewriting configuration files. More... | |
struct | ast_config |
struct | ast_config_include |
struct | ast_config_map |
struct | cache_file_include |
Hold the mtime for config files, so if we don't need to reread our config, don't. More... | |
struct | cache_file_mtime |
struct | cache_file_mtime::includes |
struct | cfmtime_head |
struct | inclfile |
Defines | |
#define | AST_INCLUDE_GLOB 1 |
#define | CB_SIZE 250 |
#define | COMMENT_END "--;" |
#define | COMMENT_META ';' |
#define | COMMENT_START ";--" |
#define | COMMENT_TAG '-' |
#define | MAX_INCLUDE_LEVEL 10 |
#define | MAX_NESTED_COMMENTS 128 |
#define | MIN_VARIABLE_FNAME_SPACE 40 |
Enumerations | |
enum | config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0, ATTRIBUTE_EXEC = 1 } |
Functions | |
static void | __init_appendbuf (void) |
static struct ast_comment * | ALLOC_COMMENT (struct ast_str *buffer) |
static int | append_mapping (const char *name, const char *driver, const char *database, const char *table, int priority) |
void | ast_category_append (struct ast_config *config, struct ast_category *category) |
char * | ast_category_browse (struct ast_config *config, const char *prev) |
Goes through categories. | |
int | ast_category_delete (struct ast_config *cfg, const char *category) |
void | ast_category_destroy (struct ast_category *cat) |
ast_variable * | ast_category_detach_variables (struct ast_category *cat) |
int | ast_category_empty (struct ast_config *cfg, const char *category) |
Removes and destroys all variables within a category. | |
int | ast_category_exist (const struct ast_config *config, const char *category_name) |
Check for category duplicates. | |
ast_variable * | ast_category_first (struct ast_category *cat) |
given a pointer to a category, return the root variable. | |
ast_category * | ast_category_get (const struct ast_config *config, const char *category_name) |
Retrieve a category if it exists. | |
void | ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match) |
Inserts new category. | |
ast_category * | ast_category_new (const char *name, const char *in_file, int lineno) |
Create a category structure. | |
void | ast_category_rename (struct ast_category *cat, const char *name) |
ast_variable * | ast_category_root (struct ast_config *config, char *cat) |
returns the root ast_variable of a config | |
int | ast_check_realtime (const char *family) |
Check if realtime engine is configured for family. | |
static void | ast_comment_destroy (struct ast_comment **comment) |
void | ast_config_destroy (struct ast_config *cfg) |
Destroys a config. | |
int | ast_config_engine_deregister (struct ast_config_engine *del) |
Deregister config engine. | |
int | ast_config_engine_register (struct ast_config_engine *new) |
Register config engine. | |
ast_category * | ast_config_get_current_category (const struct ast_config *cfg) |
Retrieve the current category name being built. | |
ast_config * | ast_config_internal_load (const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) |
ast_config * | ast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags) |
Load a config file. | |
ast_config * | ast_config_new (void) |
Create a new base configuration structure. | |
const char * | ast_config_option (struct ast_config *cfg, const char *cat, const char *var) |
Retrieve a configuration variable within the configuration set. | |
void | ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat) |
Set the category within the configuration as being current. | |
int | ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator) |
int | ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...) |
Destroy realtime configuration. | |
static void | ast_destroy_template_list (struct ast_category *cat) |
ast_config_include * | ast_include_find (struct ast_config *conf, const char *included_file) |
ast_config_include * | ast_include_new (struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size) |
void | ast_include_rename (struct ast_config *conf, const char *from_file, const char *to_file) |
static void | ast_includes_destroy (struct ast_config_include *incls) |
ast_variable * | ast_load_realtime (const char *family,...) |
Retrieve realtime configuration. | |
ast_variable * | ast_load_realtime_all (const char *family,...) |
static struct ast_variable * | ast_load_realtime_helper (const char *family, va_list ap) |
ast_config * | ast_load_realtime_multientry (const char *family,...) |
Retrieve realtime configuration. | |
int | ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *p_result,...) |
The argument parsing routine. | |
char * | ast_realtime_decode_chunk (char *chunk) |
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values. | |
int | ast_realtime_enabled (void) |
Check if there's any realtime engines loaded. | |
char * | ast_realtime_encode_chunk (struct ast_str **dest, ssize_t maxlen, const char *chunk) |
Encodes a chunk of data for realtime. | |
int | ast_realtime_require_field (const char *family,...) |
Inform realtime what fields that may be stored. | |
int | ast_store_realtime (const char *family,...) |
Create realtime configuration. | |
int | ast_unload_realtime (const char *family) |
Release any resources cached for a realtime family. | |
int | ast_update2_realtime (const char *family,...) |
Update realtime configuration. | |
int | ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...) |
Update realtime configuration. | |
void | ast_variable_append (struct ast_category *category, struct ast_variable *variable) |
ast_variable * | ast_variable_browse (const struct ast_config *config, const char *category) |
Goes through variables. | |
int | ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line) |
static void | ast_variable_destroy (struct ast_variable *doomed) |
void | ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line) |
static void | ast_variable_move (struct ast_variable *dst_var, struct ast_variable *src_var) |
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. | |
ast_variable * | ast_variables_dup (struct ast_variable *var) |
Duplicate 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 struct cache_file_mtime * | cfmtime_new (const char *filename, const char *who_asked) |
static void | clear_config_maps (void) |
static void | config_cache_attribute (const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked) |
static struct ast_config * | config_text_file_load (const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked) |
int | config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator) |
static int | count_linefeeds (char *str) |
static int | count_linefeeds_in_comments (struct ast_comment *x) |
static struct ast_config_engine * | find_engine (const char *family, int priority, char *database, int dbsiz, char *table, int tabsiz) |
Find realtime engine for realtime family. | |
static void | gen_header (FILE *f1, const char *configfile, const char *fn, const char *generator) |
static char * | handle_cli_config_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_config_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_core_show_config_mappings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static int | hash_string (const void *obj, const int flags) |
static int | hashtab_compare_strings (void *a, void *b, int flags) |
static void | inclfile_destroy (void *obj) |
static void | inherit_category (struct ast_category *new, const struct ast_category *base) |
static int | init_appendbuf (void *data) |
static void | insert_leading_blank_lines (FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno) |
static void | move_variables (struct ast_category *old, struct ast_category *new) |
static struct ast_category * | next_available_category (struct ast_category *cat) |
static int | process_text_line (struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked) |
parse one line in the configuration. | |
int | read_config_maps (void) |
Exposed re-initialization method for core process. | |
int | register_config_cli (void) |
Exposed initialization method for core process. | |
static struct inclfile * | set_fn (char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset) |
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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 |
#define MIN_VARIABLE_FNAME_SPACE 40 |
Define the minimum filename space to reserve for each ast_variable in case the filename is renamed later by ast_include_rename().
Definition at line 63 of file config.c.
Referenced by ast_variable_new().
Definition at line 1050 of file config.c.
01050 { 01051 ATTRIBUTE_INCLUDE = 0, 01052 ATTRIBUTE_EXEC = 1, 01053 };
static struct ast_comment* ALLOC_COMMENT | ( | struct ast_str * | buffer | ) | [static] |
Definition at line 130 of file config.c.
References ast_calloc, ast_str_buffer(), and ast_str_strlen().
Referenced by config_text_file_load(), and process_text_line().
00131 { 00132 struct ast_comment *x = NULL; 00133 if (!buffer || !ast_str_strlen(buffer)) { 00134 return NULL; 00135 } 00136 if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) { 00137 strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */ 00138 } 00139 return x; 00140 }
static int append_mapping | ( | const char * | name, | |
const char * | driver, | |||
const char * | database, | |||
const char * | table, | |||
int | priority | |||
) | [static] |
Definition at line 2073 of file config.c.
References ast_calloc, ast_verb, config_maps, and map.
Referenced by read_config_maps().
02074 { 02075 struct ast_config_map *map; 02076 char *dst; 02077 int length; 02078 02079 length = sizeof(*map); 02080 length += strlen(name) + 1; 02081 length += strlen(driver) + 1; 02082 length += strlen(database) + 1; 02083 if (table) 02084 length += strlen(table) + 1; 02085 02086 if (!(map = ast_calloc(1, length))) 02087 return -1; 02088 02089 dst = map->stuff; /* writable space starts here */ 02090 map->name = strcpy(dst, name); 02091 dst += strlen(dst) + 1; 02092 map->driver = strcpy(dst, driver); 02093 dst += strlen(dst) + 1; 02094 map->database = strcpy(dst, database); 02095 if (table) { 02096 dst += strlen(dst) + 1; 02097 map->table = strcpy(dst, table); 02098 } 02099 map->priority = priority; 02100 map->next = config_maps; 02101 config_maps = map; 02102 02103 ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name); 02104 02105 return 0; 02106 }
void ast_category_append | ( | struct ast_config * | config, | |
struct ast_category * | category | |||
) |
Definition at line 679 of file config.c.
References config, and ast_category::include_level.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), and write_password_to_file().
00680 { 00681 if (config->last) 00682 config->last->next = category; 00683 else 00684 config->root = category; 00685 category->include_level = config->include_level; 00686 config->last = category; 00687 config->current = category; 00688 }
char* ast_category_browse | ( | struct ast_config * | config, | |
const char * | prev | |||
) |
Goes through categories.
config | Which config structure you wish to "browse" | |
prev | A pointer to a previous category. |
a | category on success | |
NULL | on failure/no-more-categories |
Definition at line 766 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(), actual_load_config(), aji_load_config(), ast_cli_perms_init(), complete_sipnotify(), conf_exec(), config_load(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), gtalk_load_config(), iax_provision_reload(), jingle_load_config(), load_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_tech_calendars(), misdn_cfg_init(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), queues_data_provider_get(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().
00767 { 00768 struct ast_category *cat; 00769 00770 if (!prev) { 00771 /* First time browse. */ 00772 cat = config->root; 00773 } else if (config->last_browse && (config->last_browse->name == prev)) { 00774 /* Simple last browse found. */ 00775 cat = config->last_browse->next; 00776 } else { 00777 /* 00778 * Config changed since last browse. 00779 * 00780 * First try cheap last browse search. (Rebrowsing a different 00781 * previous category?) 00782 */ 00783 for (cat = config->root; cat; cat = cat->next) { 00784 if (cat->name == prev) { 00785 /* Found it. */ 00786 cat = cat->next; 00787 break; 00788 } 00789 } 00790 if (!cat) { 00791 /* 00792 * Have to do it the hard way. (Last category was deleted and 00793 * re-added?) 00794 */ 00795 for (cat = config->root; cat; cat = cat->next) { 00796 if (!strcasecmp(cat->name, prev)) { 00797 /* Found it. */ 00798 cat = cat->next; 00799 break; 00800 } 00801 } 00802 } 00803 } 00804 00805 if (cat) 00806 cat = next_available_category(cat); 00807 00808 config->last_browse = cat; 00809 return (cat) ? cat->name : NULL; 00810 }
int ast_category_delete | ( | struct ast_config * | cfg, | |
const char * | category | |||
) |
Definition at line 932 of file config.c.
References ast_category_destroy(), ast_config::last, ast_category::next, and ast_config::root.
Referenced by handle_updates().
00933 { 00934 struct ast_category *prev=NULL, *cat; 00935 00936 cat = cfg->root; 00937 while (cat) { 00938 if (cat->name == category) { 00939 if (prev) { 00940 prev->next = cat->next; 00941 if (cat == cfg->last) 00942 cfg->last = prev; 00943 } else { 00944 cfg->root = cat->next; 00945 if (cat == cfg->last) 00946 cfg->last = NULL; 00947 } 00948 ast_category_destroy(cat); 00949 return 0; 00950 } 00951 prev = cat; 00952 cat = cat->next; 00953 } 00954 00955 prev = NULL; 00956 cat = cfg->root; 00957 while (cat) { 00958 if (!strcasecmp(cat->name, category)) { 00959 if (prev) { 00960 prev->next = cat->next; 00961 if (cat == cfg->last) 00962 cfg->last = prev; 00963 } else { 00964 cfg->root = cat->next; 00965 if (cat == cfg->last) 00966 cfg->last = NULL; 00967 } 00968 ast_category_destroy(cat); 00969 return 0; 00970 } 00971 prev = cat; 00972 cat = cat->next; 00973 } 00974 return -1; 00975 }
void ast_category_destroy | ( | struct ast_category * | cat | ) |
Definition at line 718 of file config.c.
References ast_comment_destroy(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, ast_category::last, ast_category::precomments, ast_category::root, ast_category::sameline, and ast_category::trailing.
Referenced by add_cfg_entry(), ast_category_delete(), ast_category_new(), ast_config_destroy(), process_text_line(), and realtime_multi_odbc().
00719 { 00720 ast_variables_destroy(cat->root); 00721 cat->root = NULL; 00722 cat->last = NULL; 00723 ast_comment_destroy(&cat->precomments); 00724 ast_comment_destroy(&cat->sameline); 00725 ast_comment_destroy(&cat->trailing); 00726 ast_destroy_template_list(cat); 00727 ast_free(cat->file); 00728 ast_free(cat); 00729 }
struct ast_variable* ast_category_detach_variables | ( | struct ast_category * | cat | ) |
Definition at line 812 of file config.c.
References ast_category::last, and ast_category::root.
Referenced by realtime_switch_common().
00813 { 00814 struct ast_variable *v; 00815 00816 v = cat->root; 00817 cat->root = NULL; 00818 cat->last = NULL; 00819 00820 return v; 00821 }
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 977 of file config.c.
References ast_variables_destroy(), ast_category::last, ast_category::name, ast_category::next, ast_category::root, and ast_config::root.
Referenced by handle_updates().
00978 { 00979 struct ast_category *cat; 00980 00981 for (cat = cfg->root; cat; cat = cat->next) { 00982 if (!strcasecmp(cat->name, category)) 00983 continue; 00984 ast_variables_destroy(cat->root); 00985 cat->root = NULL; 00986 cat->last = NULL; 00987 return 0; 00988 } 00989 00990 return -1; 00991 }
int ast_category_exist | ( | const struct ast_config * | config, | |
const char * | category_name | |||
) |
Check for category duplicates.
config | which config to use | |
category_name | name of the category you're looking for |
Definition at line 674 of file config.c.
References ast_category_get(), and config.
00675 { 00676 return !!ast_category_get(config, category_name); 00677 }
struct ast_variable* ast_category_first | ( | struct ast_category * | cat | ) |
given a pointer to a category, return the root variable.
return the first var of a category
Definition at line 752 of file config.c.
References ast_category::root.
Referenced by process_text_line().
struct ast_category* ast_category_get | ( | const struct ast_config * | config, | |
const char * | category_name | |||
) |
Retrieve a category if it exists.
config | which config to use | |
category_name | name of the category you're looking for |
pointer | to category if found | |
NULL | if not. |
Definition at line 669 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().
00670 { 00671 return category_get(config, category_name, 0); 00672 }
void ast_category_insert | ( | struct ast_config * | config, | |
struct ast_category * | cat, | |||
const char * | match | |||
) |
Inserts new category.
config | which config to use | |
cat | newly created category to insert | |
match | which category to insert above |
Definition at line 690 of file config.c.
References config, ast_category::name, and ast_category::next.
Referenced by handle_updates().
00691 { 00692 struct ast_category *cur_category; 00693 00694 if (!cat || !match) 00695 return; 00696 if (!strcasecmp(config->root->name, match)) { 00697 cat->next = config->root; 00698 config->root = cat; 00699 return; 00700 } 00701 for (cur_category = config->root; cur_category; cur_category = cur_category->next) { 00702 if (!strcasecmp(cur_category->next->name, match)) { 00703 cat->next = cur_category->next; 00704 cur_category->next = cat; 00705 break; 00706 } 00707 } 00708 }
struct ast_category* ast_category_new | ( | const char * | name, | |
const char * | in_file, | |||
int | lineno | |||
) |
Create a category structure.
Definition at line 633 of file config.c.
References ast_calloc, ast_category_destroy(), ast_copy_string(), and ast_strdup.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), and write_password_to_file().
00634 { 00635 struct ast_category *category; 00636 00637 category = ast_calloc(1, sizeof(*category)); 00638 if (!category) { 00639 return NULL; 00640 } 00641 category->file = ast_strdup(in_file); 00642 if (!category->file) { 00643 ast_category_destroy(category); 00644 return NULL; 00645 } 00646 ast_copy_string(category->name, name, sizeof(category->name)); 00647 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */ 00648 return category; 00649 }
void ast_category_rename | ( | struct ast_category * | cat, | |
const char * | name | |||
) |
Definition at line 823 of file config.c.
References ast_copy_string(), and ast_category::name.
Referenced by handle_updates(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().
00824 { 00825 ast_copy_string(cat->name, name, sizeof(cat->name)); 00826 }
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 757 of file config.c.
References ast_category_get(), config, and ast_category::root.
Referenced by get_insecure_variable_from_config(), and get_insecure_variable_from_sipregs().
00758 { 00759 struct ast_category *category = ast_category_get(config, cat); 00760 00761 if (category) 00762 return category->root; 00763 return NULL; 00764 }
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 2394 of file config.c.
References ast_realtime_enabled(), and find_engine().
Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_queue_log(), close_mailbox(), copy_plain_file(), destroy_association(), find_realtime_gw(), handle_response_peerpoke(), handle_voicemail_show_users(), load_module(), load_moh_classes(), local_ast_moh_start(), logger_queue_rt_start(), realtime_peer(), realtime_update_peer(), rename_file(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().
02395 { 02396 struct ast_config_engine *eng; 02397 if (!ast_realtime_enabled()) { 02398 return 0; /* There are no engines at all so fail early */ 02399 } 02400 02401 eng = find_engine(family, 1, NULL, 0, NULL, 0); 02402 if (eng) 02403 return 1; 02404 return 0; 02405 }
static void ast_comment_destroy | ( | struct ast_comment ** | comment | ) | [static] |
Definition at line 508 of file config.c.
References ast_free, comment, and ast_comment::next.
Referenced by ast_category_destroy(), and ast_variable_destroy().
00509 { 00510 struct ast_comment *n, *p; 00511 00512 for (p = *comment; p; p = n) { 00513 n = p->next; 00514 ast_free(p); 00515 } 00516 00517 *comment = NULL; 00518 }
void ast_config_destroy | ( | struct ast_config * | config | ) |
Destroys a config.
config | pointer to config data structure |
Definition at line 993 of file config.c.
References ast_category_destroy(), ast_free, ast_includes_destroy(), ast_config::includes, ast_category::next, and ast_config::root.
Referenced by __ast_http_post_load(), __ast_udptl_reload(), __queues_show(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), advanced_options(), ast_config_load2(), ast_load_realtime_multientry(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), handle_cli_dialplan_save(), iax_provision_reload(), initialize_cc_max_requests(), load_config(), load_config_meetme(), load_indications(), load_module(), load_realtime_queue(), load_rpt_vars(), make_email_file(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queues_data_provider_get(), read_agent_config(), read_config_maps(), realtime_directory(), realtime_multi_handler(), realtime_multi_pgsql(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), rpt_master(), rtp_reload(), run_startup_commands(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), store_config(), tds_load_module(), unload_module(), update_realtime_members(), and vm_forwardoptions().
00994 { 00995 struct ast_category *cat, *catn; 00996 00997 if (!cfg) 00998 return; 00999 01000 ast_includes_destroy(cfg->includes); 01001 01002 cat = cfg->root; 01003 while (cat) { 01004 catn = cat; 01005 cat = cat->next; 01006 ast_category_destroy(catn); 01007 } 01008 ast_free(cfg); 01009 }
int ast_config_engine_deregister | ( | struct ast_config_engine * | del | ) |
Deregister config engine.
0 | Always |
Definition at line 2204 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().
02205 { 02206 struct ast_config_engine *ptr, *last=NULL; 02207 02208 ast_mutex_lock(&config_lock); 02209 02210 for (ptr = config_engine_list; ptr; ptr=ptr->next) { 02211 if (ptr == del) { 02212 if (last) 02213 last->next = ptr->next; 02214 else 02215 config_engine_list = ptr->next; 02216 break; 02217 } 02218 last = ptr; 02219 } 02220 02221 ast_mutex_unlock(&config_lock); 02222 02223 return 0; 02224 }
int ast_config_engine_register | ( | struct ast_config_engine * | newconfig | ) |
Register config engine.
1 | Always |
Definition at line 2185 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().
02186 { 02187 struct ast_config_engine *ptr; 02188 02189 ast_mutex_lock(&config_lock); 02190 02191 if (!config_engine_list) { 02192 config_engine_list = new; 02193 } else { 02194 for (ptr = config_engine_list; ptr->next; ptr=ptr->next); 02195 ptr->next = new; 02196 } 02197 02198 ast_mutex_unlock(&config_lock); 02199 ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name); 02200 02201 return 1; 02202 }
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 1011 of file config.c.
References ast_config::current.
Referenced by config_curl(), config_odbc(), and config_text_file_load().
01012 { 01013 return cfg->current; 01014 }
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 2266 of file config.c.
References ast_log(), ast_test_flag, config_engine_list, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, db, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, table, and text_file_engine.
Referenced by add_cfg_entry(), ast_config_load2(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), process_text_line(), and read_config_maps().
02267 { 02268 char db[256]; 02269 char table[256]; 02270 struct ast_config_engine *loader = &text_file_engine; 02271 struct ast_config *result; 02272 02273 /* The config file itself bumps include_level by 1 */ 02274 if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) { 02275 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level); 02276 return NULL; 02277 } 02278 02279 cfg->include_level++; 02280 02281 if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) { 02282 struct ast_config_engine *eng; 02283 02284 eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table)); 02285 02286 02287 if (eng && eng->load_func) { 02288 loader = eng; 02289 } else { 02290 eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table)); 02291 if (eng && eng->load_func) 02292 loader = eng; 02293 } 02294 } 02295 02296 result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked); 02297 02298 if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED) 02299 result->include_level--; 02300 else if (result != CONFIG_STATUS_FILEINVALID) 02301 cfg->include_level--; 02302 02303 return result; 02304 }
struct ast_config* ast_config_load2 | ( | const char * | filename, | |
const char * | who_asked, | |||
struct ast_flags | flags | |||
) |
Load a config file.
filename | path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR | |
who_asked | The module which is making this request. | |
flags | Optional flags: CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact; CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files). |
NULL | on error |
Definition at line 2306 of file config.c.
References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), CONFIG_STATUS_FILEINVALID, and CONFIG_STATUS_FILEUNCHANGED.
Referenced by __ast_http_load(), __ast_http_post_load(), __ast_udptl_reload(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_cli_perms_init(), ast_readconfig(), do_reload(), iax_provision_reload(), init_logger_chain(), initialize_cc_max_requests(), load_config(), load_indications(), load_modules(), misdn_cfg_init(), private_enum_init(), rtp_reload(), run_startup_commands(), and set_config().
02307 { 02308 struct ast_config *cfg; 02309 struct ast_config *result; 02310 02311 cfg = ast_config_new(); 02312 if (!cfg) 02313 return NULL; 02314 02315 result = ast_config_internal_load(filename, cfg, flags, "", who_asked); 02316 if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID) 02317 ast_config_destroy(cfg); 02318 02319 return result; 02320 }
struct ast_config* ast_config_new | ( | void | ) |
Create a new base configuration structure.
Definition at line 844 of file config.c.
References ast_calloc, config, and MAX_INCLUDE_LEVEL.
Referenced by ast_config_load2(), load_realtime_queue(), read_config_maps(), realtime_multi_curl(), realtime_multi_handler(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), setup_dahdi_int(), and write_password_to_file().
00845 { 00846 struct ast_config *config; 00847 00848 if ((config = ast_calloc(1, sizeof(*config)))) 00849 config->max_include_level = MAX_INCLUDE_LEVEL; 00850 return config; 00851 }
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 574 of file config.c.
References ast_variable_retrieve().
Referenced by actual_load_config(), pbx_load_users(), and search_directory_sub().
00575 { 00576 const char *tmp; 00577 tmp = ast_variable_retrieve(cfg, cat, var); 00578 if (!tmp) { 00579 tmp = ast_variable_retrieve(cfg, "general", var); 00580 } 00581 return tmp; 00582 }
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 1016 of file config.c.
References ast_config::current.
01017 { 01018 /* cast below is just to silence compiler warning about dropping "const" */ 01019 cfg->current = (struct ast_category *) cat; 01020 }
int ast_config_text_file_save | ( | const char * | configfile, | |
const struct ast_config * | cfg, | |||
const char * | generator | |||
) |
Definition at line 1803 of file config.c.
References ao2_container_alloc, ao2_ref, ast_debug, AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_verb, ast_comment::cmt, errno, ast_config_include::exec, ast_config_include::exec_file, f, ast_category::file, gen_header(), hash_string(), hashtab_compare_strings(), ast_category::ignored, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config::includes, insert_leading_blank_lines(), ast_category_template_instance::inst, ast_category::lineno, ast_variable::name, ast_category_template_instance::name, ast_category::name, ast_category::next, ast_variable::next, ast_category_template_instance::next, ast_comment::next, ast_config_include::next, option_debug, ast_config_include::output, ast_category::precomments, ast_category::root, ast_config::root, ast_category::sameline, set_fn(), ast_category::template_instances, ast_category::trailing, ast_variable::value, and var.
Referenced by action_updateconfig(), config_text_file_save(), vm_change_password(), vm_forwardoptions(), and write_password_to_file().
01804 { 01805 FILE *f; 01806 char fn[PATH_MAX]; 01807 struct ast_variable *var; 01808 struct ast_category *cat; 01809 struct ast_comment *cmt; 01810 struct ast_config_include *incl; 01811 int blanklines = 0; 01812 struct ao2_container *fileset; 01813 struct inclfile *fi; 01814 01815 fileset = ao2_container_alloc(1023, hash_string, hashtab_compare_strings); 01816 if (!fileset) { 01817 /* Container creation failed. */ 01818 return -1; 01819 } 01820 01821 /* reset all the output flags, in case this isn't our first time saving this data */ 01822 for (incl = cfg->includes; incl; incl = incl->next) { 01823 incl->output = 0; 01824 } 01825 01826 /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions) 01827 are all truncated to zero bytes and have that nice header*/ 01828 for (incl = cfg->includes; incl; incl = incl->next) { 01829 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*/ 01830 /* normally, fn is just set to incl->included_file, prepended with config dir if relative */ 01831 fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset); 01832 f = fopen(fn, "w"); 01833 if (f) { 01834 gen_header(f, configfile, fn, generator); 01835 fclose(f); /* this should zero out the file */ 01836 } else { 01837 ast_debug(1, "Unable to open for writing: %s\n", fn); 01838 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01839 } 01840 if (fi) { 01841 ao2_ref(fi, -1); 01842 } 01843 } 01844 } 01845 01846 /* just set fn to absolute ver of configfile */ 01847 fi = set_fn(fn, sizeof(fn), 0, configfile, fileset); 01848 if ( 01849 #ifdef __CYGWIN__ 01850 (f = fopen(fn, "w+")) 01851 #else 01852 (f = fopen(fn, "w")) 01853 #endif 01854 ) { 01855 ast_verb(2, "Saving '%s': ", fn); 01856 gen_header(f, configfile, fn, generator); 01857 cat = cfg->root; 01858 fclose(f); 01859 if (fi) { 01860 ao2_ref(fi, -1); 01861 } 01862 01863 /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */ 01864 /* since each var, cat, and associated comments can come from any file, we have to be 01865 mobile, and open each file, print, and close it on an entry-by-entry basis */ 01866 01867 while (cat) { 01868 fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset); 01869 f = fopen(fn, "a"); 01870 if (!f) { 01871 ast_debug(1, "Unable to open for writing: %s\n", fn); 01872 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01873 if (fi) { 01874 ao2_ref(fi, -1); 01875 } 01876 ao2_ref(fileset, -1); 01877 return -1; 01878 } 01879 01880 /* dump any includes that happen before this category header */ 01881 for (incl=cfg->includes; incl; incl = incl->next) { 01882 if (strcmp(incl->include_location_file, cat->file) == 0){ 01883 if (cat->lineno > incl->include_location_lineno && !incl->output) { 01884 if (incl->exec) 01885 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01886 else 01887 fprintf(f,"#include \"%s\"\n", incl->included_file); 01888 incl->output = 1; 01889 } 01890 } 01891 } 01892 01893 insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno); 01894 /* Dump section with any appropriate comment */ 01895 for (cmt = cat->precomments; cmt; cmt=cmt->next) { 01896 char *cmtp = cmt->cmt; 01897 while (*cmtp == ';' && *(cmtp+1) == '!') { 01898 char *cmtp2 = strchr(cmtp+1, '\n'); 01899 if (cmtp2) 01900 cmtp = cmtp2+1; 01901 else cmtp = 0; 01902 } 01903 if (cmtp) 01904 fprintf(f,"%s", cmtp); 01905 } 01906 fprintf(f, "[%s]", cat->name); 01907 if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) { 01908 fprintf(f, "("); 01909 if (cat->ignored) { 01910 fprintf(f, "!"); 01911 } 01912 if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) { 01913 fprintf(f, ","); 01914 } 01915 if (!AST_LIST_EMPTY(&cat->template_instances)) { 01916 struct ast_category_template_instance *x; 01917 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01918 fprintf(f,"%s",x->name); 01919 if (x != AST_LIST_LAST(&cat->template_instances)) 01920 fprintf(f,","); 01921 } 01922 } 01923 fprintf(f, ")"); 01924 } 01925 for(cmt = cat->sameline; cmt; cmt=cmt->next) 01926 { 01927 fprintf(f,"%s", cmt->cmt); 01928 } 01929 if (!cat->sameline) 01930 fprintf(f,"\n"); 01931 for (cmt = cat->trailing; cmt; cmt=cmt->next) { 01932 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01933 fprintf(f,"%s", cmt->cmt); 01934 } 01935 fclose(f); 01936 if (fi) { 01937 ao2_ref(fi, -1); 01938 } 01939 01940 var = cat->root; 01941 while (var) { 01942 struct ast_category_template_instance *x; 01943 int found = 0; 01944 AST_LIST_TRAVERSE(&cat->template_instances, x, next) { 01945 struct ast_variable *v; 01946 for (v = x->inst->root; v; v = v->next) { 01947 if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) { 01948 found = 1; 01949 break; 01950 } 01951 } 01952 if (found) 01953 break; 01954 } 01955 if (found) { 01956 var = var->next; 01957 continue; 01958 } 01959 fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset); 01960 f = fopen(fn, "a"); 01961 if (!f) { 01962 ast_debug(1, "Unable to open for writing: %s\n", fn); 01963 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 01964 if (fi) { 01965 ao2_ref(fi, -1); 01966 } 01967 ao2_ref(fileset, -1); 01968 return -1; 01969 } 01970 01971 /* dump any includes that happen before this category header */ 01972 for (incl=cfg->includes; incl; incl = incl->next) { 01973 if (strcmp(incl->include_location_file, var->file) == 0){ 01974 if (var->lineno > incl->include_location_lineno && !incl->output) { 01975 if (incl->exec) 01976 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 01977 else 01978 fprintf(f,"#include \"%s\"\n", incl->included_file); 01979 incl->output = 1; 01980 } 01981 } 01982 } 01983 01984 insert_leading_blank_lines(f, fi, var->precomments, var->lineno); 01985 for (cmt = var->precomments; cmt; cmt=cmt->next) { 01986 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01987 fprintf(f,"%s", cmt->cmt); 01988 } 01989 if (var->sameline) 01990 fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt); 01991 else 01992 fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value); 01993 for (cmt = var->trailing; cmt; cmt=cmt->next) { 01994 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!') 01995 fprintf(f,"%s", cmt->cmt); 01996 } 01997 if (var->blanklines) { 01998 blanklines = var->blanklines; 01999 while (blanklines--) 02000 fprintf(f, "\n"); 02001 } 02002 02003 fclose(f); 02004 if (fi) { 02005 ao2_ref(fi, -1); 02006 } 02007 02008 var = var->next; 02009 } 02010 cat = cat->next; 02011 } 02012 if (!option_debug) 02013 ast_verb(2, "Saved\n"); 02014 } else { 02015 ast_debug(1, "Unable to open for writing: %s\n", fn); 02016 ast_verb(2, "Unable to write (%s)", strerror(errno)); 02017 if (fi) { 02018 ao2_ref(fi, -1); 02019 } 02020 ao2_ref(fileset, -1); 02021 return -1; 02022 } 02023 02024 /* Now, for files with trailing #include/#exec statements, 02025 we have to make sure every entry is output */ 02026 for (incl=cfg->includes; incl; incl = incl->next) { 02027 if (!incl->output) { 02028 /* open the respective file */ 02029 fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset); 02030 f = fopen(fn, "a"); 02031 if (!f) { 02032 ast_debug(1, "Unable to open for writing: %s\n", fn); 02033 ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno)); 02034 if (fi) { 02035 ao2_ref(fi, -1); 02036 } 02037 ao2_ref(fileset, -1); 02038 return -1; 02039 } 02040 02041 /* output the respective include */ 02042 if (incl->exec) 02043 fprintf(f,"#exec \"%s\"\n", incl->exec_file); 02044 else 02045 fprintf(f,"#include \"%s\"\n", incl->included_file); 02046 fclose(f); 02047 incl->output = 1; 02048 if (fi) { 02049 ao2_ref(fi, -1); 02050 } 02051 } 02052 } 02053 ao2_ref(fileset, -1); /* this should destroy the hash container */ 02054 02055 return 0; 02056 }
int ast_destroy_realtime | ( | const char * | family, | |
const char * | keyfield, | |||
const char * | lookup, | |||
... | ||||
) |
Destroy realtime configuration.
family | which family/config to be destroyed | |
keyfield | which field to use as the key | |
lookup | which value to look for in the key field to match the entry. |
Definition at line 2557 of file config.c.
References db, ast_config_engine::destroy_func, find_engine(), and table.
Referenced by cli_realtime_destroy(), function_realtime_readdestroy(), and vm_delete().
02558 { 02559 struct ast_config_engine *eng; 02560 int res = -1, i; 02561 char db[256]; 02562 char table[256]; 02563 va_list ap; 02564 02565 va_start(ap, lookup); 02566 for (i = 1; ; i++) { 02567 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02568 if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, ap))) { 02569 break; 02570 } 02571 } else { 02572 break; 02573 } 02574 } 02575 va_end(ap); 02576 02577 return res; 02578 }
static void ast_destroy_template_list | ( | struct ast_category * | cat | ) | [static] |
Definition at line 710 of file config.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_category_template_instance::next, and ast_category::template_instances.
Referenced by ast_category_destroy().
00711 { 00712 struct ast_category_template_instance *x; 00713 00714 while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next))) 00715 ast_free(x); 00716 }
struct ast_config_include* ast_include_find | ( | struct ast_config * | conf, | |
const char * | included_file | |||
) |
Definition at line 460 of file config.c.
References ast_config_include::included_file, ast_config::includes, and ast_config_include::next.
Referenced by ast_include_new().
00461 { 00462 struct ast_config_include *x; 00463 for (x=conf->includes;x;x=x->next) { 00464 if (strcmp(x->included_file,included_file) == 0) 00465 return x; 00466 } 00467 return 0; 00468 }
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 320 of file config.c.
References ast_calloc, ast_include_find(), ast_includes_destroy(), ast_log(), ast_strdup, ast_strlen_zero(), ast_config::includes, and LOG_WARNING.
Referenced by process_text_line().
00321 { 00322 /* a file should be included ONCE. Otherwise, if one of the instances is changed, 00323 * then all be changed. -- how do we know to include it? -- Handling modified 00324 * instances is possible, I'd have 00325 * to create a new master for each instance. */ 00326 struct ast_config_include *inc; 00327 struct stat statbuf; 00328 00329 inc = ast_include_find(conf, included_file); 00330 if (inc) { 00331 do { 00332 inc->inclusion_count++; 00333 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count); 00334 } while (stat(real_included_file_name, &statbuf) == 0); 00335 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); 00336 } else 00337 *real_included_file_name = 0; 00338 00339 inc = ast_calloc(1,sizeof(struct ast_config_include)); 00340 if (!inc) { 00341 return NULL; 00342 } 00343 inc->include_location_file = ast_strdup(from_file); 00344 inc->include_location_lineno = from_lineno; 00345 if (!ast_strlen_zero(real_included_file_name)) 00346 inc->included_file = ast_strdup(real_included_file_name); 00347 else 00348 inc->included_file = ast_strdup(included_file); 00349 00350 inc->exec = is_exec; 00351 if (is_exec) 00352 inc->exec_file = ast_strdup(exec_file); 00353 00354 if (!inc->include_location_file 00355 || !inc->included_file 00356 || (is_exec && !inc->exec_file)) { 00357 ast_includes_destroy(inc); 00358 return NULL; 00359 } 00360 00361 /* attach this new struct to the conf struct */ 00362 inc->next = conf->includes; 00363 conf->includes = inc; 00364 00365 return inc; 00366 }
void ast_include_rename | ( | struct ast_config * | conf, | |
const char * | from_file, | |||
const char * | to_file | |||
) |
Definition at line 368 of file config.c.
References ast_free, ast_strdup, ast_variable_destroy(), ast_variable_move(), ast_variable_new(), ast_variable::file, ast_category::file, ast_config_include::include_location_file, ast_config::includes, ast_category::last, ast_variable::name, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, ast_config::root, str, and ast_variable::value.
Referenced by action_updateconfig().
00369 { 00370 struct ast_config_include *incl; 00371 struct ast_category *cat; 00372 char *str; 00373 00374 int from_len = strlen(from_file); 00375 int to_len = strlen(to_file); 00376 00377 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */ 00378 return; 00379 00380 /* the manager code allows you to read in one config file, then 00381 * write it back out under a different name. But, the new arrangement 00382 * ties output lines to the file name. So, before you try to write 00383 * the config file to disk, better riffle thru the data and make sure 00384 * the file names are changed. 00385 */ 00386 /* file names are on categories, includes (of course), and on variables. So, 00387 * traverse all this and swap names */ 00388 00389 for (incl = conf->includes; incl; incl=incl->next) { 00390 if (strcmp(incl->include_location_file,from_file) == 0) { 00391 if (from_len >= to_len) 00392 strcpy(incl->include_location_file, to_file); 00393 else { 00394 /* Keep the old filename if the allocation fails. */ 00395 str = ast_strdup(to_file); 00396 if (str) { 00397 ast_free(incl->include_location_file); 00398 incl->include_location_file = str; 00399 } 00400 } 00401 } 00402 } 00403 for (cat = conf->root; cat; cat = cat->next) { 00404 struct ast_variable **prev; 00405 struct ast_variable *v; 00406 struct ast_variable *new_var; 00407 00408 if (strcmp(cat->file,from_file) == 0) { 00409 if (from_len >= to_len) 00410 strcpy(cat->file, to_file); 00411 else { 00412 /* Keep the old filename if the allocation fails. */ 00413 str = ast_strdup(to_file); 00414 if (str) { 00415 ast_free(cat->file); 00416 cat->file = str; 00417 } 00418 } 00419 } 00420 for (prev = &cat->root, v = cat->root; v; prev = &v->next, v = v->next) { 00421 if (strcmp(v->file, from_file)) { 00422 continue; 00423 } 00424 00425 /* 00426 * Calculate actual space available. The file string is 00427 * intentionally stuffed before the name string just so we can 00428 * do this. 00429 */ 00430 if (to_len < v->name - v->file) { 00431 /* The new name will fit in the available space. */ 00432 str = (char *) v->file;/* Stupid compiler complains about discarding qualifiers even though I used a cast. */ 00433 strcpy(str, to_file);/* SAFE */ 00434 continue; 00435 } 00436 00437 /* Keep the old filename if the allocation fails. */ 00438 new_var = ast_variable_new(v->name, v->value, to_file); 00439 if (!new_var) { 00440 continue; 00441 } 00442 00443 /* Move items from the old list node to the replacement node. */ 00444 ast_variable_move(new_var, v); 00445 00446 /* Replace the old node in the list with the new node. */ 00447 new_var->next = v->next; 00448 if (cat->last == v) { 00449 cat->last = new_var; 00450 } 00451 *prev = new_var; 00452 00453 ast_variable_destroy(v); 00454 00455 v = new_var; 00456 } 00457 } 00458 }
static void ast_includes_destroy | ( | struct ast_config_include * | incls | ) | [static] |
Definition at line 731 of file config.c.
References ast_free, ast_config_include::exec_file, ast_config_include::include_location_file, ast_config_include::included_file, and ast_config_include::next.
Referenced by ast_config_destroy(), and ast_include_new().
00732 { 00733 struct ast_config_include *incl,*inclnext; 00734 00735 for (incl=incls; incl; incl = inclnext) { 00736 inclnext = incl->next; 00737 ast_free(incl->include_location_file); 00738 ast_free(incl->exec_file); 00739 ast_free(incl->included_file); 00740 ast_free(incl); 00741 } 00742 }
struct ast_variable* ast_load_realtime | ( | const char * | family, | |
... | ||||
) |
Retrieve realtime configuration.
family | which family/config to lookup |
The difference between these two calls is that ast_load_realtime excludes fields whose values are NULL, while ast_load_realtime_all loads all columns.
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2355 of file config.c.
References ast_load_realtime_helper(), ast_strlen_zero(), ast_variable_destroy(), ast_variable::next, and ast_variable::value.
Referenced by conf_run(), copy_plain_file(), find_conf_realtime(), find_realtime(), find_realtime_gw(), find_user_realtime(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), queue_function_queuewaitingcount(), realtime_alias(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_switch_common(), realtime_user(), and rt_extend_conf().
02356 { 02357 struct ast_variable *res; 02358 struct ast_variable *cur; 02359 struct ast_variable **prev; 02360 va_list ap; 02361 02362 va_start(ap, family); 02363 res = ast_load_realtime_helper(family, ap); 02364 va_end(ap); 02365 02366 /* Filter the list. */ 02367 prev = &res; 02368 cur = res; 02369 while (cur) { 02370 if (ast_strlen_zero(cur->value)) { 02371 /* Eliminate empty entries */ 02372 struct ast_variable *next; 02373 02374 next = cur->next; 02375 *prev = next; 02376 ast_variable_destroy(cur); 02377 cur = next; 02378 } else { 02379 /* Make blank entries empty and keep them. */ 02380 if (cur->value[0] == ' ' && cur->value[1] == '\0') { 02381 char *vptr = (char *) cur->value; 02382 02383 vptr[0] = '\0'; 02384 } 02385 02386 prev = &cur->next; 02387 cur = cur->next; 02388 } 02389 } 02390 return res; 02391 }
struct ast_variable* ast_load_realtime_all | ( | const char * | family, | |
... | ||||
) |
Definition at line 2343 of file config.c.
References ast_load_realtime_helper().
Referenced by cli_realtime_load(), function_realtime_read(), function_realtime_readdestroy(), and realtimefield_read().
02344 { 02345 struct ast_variable *res; 02346 va_list ap; 02347 02348 va_start(ap, family); 02349 res = ast_load_realtime_helper(family, ap); 02350 va_end(ap); 02351 02352 return res; 02353 }
static struct ast_variable* ast_load_realtime_helper | ( | const char * | family, | |
va_list | ap | |||
) | [static] |
Definition at line 2322 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().
02323 { 02324 struct ast_config_engine *eng; 02325 char db[256]; 02326 char table[256]; 02327 struct ast_variable *res=NULL; 02328 int i; 02329 02330 for (i = 1; ; i++) { 02331 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02332 if (eng->realtime_func && (res = eng->realtime_func(db, table, ap))) { 02333 return res; 02334 } 02335 } else { 02336 return NULL; 02337 } 02338 } 02339 02340 return res; 02341 }
struct ast_config* ast_load_realtime_multientry | ( | const char * | family, | |
... | ||||
) |
Retrieve realtime configuration.
family | which family/config to lookup |
NULL | Error or no results returned |
Definition at line 2457 of file config.c.
References ast_config_destroy(), db, find_engine(), ast_config_engine::realtime_multi_func, ast_config::root, and table.
Referenced by __queues_show(), conf_exec(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), load_realtime_queue(), queues_data_provider_get(), realtime_directory(), realtime_switch_common(), show_users_realtime(), and update_realtime_members().
02458 { 02459 struct ast_config_engine *eng; 02460 char db[256]; 02461 char table[256]; 02462 struct ast_config *res = NULL; 02463 va_list ap; 02464 int i; 02465 02466 va_start(ap, family); 02467 for (i = 1; ; i++) { 02468 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02469 if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, ap))) { 02470 /* If we were returned an empty cfg, destroy it and return NULL */ 02471 if (!res->root) { 02472 ast_config_destroy(res); 02473 res = NULL; 02474 } 02475 break; 02476 } 02477 } else { 02478 break; 02479 } 02480 } 02481 va_end(ap); 02482 02483 return res; 02484 }
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 2612 of file config.c.
References ahp, ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_strdupa, hp, PARSE_ADDR, PARSE_DEFAULT, PARSE_DOUBLE, PARSE_IN_RANGE, PARSE_INADDR, PARSE_INT32, PARSE_OUT_RANGE, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, PARSE_PORT_REQUIRE, PARSE_TYPE, PARSE_UINT32, and strsep().
Referenced by ast_tls_read_conf(), and check_via_response().
02614 { 02615 va_list ap; 02616 int error = 0; 02617 02618 va_start(ap, p_result); 02619 switch (flags & PARSE_TYPE) { 02620 case PARSE_INT32: 02621 { 02622 int32_t *result = p_result; 02623 int32_t x, def = result ? *result : 0, 02624 high = (int32_t)0x7fffffff, 02625 low = (int32_t)0x80000000; 02626 /* optional argument: first default value, then range */ 02627 if (flags & PARSE_DEFAULT) 02628 def = va_arg(ap, int32_t); 02629 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02630 /* range requested, update bounds */ 02631 low = va_arg(ap, int32_t); 02632 high = va_arg(ap, int32_t); 02633 } 02634 x = strtol(arg, NULL, 0); 02635 error = (x < low) || (x > high); 02636 if (flags & PARSE_OUT_RANGE) 02637 error = !error; 02638 if (result) 02639 *result = error ? def : x; 02640 ast_debug(3, 02641 "extract int from [%s] in [%d, %d] gives [%d](%d)\n", 02642 arg, low, high, 02643 result ? *result : x, error); 02644 break; 02645 } 02646 02647 case PARSE_UINT32: 02648 { 02649 uint32_t *result = p_result; 02650 uint32_t x, def = result ? *result : 0, 02651 low = 0, high = (uint32_t)~0; 02652 /* optional argument: first default value, then range */ 02653 if (flags & PARSE_DEFAULT) 02654 def = va_arg(ap, uint32_t); 02655 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02656 /* range requested, update bounds */ 02657 low = va_arg(ap, uint32_t); 02658 high = va_arg(ap, uint32_t); 02659 } 02660 x = strtoul(arg, NULL, 0); 02661 error = (x < low) || (x > high); 02662 if (flags & PARSE_OUT_RANGE) 02663 error = !error; 02664 if (result) 02665 *result = error ? def : x; 02666 ast_debug(3, 02667 "extract uint from [%s] in [%u, %u] gives [%u](%d)\n", 02668 arg, low, high, 02669 result ? *result : x, error); 02670 break; 02671 } 02672 02673 case PARSE_DOUBLE: 02674 { 02675 double *result = p_result; 02676 double x, def = result ? *result : 0, 02677 low = -HUGE_VAL, high = HUGE_VAL; 02678 02679 /* optional argument: first default value, then range */ 02680 if (flags & PARSE_DEFAULT) 02681 def = va_arg(ap, double); 02682 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) { 02683 /* range requested, update bounds */ 02684 low = va_arg(ap, double); 02685 high = va_arg(ap, double); 02686 } 02687 x = strtod(arg, NULL); 02688 error = (x < low) || (x > high); 02689 if (flags & PARSE_OUT_RANGE) 02690 error = !error; 02691 if (result) 02692 *result = error ? def : x; 02693 ast_debug(3, 02694 "extract double from [%s] in [%f, %f] gives [%f](%d)\n", 02695 arg, low, high, 02696 result ? *result : x, error); 02697 break; 02698 } 02699 case PARSE_ADDR: 02700 { 02701 struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result; 02702 02703 if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) { 02704 error = 1; 02705 } 02706 02707 ast_debug(3, "extract addr from %s gives %s(%d)\n", 02708 arg, ast_sockaddr_stringify(addr), error); 02709 02710 break; 02711 } 02712 case PARSE_INADDR: /* TODO Remove this (use PARSE_ADDR instead). */ 02713 { 02714 char *port, *buf; 02715 struct sockaddr_in _sa_buf; /* buffer for the result */ 02716 struct sockaddr_in *sa = p_result ? 02717 (struct sockaddr_in *)p_result : &_sa_buf; 02718 /* default is either the supplied value or the result itself */ 02719 struct sockaddr_in *def = (flags & PARSE_DEFAULT) ? 02720 va_arg(ap, struct sockaddr_in *) : sa; 02721 struct hostent *hp; 02722 struct ast_hostent ahp; 02723 02724 memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */ 02725 /* duplicate the string to strip away the :port */ 02726 port = ast_strdupa(arg); 02727 buf = strsep(&port, ":"); 02728 sa->sin_family = AF_INET; /* assign family */ 02729 /* 02730 * honor the ports flag setting, assign default value 02731 * in case of errors or field unset. 02732 */ 02733 flags &= PARSE_PORT_MASK; /* the only flags left to process */ 02734 if (port) { 02735 if (flags == PARSE_PORT_FORBID) { 02736 error = 1; /* port was forbidden */ 02737 sa->sin_port = def->sin_port; 02738 } else if (flags == PARSE_PORT_IGNORE) 02739 sa->sin_port = def->sin_port; 02740 else /* accept or require */ 02741 sa->sin_port = htons(strtol(port, NULL, 0)); 02742 } else { 02743 sa->sin_port = def->sin_port; 02744 if (flags == PARSE_PORT_REQUIRE) 02745 error = 1; 02746 } 02747 /* Now deal with host part, even if we have errors before. */ 02748 hp = ast_gethostbyname(buf, &ahp); 02749 if (hp) /* resolved successfully */ 02750 memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr)); 02751 else { 02752 error = 1; 02753 sa->sin_addr = def->sin_addr; 02754 } 02755 ast_debug(3, 02756 "extract inaddr from [%s] gives [%s:%d](%d)\n", 02757 arg, ast_inet_ntoa(sa->sin_addr), 02758 ntohs(sa->sin_port), error); 02759 break; 02760 } 02761 } 02762 va_end(ap); 02763 return error; 02764 }
char* ast_realtime_decode_chunk | ( | char * | chunk | ) |
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values.
chunk | Data to be decoded |
Definition at line 2580 of file config.c.
Referenced by realtime_multi_pgsql(), and realtime_pgsql().
02581 { 02582 char *orig = chunk; 02583 for (; *chunk; chunk++) { 02584 if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) { 02585 sscanf(chunk + 1, "%02hhX", chunk); 02586 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1); 02587 } 02588 } 02589 return orig; 02590 }
int ast_realtime_enabled | ( | void | ) |
Check if there's any realtime engines loaded.
Definition at line 2408 of file config.c.
References config_maps.
Referenced by action_coresettings(), ast_check_realtime(), and handle_show_settings().
02409 { 02410 return config_maps ? 1 : 0; 02411 }
char* ast_realtime_encode_chunk | ( | struct ast_str ** | dest, | |
ssize_t | maxlen, | |||
const char * | chunk | |||
) |
Encodes a chunk of data for realtime.
dest | Destination buffer | |
maxlen | Length passed through to ast_str_* functions | |
chunk | Source data to be encoded |
Definition at line 2592 of file config.c.
References ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_set().
02593 { 02594 if (!strchr(chunk, ';') && !strchr(chunk, '^')) { 02595 ast_str_set(dest, maxlen, "%s", chunk); 02596 } else { 02597 ast_str_reset(*dest); 02598 for (; *chunk; chunk++) { 02599 if (strchr(";^", *chunk)) { 02600 ast_str_append(dest, maxlen, "^%02hhX", *chunk); 02601 } else { 02602 ast_str_append(dest, maxlen, "%c", *chunk); 02603 } 02604 } 02605 } 02606 return ast_str_buffer(*dest); 02607 }
int ast_realtime_require_field | ( | const char * | family, | |
... | ||||
) |
Inform realtime what fields that may be stored.
family | which family/config is referenced |
The arguments are specified in groups of 3: column name, column type, and column size. The column types are specified as integer constants, defined by the enum require_type. Note that the size is specified as the number of equivalent character fields that a field may take up, even if a field is otherwise specified as an integer type. This is due to the fact that some fields have historically been specified as character types, even if they contained integer values.
A family should always specify its fields to the minimum necessary requirements to fulfill all possible values (within reason; for example, a timeout value may reasonably be specified as an INTEGER2, with size 5. Even though values above 32767 seconds are possible, they are unlikely to be useful, and we should not complain about that size).
0 | Required fields met specified standards | |
-1 | One or more fields was missing or insufficient |
Definition at line 2413 of file config.c.
References db, find_engine(), ast_config_engine::require_func, and table.
Referenced by ast_queue_log(), change_password_realtime(), conf_run(), load_module(), and logger_queue_rt_start().
02414 { 02415 struct ast_config_engine *eng; 02416 char db[256]; 02417 char table[256]; 02418 va_list ap; 02419 int res = -1, i; 02420 02421 va_start(ap, family); 02422 for (i = 1; ; i++) { 02423 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02424 /* If the require succeeds, it returns 0. */ 02425 if (eng->require_func && !(res = eng->require_func(db, table, ap))) { 02426 break; 02427 } 02428 } else { 02429 break; 02430 } 02431 } 02432 va_end(ap); 02433 02434 return res; 02435 }
int ast_store_realtime | ( | const char * | family, | |
... | ||||
) |
Create realtime configuration.
family | which family/config to be created |
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.
Definition at line 2533 of file config.c.
References db, find_engine(), ast_config_engine::store_func, and table.
Referenced by ast_queue_log(), cli_realtime_store(), and function_realtime_store().
02534 { 02535 struct ast_config_engine *eng; 02536 int res = -1, i; 02537 char db[256]; 02538 char table[256]; 02539 va_list ap; 02540 02541 va_start(ap, family); 02542 for (i = 1; ; i++) { 02543 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02544 /* If the store succeeds, it returns 0. */ 02545 if (eng->store_func && !(res = eng->store_func(db, table, ap))) { 02546 break; 02547 } 02548 } else { 02549 break; 02550 } 02551 } 02552 va_end(ap); 02553 02554 return res; 02555 }
int ast_unload_realtime | ( | const char * | family | ) |
Release any resources cached for a realtime family.
family | which family/config to destroy |
0 | If any cache was purged | |
-1 | If no cache was found |
Definition at line 2437 of file config.c.
References db, find_engine(), table, and ast_config_engine::unload_func.
Referenced by __unload_module(), load_config(), logger_queue_init(), reload(), reload_config(), reload_logger(), and unload_module().
02438 { 02439 struct ast_config_engine *eng; 02440 char db[256]; 02441 char table[256]; 02442 int res = -1, i; 02443 02444 for (i = 1; ; i++) { 02445 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02446 if (eng->unload_func) { 02447 /* Do this for ALL engines */ 02448 res = eng->unload_func(db, table); 02449 } 02450 } else { 02451 break; 02452 } 02453 } 02454 return res; 02455 }
int ast_update2_realtime | ( | const char * | family, | |
... | ||||
) |
Update realtime configuration.
family | which family/config to be updated |
Definition at line 2510 of file config.c.
References db, find_engine(), table, and ast_config_engine::update2_func.
Referenced by change_password_realtime(), and cli_realtime_update2().
02511 { 02512 struct ast_config_engine *eng; 02513 int res = -1, i; 02514 char db[256]; 02515 char table[256]; 02516 va_list ap; 02517 02518 va_start(ap, family); 02519 for (i = 1; ; i++) { 02520 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02521 if (eng->update2_func && !(res = eng->update2_func(db, table, ap))) { 02522 break; 02523 } 02524 } else { 02525 break; 02526 } 02527 } 02528 va_end(ap); 02529 02530 return res; 02531 }
int ast_update_realtime | ( | const char * | family, | |
const char * | keyfield, | |||
const char * | lookup, | |||
... | ||||
) |
Update realtime configuration.
family | which family/config to be updated | |
keyfield | which field to use as the key | |
lookup | which value to look for in the key field to match the entry. |
Definition at line 2486 of file config.c.
References db, find_engine(), table, and ast_config_engine::update_func.
Referenced by cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), handle_response_peerpoke(), realtime_update_peer(), rename_file(), rt_extend_conf(), sip_poke_noanswer(), and update_realtime_member_field().
02487 { 02488 struct ast_config_engine *eng; 02489 int res = -1, i; 02490 char db[256]; 02491 char table[256]; 02492 va_list ap; 02493 02494 va_start(ap, lookup); 02495 for (i = 1; ; i++) { 02496 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) { 02497 /* If the update succeeds, it returns 0. */ 02498 if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, ap))) { 02499 break; 02500 } 02501 } else { 02502 break; 02503 } 02504 } 02505 va_end(ap); 02506 02507 return res; 02508 }
void ast_variable_append | ( | struct ast_category * | category, | |
struct ast_variable * | variable | |||
) |
Definition at line 471 of file config.c.
References ast_category::last, ast_variable::next, and ast_category::root.
Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), inherit_category(), move_variables(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), vm_change_password(), and write_password_to_file().
00472 { 00473 if (!variable) 00474 return; 00475 if (category->last) 00476 category->last->next = variable; 00477 else 00478 category->root = variable; 00479 category->last = variable; 00480 while (category->last->next) 00481 category->last = category->last->next; 00482 }
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 561 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(), actual_load_config(), adsi_load(), aji_load_config(), ast_cli_perms_init(), ast_plc_reload(), ast_readconfig(), ast_variable_retrieve(), build_calendar(), build_device(), build_event_channel(), caldav_load_calendar(), check_tx_freq(), collect_function_digits(), conf_exec(), config_load(), config_module(), do_say(), do_scheduler(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), jingle_load_config(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_rpt_vars(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_create_provider(), parse_config(), parse_tone_zone(), pbx_load_config(), process_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_single_queue(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().
00562 { 00563 struct ast_category *cat = NULL; 00564 00565 if (category && config->last_browse && (config->last_browse->name == category)) { 00566 cat = config->last_browse; 00567 } else { 00568 cat = ast_category_get(config, category); 00569 } 00570 00571 return (cat) ? cat->root : NULL; 00572 }
int ast_variable_delete | ( | struct ast_category * | category, | |
const char * | variable, | |||
const char * | match, | |||
const char * | line | |||
) |
Definition at line 853 of file config.c.
References ast_strlen_zero(), ast_variable_destroy(), ast_category::last, ast_variable::name, ast_variable::next, ast_category::root, and ast_variable::value.
Referenced by handle_updates().
00854 { 00855 struct ast_variable *cur, *prev=NULL, *curn; 00856 int res = -1; 00857 int num_item = 0; 00858 int req_item; 00859 00860 req_item = -1; 00861 if (!ast_strlen_zero(line)) { 00862 /* Requesting to delete by item number. */ 00863 if (sscanf(line, "%30d", &req_item) != 1 00864 || req_item < 0) { 00865 /* Invalid item number to delete. */ 00866 return -1; 00867 } 00868 } 00869 00870 prev = NULL; 00871 cur = category->root; 00872 while (cur) { 00873 curn = cur->next; 00874 /* Delete by item number or by variable name with optional value. */ 00875 if ((0 <= req_item && num_item == req_item) 00876 || (req_item < 0 && !strcasecmp(cur->name, variable) 00877 && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) { 00878 if (prev) { 00879 prev->next = cur->next; 00880 if (cur == category->last) 00881 category->last = prev; 00882 } else { 00883 category->root = cur->next; 00884 if (cur == category->last) 00885 category->last = NULL; 00886 } 00887 ast_variable_destroy(cur); 00888 res = 0; 00889 } else 00890 prev = cur; 00891 00892 cur = curn; 00893 ++num_item; 00894 } 00895 return res; 00896 }
static void ast_variable_destroy | ( | struct ast_variable * | doomed | ) | [static] |
Definition at line 520 of file config.c.
References ast_comment_destroy(), ast_free, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.
Referenced by ast_include_rename(), ast_load_realtime(), ast_variable_delete(), ast_variable_update(), and ast_variables_destroy().
00521 { 00522 ast_comment_destroy(&doomed->precomments); 00523 ast_comment_destroy(&doomed->sameline); 00524 ast_comment_destroy(&doomed->trailing); 00525 ast_free(doomed); 00526 }
void ast_variable_insert | ( | struct ast_category * | category, | |
struct ast_variable * | variable, | |||
const char * | line | |||
) |
Definition at line 484 of file config.c.
References ast_variable::next, and ast_category::root.
Referenced by handle_updates().
00485 { 00486 struct ast_variable *cur = category->root; 00487 int lineno; 00488 int insertline; 00489 00490 if (!variable || sscanf(line, "%30d", &insertline) != 1) { 00491 return; 00492 } 00493 if (!insertline) { 00494 variable->next = category->root; 00495 category->root = variable; 00496 } else { 00497 for (lineno = 1; lineno < insertline; lineno++) { 00498 cur = cur->next; 00499 if (!cur->next) { 00500 break; 00501 } 00502 } 00503 variable->next = cur->next; 00504 cur->next = variable; 00505 } 00506 }
static void ast_variable_move | ( | struct ast_variable * | dst_var, | |
struct ast_variable * | src_var | |||
) | [static] |
Definition at line 307 of file config.c.
References ast_variable::blanklines, ast_variable::lineno, ast_variable::object, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.
Referenced by ast_include_rename(), and ast_variable_update().
00308 { 00309 dst_var->lineno = src_var->lineno; 00310 dst_var->object = src_var->object; 00311 dst_var->blanklines = src_var->blanklines; 00312 dst_var->precomments = src_var->precomments; 00313 src_var->precomments = NULL; 00314 dst_var->sameline = src_var->sameline; 00315 src_var->sameline = NULL; 00316 dst_var->trailing = src_var->trailing; 00317 src_var->trailing = NULL; 00318 }
struct ast_variable* ast_variable_new | ( | const char * | name, | |
const char * | value, | |||
const char * | filename | |||
) |
Definition at line 266 of file config.c.
References __ast_calloc(), ast_calloc, and MIN_VARIABLE_FNAME_SPACE.
Referenced by add_cfg_entry(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), apply_outgoing(), ast_channeltype_list(), ast_include_rename(), ast_variable_update(), ast_variables_dup(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), dup_vars(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), man_do_variable_value(), manager_sipnotify(), parkandannounce_exec(), parse_cookies(), process_text_line(), realtime_curl(), realtime_directory(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_multi_curl(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_odbc(), realtime_pgsql(), sip_cli_notify(), variable_clone(), vm_change_password(), and write_password_to_file().
00268 { 00269 struct ast_variable *variable; 00270 int name_len = strlen(name) + 1; 00271 int val_len = strlen(value) + 1; 00272 int fn_len = strlen(filename) + 1; 00273 00274 /* Ensure a minimum length in case the filename is changed later. */ 00275 if (fn_len < MIN_VARIABLE_FNAME_SPACE) { 00276 fn_len = MIN_VARIABLE_FNAME_SPACE; 00277 } 00278 00279 if ( 00280 #ifdef MALLOC_DEBUG 00281 (variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable), file, lineno, func)) 00282 #else 00283 (variable = ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable))) 00284 #endif 00285 ) { 00286 char *dst = variable->stuff; /* writable space starts here */ 00287 00288 /* Put file first so ast_include_rename() can calculate space available. */ 00289 variable->file = strcpy(dst, filename); 00290 dst += fn_len; 00291 variable->name = strcpy(dst, name); 00292 dst += name_len; 00293 variable->value = strcpy(dst, value); 00294 } 00295 return variable; 00296 }
const char* ast_variable_retrieve | ( | const struct ast_config * | config, | |
const char * | category, | |||
const char * | variable | |||
) |
Gets a variable.
config | which (opened) config to use | |
category | category under which the variable lies | |
variable | which variable you wish to get the data for |
The | variable value on success | |
NULL | if unable to find it. |
Definition at line 585 of file config.c.
References ast_variable_browse(), config, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __ast_udptl_reload(), _dsp_init(), actual_load_config(), advanced_options(), aji_load_config(), ast_config_option(), build_extension(), conf_exec(), config_function_read(), config_module(), directory_exec(), do_reload(), do_scheduler(), festival_exec(), function_macro(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), get_wait_interval(), gtalk_load_config(), iax_template_parse(), init_acf_query(), init_logger_chain(), initialize_cc_max_requests(), jingle_load_config(), load_config(), load_config_meetme(), load_indications(), load_module(), load_rpt_vars(), load_tech_calendars(), make_email_file(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queue_set_global_params(), read_agent_config(), read_password_from_file(), realtime_directory(), reload_config(), reload_followme(), reload_single_queue(), retreive_memory(), retrieve_astcfgint(), rpt(), rpt_master(), rpt_tele_thread(), rpt_telemetry(), rtp_reload(), saynode(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), telem_lookup(), update_realtime_members(), vm_change_password(), and vm_forwardoptions().
00586 { 00587 struct ast_variable *v; 00588 00589 if (category) { 00590 for (v = ast_variable_browse(config, category); v; v = v->next) { 00591 if (!strcasecmp(variable, v->name)) { 00592 return v->value; 00593 } 00594 } 00595 } else { 00596 struct ast_category *cat; 00597 00598 for (cat = config->root; cat; cat = cat->next) { 00599 for (v = cat->root; v; v = v->next) { 00600 if (!strcasecmp(variable, v->name)) { 00601 return v->value; 00602 } 00603 } 00604 } 00605 } 00606 00607 return NULL; 00608 }
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 898 of file config.c.
References ast_strlen_zero(), ast_variable_destroy(), ast_variable_move(), ast_variable_new(), ast_variable::file, ast_category::last, ast_variable::name, ast_variable::next, ast_category::root, and ast_variable::value.
Referenced by handle_updates(), process_text_line(), vm_change_password(), and vm_forwardoptions().
00900 { 00901 struct ast_variable *cur, *prev=NULL, *newer=NULL; 00902 00903 for (cur = category->root; cur; prev = cur, cur = cur->next) { 00904 if (strcasecmp(cur->name, variable) || 00905 (!ast_strlen_zero(match) && strcasecmp(cur->value, match))) 00906 continue; 00907 00908 if (!(newer = ast_variable_new(variable, value, cur->file))) 00909 return -1; 00910 00911 ast_variable_move(newer, cur); 00912 newer->object = newer->object || object; 00913 00914 /* Replace the old node in the list with the new node. */ 00915 newer->next = cur->next; 00916 if (prev) 00917 prev->next = newer; 00918 else 00919 category->root = newer; 00920 if (category->last == cur) 00921 category->last = newer; 00922 00923 ast_variable_destroy(cur); 00924 00925 return 0; 00926 } 00927 00928 /* Could not find variable to update */ 00929 return -1; 00930 }
void ast_variables_destroy | ( | struct ast_variable * | var | ) |
Free variable list.
var | the linked list of variables to free |
Definition at line 550 of file config.c.
References ast_variable_destroy(), and ast_variable::next.
Referenced by __sip_destroy(), action_originate(), ast_category_destroy(), ast_category_empty(), ast_http_get_cookies(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variables_dup(), build_peer(), build_user(), check_peer_ok(), cli_realtime_load(), conf_run(), destroy_dahdi_pvt(), dup_vars(), find_conf_realtime(), find_realtime(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), get_insecure_variable_from_sipregs(), handle_uri(), httpd_helper_thread(), httpstatus_callback(), ldap_loadentry(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), parkandannounce_exec(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_common(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_user(), rt_extend_conf(), sip_destroy_peer(), socket_process(), table_configs_free(), and user_destructor().
00551 { 00552 struct ast_variable *vn; 00553 00554 while (v) { 00555 vn = v; 00556 v = v->next; 00557 ast_variable_destroy(vn); 00558 } 00559 }
struct ast_variable* ast_variables_dup | ( | struct ast_variable * | var | ) |
Duplicate variable list.
var | the linked list of variables to clone |
Definition at line 528 of file config.c.
References ast_variable_new(), ast_variables_destroy(), ast_variable::next, and var.
Referenced by get_insecure_variable_from_sippeers(), and get_insecure_variable_from_sipregs().
00529 { 00530 struct ast_variable *cloned; 00531 struct ast_variable *tmp; 00532 00533 if (!(cloned = ast_variable_new(var->name, var->value, var->file))) { 00534 return NULL; 00535 } 00536 00537 tmp = cloned; 00538 00539 while ((var = var->next)) { 00540 if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) { 00541 ast_variables_destroy(cloned); 00542 return NULL; 00543 } 00544 tmp = tmp->next; 00545 } 00546 00547 return cloned; 00548 }
static struct ast_category* category_get | ( | const struct ast_config * | config, | |
const char * | category_name, | |||
int | ignored | |||
) | [static] |
Definition at line 651 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().
00652 { 00653 struct ast_category *cat; 00654 00655 /* try exact match first, then case-insensitive match */ 00656 for (cat = config->root; cat; cat = cat->next) { 00657 if (cat->name == category_name && (ignored || !cat->ignored)) 00658 return cat; 00659 } 00660 00661 for (cat = config->root; cat; cat = cat->next) { 00662 if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored)) 00663 return cat; 00664 } 00665 00666 return NULL; 00667 }
static void CB_ADD | ( | struct ast_str ** | cb, | |
const char * | str | |||
) | [static] |
Definition at line 108 of file config.c.
References ast_str_append().
Referenced by config_text_file_load().
00109 { 00110 ast_str_append(cb, 0, "%s", str); 00111 }
static void CB_ADD_LEN | ( | struct ast_str ** | cb, | |
const char * | str, | |||
int | len | |||
) | [static] |
Definition at line 113 of file config.c.
References ast_copy_string(), and ast_str_append().
Referenced by config_text_file_load().
00114 { 00115 char *s = alloca(len + 1); 00116 ast_copy_string(s, str, len); 00117 ast_str_append(cb, 0, "%s", str); 00118 }
Definition at line 120 of file config.c.
References ast_str_reset().
Referenced by config_text_file_load(), and process_text_line().
00121 { 00122 if (cb) { 00123 ast_str_reset(cb); 00124 } 00125 if (llb) { 00126 ast_str_reset(llb); 00127 } 00128 }
static struct cache_file_mtime* cfmtime_new | ( | const char * | filename, | |
const char * | who_asked | |||
) | [static] |
Definition at line 1032 of file config.c.
References ast_calloc.
Referenced by config_cache_attribute(), and config_text_file_load().
01033 { 01034 struct cache_file_mtime *cfmtime; 01035 char *dst; 01036 01037 cfmtime = ast_calloc(1, 01038 sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1); 01039 if (!cfmtime) { 01040 return NULL; 01041 } 01042 dst = cfmtime->filename; /* writable space starts here */ 01043 strcpy(dst, filename); 01044 dst += strlen(dst) + 1; 01045 cfmtime->who_asked = strcpy(dst, who_asked); 01046 01047 return cfmtime; 01048 }
static void clear_config_maps | ( | void | ) | [static] |
Definition at line 2058 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().
02059 { 02060 struct ast_config_map *map; 02061 02062 ast_mutex_lock(&config_lock); 02063 02064 while (config_maps) { 02065 map = config_maps; 02066 config_maps = config_maps->next; 02067 ast_free(map); 02068 } 02069 02070 ast_mutex_unlock(&config_lock); 02071 }
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 1055 of file config.c.
References ast_calloc, AST_LIST_INSERT_SORTALPHA, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, cfmtime_new(), cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, cache_file_mtime::mtime, and cache_file_mtime::who_asked.
Referenced by process_text_line().
01056 { 01057 struct cache_file_mtime *cfmtime; 01058 struct cache_file_include *cfinclude; 01059 struct stat statbuf = { 0, }; 01060 01061 /* Find our cached entry for this configuration file */ 01062 AST_LIST_LOCK(&cfmtime_head); 01063 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 01064 if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked)) 01065 break; 01066 } 01067 if (!cfmtime) { 01068 cfmtime = cfmtime_new(configfile, who_asked); 01069 if (!cfmtime) { 01070 AST_LIST_UNLOCK(&cfmtime_head); 01071 return; 01072 } 01073 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 01074 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 01075 } 01076 01077 if (!stat(configfile, &statbuf)) 01078 cfmtime->mtime = 0; 01079 else 01080 cfmtime->mtime = statbuf.st_mtime; 01081 01082 switch (attrtype) { 01083 case ATTRIBUTE_INCLUDE: 01084 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 01085 if (!strcmp(cfinclude->include, filename)) { 01086 AST_LIST_UNLOCK(&cfmtime_head); 01087 return; 01088 } 01089 } 01090 cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1); 01091 if (!cfinclude) { 01092 AST_LIST_UNLOCK(&cfmtime_head); 01093 return; 01094 } 01095 strcpy(cfinclude->include, filename); 01096 AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list); 01097 break; 01098 case ATTRIBUTE_EXEC: 01099 cfmtime->has_exec = 1; 01100 break; 01101 } 01102 AST_LIST_UNLOCK(&cfmtime_head); 01103 }
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 1360 of file config.c.
References ALLOC_COMMENT(), ast_clear_flag, ast_config_AST_CONFIG_DIR, ast_config_get_current_category(), ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_SORTALPHA, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, cfmtime_new(), comment, COMMENT_META, COMMENT_TAG, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, GLOB_ABORTED, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, cache_file_mtime::mtime, MY_GLOB_FLAGS, process_text_line(), ast_variable::trailing, ast_category::trailing, and cache_file_mtime::who_asked.
01361 { 01362 char fn[256]; 01363 #if defined(LOW_MEMORY) 01364 char buf[512]; 01365 #else 01366 char buf[8192]; 01367 #endif 01368 char *new_buf, *comment_p, *process_buf; 01369 FILE *f; 01370 int lineno=0; 01371 int comment = 0, nest[MAX_NESTED_COMMENTS]; 01372 struct ast_category *cat = NULL; 01373 int count = 0; 01374 struct stat statbuf; 01375 struct cache_file_mtime *cfmtime = NULL; 01376 struct cache_file_include *cfinclude; 01377 struct ast_variable *last_var = 0; 01378 struct ast_category *last_cat = 0; 01379 /*! Growable string buffer */ 01380 struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/ 01381 struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */ 01382 01383 if (cfg) 01384 cat = ast_config_get_current_category(cfg); 01385 01386 if (filename[0] == '/') { 01387 ast_copy_string(fn, filename, sizeof(fn)); 01388 } else { 01389 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 01390 } 01391 01392 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01393 comment_buffer = ast_str_create(CB_SIZE); 01394 if (comment_buffer) 01395 lline_buffer = ast_str_create(CB_SIZE); 01396 if (!lline_buffer) { 01397 ast_free(comment_buffer); 01398 ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n"); 01399 return NULL; 01400 } 01401 } 01402 #ifdef AST_INCLUDE_GLOB 01403 { 01404 int glob_ret; 01405 glob_t globbuf; 01406 globbuf.gl_offs = 0; /* initialize it to silence gcc */ 01407 glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf); 01408 if (glob_ret == GLOB_NOSPACE) 01409 ast_log(LOG_WARNING, 01410 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn); 01411 else if (glob_ret == GLOB_ABORTED) 01412 ast_log(LOG_WARNING, 01413 "Glob Expansion of pattern '%s' failed: Read error\n", fn); 01414 else { 01415 /* loop over expanded files */ 01416 int i; 01417 for (i=0; i<globbuf.gl_pathc; i++) { 01418 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn)); 01419 #endif 01420 /* 01421 * The following is not a loop, but just a convenient way to define a block 01422 * (using do { } while(0) ), and be able to exit from it with 'continue' 01423 * or 'break' in case of errors. Nice trick. 01424 */ 01425 do { 01426 if (stat(fn, &statbuf)) 01427 continue; 01428 01429 if (!S_ISREG(statbuf.st_mode)) { 01430 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn); 01431 continue; 01432 } 01433 01434 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) { 01435 /* Find our cached entry for this configuration file */ 01436 AST_LIST_LOCK(&cfmtime_head); 01437 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 01438 if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) 01439 break; 01440 } 01441 if (!cfmtime) { 01442 cfmtime = cfmtime_new(fn, who_asked); 01443 if (!cfmtime) 01444 continue; 01445 /* Note that the file mtime is initialized to 0, i.e. 1970 */ 01446 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename); 01447 } 01448 } 01449 01450 if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) { 01451 /* File is unchanged, what about the (cached) includes (if any)? */ 01452 int unchanged = 1; 01453 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) { 01454 /* We must glob here, because if we did not, then adding a file to globbed directory would 01455 * incorrectly cause no reload to be necessary. */ 01456 char fn2[256]; 01457 #ifdef AST_INCLUDE_GLOB 01458 int glob_return; 01459 glob_t glob_buf = { .gl_offs = 0 }; 01460 glob_return = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &glob_buf); 01461 /* On error, we reparse */ 01462 if (glob_return == GLOB_NOSPACE || glob_return == GLOB_ABORTED) 01463 unchanged = 0; 01464 else { 01465 /* loop over expanded files */ 01466 int j; 01467 for (j = 0; j < glob_buf.gl_pathc; j++) { 01468 ast_copy_string(fn2, glob_buf.gl_pathv[j], sizeof(fn2)); 01469 #else 01470 ast_copy_string(fn2, cfinclude->include); 01471 #endif 01472 if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) { 01473 /* that second-to-last field needs to be looked at in this case... TODO */ 01474 unchanged = 0; 01475 /* One change is enough to short-circuit and reload the whole shebang */ 01476 break; 01477 } 01478 #ifdef AST_INCLUDE_GLOB 01479 } 01480 } 01481 #endif 01482 } 01483 01484 if (unchanged) { 01485 AST_LIST_UNLOCK(&cfmtime_head); 01486 return CONFIG_STATUS_FILEUNCHANGED; 01487 } 01488 } 01489 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01490 AST_LIST_UNLOCK(&cfmtime_head); 01491 01492 /* If cfg is NULL, then we just want an answer */ 01493 if (cfg == NULL) { 01494 ast_free(comment_buffer); 01495 ast_free(lline_buffer); 01496 return NULL; 01497 } 01498 01499 if (cfmtime) 01500 cfmtime->mtime = statbuf.st_mtime; 01501 01502 ast_verb(2, "Parsing '%s': ", fn); 01503 fflush(stdout); 01504 if (!(f = fopen(fn, "r"))) { 01505 ast_debug(1, "No file to parse: %s\n", fn); 01506 ast_verb(2, "Not found (%s)\n", strerror(errno)); 01507 continue; 01508 } 01509 count++; 01510 /* If we get to this point, then we're loading regardless */ 01511 ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED); 01512 ast_debug(1, "Parsing %s\n", fn); 01513 ast_verb(2, "Found\n"); 01514 while (!feof(f)) { 01515 lineno++; 01516 if (fgets(buf, sizeof(buf), f)) { 01517 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && ast_str_strlen(lline_buffer)) { 01518 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01519 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01520 } 01521 01522 new_buf = buf; 01523 if (comment) 01524 process_buf = NULL; 01525 else 01526 process_buf = buf; 01527 01528 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer) && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) { 01529 /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */ 01530 CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */ 01531 continue; /* go get a new line, then */ 01532 } 01533 01534 while ((comment_p = strchr(new_buf, COMMENT_META))) { 01535 if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) { 01536 /* Escaped semicolons aren't comments. */ 01537 new_buf = comment_p + 1; 01538 } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) { 01539 /* Meta-Comment start detected ";--" */ 01540 if (comment < MAX_NESTED_COMMENTS) { 01541 *comment_p = '\0'; 01542 new_buf = comment_p + 3; 01543 comment++; 01544 nest[comment-1] = lineno; 01545 } else { 01546 ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS); 01547 } 01548 } else if ((comment_p >= new_buf + 2) && 01549 (*(comment_p - 1) == COMMENT_TAG) && 01550 (*(comment_p - 2) == COMMENT_TAG)) { 01551 /* Meta-Comment end detected */ 01552 comment--; 01553 new_buf = comment_p + 1; 01554 if (!comment) { 01555 /* Back to non-comment now */ 01556 if (process_buf) { 01557 /* Actually have to move what's left over the top, then continue */ 01558 char *oldptr; 01559 oldptr = process_buf + strlen(process_buf); 01560 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01561 CB_ADD(&comment_buffer, ";"); 01562 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1); 01563 } 01564 01565 memmove(oldptr, new_buf, strlen(new_buf) + 1); 01566 new_buf = oldptr; 01567 } else 01568 process_buf = new_buf; 01569 } 01570 } else { 01571 if (!comment) { 01572 /* If ; is found, and we are not nested in a comment, 01573 we immediately stop all comment processing */ 01574 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01575 CB_ADD(&lline_buffer, comment_p); 01576 } 01577 *comment_p = '\0'; 01578 new_buf = comment_p; 01579 } else 01580 new_buf = comment_p + 1; 01581 } 01582 } 01583 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) { 01584 CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */ 01585 } 01586 01587 if (process_buf) { 01588 char *buffer = ast_strip(process_buf); 01589 if (!ast_strlen_zero(buffer)) { 01590 if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) { 01591 cfg = CONFIG_STATUS_FILEINVALID; 01592 break; 01593 } 01594 } 01595 } 01596 } 01597 } 01598 /* end of file-- anything in a comment buffer? */ 01599 if (last_cat) { 01600 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01601 if (lline_buffer && ast_str_strlen(lline_buffer)) { 01602 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01603 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01604 } 01605 last_cat->trailing = ALLOC_COMMENT(comment_buffer); 01606 } 01607 } else if (last_var) { 01608 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01609 if (lline_buffer && ast_str_strlen(lline_buffer)) { 01610 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */ 01611 ast_str_reset(lline_buffer); /* erase the lline buffer */ 01612 } 01613 last_var->trailing = ALLOC_COMMENT(comment_buffer); 01614 } 01615 } else { 01616 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) { 01617 ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer)); 01618 } 01619 } 01620 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01621 CB_RESET(comment_buffer, lline_buffer); 01622 01623 fclose(f); 01624 } while (0); 01625 if (comment) { 01626 ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]); 01627 } 01628 #ifdef AST_INCLUDE_GLOB 01629 if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { 01630 break; 01631 } 01632 } 01633 globfree(&globbuf); 01634 } 01635 } 01636 #endif 01637 01638 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { 01639 ast_free(comment_buffer); 01640 ast_free(lline_buffer); 01641 comment_buffer = NULL; 01642 lline_buffer = NULL; 01643 } 01644 01645 if (count == 0) 01646 return NULL; 01647 01648 return cfg; 01649 }
int config_text_file_save | ( | const char * | configfile, | |
const struct ast_config * | cfg, | |||
const char * | generator | |||
) |
Definition at line 1798 of file config.c.
References ast_config_text_file_save().
01799 { 01800 return ast_config_text_file_save(configfile, cfg, generator); 01801 }
static int count_linefeeds | ( | char * | str | ) | [static] |
static int count_linefeeds_in_comments | ( | struct ast_comment * | x | ) | [static] |
Definition at line 1751 of file config.c.
References ast_comment::cmt, count_linefeeds(), and ast_comment::next.
Referenced by insert_leading_blank_lines().
01752 { 01753 int count = 0; 01754 01755 while (x) { 01756 count += count_linefeeds(x->cmt); 01757 x = x->next; 01758 } 01759 return count; 01760 }
static struct ast_config_engine* find_engine | ( | const char * | family, | |
int | priority, | |||
char * | database, | |||
int | dbsiz, | |||
char * | table, | |||
int | tabsiz | |||
) | [static] |
Find realtime engine for realtime family.
Definition at line 2227 of file config.c.
References ast_copy_string(), ast_mutex_lock, config_lock, config_maps, and map.
Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_realtime_require_field(), ast_speech_new(), ast_speech_register(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), and ast_update_realtime().
02228 { 02229 struct ast_config_engine *eng, *ret = NULL; 02230 struct ast_config_map *map; 02231 02232 ast_mutex_lock(&config_lock); 02233 02234 for (map = config_maps; map; map = map->next) { 02235 if (!strcasecmp(family, map->name) && (priority == map->priority)) { 02236 if (database) 02237 ast_copy_string(database, map->database, dbsiz); 02238 if (table) 02239 ast_copy_string(table, map->table ? map->table : family, tabsiz); 02240 break; 02241 } 02242 } 02243 02244 /* Check if the required driver (engine) exist */ 02245 if (map) { 02246 for (eng = config_engine_list; !ret && eng; eng = eng->next) { 02247 if (!strcasecmp(eng->name, map->driver)) 02248 ret = eng; 02249 } 02250 } 02251 02252 ast_mutex_unlock(&config_lock); 02253 02254 /* if we found a mapping, but the engine is not available, then issue a warning */ 02255 if (map && !ret) 02256 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver); 02257 02258 return ret; 02259 }
static void gen_header | ( | FILE * | f1, | |
const char * | configfile, | |||
const char * | fn, | |||
const char * | generator | |||
) | [static] |
Definition at line 1672 of file config.c.
References ast_copy_string().
Referenced by ast_config_text_file_save().
01673 { 01674 char date[256]=""; 01675 time_t t; 01676 01677 time(&t); 01678 ast_copy_string(date, ctime(&t), sizeof(date)); 01679 01680 fprintf(f1, ";!\n"); 01681 fprintf(f1, ";! Automatically generated configuration file\n"); 01682 if (strcmp(configfile, fn)) 01683 fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn); 01684 else 01685 fprintf(f1, ";! Filename: %s\n", configfile); 01686 fprintf(f1, ";! Generator: %s\n", generator); 01687 fprintf(f1, ";! Creation Date: %s", date); 01688 fprintf(f1, ";!\n"); 01689 }
static char* handle_cli_config_list | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2865 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.
02866 { 02867 struct cache_file_mtime *cfmtime; 02868 02869 switch (cmd) { 02870 case CLI_INIT: 02871 e->command = "config list"; 02872 e->usage = 02873 "Usage: config list\n" 02874 " Show all modules that have loaded a configuration file\n"; 02875 return NULL; 02876 case CLI_GENERATE: 02877 return NULL; 02878 } 02879 02880 AST_LIST_LOCK(&cfmtime_head); 02881 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02882 ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename); 02883 } 02884 AST_LIST_UNLOCK(&cfmtime_head); 02885 02886 return CLI_SUCCESS; 02887 }
static char* handle_cli_config_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2803 of file config.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli_command, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, cache_file_mtime::list, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.
02804 { 02805 struct cache_file_mtime *cfmtime; 02806 char *prev = "", *completion_value = NULL; 02807 int wordlen, which = 0; 02808 02809 switch (cmd) { 02810 case CLI_INIT: 02811 e->command = "config reload"; 02812 e->usage = 02813 "Usage: config reload <filename.conf>\n" 02814 " Reloads all modules that reference <filename.conf>\n"; 02815 return NULL; 02816 case CLI_GENERATE: 02817 if (a->pos > 2) { 02818 return NULL; 02819 } 02820 02821 wordlen = strlen(a->word); 02822 02823 AST_LIST_LOCK(&cfmtime_head); 02824 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02825 /* Skip duplicates - this only works because the list is sorted by filename */ 02826 if (strcmp(cfmtime->filename, prev) == 0) { 02827 continue; 02828 } 02829 02830 /* Core configs cannot be reloaded */ 02831 if (ast_strlen_zero(cfmtime->who_asked)) { 02832 continue; 02833 } 02834 02835 if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) { 02836 completion_value = ast_strdup(cfmtime->filename); 02837 break; 02838 } 02839 02840 /* Otherwise save that we've seen this filename */ 02841 prev = cfmtime->filename; 02842 } 02843 AST_LIST_UNLOCK(&cfmtime_head); 02844 02845 return completion_value; 02846 } 02847 02848 if (a->argc != 3) { 02849 return CLI_SHOWUSAGE; 02850 } 02851 02852 AST_LIST_LOCK(&cfmtime_head); 02853 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) { 02854 if (!strcmp(cfmtime->filename, a->argv[2])) { 02855 char *buf = alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1); 02856 sprintf(buf, "module reload %s", cfmtime->who_asked); 02857 ast_cli_command(a->fd, buf); 02858 } 02859 } 02860 AST_LIST_UNLOCK(&cfmtime_head); 02861 02862 return CLI_SUCCESS; 02863 }
static char* handle_cli_core_show_config_mappings | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2766 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.
02767 { 02768 struct ast_config_engine *eng; 02769 struct ast_config_map *map; 02770 02771 switch (cmd) { 02772 case CLI_INIT: 02773 e->command = "core show config mappings"; 02774 e->usage = 02775 "Usage: core show config mappings\n" 02776 " Shows the filenames to config engines.\n"; 02777 return NULL; 02778 case CLI_GENERATE: 02779 return NULL; 02780 } 02781 02782 ast_mutex_lock(&config_lock); 02783 02784 if (!config_engine_list) { 02785 ast_cli(a->fd, "No config mappings found.\n"); 02786 } else { 02787 for (eng = config_engine_list; eng; eng = eng->next) { 02788 ast_cli(a->fd, "Config Engine: %s\n", eng->name); 02789 for (map = config_maps; map; map = map->next) { 02790 if (!strcasecmp(map->driver, eng->name)) { 02791 ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database, 02792 map->table ? map->table : map->name); 02793 } 02794 } 02795 } 02796 } 02797 02798 ast_mutex_unlock(&config_lock); 02799 02800 return CLI_SUCCESS; 02801 }
static int hash_string | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 150 of file config.c.
Referenced by ast_config_text_file_save().
00151 { 00152 char *str = ((struct inclfile *) obj)->fname; 00153 int total; 00154 00155 for (total = 0; *str; str++) { 00156 unsigned int tmp = total; 00157 total <<= 1; /* multiply by 2 */ 00158 total += tmp; /* multiply by 3 */ 00159 total <<= 2; /* multiply by 12 */ 00160 total += tmp; /* multiply by 13 */ 00161 00162 total += ((unsigned int) (*str)); 00163 } 00164 if (total < 0) { 00165 total = -total; 00166 } 00167 return total; 00168 }
static int hashtab_compare_strings | ( | void * | a, | |
void * | b, | |||
int | flags | |||
) | [static] |
Definition at line 170 of file config.c.
References CMP_MATCH, CMP_STOP, and inclfile::fname.
Referenced by ast_config_text_file_save().
00171 { 00172 const struct inclfile *ae = a, *be = b; 00173 return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0; 00174 }
static void inclfile_destroy | ( | void * | obj | ) | [static] |
static void inherit_category | ( | struct ast_category * | new, | |
const struct ast_category * | base | |||
) | [static] |
Definition at line 828 of file config.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_variable_append(), ast_category::name, ast_category_template_instance::next, ast_category::root, ast_category::template_instances, var, and variable_clone().
Referenced by process_text_line().
00829 { 00830 struct ast_variable *var; 00831 struct ast_category_template_instance *x; 00832 00833 x = ast_calloc(1, sizeof(*x)); 00834 if (!x) { 00835 return; 00836 } 00837 strcpy(x->name, base->name); 00838 x->inst = base; 00839 AST_LIST_INSERT_TAIL(&new->template_instances, x, next); 00840 for (var = base->root; var; var = var->next) 00841 ast_variable_append(new, variable_clone(var)); 00842 }
static int init_appendbuf | ( | void * | data | ) | [static] |
Definition at line 96 of file config.c.
References ast_str_create(), and str.
00097 { 00098 struct ast_str **str = data; 00099 *str = ast_str_create(16); 00100 return *str ? 0 : -1; 00101 }
static void insert_leading_blank_lines | ( | FILE * | fp, | |
struct inclfile * | fi, | |||
struct ast_comment * | precomments, | |||
int | lineno | |||
) | [static] |
Definition at line 1762 of file config.c.
References count_linefeeds_in_comments(), and inclfile::lineno.
Referenced by ast_config_text_file_save().
01763 { 01764 int precomment_lines; 01765 int i; 01766 01767 if (!fi) { 01768 /* No file scratch pad object so insert no blank lines. */ 01769 return; 01770 } 01771 01772 precomment_lines = count_linefeeds_in_comments(precomments); 01773 01774 /* I don't have to worry about those ;! comments, they are 01775 stored in the precomments, but not printed back out. 01776 I did have to make sure that comments following 01777 the ;! header comments were not also deleted in the process */ 01778 if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */ 01779 return; 01780 } else if (lineno == 0) { 01781 /* Line replacements also mess things up */ 01782 return; 01783 } else if (lineno - precomment_lines - fi->lineno < 5) { 01784 /* Only insert less than 5 blank lines; if anything more occurs, 01785 * it's probably due to context deletion. */ 01786 for (i = fi->lineno; i < lineno - precomment_lines; i++) { 01787 fprintf(fp, "\n"); 01788 } 01789 } else { 01790 /* Deletion occurred - insert a single blank line, for separation of 01791 * contexts. */ 01792 fprintf(fp, "\n"); 01793 } 01794 01795 fi->lineno = lineno + 1; /* Advance the file lineno */ 01796 }
static void move_variables | ( | struct ast_category * | old, | |
struct ast_category * | new | |||
) | [static] |
Definition at line 624 of file config.c.
References ast_variable_append(), ast_category::root, and var.
Referenced by process_text_line().
00625 { 00626 struct ast_variable *var = old->root; 00627 00628 old->root = NULL; 00629 /* we can just move the entire list in a single op */ 00630 ast_variable_append(new, var); 00631 }
static struct ast_category* next_available_category | ( | struct ast_category * | cat | ) | [static] |
Definition at line 744 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 1112 of file config.c.
References ALLOC_COMMENT(), appendbuf, ast_category_append(), ast_category_destroy(), ast_category_first(), ast_category_new(), ast_config_internal_load(), ast_include_new(), ast_log(), ast_opt_exec_includes, ast_safe_system(), ast_skip_blanks(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_trim_blanks(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_tvnow(), ast_variable_append(), ast_variable_new(), ast_variable_update(), ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, ast_variable::blanklines, category_get(), CB_RESET(), config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, ast_config::include_level, inherit_category(), ast_variable::lineno, LOG_ERROR, LOG_WARNING, move_variables(), ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), and var.
Referenced by config_text_file_load().
01118 { 01119 char *c; 01120 char *cur = buf; 01121 struct ast_variable *v; 01122 char cmd[512], exec_file[512]; 01123 01124 /* Actually parse the entry */ 01125 if (cur[0] == '[') { /* A category header */ 01126 /* format is one of the following: 01127 * [foo] define a new category named 'foo' 01128 * [foo](!) define a new template category named 'foo' 01129 * [foo](+) append to category 'foo', error if foo does not exist. 01130 * [foo](a) define a new category and inherit from template a. 01131 * You can put a comma-separated list of templates and '!' and '+' 01132 * between parentheses, with obvious meaning. 01133 */ 01134 struct ast_category *newcat = NULL; 01135 char *catname; 01136 01137 c = strchr(cur, ']'); 01138 if (!c) { 01139 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile); 01140 return -1; 01141 } 01142 *c++ = '\0'; 01143 cur++; 01144 if (*c++ != '(') 01145 c = NULL; 01146 catname = cur; 01147 if (!(*cat = newcat = ast_category_new(catname, 01148 S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile), 01149 lineno))) { 01150 return -1; 01151 } 01152 (*cat)->lineno = lineno; 01153 *last_var = 0; 01154 *last_cat = newcat; 01155 01156 /* add comments */ 01157 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01158 newcat->precomments = ALLOC_COMMENT(comment_buffer); 01159 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01160 newcat->sameline = ALLOC_COMMENT(lline_buffer); 01161 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01162 CB_RESET(comment_buffer, lline_buffer); 01163 01164 /* If there are options or categories to inherit from, process them now */ 01165 if (c) { 01166 if (!(cur = strchr(c, ')'))) { 01167 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile); 01168 return -1; 01169 } 01170 *cur = '\0'; 01171 while ((cur = strsep(&c, ","))) { 01172 if (!strcasecmp(cur, "!")) { 01173 (*cat)->ignored = 1; 01174 } else if (!strcasecmp(cur, "+")) { 01175 *cat = category_get(cfg, catname, 1); 01176 if (!(*cat)) { 01177 if (newcat) 01178 ast_category_destroy(newcat); 01179 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile); 01180 return -1; 01181 } 01182 if (newcat) { 01183 move_variables(newcat, *cat); 01184 ast_category_destroy(newcat); 01185 newcat = NULL; 01186 } 01187 } else { 01188 struct ast_category *base; 01189 01190 base = category_get(cfg, cur, 1); 01191 if (!base) { 01192 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile); 01193 return -1; 01194 } 01195 inherit_category(*cat, base); 01196 } 01197 } 01198 } 01199 if (newcat) 01200 ast_category_append(cfg, *cat); 01201 } else if (cur[0] == '#') { /* A directive - #include or #exec */ 01202 char *cur2; 01203 char real_inclusion_name[256]; 01204 int do_include = 0; /* otherwise, it is exec */ 01205 01206 cur++; 01207 c = cur; 01208 while (*c && (*c > 32)) { 01209 c++; 01210 } 01211 01212 if (*c) { 01213 *c = '\0'; 01214 /* Find real argument */ 01215 c = ast_strip(c + 1); 01216 if (!(*c)) { 01217 c = NULL; 01218 } 01219 } else { 01220 c = NULL; 01221 } 01222 if (!strcasecmp(cur, "include")) { 01223 do_include = 1; 01224 } else if (!strcasecmp(cur, "exec")) { 01225 if (!ast_opt_exec_includes) { 01226 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n"); 01227 return 0; /* XXX is this correct ? or we should return -1 ? */ 01228 } 01229 } else { 01230 ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile); 01231 return 0; /* XXX is this correct ? or we should return -1 ? */ 01232 } 01233 01234 if (c == NULL) { 01235 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 01236 do_include ? "include" : "exec", 01237 do_include ? "filename" : "/path/to/executable", 01238 lineno, 01239 configfile); 01240 return 0; /* XXX is this correct ? or we should return -1 ? */ 01241 } 01242 01243 cur = c; 01244 /* Strip off leading and trailing "'s and <>'s */ 01245 /* Dequote */ 01246 if ((*c == '"') || (*c == '<')) { 01247 char quote_char = *c; 01248 if (quote_char == '<') { 01249 quote_char = '>'; 01250 } 01251 01252 if (*(c + strlen(c) - 1) == quote_char) { 01253 cur++; 01254 *(c + strlen(c) - 1) = '\0'; 01255 } 01256 } 01257 cur2 = cur; 01258 01259 /* #exec </path/to/executable> 01260 We create a tmp file, then we #include it, then we delete it. */ 01261 if (!do_include) { 01262 struct timeval now = ast_tvnow(); 01263 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01264 config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked); 01265 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self()); 01266 snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file); 01267 ast_safe_system(cmd); 01268 cur = exec_file; 01269 } else { 01270 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) 01271 config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked); 01272 exec_file[0] = '\0'; 01273 } 01274 /* A #include */ 01275 /* record this inclusion */ 01276 ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name)); 01277 01278 do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0; 01279 if (!ast_strlen_zero(exec_file)) 01280 unlink(exec_file); 01281 if (!do_include) { 01282 ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur); 01283 return -1; 01284 } 01285 /* XXX otherwise what ? the default return is 0 anyways */ 01286 01287 } else { 01288 /* Just a line (variable = value) */ 01289 int object = 0; 01290 if (!(*cat)) { 01291 ast_log(LOG_WARNING, 01292 "parse error: No category context for line %d of %s\n", lineno, configfile); 01293 return -1; 01294 } 01295 c = strchr(cur, '='); 01296 01297 if (c && c > cur && (*(c - 1) == '+')) { 01298 struct ast_variable *var, *replace = NULL; 01299 struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str)); 01300 01301 if (!str || !*str) { 01302 return -1; 01303 } 01304 01305 *(c - 1) = '\0'; 01306 c++; 01307 cur = ast_strip(cur); 01308 01309 /* Must iterate through category until we find last variable of same name (since there could be multiple) */ 01310 for (var = ast_category_first(*cat); var; var = var->next) { 01311 if (!strcmp(var->name, cur)) { 01312 replace = var; 01313 } 01314 } 01315 01316 if (!replace) { 01317 /* Nothing to replace; just set a variable normally. */ 01318 goto set_new_variable; 01319 } 01320 01321 ast_str_set(str, 0, "%s", replace->value); 01322 ast_str_append(str, 0, "%s", c); 01323 ast_str_trim_blanks(*str); 01324 ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object); 01325 } else if (c) { 01326 *c = 0; 01327 c++; 01328 /* Ignore > in => */ 01329 if (*c== '>') { 01330 object = 1; 01331 c++; 01332 } 01333 set_new_variable: 01334 if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) { 01335 v->lineno = lineno; 01336 v->object = object; 01337 *last_cat = 0; 01338 *last_var = v; 01339 /* Put and reset comments */ 01340 v->blanklines = 0; 01341 ast_variable_append(*cat, v); 01342 /* add comments */ 01343 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01344 v->precomments = ALLOC_COMMENT(comment_buffer); 01345 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01346 v->sameline = ALLOC_COMMENT(lline_buffer); 01347 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) 01348 CB_RESET(comment_buffer, lline_buffer); 01349 01350 } else { 01351 return -1; 01352 } 01353 } else { 01354 ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile); 01355 } 01356 } 01357 return 0; 01358 }
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 2108 of file config.c.
References append_mapping(), ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log(), ast_variable_browse(), clear_config_maps(), config, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, ast_flags::flags, LOG_WARNING, ast_config::max_include_level, ast_variable::name, ast_variable::next, strsep(), table, and ast_variable::value.
Referenced by main().
02109 { 02110 struct ast_config *config, *configtmp; 02111 struct ast_variable *v; 02112 char *driver, *table, *database, *textpri, *stringp, *tmp; 02113 struct ast_flags flags = { CONFIG_FLAG_NOREALTIME }; 02114 int pri; 02115 02116 clear_config_maps(); 02117 02118 configtmp = ast_config_new(); 02119 configtmp->max_include_level = 1; 02120 config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig"); 02121 if (config == CONFIG_STATUS_FILEINVALID) { 02122 return -1; 02123 } else if (!config) { 02124 ast_config_destroy(configtmp); 02125 return 0; 02126 } 02127 02128 for (v = ast_variable_browse(config, "settings"); v; v = v->next) { 02129 char buf[512]; 02130 ast_copy_string(buf, v->value, sizeof(buf)); 02131 stringp = buf; 02132 driver = strsep(&stringp, ","); 02133 02134 if ((tmp = strchr(stringp, '\"'))) 02135 stringp = tmp; 02136 02137 /* check if the database text starts with a double quote */ 02138 if (*stringp == '"') { 02139 stringp++; 02140 database = strsep(&stringp, "\""); 02141 strsep(&stringp, ","); 02142 } else { 02143 /* apparently this text has no quotes */ 02144 database = strsep(&stringp, ","); 02145 } 02146 02147 table = strsep(&stringp, ","); 02148 textpri = strsep(&stringp, ","); 02149 if (!textpri || !(pri = atoi(textpri))) { 02150 pri = 1; 02151 } 02152 02153 if (!strcmp(v->name, extconfig_conf)) { 02154 ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf); 02155 continue; 02156 } 02157 02158 if (!strcmp(v->name, "asterisk.conf")) { 02159 ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n"); 02160 continue; 02161 } 02162 02163 if (!strcmp(v->name, "logger.conf")) { 02164 ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n"); 02165 continue; 02166 } 02167 02168 if (!driver || !database) 02169 continue; 02170 if (!strcasecmp(v->name, "sipfriends")) { 02171 ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n"); 02172 append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri); 02173 } else if (!strcasecmp(v->name, "iaxfriends")) { 02174 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"); 02175 append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri); 02176 append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri); 02177 } else 02178 append_mapping(v->name, driver, database, table, pri); 02179 } 02180 02181 ast_config_destroy(config); 02182 return 0; 02183 }
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 2895 of file config.c.
References ARRAY_LEN, ast_cli_register_multiple(), and cli_config.
Referenced by main().
02896 { 02897 ast_cli_register_multiple(cli_config, ARRAY_LEN(cli_config)); 02898 return 0; 02899 }
static struct inclfile* set_fn | ( | char * | fn, | |
int | fn_size, | |||
const char * | file, | |||
const char * | configfile, | |||
struct ao2_container * | fileset | |||
) | [static] |
Definition at line 1699 of file config.c.
References ao2_alloc, ao2_find, ao2_link, ao2_ref, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_strdup, ast_strlen_zero(), inclfile::fname, inclfile_destroy(), inclfile::lineno, and OBJ_POINTER.
Referenced by ast_config_text_file_save().
01700 { 01701 struct inclfile lookup; 01702 struct inclfile *fi; 01703 01704 if (ast_strlen_zero(file)) { 01705 if (configfile[0] == '/') 01706 ast_copy_string(fn, configfile, fn_size); 01707 else 01708 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile); 01709 } else if (file[0] == '/') 01710 ast_copy_string(fn, file, fn_size); 01711 else 01712 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file); 01713 lookup.fname = fn; 01714 fi = ao2_find(fileset, &lookup, OBJ_POINTER); 01715 if (fi) { 01716 /* Found existing include file scratch pad. */ 01717 return fi; 01718 } 01719 01720 /* set up a file scratch pad */ 01721 fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy); 01722 if (!fi) { 01723 /* Scratch pad creation failed. */ 01724 return NULL; 01725 } 01726 fi->fname = ast_strdup(fn); 01727 if (!fi->fname) { 01728 /* Scratch pad creation failed. */ 01729 ao2_ref(fi, -1); 01730 return NULL; 01731 } 01732 fi->lineno = 1; 01733 01734 ao2_link(fileset, fi); 01735 01736 return fi; 01737 }
static struct ast_variable* variable_clone | ( | const struct ast_variable * | old | ) | [static] |
Definition at line 610 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().
00611 { 00612 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file); 00613 00614 if (new) { 00615 new->lineno = old->lineno; 00616 new->object = old->object; 00617 new->blanklines = old->blanklines; 00618 /* TODO: clone comments? */ 00619 } 00620 00621 return new; 00622 }
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 2889 of file config.c.
Referenced by register_config_cli().
struct ast_config_engine* config_engine_list [static] |
Definition at line 192 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 191 of file config.c.
Referenced by ast_calendar_config_release(), ast_config_engine_deregister(), ast_config_engine_register(), clear_config_maps(), find_engine(), handle_cli_core_show_config_mappings(), load_config(), and load_tech_calendars().
struct ast_config_map * config_maps [static] |
Referenced by append_mapping(), ast_realtime_enabled(), clear_config_maps(), find_engine(), and handle_cli_core_show_config_mappings().
char* extconfig_conf = "extconfig.conf" [static] |
struct ast_config_engine text_file_engine [static] |
Initial value:
{ .name = "text", .load_func = config_text_file_load, }
Definition at line 2261 of file config.c.
Referenced by ast_config_internal_load().