main/config.c File Reference

Configuration File Parser. More...

#include "asterisk.h"
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include <time.h>
#include <sys/stat.h>
#include <math.h>
#include <regex.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"

Include dependency graph for main/config.c:

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  cfg_hook
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
#define realtime_arguments_to_fields(ap, result)   realtime_arguments_to_fields2(ap, 0, result)

Enumerations

enum  config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0, ATTRIBUTE_EXEC = 1 }

Functions

static void __init_appendbuf (void)
static struct ast_commentALLOC_COMMENT (struct ast_str *buffer)
void ast_category_append (struct ast_config *config, struct ast_category *category)
 Appends a category to a config.
char * ast_category_browse (struct ast_config *config, const char *prev)
 Browse categories.
struct ast_categoryast_category_browse_filtered (struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
 Browse categories with filters.
struct ast_categoryast_category_delete (struct ast_config *config, struct ast_category *category)
 Delete a category.
void ast_category_destroy (struct ast_category *cat)
struct ast_variableast_category_detach_variables (struct ast_category *cat)
int ast_category_empty (struct ast_category *category)
 Removes and destroys all variables in a category.
int ast_category_exist (const struct ast_config *config, const char *category_name, const char *filter)
 Check for category duplicates.
struct ast_variableast_category_first (struct ast_category *cat)
 given a pointer to a category, return the root variable.
struct ast_categoryast_category_get (const struct ast_config *config, const char *category_name, const char *filter)
 Retrieve a category if it exists.
const char * ast_category_get_name (const struct ast_category *category)
 Return the name of the category.
struct ast_strast_category_get_templates (const struct ast_category *category)
 Return the template names this category inherits from.
int ast_category_inherit (struct ast_category *new, const struct ast_category *base)
 Applies base (template) to category.
int ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match)
 Inserts new category.
int ast_category_is_template (const struct ast_category *category)
 Check if category is a template.
struct ast_categoryast_category_new (const char *name, const char *in_file, int lineno)
 Create a category.
struct ast_categoryast_category_new_template (const char *name, const char *in_file, int lineno)
 Create a category making it a template.
void ast_category_rename (struct ast_category *cat, const char *name)
struct ast_variableast_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)
struct ast_configast_config_copy (const struct ast_config *old)
 Copies the contents of one ast_config into another.
void ast_config_destroy (struct ast_config *cfg)
 Destroys a config.
int ast_config_engine_deregister (struct ast_config_engine *del)
 Deregister config engine.
int ast_config_engine_register (struct ast_config_engine *new)
 Register config engine.
struct ast_categoryast_config_get_current_category (const struct ast_config *cfg)
 Retrieve the current category name being built.
int ast_config_hook_register (const char *name, const char *filename, const char *module, enum config_hook_flags flags, config_hook_cb hook_cb)
 Register a config hook for a particular file and module.
void ast_config_hook_unregister (const char *name)
 Unregister a config hook.
struct ast_configast_config_internal_load (const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
struct ast_configast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags)
 Load a config file.
struct ast_configast_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.
void ast_config_sort_categories (struct ast_config *config, int descending, int(*comparator)(struct ast_category *p, struct ast_category *q))
 Sorts categories in a config in the order of a numerical value contained within them.
int ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator)
 Save a config text file preserving the pre 13.2 behavior.
int ast_config_text_file_save2 (const char *configfile, const struct ast_config *cfg, const char *generator, uint32_t flags)
 Save a config text file.
int ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...)
 Destroy realtime configuration.
int ast_destroy_realtime_fields (const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
 Destroy realtime configuration.
static void ast_destroy_template_list (struct ast_category *cat)
struct ast_config_includeast_include_find (struct ast_config *conf, const char *included_file)
struct ast_config_includeast_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)
struct ast_variableast_load_realtime (const char *family,...)
struct ast_variableast_load_realtime_all (const char *family,...)
struct ast_variableast_load_realtime_all_fields (const char *family, const struct ast_variable *fields)
struct ast_variableast_load_realtime_fields (const char *family, const struct ast_variable *fields)
 Retrieve realtime configuration.
struct ast_configast_load_realtime_multientry (const char *family,...)
 Retrieve realtime configuration.
struct ast_configast_load_realtime_multientry_fields (const char *family, const struct ast_variable *fields)
 Retrieve realtime configuration.
int ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *p_result,...)
 Helper function to parse arguments See documentation in config.h.
static int ast_realtime_append_mapping (const char *name, const char *driver, const char *database, const char *table, int priority)
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_is_mapping_defined (const char *family)
 Determine if a mapping exists for a given family.
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_store_realtime_fields (const char *family, const struct ast_variable *fields)
 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_update2_realtime_fields (const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
 Update realtime configuration.
int ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...)
 Update realtime configuration.
int ast_update_realtime_fields (const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
 Update realtime configuration.
void ast_variable_append (struct ast_category *category, struct ast_variable *variable)
struct ast_variableast_variable_browse (const struct ast_config *config, const char *category)
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)
const char * ast_variable_find (const struct ast_category *category, const char *variable)
 Gets a variable from a specific category structure.
const char * ast_variable_find_in_list (const struct ast_variable *list, const char *variable)
 Gets a variable from a variable list.
void ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line)
struct ast_variableast_variable_list_append_hint (struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *newvar)
 Appends a variable list to the end of another list.
struct ast_variableast_variable_list_sort (struct ast_variable *start)
 Performs an in-place sort on the variable list by ascending name.
static void ast_variable_move (struct ast_variable *dst_var, struct ast_variable *src_var)
struct ast_variableast_variable_new (const char *name, const char *value, const char *filename)
const char * ast_variable_retrieve (struct ast_config *config, const char *category, const char *variable)
const char * ast_variable_retrieve_filtered (struct ast_config *config, const char *category, const char *variable, const char *filter)
 Gets a variable by context and variable names.
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.
struct ast_variableast_variables_dup (struct ast_variable *var)
 Duplicate variable list.
struct ast_variableast_variables_reverse (struct ast_variable *var)
 Reverse a variable list.
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 int cfmstat_cmp (struct cache_file_mtime *cfmtime, struct stat *statbuf)
static void cfmstat_save (struct cache_file_mtime *cfmtime, struct stat *statbuf)
static struct cache_file_mtimecfmtime_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 void config_cache_destroy_entry (struct cache_file_mtime *cfmtime)
static void config_cache_flush_includes (struct cache_file_mtime *cfmtime)
static void config_cache_remove (const char *filename, const char *who_asked)
static void config_hook_exec (const char *filename, const char *module, const struct ast_config *cfg)
static void config_shutdown (void)
static struct ast_configconfig_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 int does_category_match (struct ast_category *cat, const char *category_name, const char *match)
 Returns true if ALL of the regex expressions and category name match. Both can be NULL (I.E. no predicate) which results in a true return;.
static struct ast_config_enginefind_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 int hook_cmp (void *obj, void *arg, int flags)
static void hook_destroy (void *obj)
static int hook_hash (const void *obj, const int flags)
static void inclfile_destroy (void *obj)
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 make_fn (char *fn, size_t fn_size, const char *file, const char *configfile)
static void move_variables (struct ast_category *old, struct ast_category *new)
static struct ast_categorynew_category (const char *name, const char *in_file, int lineno, int template)
static struct ast_categorynext_available_category (struct ast_category *cat, const char *name, const char *filter)
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.
static int realtime_arguments_to_fields2 (va_list ap, int skip, struct ast_variable **result)
int register_config_cli (void)
 Exposed initialization method for core process.
static struct inclfileset_fn (char *fn, size_t fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
static struct ast_variablevariable_clone (const struct ast_variable *old)
static struct ast_variablevariable_list_switch (struct ast_variable *l1, struct ast_variable *l2)

Variables

static struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , }
static struct ao2_containercfg_hooks
static struct ast_cli_entry cli_config []
static struct ast_config_engineconfig_engine_list
static ast_mutex_t config_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct ast_config_mapconfig_maps
static char * extconfig_conf = "extconfig.conf"
static struct ast_config_engine text_file_engine


Detailed Description

Configuration File Parser.

Author:
Mark Spencer <markster@digium.com>
Includes the Asterisk Realtime API - ARA See http://wiki.asterisk.org

Definition in file main/config.c.


Define Documentation

#define AST_INCLUDE_GLOB   1

Definition at line 45 of file main/config.c.

#define CB_SIZE   250

Definition at line 121 of file main/config.c.

Referenced by config_text_file_load().

#define COMMENT_END   "--;"

Definition at line 59 of file main/config.c.

#define COMMENT_META   ';'

Definition at line 60 of file main/config.c.

Referenced by config_text_file_load().

#define COMMENT_START   ";--"

Definition at line 58 of file main/config.c.

#define COMMENT_TAG   '-'

Definition at line 61 of file main/config.c.

Referenced by config_text_file_load().

#define MAX_INCLUDE_LEVEL   10

Definition at line 211 of file main/config.c.

Referenced by ast_config_new().

#define MAX_NESTED_COMMENTS   128

Definition at line 57 of file main/config.c.

Referenced by config_text_file_load().

#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 68 of file main/config.c.

Referenced by ast_variable_new().

#define realtime_arguments_to_fields ( ap,
result   )     realtime_arguments_to_fields2(ap, 0, result)


Enumeration Type Documentation

Enumerator:
ATTRIBUTE_INCLUDE 
ATTRIBUTE_EXEC 

Definition at line 1454 of file main/config.c.

01454                                  {
01455    ATTRIBUTE_INCLUDE = 0,
01456    ATTRIBUTE_EXEC = 1,
01457 };


Function Documentation

static void __init_appendbuf ( void   )  [static]

Definition at line 118 of file main/config.c.

00124 {

static struct ast_comment* ALLOC_COMMENT ( struct ast_str buffer  )  [static, read]

Definition at line 147 of file main/config.c.

References ast_calloc, ast_str_buffer(), ast_str_strlen(), ast_comment::cmt, and NULL.

Referenced by config_text_file_load(), and process_text_line().

00148 {
00149    struct ast_comment *x = NULL;
00150    if (!buffer || !ast_str_strlen(buffer)) {
00151       return NULL;
00152    }
00153    if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
00154       strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
00155    }
00156    return x;
00157 }

void ast_category_append ( struct ast_config config,
struct ast_category category 
)

Appends a category to a config.

Parameters:
config which config to use
cat category to insert

Definition at line 941 of file main/config.c.

References ast_config::current, ast_config::include_level, ast_category::include_level, ast_config::last, ast_category::next, NULL, ast_category::prev, and ast_config::root.

Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), append_row_to_cfg(), ast_config_copy(), AST_TEST_DEFINE(), build_cfg(), config_curl(), config_ldap(), config_mysql(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_mysql(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_sorcery_multi(), realtime_sorcery_store(), realtime_sorcery_update(), static_realtime_cb(), and write_password_to_file().

00942 {
00943    if (config->last) {
00944       config->last->next = category;
00945       category->prev = config->last;
00946    } else {
00947       config->root = category;
00948       category->prev = NULL;
00949    }
00950    category->next = NULL;
00951    category->include_level = config->include_level;
00952 
00953    config->last = category;
00954    config->current = category;
00955 }

char* ast_category_browse ( struct ast_config config,
const char *  prev 
)

Browse categories.

Parameters:
config Which config structure you wish to "browse"
prev_name A pointer to a previous category name.
This function is kind of non-intuitive in it's use. To begin, one passes NULL as the second argument. It will return a pointer to the string of the first category in the file. From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards.

Return values:
a category name on success
NULL on failure/no-more-categories
Note:
ast_category_browse maintains internal state. Therefore is not thread safe, cannot be called recursively, and it is not safe to add or remove categories while browsing. ast_category_browse_filtered does not have these restrictions.

Definition at line 1163 of file main/config.c.

References ast_config::last_browse, ast_category::name, ast_category::next, next_available_category(), NULL, and ast_config::root.

Referenced by __init_manager(), __queues_show(), actual_load_config(), ast_cli_perms_init(), AST_TEST_DEFINE(), complete_sip_notify(), conf_exec(), config_load(), find_queue_by_name_rt(), find_realtime(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), iax_provision_reload(), internal_process_ast_config(), load_common(), load_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_realtime_rules(), load_tech_calendars(), load_users(), mbl_load_config(), misdn_cfg_init(), named_acl_find_realtime(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), queues_data_provider_get(), realtime_directory(), realtime_sorcery(), realtime_sorcery_multi(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), search_directory(), search_directory_sub(), set_config(), set_member_value(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), test_config_validity(), update_realtime_members(), and vm_change_password().

01164 {
01165    struct ast_category *cat;
01166 
01167    if (!prev) {
01168       /* First time browse. */
01169       cat = config->root;
01170    } else if (config->last_browse && (config->last_browse->name == prev)) {
01171       /* Simple last browse found. */
01172       cat = config->last_browse->next;
01173    } else {
01174       /*
01175        * Config changed since last browse.
01176        *
01177        * First try cheap last browse search. (Rebrowsing a different
01178        * previous category?)
01179        */
01180       for (cat = config->root; cat; cat = cat->next) {
01181          if (cat->name == prev) {
01182             /* Found it. */
01183             cat = cat->next;
01184             break;
01185          }
01186       }
01187       if (!cat) {
01188          /*
01189           * Have to do it the hard way. (Last category was deleted and
01190           * re-added?)
01191           */
01192          for (cat = config->root; cat; cat = cat->next) {
01193             if (!strcasecmp(cat->name, prev)) {
01194                /* Found it. */
01195                cat = cat->next;
01196                break;
01197             }
01198          }
01199       }
01200    }
01201 
01202    if (cat)
01203       cat = next_available_category(cat, NULL, NULL);
01204 
01205    config->last_browse = cat;
01206    return (cat) ? cat->name : NULL;
01207 }

struct ast_category* ast_category_browse_filtered ( struct ast_config config,
const char *  category_name,
struct ast_category prev,
const char *  filter 
) [read]

Browse categories with filters.

Parameters:
config Which config structure you wish to "browse"
category_name An optional category name. Pass NULL to not restrict by category name.
prev A pointer to the starting category structure. Pass NULL to start at the beginning.
filter An optional comma-separated list of <name_regex>=<value_regex> pairs. Only categories with matching variables will be returned. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.
Return values:
a category on success
NULL on failure/no-more-categories

Definition at line 1209 of file main/config.c.

References ast_category::next, next_available_category(), and ast_config::root.

Referenced by action_getconfig(), action_getconfigjson(), action_listcategories(), AST_TEST_DEFINE(), ast_variable_retrieve_filtered(), handle_updates(), object_type_loaded_observer(), sorcery_config_internal_load(), and sorcery_realtime_retrieve_multiple().

01211 {
01212    struct ast_category *cat;
01213 
01214    if (!prev) {
01215       prev = config->root;
01216    } else {
01217       prev = prev->next;
01218    }
01219 
01220    cat = next_available_category(prev, category_name, filter);
01221 
01222    return cat;
01223 }

struct ast_category* ast_category_delete ( struct ast_config cfg,
struct ast_category category 
) [read]

Delete a category.

Parameters:
config which config to use
category category to delete
Returns:
the category after the deleted one which could be NULL.
Note:
It is not safe to call ast_category_delete while browsing with ast_category_browse. It is safe with ast_category_browse_filtered.

Definition at line 1352 of file main/config.c.

References ast_category_destroy(), ast_config::last, ast_config::last_browse, ast_category::next, NULL, ast_category::prev, and ast_config::root.

Referenced by AST_TEST_DEFINE(), handle_updates(), object_type_loaded_observer(), realtime_sorcery_destroy(), and realtime_sorcery_update().

01354 {
01355    struct ast_category *prev;
01356 
01357    if (!config || !category) {
01358       return NULL;
01359    }
01360 
01361    if (category->prev) {
01362       category->prev->next = category->next;
01363    } else {
01364       config->root = category->next;
01365    }
01366 
01367    if (category->next) {
01368       category->next->prev = category->prev;
01369    } else {
01370       config->last = category->prev;
01371    }
01372 
01373    prev = category->prev;
01374 
01375    if (config->last_browse == category) {
01376       config->last_browse = prev;
01377    }
01378 
01379    ast_category_destroy(category);
01380 
01381    return prev;
01382 }

void ast_category_destroy ( struct ast_category cat  ) 

struct ast_variable* ast_category_detach_variables ( struct ast_category cat  )  [read]

Definition at line 1225 of file main/config.c.

References ast_category::last, NULL, and ast_category::root.

Referenced by realtime_switch_common(), and sorcery_realtime_retrieve_multiple().

01226 {
01227    struct ast_variable *v;
01228 
01229    v = cat->root;
01230    cat->root = NULL;
01231    cat->last = NULL;
01232 
01233    return v;
01234 }

int ast_category_empty ( struct ast_category category  ) 

Removes and destroys all variables in a category.

Parameters:
category category to empty
Return values:
0 if succeeded
-1 if categopry is NULL

Definition at line 1384 of file main/config.c.

References ast_variables_destroy(), ast_category::last, NULL, and ast_category::root.

Referenced by AST_TEST_DEFINE(), and handle_updates().

01385 {
01386    if (!category) {
01387       return -1;
01388    }
01389 
01390    ast_variables_destroy(category->root);
01391    category->root = NULL;
01392    category->last = NULL;
01393 
01394    return 0;
01395 }

int ast_category_exist ( const struct ast_config config,
const char *  category_name,
const char *  filter 
)

Check for category duplicates.

Parameters:
config which config to use
category_name name of the category you're looking for
filter an optional comma-separated list of <name_regex>=<value_regex> pairs. Only categories with matching variables will be returned. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.
This will search through the categories within a given config file for a match.

Returns:
non-zero if found

Definition at line 935 of file main/config.c.

References ast_category_get().

Referenced by realtime_sorcery_store().

00937 {
00938    return !!ast_category_get(config, category_name, filter);
00939 }

struct ast_variable* ast_category_first ( struct ast_category cat  )  [read]

given a pointer to a category, return the root variable.

return the first var of a category

Definition at line 1031 of file main/config.c.

References NULL, and ast_category::root.

Referenced by acl_order_comparator(), action_getconfig(), action_getconfigjson(), handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), object_type_loaded_observer(), process_text_line(), sorcery_config_internal_load(), and wizard_apply_handler().

01032 {
01033    return (cat) ? cat->root : NULL;
01034 }

struct ast_category* ast_category_get ( const struct ast_config config,
const char *  category_name,
const char *  filter 
) [read]

Retrieve a category if it exists.

Parameters:
config which config to use
category_name name of the category you're looking for
filter If a config contains more than 1 category with the same name, you can specify a filter to narrow the search. The filter is a comma-separated list of <name_regex>=<value_regex> pairs. Only a category with matching variables will be returned. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.
This will search through the categories within a given config file for a match.

Return values:
pointer to category if found
NULL if not.

Definition at line 882 of file main/config.c.

References does_category_match(), ast_category::name, ast_category::next, NULL, and ast_config::root.

Referenced by add_message_id(), ast_category_exist(), ast_category_root(), AST_TEST_DEFINE(), ast_variable_browse(), handle_updates(), object_type_loaded_observer(), process_text_line(), realtime_directory(), realtime_sorcery_destroy(), realtime_sorcery_update(), realtime_switch_common(), vm_change_password(), and vm_forwardoptions().

00884 {
00885    struct ast_category *cat;
00886 
00887    for (cat = config->root; cat; cat = cat->next) {
00888       if (cat->name == category_name && does_category_match(cat, category_name, filter)) {
00889          return cat;
00890       }
00891    }
00892 
00893    for (cat = config->root; cat; cat = cat->next) {
00894       if (does_category_match(cat, category_name, filter)) {
00895          return cat;
00896       }
00897    }
00898 
00899    return NULL;
00900 }

const char* ast_category_get_name ( const struct ast_category category  ) 

Return the name of the category.

Parameters:
category category structure
Return values:
pointer to category name if found
NULL if not.

Definition at line 902 of file main/config.c.

References ast_category::name.

Referenced by action_getconfig(), action_getconfigjson(), action_listcategories(), AST_TEST_DEFINE(), handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), object_type_loaded_observer(), and sorcery_config_internal_load().

00903 {
00904    return category->name;
00905 }

struct ast_str* ast_category_get_templates ( const struct ast_category category  )  [read]

Return the template names this category inherits from.

Parameters:
category category structure
Returns:
an ast_str (which must be freed after use) with a comma separated list of templates names or NULL if there were no templates.

Definition at line 912 of file main/config.c.

References AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_str_append(), ast_str_create(), first, NULL, str, and ast_category::template_instances.

Referenced by action_getconfig(), and action_getconfigjson().

00913 {
00914    struct ast_category_template_instance *template;
00915    struct ast_str *str;
00916    int first = 1;
00917 
00918    if (AST_LIST_EMPTY(&category->template_instances)) {
00919       return NULL;
00920    }
00921 
00922    str = ast_str_create(128);
00923    if (!str) {
00924       return NULL;
00925    }
00926 
00927    AST_LIST_TRAVERSE(&category->template_instances, template, next) {
00928       ast_str_append(&str, 0, "%s%s", first ? "" : ",", template->name);
00929       first = 0;
00930    }
00931 
00932    return str;
00933 }

int ast_category_inherit ( struct ast_category existing,
const struct ast_category base 
)

Applies base (template) to category.

Parameters:
existing existing category
base base category
This function is used to apply a base (template) to an existing category

Return values:
0 if succeeded
-1 if the memory allocation failed

Definition at line 1241 of file main/config.c.

References ast_calloc, AST_LIST_INSERT_TAIL, ast_variable_append(), ast_variable::inherited, ast_category_template_instance::inst, ast_category::name, ast_category_template_instance::name, ast_variable::next, ast_category::root, var, and variable_clone().

Referenced by handle_updates(), and process_text_line().

01242 {
01243    struct ast_variable *var;
01244    struct ast_category_template_instance *x;
01245 
01246    x = ast_calloc(1, sizeof(*x));
01247    if (!x) {
01248       return -1;
01249    }
01250    strcpy(x->name, base->name);
01251    x->inst = base;
01252    AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
01253    for (var = base->root; var; var = var->next) {
01254       struct ast_variable *cloned = variable_clone(var);
01255       if (!cloned) {
01256          return -1;
01257       }
01258       cloned->inherited = 1;
01259       ast_variable_append(new, cloned);
01260    }
01261    return 0;
01262 }

int ast_category_insert ( struct ast_config config,
struct ast_category cat,
const char *  match 
)

Inserts new category.

Parameters:
config which config to use
cat newly created category to insert
match which category to insert above
This function is used to insert a new category above another category matching the match parameter.

Return values:
0 if succeeded
-1 if the specified match category wasn't found

Definition at line 957 of file main/config.c.

References ast_category::name, ast_category::next, NULL, ast_category::prev, and ast_config::root.

Referenced by AST_TEST_DEFINE(), and handle_updates().

00958 {
00959    struct ast_category *cur_category;
00960 
00961    if (!config || !config->root || !cat || !match) {
00962       return -1;
00963    }
00964 
00965    if (!strcasecmp(config->root->name, match)) {
00966       cat->next = config->root;
00967       cat->prev = NULL;
00968       config->root->prev = cat;
00969       config->root = cat;
00970       return 0;
00971    }
00972 
00973    for (cur_category = config->root->next; cur_category; cur_category = cur_category->next) {
00974       if (!strcasecmp(cur_category->name, match)) {
00975          cat->prev = cur_category->prev;
00976          cat->prev->next = cat;
00977 
00978          cat->next = cur_category;
00979          cur_category->prev = cat;
00980 
00981          return 0;
00982       }
00983    }
00984 
00985    return -1;
00986 }

int ast_category_is_template ( const struct ast_category category  ) 

Check if category is a template.

Parameters:
category category structure
Return values:
1 if a template.
0 if not.

Definition at line 907 of file main/config.c.

References ast_category::ignored.

Referenced by action_getconfig(), and action_getconfigjson().

00908 {
00909    return category->ignored;
00910 }

struct ast_category* ast_category_new ( const char *  name,
const char *  in_file,
int  lineno 
) [read]

struct ast_category* ast_category_new_template ( const char *  name,
const char *  in_file,
int  lineno 
) [read]

Create a category making it a template.

Parameters:
name name of new template
in_file filename which contained the new config
lineno line number

Definition at line 877 of file main/config.c.

References new_category().

Referenced by AST_TEST_DEFINE(), and handle_updates().

00878 {
00879    return new_category(name, in_file, lineno, 1);
00880 }

void ast_category_rename ( struct ast_category cat,
const char *  name 
)

struct ast_variable* ast_category_root ( struct ast_config config,
char *  cat 
) [read]

returns the root ast_variable of a config

Parameters:
config pointer to an ast_config data structure
cat name of the category for which you want the root
Returns:
the category specified

Definition at line 1036 of file main/config.c.

References ast_category_get(), NULL, and ast_category::root.

Referenced by config_function_read(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), realtime_sorcery(), realtime_sorcery_multi(), and register_realtime_peers_with_callbackextens().

01037 {
01038    struct ast_category *category = ast_category_get(config, cat, NULL);
01039 
01040    if (category)
01041       return category->root;
01042    return NULL;
01043 }

int ast_check_realtime ( const char *  family  ) 

Check if realtime engine is configured for family.

Parameters:
family which family/config to be checked
Returns:
1 if family is configured in realtime and engine exists

Definition at line 3185 of file main/config.c.

References ast_realtime_enabled(), find_engine(), and NULL.

Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_named_acl_find(), ast_queue_log(), close_mailbox(), copy_plain_file(), destroy_association(), find_realtime_gw(), handle_response_peerpoke(), handle_voicemail_show_users(), leave_voicemail(), load_module(), load_moh_classes(), load_realtime_rules(), local_ast_moh_start(), logger_queue_rt_start(), msg_create_from_file(), realtime_peer(), realtime_update_peer(), register_realtime_peers_with_callbackextens(), rename_file(), set_member_value(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().

03186 {
03187    struct ast_config_engine *eng;
03188    if (!ast_realtime_enabled()) {
03189       return 0;   /* There are no engines at all so fail early */
03190    }
03191 
03192    eng = find_engine(family, 1, NULL, 0, NULL, 0);
03193    if (eng)
03194       return 1;
03195    return 0;
03196 }

static void ast_comment_destroy ( struct ast_comment **  comment  )  [static]

Definition at line 527 of file main/config.c.

References ast_free, ast_comment::next, and NULL.

Referenced by ast_category_destroy(), and ast_variable_destroy().

00528 {
00529    struct ast_comment *n, *p;
00530 
00531    for (p = *comment; p; p = n) {
00532       n = p->next;
00533       ast_free(p);
00534    }
00535 
00536    *comment = NULL;
00537 }

struct ast_config* ast_config_copy ( const struct ast_config orig  )  [read]

Copies the contents of one ast_config into another.

Note:
This creates a config on the heap. The caller of this must be prepared to free the memory returned.
Parameters:
orig the config to copy
Returns:
The new config on success, NULL on failure.

Definition at line 2901 of file main/config.c.

References ast_category_append(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_variables_dup(), ast_category::file, ast_category::last, ast_category::lineno, ast_category::name, ast_category::next, NULL, ast_category::root, and ast_config::root.

Referenced by AST_TEST_DEFINE(), and config_hook_exec().

02902 {
02903    struct ast_config *new_config = ast_config_new();
02904    struct ast_category *cat_iter;
02905 
02906    if (!new_config) {
02907       return NULL;
02908    }
02909 
02910    for (cat_iter = old->root; cat_iter; cat_iter = cat_iter->next) {
02911       struct ast_category *new_cat =
02912          ast_category_new(cat_iter->name, cat_iter->file, cat_iter->lineno);
02913       if (!new_cat) {
02914          goto fail;
02915       }
02916       ast_category_append(new_config, new_cat);
02917       if (cat_iter->root) {
02918          new_cat->root = ast_variables_dup(cat_iter->root);
02919          if (!new_cat->root) {
02920             goto fail;
02921          }
02922          new_cat->last = cat_iter->last;
02923       }
02924    }
02925 
02926    return new_config;
02927 
02928 fail:
02929    ast_config_destroy(new_config);
02930    return NULL;
02931 }

void ast_config_destroy ( struct ast_config cfg  ) 

Destroys a config.

Parameters:
config pointer to config data structure
Free memory associated with a given config

Definition at line 1397 of file main/config.c.

References ast_category_destroy(), ast_free, ast_includes_destroy(), ast_variables_destroy(), free, ast_config::includes, ast_category::next, ast_category::root, and ast_config::root.

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_sorcery_apply_config(), __init_manager(), __queues_show(), _dsp_init(), aco_process_config(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), ast_cli_perms_init(), ast_config_copy(), ast_config_load2(), ast_load_realtime_multientry_fields(), ast_plc_reload(), ast_readconfig(), AST_TEST_DEFINE(), build_cfg(), conf_exec(), config_function_read(), config_load(), config_module(), deinitialize_sorcery(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_load_queue_rt_friendly(), find_realtime(), forward_message(), get_defaults(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), handle_cli_dialplan_save(), hook_cb(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), load_common(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_realtime_rules(), load_users(), localized_config_load(), localized_config_load_with_comments(), make_email_file(), mbl_load_config(), message_range_and_existence_check(), misdn_cfg_init(), my_load_module(), named_acl_find_realtime(), notify_new_message(), object_type_loaded_observer(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), process_text_line(), queues_data_provider_get(), read_config_maps(), read_password_from_file(), realtime_directory(), realtime_multi_handler(), realtime_multi_mysql(), realtime_multi_pgsql(), realtime_sorcery_multi(), realtime_sqlite3_multi(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), rtp_reload(), run_startup_commands(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), smdi_load(), sorcery_config_internal_load(), sorcery_realtime_retrieve_multiple(), tds_load_module(), unload_module(), update_realtime_members(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), vm_msg_snapshot_create(), and write_password_to_file().

01398 {
01399    struct ast_category *cat, *catn;
01400 
01401    if (!cfg)
01402       return;
01403 
01404    ast_includes_destroy(cfg->includes);
01405 
01406    cat = cfg->root;
01407    while (cat) {
01408       catn = cat;
01409       cat = cat->next;
01410       ast_category_destroy(catn);
01411    }
01412    ast_free(cfg);
01413 }

int ast_config_engine_deregister ( struct ast_config_engine del  ) 

Deregister config engine.

Return values:
0 Always

Definition at line 2829 of file main/config.c.

References config_lock, last, lock, ast_config_engine::next, NULL, and SCOPED_MUTEX.

Referenced by unload_module().

02830 {
02831    struct ast_config_engine *ptr, *last=NULL;
02832 
02833    SCOPED_MUTEX(lock, &config_lock);
02834 
02835    for (ptr = config_engine_list; ptr; ptr=ptr->next) {
02836       if (ptr == del) {
02837          if (last)
02838             last->next = ptr->next;
02839          else
02840             config_engine_list = ptr->next;
02841          break;
02842       }
02843       last = ptr;
02844    }
02845 
02846    return 0;
02847 }

int ast_config_engine_register ( struct ast_config_engine newconfig  ) 

Register config engine.

Return values:
1 Always

Definition at line 2813 of file main/config.c.

References config_lock, lock, ast_config_engine::next, and SCOPED_MUTEX.

Referenced by load_module().

02814 {
02815    struct ast_config_engine *ptr;
02816 
02817    SCOPED_MUTEX(lock, &config_lock);
02818 
02819    if (!config_engine_list) {
02820       config_engine_list = new;
02821    } else {
02822       for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
02823       ptr->next = new;
02824    }
02825 
02826    return 1;
02827 }

struct ast_category* ast_config_get_current_category ( const struct ast_config cfg  )  [read]

Retrieve the current category name being built.

API for backend configuration engines while building a configuration set.

Definition at line 1415 of file main/config.c.

References ast_config::current.

Referenced by config_curl(), config_odbc(), and config_text_file_load().

01416 {
01417    return cfg->current;
01418 }

int ast_config_hook_register ( const char *  name,
const char *  filename,
const char *  module,
enum config_hook_flags  flags,
config_hook_cb  hook 
)

Register a config hook for a particular file and module.

Parameters:
name The name of the hook you are registering.
filename The file whose config you wish to hook into.
module The module that is reloading the config. This can be useful if multiple modules may possibly reload the same file, but you are only interested when a specific module reloads the file
flags Flags that affect the way hooks work.
hook The callback to be called when config is loaded. return 0 Success return -1 Unsuccess, also known as UTTER AND COMPLETE FAILURE

Definition at line 3901 of file main/config.c.

References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, ast_strdup, cfg_hook::filename, cfg_hook::hook_cb, hook_cmp(), hook_destroy(), hook_hash(), cfg_hook::module, and cfg_hook::name.

Referenced by AST_TEST_DEFINE().

03906 {
03907    struct cfg_hook *hook;
03908    if (!cfg_hooks && !(cfg_hooks = ao2_container_alloc(17, hook_hash, hook_cmp))) {
03909       return -1;
03910    }
03911 
03912    if (!(hook = ao2_alloc(sizeof(*hook), hook_destroy))) {
03913       return -1;
03914    }
03915 
03916    hook->hook_cb = hook_cb;
03917    hook->filename = ast_strdup(filename);
03918    hook->name = ast_strdup(name);
03919    hook->module = ast_strdup(module);
03920 
03921    ao2_link(cfg_hooks, hook);
03922    ao2_ref(hook, -1);
03923    return 0;
03924 }

void ast_config_hook_unregister ( const char *  name  ) 

Unregister a config hook.

Parameters:
name The name of the hook to unregister

Definition at line 3873 of file main/config.c.

References ao2_find, ast_strdupa, cfg_hook::name, OBJ_NODATA, OBJ_POINTER, OBJ_UNLINK, and tmp().

03874 {
03875    struct cfg_hook tmp;
03876 
03877    tmp.name = ast_strdupa(name);
03878 
03879    ao2_find(cfg_hooks, &tmp, OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA);
03880 }

struct ast_config* ast_config_internal_load ( const char *  filename,
struct ast_config cfg,
struct ast_flags  flags,
const char *  suggested_include_file,
const char *  who_asked 
) [read]

Definition at line 2934 of file main/config.c.

References ast_log, ast_test_flag, CONFIG_FLAG_NOREALTIME, config_hook_exec(), 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, NULL, and result.

Referenced by add_cfg_entry(), ast_config_load2(), config_curl(), config_ldap(), config_mysql(), config_odbc(), config_pgsql(), localized_config_load(), localized_config_load_with_comments(), process_text_line(), read_config_maps(), and static_realtime_cb().

02935 {
02936    char db[256];
02937    char table[256];
02938    struct ast_config_engine *loader = &text_file_engine;
02939    struct ast_config *result;
02940 
02941    /* The config file itself bumps include_level by 1 */
02942    if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
02943       ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
02944       return NULL;
02945    }
02946 
02947    cfg->include_level++;
02948 
02949    if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) {
02950       struct ast_config_engine *eng;
02951 
02952       eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
02953 
02954 
02955       if (eng && eng->load_func) {
02956          loader = eng;
02957       } else {
02958          eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
02959          if (eng && eng->load_func)
02960             loader = eng;
02961       }
02962    }
02963 
02964    result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
02965 
02966    if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED) {
02967       result->include_level--;
02968       config_hook_exec(filename, who_asked, result);
02969    } else if (result != CONFIG_STATUS_FILEINVALID) {
02970       cfg->include_level--;
02971    }
02972 
02973    return result;
02974 }

struct ast_config* ast_config_load2 ( const char *  filename,
const char *  who_asked,
struct ast_flags  flags 
) [read]

Load a config file.

Parameters:
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).
Create a config structure from a given configuration file.

Returns:
an ast_config data structure on success
Return values:
NULL on error

Definition at line 2976 of file main/config.c.

References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, NULL, and result.

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_sorcery_apply_config(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_cli_perms_init(), ast_readconfig(), AST_TEST_DEFINE(), do_reload(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), load_config(), load_indications(), load_modules(), misdn_cfg_init(), object_type_loaded_observer(), private_enum_init(), rtp_reload(), run_startup_commands(), set_config(), and sorcery_config_internal_load().

02977 {
02978    struct ast_config *cfg;
02979    struct ast_config *result;
02980 
02981    cfg = ast_config_new();
02982    if (!cfg)
02983       return NULL;
02984 
02985    result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
02986    if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID)
02987       ast_config_destroy(cfg);
02988 
02989    return result;
02990 }

struct ast_config* ast_config_new ( void   )  [read]

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.

Returns:
Value of var, or NULL if not found.

Definition at line 670 of file main/config.c.

References ast_variable_retrieve(), and tmp().

Referenced by actual_load_config(), pbx_load_users(), and search_directory_sub().

00671 {
00672    const char *tmp;
00673    tmp = ast_variable_retrieve(cfg, cat, var);
00674    if (!tmp) {
00675       tmp = ast_variable_retrieve(cfg, "general", var);
00676    }
00677    return tmp;
00678 }

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 1420 of file main/config.c.

References ast_config::current.

01421 {
01422    /* cast below is just to silence compiler warning about dropping "const" */
01423    cfg->current = (struct ast_category *) cat;
01424 }

void ast_config_sort_categories ( struct ast_config config,
int  descending,
int(*)(struct ast_category *p, struct ast_category *q)  comparator 
)

Sorts categories in a config in the order of a numerical value contained within them.

Parameters:
config The config structure you wish to sort
comparator variable Which numerical value you wish to sort by
descending If true, we sort highest to lowest instead of lowest to highest
This function will assume a value of 0 for any non-numerical strings and NULL fields.

Definition at line 1045 of file main/config.c.

References e, ast_category::next, NULL, and ast_config::root.

Referenced by named_acl_find_realtime().

01047 {
01048    /*
01049     * The contents of this function are adapted from
01050     * an example of linked list merge sorting
01051     * copyright 2001 Simon Tatham.
01052     *
01053     * Permission is hereby granted, free of charge, to any person
01054     * obtaining a copy of this software and associated documentation
01055     * files (the "Software"), to deal in the Software without
01056     * restriction, including without limitation the rights to use,
01057     * copy, modify, merge, publish, distribute, sublicense, and/or
01058     * sell copies of the Software, and to permit persons to whom the
01059     * Software is furnished to do so, subject to the following
01060     * conditions:
01061     *
01062     * The above copyright notice and this permission notice shall be
01063     * included in all copies or substantial portions of the Software.
01064     *
01065     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
01066     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
01067     * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
01068     * NONINFRINGEMENT.  IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
01069     * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
01070     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
01071     * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
01072     * SOFTWARE.
01073     */
01074 
01075    int insize = 1;
01076    struct ast_category *p, *q, *e, *tail;
01077    int nmerges, psize, qsize, i;
01078 
01079    /* If the descending flag was sent, we'll apply inversion to the comparison function's return. */
01080    if (descending) {
01081       descending = -1;
01082    } else {
01083       descending = 1;
01084    }
01085 
01086    if (!config->root) {
01087       return;
01088    }
01089 
01090    while (1) {
01091       p = config->root;
01092       config->root = NULL;
01093       tail = NULL;
01094 
01095       nmerges = 0; /* count number of merges we do in this pass */
01096 
01097       while (p) {
01098          nmerges++; /* there exists a merge to be done */
01099 
01100          /* step `insize' places along from p */
01101          q = p;
01102          psize = 0;
01103          for (i = 0; i < insize; i++) {
01104             psize++;
01105             q = q->next;
01106             if (!q) {
01107                break;
01108             }
01109          }
01110 
01111          /* if q hasn't fallen off end, we have two lists to merge */
01112          qsize = insize;
01113 
01114          /* now we have two lists; merge them */
01115          while (psize > 0 || (qsize > 0 && q)) {
01116             /* decide whether next element of merge comes from p or q */
01117             if (psize == 0) {
01118                /* p is empty; e must come from q. */
01119                e = q;
01120                q = q->next;
01121                qsize--;
01122             } else if (qsize == 0 || !q) {
01123                /* q is empty; e must come from p. */
01124                e = p; p = p->next; psize--;
01125             } else if ((comparator(p,q) * descending) <= 0) {
01126                /* First element of p is lower (or same) e must come from p. */
01127                e = p;
01128                p = p->next;
01129                psize--;
01130             } else {
01131                /* First element of q is lower; e must come from q. */
01132                e = q;
01133                q = q->next;
01134                qsize--;
01135             }
01136 
01137             /* add the next element to the merged list */
01138             if (tail) {
01139                tail->next = e;
01140             } else {
01141                config->root = e;
01142             }
01143             tail = e;
01144          }
01145 
01146          /* now p has stepped `insize' places along, and q has too */
01147          p = q;
01148       }
01149 
01150       tail->next = NULL;
01151 
01152       /* If we have done only one merge, we're finished. */
01153       if (nmerges <= 1) { /* allow for nmerges==0, the empty list case */
01154          return;
01155       }
01156 
01157       /* Otherwise repeat, merging lists twice the size */
01158       insize *= 2;
01159    }
01160 
01161 }

int ast_config_text_file_save ( const char *  filename,
const struct ast_config cfg,
const char *  generator 
)

Save a config text file preserving the pre 13.2 behavior.

Parameters:
filename Filename
cfg ast_config
generator generator
Returns:
0 on success or -1 on failure.

Definition at line 2374 of file main/config.c.

References ast_config_text_file_save2(), and CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT.

Referenced by add_message_id(), vm_change_password(), vm_forwardoptions(), and write_password_to_file().

02375 {
02376    return ast_config_text_file_save2(configfile, cfg, generator, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT);
02377 }

int ast_config_text_file_save2 ( const char *  filename,
const struct ast_config cfg,
const char *  generator,
uint32_t  flags 
)

Save a config text file.

Since:
13.2.0
Parameters:
filename Filename
cfg ast_config
generator generator
flags List of config_save_flags
Returns:
0 on success or -1 on failure.

Definition at line 2379 of file main/config.c.

References ao2_container_alloc, ao2_ref, ast_debug, ast_escape_semicolons(), AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_log, ast_verb, ast_variable::blanklines, ast_comment::cmt, config_hook_exec(), CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT, errno, ast_config_include::exec, ast_config_include::exec_file, f, ast_variable::file, ast_category::file, gen_header(), hash_string(), hashtab_compare_strings(), ast_category::ignored, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config::includes, ast_variable::inherited, insert_leading_blank_lines(), ast_category_template_instance::inst, ast_variable::lineno, ast_category::lineno, LOG_ERROR, make_fn(), ast_variable::name, ast_category_template_instance::name, ast_category::name, ast_category::next, ast_variable::next, ast_comment::next, ast_config_include::next, ast_variable::object, option_debug, ast_config_include::output, ast_variable::precomments, ast_category::precomments, ast_category::root, ast_config::root, ast_variable::sameline, ast_category::sameline, set_fn(), ast_category::template_instances, ast_variable::trailing, ast_category::trailing, ast_variable::value, and var.

Referenced by action_updateconfig(), ast_config_text_file_save(), and config_text_file_save().

02380 {
02381    FILE *f;
02382    char fn[PATH_MAX];
02383    struct ast_variable *var;
02384    struct ast_category *cat;
02385    struct ast_comment *cmt;
02386    struct ast_config_include *incl;
02387    int blanklines = 0;
02388    struct ao2_container *fileset;
02389    struct inclfile *fi;
02390 
02391    fileset = ao2_container_alloc(1023, hash_string, hashtab_compare_strings);
02392    if (!fileset) {
02393       /* Container creation failed. */
02394       return -1;
02395    }
02396 
02397    /* Check all the files for write access before attempting to modify any of them */
02398    for (incl = cfg->includes; incl; incl = incl->next) {
02399       /* reset all the output flags in case this isn't our first time saving this data */
02400       incl->output = 0;
02401       /* now make sure we have write access */
02402       if (!incl->exec) {
02403          make_fn(fn, sizeof(fn), incl->included_file, configfile);
02404          if (access(fn, R_OK | W_OK)) {
02405             ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02406             return -1;
02407          }
02408       }
02409    }
02410 
02411    /* now make sure we have write access to the main config file */
02412    make_fn(fn, sizeof(fn), 0, configfile);
02413    if (access(fn, R_OK | W_OK)) {
02414       ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02415       return -1;
02416    }
02417 
02418    /* Now that we know we have write access to all files, it's safe to start truncating them */
02419 
02420    /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
02421       are all truncated to zero bytes and have that nice header*/
02422    for (incl = cfg->includes; incl; incl = incl->next) {
02423       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*/
02424          /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
02425          fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
02426          f = fopen(fn, "w");
02427          if (f) {
02428             gen_header(f, configfile, fn, generator);
02429             fclose(f); /* this should zero out the file */
02430          } else {
02431             ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02432          }
02433          if (fi) {
02434             ao2_ref(fi, -1);
02435          }
02436       }
02437    }
02438 
02439    /* just set fn to absolute ver of configfile */
02440    fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
02441    if (
02442 #ifdef __CYGWIN__
02443       (f = fopen(fn, "w+"))
02444 #else
02445       (f = fopen(fn, "w"))
02446 #endif
02447       ) {
02448       ast_verb(2, "Saving '%s'\n", fn);
02449       gen_header(f, configfile, fn, generator);
02450       cat = cfg->root;
02451       fclose(f);
02452       if (fi) {
02453          ao2_ref(fi, -1);
02454       }
02455 
02456       /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
02457       /* since each var, cat, and associated comments can come from any file, we have to be
02458          mobile, and open each file, print, and close it on an entry-by-entry basis */
02459 
02460       while (cat) {
02461          fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
02462          f = fopen(fn, "a");
02463          if (!f) {
02464             ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02465             if (fi) {
02466                ao2_ref(fi, -1);
02467             }
02468             ao2_ref(fileset, -1);
02469             return -1;
02470          }
02471 
02472          /* dump any includes that happen before this category header */
02473          for (incl=cfg->includes; incl; incl = incl->next) {
02474             if (strcmp(incl->include_location_file, cat->file) == 0){
02475                if (cat->lineno > incl->include_location_lineno && !incl->output) {
02476                   if (incl->exec)
02477                      fprintf(f,"#exec \"%s\"\n", incl->exec_file);
02478                   else
02479                      fprintf(f,"#include \"%s\"\n", incl->included_file);
02480                   incl->output = 1;
02481                }
02482             }
02483          }
02484 
02485          insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno);
02486          /* Dump section with any appropriate comment */
02487          for (cmt = cat->precomments; cmt; cmt=cmt->next) {
02488             char *cmtp = cmt->cmt;
02489             while (cmtp && *cmtp == ';' && *(cmtp+1) == '!') {
02490                char *cmtp2 = strchr(cmtp+1, '\n');
02491                if (cmtp2)
02492                   cmtp = cmtp2+1;
02493                else cmtp = 0;
02494             }
02495             if (cmtp)
02496                fprintf(f,"%s", cmtp);
02497          }
02498          fprintf(f, "[%s]", cat->name);
02499          if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
02500             fprintf(f, "(");
02501             if (cat->ignored) {
02502                fprintf(f, "!");
02503             }
02504             if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
02505                fprintf(f, ",");
02506             }
02507             if (!AST_LIST_EMPTY(&cat->template_instances)) {
02508                struct ast_category_template_instance *x;
02509                AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
02510                   fprintf(f,"%s",x->name);
02511                   if (x != AST_LIST_LAST(&cat->template_instances))
02512                      fprintf(f,",");
02513                }
02514             }
02515             fprintf(f, ")");
02516          }
02517          for(cmt = cat->sameline; cmt; cmt=cmt->next)
02518          {
02519             fprintf(f,"%s", cmt->cmt);
02520          }
02521          if (!cat->sameline)
02522             fprintf(f,"\n");
02523          for (cmt = cat->trailing; cmt; cmt=cmt->next) {
02524             if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
02525                fprintf(f,"%s", cmt->cmt);
02526          }
02527          fclose(f);
02528          if (fi) {
02529             ao2_ref(fi, -1);
02530          }
02531 
02532          var = cat->root;
02533          while (var) {
02534             struct ast_category_template_instance *x;
02535             int found = 0;
02536 
02537             AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
02538                struct ast_variable *v;
02539                for (v = x->inst->root; v; v = v->next) {
02540 
02541                   if (flags & CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT) {
02542                      if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
02543                         found = 1;
02544                         break;
02545                      }
02546                   } else {
02547                      if (var->inherited) {
02548                         found = 1;
02549                         break;
02550                      } else {
02551                         if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
02552                            found = 1;
02553                            break;
02554                         }
02555                      }
02556                   }
02557                }
02558                if (found) {
02559                   break;
02560                }
02561             }
02562             if (found) {
02563                var = var->next;
02564                continue;
02565             }
02566             fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
02567             f = fopen(fn, "a");
02568             if (!f) {
02569                ast_debug(1, "Unable to open for writing: %s\n", fn);
02570                ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
02571                if (fi) {
02572                   ao2_ref(fi, -1);
02573                }
02574                ao2_ref(fileset, -1);
02575                return -1;
02576             }
02577 
02578             /* dump any includes that happen before this category header */
02579             for (incl=cfg->includes; incl; incl = incl->next) {
02580                if (strcmp(incl->include_location_file, var->file) == 0){
02581                   if (var->lineno > incl->include_location_lineno && !incl->output) {
02582                      if (incl->exec)
02583                         fprintf(f,"#exec \"%s\"\n", incl->exec_file);
02584                      else
02585                         fprintf(f,"#include \"%s\"\n", incl->included_file);
02586                      incl->output = 1;
02587                   }
02588                }
02589             }
02590 
02591             insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
02592             for (cmt = var->precomments; cmt; cmt=cmt->next) {
02593                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
02594                   fprintf(f,"%s", cmt->cmt);
02595             }
02596 
02597             { /* Block for 'escaped' scope */
02598                int escaped_len = 2 * strlen(var->value) + 1;
02599                char escaped[escaped_len];
02600 
02601                ast_escape_semicolons(var->value, escaped, escaped_len);
02602 
02603                if (var->sameline) {
02604                   fprintf(f, "%s %s %s  %s", var->name, (var->object ? "=>" : "="),
02605                      escaped, var->sameline->cmt);
02606                } else {
02607                   fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="),
02608                      escaped);
02609                }
02610             }
02611 
02612             for (cmt = var->trailing; cmt; cmt=cmt->next) {
02613                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
02614                   fprintf(f,"%s", cmt->cmt);
02615             }
02616             if (var->blanklines) {
02617                blanklines = var->blanklines;
02618                while (blanklines--)
02619                   fprintf(f, "\n");
02620             }
02621 
02622             fclose(f);
02623             if (fi) {
02624                ao2_ref(fi, -1);
02625             }
02626 
02627             var = var->next;
02628          }
02629          cat = cat->next;
02630       }
02631       if (!option_debug) {
02632          ast_verb(2, "Saving '%s': saved\n", fn);
02633       }
02634    } else {
02635       ast_debug(1, "Unable to open for writing: %s\n", fn);
02636       ast_verb(2, "Unable to write '%s' (%s)\n", fn, strerror(errno));
02637       if (fi) {
02638          ao2_ref(fi, -1);
02639       }
02640       ao2_ref(fileset, -1);
02641       return -1;
02642    }
02643 
02644    /* Now, for files with trailing #include/#exec statements,
02645       we have to make sure every entry is output */
02646    for (incl=cfg->includes; incl; incl = incl->next) {
02647       if (!incl->output) {
02648          /* open the respective file */
02649          fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
02650          f = fopen(fn, "a");
02651          if (!f) {
02652             ast_debug(1, "Unable to open for writing: %s\n", fn);
02653             ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
02654             if (fi) {
02655                ao2_ref(fi, -1);
02656             }
02657             ao2_ref(fileset, -1);
02658             return -1;
02659          }
02660 
02661          /* output the respective include */
02662          if (incl->exec)
02663             fprintf(f,"#exec \"%s\"\n", incl->exec_file);
02664          else
02665             fprintf(f,"#include \"%s\"\n", incl->included_file);
02666          fclose(f);
02667          incl->output = 1;
02668          if (fi) {
02669             ao2_ref(fi, -1);
02670          }
02671       }
02672    }
02673    ao2_ref(fileset, -1); /* this should destroy the hash container */
02674 
02675    /* pass new configuration to any config hooks */
02676    config_hook_exec(configfile, generator, cfg);
02677 
02678    return 0;
02679 }

int ast_destroy_realtime ( const char *  family,
const char *  keyfield,
const char *  lookup,
  ... 
)

Destroy realtime configuration.

Parameters:
family which family/config to be destroyed
keyfield which field to use as the key
lookup which value to look for in the key field to match the entry.
This function is used to destroy an entry in realtime configuration space. Additional params are used as keys.

Returns:
Number of rows affected, or -1 on error.
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 3428 of file main/config.c.

References ast_destroy_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by cli_realtime_destroy(), function_realtime_readdestroy(), leave_voicemail(), msg_create_from_file(), and vm_delete().

03429 {
03430    RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
03431    int res = 0;
03432    va_list ap;
03433 
03434    va_start(ap, lookup);
03435    if (realtime_arguments_to_fields(ap, &fields)) {
03436       res = -1;
03437    }
03438    va_end(ap);
03439 
03440    if (res) {
03441       return -1;
03442    }
03443 
03444    return ast_destroy_realtime_fields(family, keyfield, lookup, fields);
03445 }

int ast_destroy_realtime_fields ( const char *  family,
const char *  keyfield,
const char *  lookup,
const struct ast_variable fields 
)

Destroy realtime configuration.

Parameters:
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.
fields fields themselves
This function is used to destroy an entry in realtime configuration space. Additional params are used as keys.

Returns:
Number of rows affected, or -1 on error.

Definition at line 3408 of file main/config.c.

References db, ast_config_engine::destroy_func, and find_engine().

Referenced by ast_destroy_realtime(), and sorcery_realtime_delete().

03409 {
03410    struct ast_config_engine *eng;
03411    int res = -1, i;
03412    char db[256];
03413    char table[256];
03414 
03415    for (i = 1; ; i++) {
03416       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03417          if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, fields))) {
03418             break;
03419          }
03420       } else {
03421          break;
03422       }
03423    }
03424 
03425    return res;
03426 }

static void ast_destroy_template_list ( struct ast_category cat  )  [static]

Definition at line 988 of file main/config.c.

References ast_free, AST_LIST_REMOVE_HEAD, and ast_category::template_instances.

Referenced by ast_category_destroy().

00989 {
00990    struct ast_category_template_instance *x;
00991 
00992    while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
00993       ast_free(x);
00994 }

struct ast_config_include* ast_include_find ( struct ast_config conf,
const char *  included_file 
) [read]

Definition at line 479 of file main/config.c.

References ast_config_include::included_file, ast_config::includes, and ast_config_include::next.

Referenced by ast_include_new().

00480 {
00481    struct ast_config_include *x;
00482    for (x=conf->includes;x;x=x->next) {
00483       if (strcmp(x->included_file,included_file) == 0)
00484          return x;
00485    }
00486    return 0;
00487 }

struct ast_config_include* ast_include_new ( struct ast_config conf,
const char *  from_file,
const char *  included_file,
int  is_exec,
const char *  exec_file,
int  from_lineno,
char *  real_included_file_name,
int  real_included_file_name_size 
) [read]

Definition at line 339 of file main/config.c.

References ast_calloc, ast_include_find(), ast_includes_destroy(), ast_log, ast_strdup, ast_strlen_zero, ast_config_include::exec, ast_config_include::exec_file, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config::includes, ast_config_include::inclusion_count, LOG_WARNING, ast_config_include::next, and NULL.

Referenced by process_text_line().

00340 {
00341    /* a file should be included ONCE. Otherwise, if one of the instances is changed,
00342     * then all be changed. -- how do we know to include it? -- Handling modified
00343     * instances is possible, I'd have
00344     * to create a new master for each instance. */
00345    struct ast_config_include *inc;
00346    struct stat statbuf;
00347 
00348    inc = ast_include_find(conf, included_file);
00349    if (inc) {
00350       do {
00351          inc->inclusion_count++;
00352          snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
00353       } while (stat(real_included_file_name, &statbuf) == 0);
00354       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);
00355    } else
00356       *real_included_file_name = 0;
00357 
00358    inc = ast_calloc(1,sizeof(struct ast_config_include));
00359    if (!inc) {
00360       return NULL;
00361    }
00362    inc->include_location_file = ast_strdup(from_file);
00363    inc->include_location_lineno = from_lineno;
00364    if (!ast_strlen_zero(real_included_file_name))
00365       inc->included_file = ast_strdup(real_included_file_name);
00366    else
00367       inc->included_file = ast_strdup(included_file);
00368 
00369    inc->exec = is_exec;
00370    if (is_exec)
00371       inc->exec_file = ast_strdup(exec_file);
00372 
00373    if (!inc->include_location_file
00374       || !inc->included_file
00375       || (is_exec && !inc->exec_file)) {
00376       ast_includes_destroy(inc);
00377       return NULL;
00378    }
00379 
00380    /* attach this new struct to the conf struct */
00381    inc->next = conf->includes;
00382    conf->includes = inc;
00383 
00384    return inc;
00385 }

void ast_include_rename ( struct ast_config conf,
const char *  from_file,
const char *  to_file 
)

Definition at line 387 of file main/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().

00388 {
00389    struct ast_config_include *incl;
00390    struct ast_category *cat;
00391    char *str;
00392 
00393    int from_len = strlen(from_file);
00394    int to_len = strlen(to_file);
00395 
00396    if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
00397       return;
00398 
00399    /* the manager code allows you to read in one config file, then
00400     * write it back out under a different name. But, the new arrangement
00401     * ties output lines to the file name. So, before you try to write
00402     * the config file to disk, better riffle thru the data and make sure
00403     * the file names are changed.
00404     */
00405    /* file names are on categories, includes (of course), and on variables. So,
00406     * traverse all this and swap names */
00407 
00408    for (incl = conf->includes; incl; incl=incl->next) {
00409       if (strcmp(incl->include_location_file,from_file) == 0) {
00410          if (from_len >= to_len)
00411             strcpy(incl->include_location_file, to_file);
00412          else {
00413             /* Keep the old filename if the allocation fails. */
00414             str = ast_strdup(to_file);
00415             if (str) {
00416                ast_free(incl->include_location_file);
00417                incl->include_location_file = str;
00418             }
00419          }
00420       }
00421    }
00422    for (cat = conf->root; cat; cat = cat->next) {
00423       struct ast_variable **prev;
00424       struct ast_variable *v;
00425       struct ast_variable *new_var;
00426 
00427       if (strcmp(cat->file,from_file) == 0) {
00428          if (from_len >= to_len)
00429             strcpy(cat->file, to_file);
00430          else {
00431             /* Keep the old filename if the allocation fails. */
00432             str = ast_strdup(to_file);
00433             if (str) {
00434                ast_free(cat->file);
00435                cat->file = str;
00436             }
00437          }
00438       }
00439       for (prev = &cat->root, v = cat->root; v; prev = &v->next, v = v->next) {
00440          if (strcmp(v->file, from_file)) {
00441             continue;
00442          }
00443 
00444          /*
00445           * Calculate actual space available.  The file string is
00446           * intentionally stuffed before the name string just so we can
00447           * do this.
00448           */
00449          if (to_len < v->name - v->file) {
00450             /* The new name will fit in the available space. */
00451             str = (char *) v->file;/* Stupid compiler complains about discarding qualifiers even though I used a cast. */
00452             strcpy(str, to_file);/* SAFE */
00453             continue;
00454          }
00455 
00456          /* Keep the old filename if the allocation fails. */
00457          new_var = ast_variable_new(v->name, v->value, to_file);
00458          if (!new_var) {
00459             continue;
00460          }
00461 
00462          /* Move items from the old list node to the replacement node. */
00463          ast_variable_move(new_var, v);
00464 
00465          /* Replace the old node in the list with the new node. */
00466          new_var->next = v->next;
00467          if (cat->last == v) {
00468             cat->last = new_var;
00469          }
00470          *prev = new_var;
00471 
00472          ast_variable_destroy(v);
00473 
00474          v = new_var;
00475       }
00476    }
00477 }

static void ast_includes_destroy ( struct ast_config_include incls  )  [static]

Definition at line 1009 of file main/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().

01010 {
01011    struct ast_config_include *incl,*inclnext;
01012 
01013    for (incl=incls; incl; incl = inclnext) {
01014       inclnext = incl->next;
01015       ast_free(incl->include_location_file);
01016       ast_free(incl->exec_file);
01017       ast_free(incl->included_file);
01018       ast_free(incl);
01019    }
01020 }

struct ast_variable* ast_load_realtime ( const char *  family,
  ... 
) [read]

Definition at line 3161 of file main/config.c.

References ast_load_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by conf_run(), copy_plain_file(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_realtime_gw(), find_user_realtime(), leave_queue(), local_ast_moh_start(), queue_function_queuegetchannel(), queue_function_queuewaitingcount(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_switch_common(), realtime_user(), and rt_extend_conf().

03162 {
03163    RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
03164    int field_res = 0;
03165    va_list ap;
03166 
03167    va_start(ap, family);
03168    if (realtime_arguments_to_fields(ap, &fields)) {
03169       field_res = -1;
03170    }
03171    va_end(ap);
03172 
03173    if (field_res) {
03174       return NULL;
03175    }
03176 
03177    if (!fields) {
03178       return NULL;
03179    }
03180 
03181    return ast_load_realtime_fields(family, fields);
03182 }

struct ast_variable* ast_load_realtime_all ( const char *  family,
  ... 
) [read]

Definition at line 3109 of file main/config.c.

References ast_load_realtime_all_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by cli_realtime_load(), function_realtime_read(), function_realtime_readdestroy(), and realtimefield_read().

03110 {
03111    RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
03112    struct ast_variable *res = NULL;
03113    va_list ap;
03114 
03115    va_start(ap, family);
03116    realtime_arguments_to_fields(ap, &fields);
03117    va_end(ap);
03118 
03119    if (fields) {
03120       res = ast_load_realtime_all_fields(family, fields);
03121    }
03122 
03123    return res;
03124 }

struct ast_variable* ast_load_realtime_all_fields ( const char *  family,
const struct ast_variable fields 
) [read]

Definition at line 3088 of file main/config.c.

References db, find_engine(), NULL, and ast_config_engine::realtime_func.

Referenced by ast_load_realtime_all(), and ast_load_realtime_fields().

03089 {
03090    struct ast_config_engine *eng;
03091    char db[256];
03092    char table[256];
03093    struct ast_variable *res=NULL;
03094    int i;
03095 
03096    for (i = 1; ; i++) {
03097       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03098          if (eng->realtime_func && (res = eng->realtime_func(db, table, fields))) {
03099             return res;
03100          }
03101       } else {
03102          return NULL;
03103       }
03104    }
03105 
03106    return res;
03107 }

struct ast_variable* ast_load_realtime_fields ( const char *  family,
const struct ast_variable fields 
) [read]

Retrieve realtime configuration.

Parameters:
family which family/config to lookup
This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters.

Note:
Unlike the variables in ast_config, the resulting list of variables MUST be freed with ast_variables_destroy() as there is no container.

The difference between these two calls is that ast_load_realtime excludes fields whose values are NULL, while ast_load_realtime_all loads all columns.

You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 3126 of file main/config.c.

References ast_load_realtime_all_fields(), ast_strlen_zero, ast_variable_destroy(), ast_variable::next, ast_category::prev, and ast_variable::value.

Referenced by ast_load_realtime(), and sorcery_realtime_retrieve_fields().

03127 {
03128    struct ast_variable *res;
03129    struct ast_variable *cur;
03130    struct ast_variable **prev;
03131 
03132    res = ast_load_realtime_all_fields(family, fields);
03133 
03134    /* Filter the list. */
03135    prev = &res;
03136    cur = res;
03137    while (cur) {
03138       if (ast_strlen_zero(cur->value)) {
03139          /* Eliminate empty entries */
03140          struct ast_variable *next;
03141 
03142          next = cur->next;
03143          *prev = next;
03144          ast_variable_destroy(cur);
03145          cur = next;
03146       } else {
03147          /* Make blank entries empty and keep them. */
03148          if (cur->value[0] == ' ' && cur->value[1] == '\0') {
03149             char *vptr = (char *) cur->value;
03150 
03151             vptr[0] = '\0';
03152          }
03153 
03154          prev = &cur->next;
03155          cur = cur->next;
03156       }
03157    }
03158    return res;
03159 }

struct ast_config* ast_load_realtime_multientry ( const char *  family,
  ... 
) [read]

Retrieve realtime configuration.

Parameters:
family which family/config to lookup
This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. Unlike the ast_load_realtime, this function can return more than one entry and is thus stored inside a traditional ast_config structure rather than just returning a linked list of variables.

Returns:
An ast_config with one or more results
Return values:
NULL Error or no results returned
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 3274 of file main/config.c.

References ast_load_realtime_multientry_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by __queues_show(), conf_exec(), find_load_queue_rt_friendly(), find_realtime(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), load_module(), load_realtime_rules(), named_acl_find_realtime(), queues_data_provider_get(), realtime_directory(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), set_member_value(), show_users_realtime(), and update_realtime_members().

03275 {
03276    RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
03277    va_list ap;
03278 
03279    va_start(ap, family);
03280    realtime_arguments_to_fields(ap, &fields);
03281    va_end(ap);
03282 
03283    if (!fields) {
03284       return NULL;
03285    }
03286 
03287    return ast_load_realtime_multientry_fields(family, fields);
03288 }

struct ast_config* ast_load_realtime_multientry_fields ( const char *  family,
const struct ast_variable fields 
) [read]

Retrieve realtime configuration.

Parameters:
family which family/config to lookup
fields list of fields
This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. Unlike the ast_load_realtime, this function can return more than one entry and is thus stored inside a traditional ast_config structure rather than just returning a linked list of variables.

Returns:
An ast_config with one or more results
Return values:
NULL Error or no results returned

Definition at line 3248 of file main/config.c.

References ast_config_destroy(), db, find_engine(), NULL, ast_config_engine::realtime_multi_func, and ast_config::root.

Referenced by ast_load_realtime_multientry(), and sorcery_realtime_retrieve_multiple().

03249 {
03250    struct ast_config_engine *eng;
03251    char db[256];
03252    char table[256];
03253    struct ast_config *res = NULL;
03254    int i;
03255 
03256    for (i = 1; ; i++) {
03257       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03258          if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, fields))) {
03259             /* If we were returned an empty cfg, destroy it and return NULL */
03260             if (!res->root) {
03261                ast_config_destroy(res);
03262                res = NULL;
03263             }
03264             break;
03265          }
03266       } else {
03267          break;
03268       }
03269    }
03270 
03271    return res;
03272 }

int ast_parse_arg ( const char *  arg,
enum ast_parse_flags  flags,
void *  p_result,
  ... 
)

Helper function to parse arguments See documentation in config.h.

The argument parsing routine.

Definition at line 3479 of file main/config.c.

References ahp, ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_skip_blanks(), ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_strdupa, ast_strlen_zero, buf, ERANGE, errno, error(), hp, INT32_MAX, INT32_MIN, NULL, 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_RANGE_DEFAULTS, PARSE_TYPE, PARSE_UINT32, result, strsep(), and UINT32_MAX.

Referenced by __ast_http_load(), __init_manager(), app_exec(), AST_TEST_DEFINE(), ast_tls_read_conf(), build_peer(), build_user(), configure_local_rtp(), double_handler_fn(), general_set(), iax2_call(), iax2_request(), int_handler_fn(), realtime_peer(), reload_config(), rtp_reload(), set_config(), setup_rtp_connection(), setup_rtp_remote(), setup_udptl_connection(), sockaddr_handler_fn(), uint_handler_fn(), and xfer_set().

03481 {
03482    va_list ap;
03483    int error = 0;
03484 
03485    va_start(ap, p_result);
03486    switch (flags & PARSE_TYPE) {
03487    case PARSE_INT32:
03488    {
03489       long int x = 0;
03490       int32_t *result = p_result;
03491       int32_t def = result ? *result : 0, high = INT32_MAX, low = INT32_MIN;
03492       char *endptr = NULL;
03493 
03494       /* optional arguments: default value and/or (low, high) */
03495       if (flags & PARSE_DEFAULT) {
03496          def = va_arg(ap, int32_t);
03497       }
03498       if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
03499          low = va_arg(ap, int32_t);
03500          high = va_arg(ap, int32_t);
03501       }
03502       if (ast_strlen_zero(arg)) {
03503          error = 1;
03504          goto int32_done;
03505       }
03506       errno = 0;
03507       x = strtol(arg, &endptr, 0);
03508       if (*endptr || errno || x < INT32_MIN || x > INT32_MAX) {
03509          /* Parse error, or type out of int32_t bounds */
03510          error = 1;
03511          goto int32_done;
03512       }
03513       error = (x < low) || (x > high);
03514       if (flags & PARSE_RANGE_DEFAULTS) {
03515          if (x < low) {
03516             def = low;
03517          } else if (x > high) {
03518             def = high;
03519          }
03520       }
03521       if (flags & PARSE_OUT_RANGE) {
03522          error = !error;
03523       }
03524 int32_done:
03525       if (result) {
03526          *result  = error ? def : x;
03527       }
03528 
03529       ast_debug(3, "extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
03530             arg, low, high, result ? *result : x, error);
03531       break;
03532    }
03533 
03534    case PARSE_UINT32:
03535    {
03536       unsigned long int x = 0;
03537       uint32_t *result = p_result;
03538       uint32_t def = result ? *result : 0, low = 0, high = UINT32_MAX;
03539       char *endptr = NULL;
03540 
03541       /* optional argument: first default value, then range */
03542       if (flags & PARSE_DEFAULT) {
03543          def = va_arg(ap, uint32_t);
03544       }
03545       if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
03546          /* range requested, update bounds */
03547          low = va_arg(ap, uint32_t);
03548          high = va_arg(ap, uint32_t);
03549       }
03550 
03551       if (ast_strlen_zero(arg)) {
03552          error = 1;
03553          goto uint32_done;
03554       }
03555       /* strtoul will happilly and silently negate negative numbers */
03556       arg = ast_skip_blanks(arg);
03557       if (*arg == '-') {
03558          error = 1;
03559          goto uint32_done;
03560       }
03561       errno = 0;
03562       x = strtoul(arg, &endptr, 0);
03563       if (*endptr || errno || x > UINT32_MAX) {
03564          error = 1;
03565          goto uint32_done;
03566       }
03567       error = (x < low) || (x > high);
03568       if (flags & PARSE_RANGE_DEFAULTS) {
03569          if (x < low) {
03570             def = low;
03571          } else if (x > high) {
03572             def = high;
03573          }
03574       }
03575       if (flags & PARSE_OUT_RANGE) {
03576          error = !error;
03577       }
03578 uint32_done:
03579       if (result) {
03580          *result  = error ? def : x;
03581       }
03582       ast_debug(3, "extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
03583             arg, low, high, result ? *result : x, error);
03584       break;
03585    }
03586 
03587    case PARSE_DOUBLE:
03588    {
03589       double *result = p_result;
03590       double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
03591       char *endptr = NULL;
03592 
03593       /* optional argument: first default value, then range */
03594       if (flags & PARSE_DEFAULT) {
03595          def = va_arg(ap, double);
03596       }
03597       if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
03598          /* range requested, update bounds */
03599          low = va_arg(ap, double);
03600          high = va_arg(ap, double);
03601       }
03602       if (ast_strlen_zero(arg)) {
03603          error = 1;
03604          goto double_done;
03605       }
03606       errno = 0;
03607       x = strtod(arg, &endptr);
03608       if (*endptr || errno == ERANGE) {
03609          error = 1;
03610          goto double_done;
03611       }
03612       error = (x < low) || (x > high);
03613       if (flags & PARSE_OUT_RANGE) {
03614          error = !error;
03615       }
03616 double_done:
03617       if (result) {
03618          *result = error ? def : x;
03619       }
03620       ast_debug(3, "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
03621             arg, low, high, result ? *result : x, error);
03622       break;
03623    }
03624    case PARSE_ADDR:
03625        {
03626       struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result;
03627 
03628       if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) {
03629          error = 1;
03630       }
03631 
03632       ast_debug(3, "extract addr from %s gives %s(%d)\n",
03633            arg, ast_sockaddr_stringify(addr), error);
03634 
03635       break;
03636        }
03637    case PARSE_INADDR:   /* TODO Remove this (use PARSE_ADDR instead). */
03638        {
03639       char *port, *buf;
03640       struct sockaddr_in _sa_buf;   /* buffer for the result */
03641       struct sockaddr_in *sa = p_result ?
03642          (struct sockaddr_in *)p_result : &_sa_buf;
03643       /* default is either the supplied value or the result itself */
03644       struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
03645          va_arg(ap, struct sockaddr_in *) : sa;
03646       struct hostent *hp;
03647       struct ast_hostent ahp;
03648 
03649       memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
03650       /* duplicate the string to strip away the :port */
03651       port = ast_strdupa(arg);
03652       buf = strsep(&port, ":");
03653       sa->sin_family = AF_INET;  /* assign family */
03654       /*
03655        * honor the ports flag setting, assign default value
03656        * in case of errors or field unset.
03657        */
03658       flags &= PARSE_PORT_MASK; /* the only flags left to process */
03659       if (port) {
03660          if (flags == PARSE_PORT_FORBID) {
03661             error = 1;  /* port was forbidden */
03662             sa->sin_port = def->sin_port;
03663          } else if (flags == PARSE_PORT_IGNORE)
03664             sa->sin_port = def->sin_port;
03665          else /* accept or require */
03666             sa->sin_port = htons(strtol(port, NULL, 0));
03667       } else {
03668          sa->sin_port = def->sin_port;
03669          if (flags == PARSE_PORT_REQUIRE)
03670             error = 1;
03671       }
03672       /* Now deal with host part, even if we have errors before. */
03673       hp = ast_gethostbyname(buf, &ahp);
03674       if (hp)  /* resolved successfully */
03675          memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
03676       else {
03677          error = 1;
03678          sa->sin_addr = def->sin_addr;
03679       }
03680       ast_debug(3,
03681          "extract inaddr from [%s] gives [%s:%d](%d)\n",
03682          arg, ast_inet_ntoa(sa->sin_addr),
03683          ntohs(sa->sin_port), error);
03684       break;
03685        }
03686    }
03687    va_end(ap);
03688    return error;
03689 }

static int ast_realtime_append_mapping ( const char *  name,
const char *  driver,
const char *  database,
const char *  table,
int  priority 
) [static]

Definition at line 2697 of file main/config.c.

References ast_calloc, ast_verb, config_maps, ast_config_map::database, ast_config_map::driver, map, ast_config_map::name, ast_config_map::next, ast_config_map::priority, ast_config_map::stuff, and ast_config_map::table.

Referenced by load_module(), and read_config_maps().

02699 {
02700    struct ast_config_map *map;
02701    char *dst;
02702    int length;
02703 
02704    length = sizeof(*map);
02705    length += strlen(name) + 1;
02706    length += strlen(driver) + 1;
02707    length += strlen(database) + 1;
02708    if (table)
02709       length += strlen(table) + 1;
02710 
02711    if (!(map = ast_calloc(1, length)))
02712       return -1;
02713 
02714    dst = map->stuff; /* writable space starts here */
02715    map->name = strcpy(dst, name);
02716    dst += strlen(dst) + 1;
02717    map->driver = strcpy(dst, driver);
02718    dst += strlen(dst) + 1;
02719    map->database = strcpy(dst, database);
02720    if (table) {
02721       dst += strlen(dst) + 1;
02722       map->table = strcpy(dst, table);
02723    }
02724    map->priority = priority;
02725    map->next = config_maps;
02726    config_maps = map;
02727 
02728    ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
02729 
02730    return 0;
02731 }

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.

Parameters:
chunk Data to be decoded
Returns:
The decoded data, in the original buffer
Since:
1.8
Warning:
This function modifies the original buffer

Definition at line 3447 of file main/config.c.

Referenced by realtime_multi_pgsql(), and realtime_pgsql().

03448 {
03449    char *orig = chunk;
03450    for (; *chunk; chunk++) {
03451       if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
03452          sscanf(chunk + 1, "%02hhX", (unsigned char *)chunk);
03453          memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
03454       }
03455    }
03456    return orig;
03457 }

int ast_realtime_enabled ( void   ) 

Check if there's any realtime engines loaded.

Definition at line 3199 of file main/config.c.

References config_maps.

Referenced by action_coresettings(), ast_check_realtime(), and handle_show_settings().

03200 {
03201    return config_maps ? 1 : 0;
03202 }

char* ast_realtime_encode_chunk ( struct ast_str **  dest,
ssize_t  maxlen,
const char *  chunk 
)

Encodes a chunk of data for realtime.

Parameters:
dest Destination buffer
maxlen Length passed through to ast_str_* functions
chunk Source data to be encoded
Returns:
Buffer within dest
Since:
1.8

Definition at line 3459 of file main/config.c.

References ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_set().

03460 {
03461    if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
03462       ast_str_set(dest, maxlen, "%s", chunk);
03463    } else {
03464       ast_str_reset(*dest);
03465       for (; *chunk; chunk++) {
03466          if (strchr(";^", *chunk)) {
03467             ast_str_append(dest, maxlen, "^%02hhX", *chunk);
03468          } else {
03469             ast_str_append(dest, maxlen, "%c", *chunk);
03470          }
03471       }
03472    }
03473    return ast_str_buffer(*dest);
03474 }

int ast_realtime_is_mapping_defined ( const char *  family  ) 

Determine if a mapping exists for a given family.

Parameters:
family which family you are looking to see if a mapping exists for
Return values:
1 if it is mapped
0 if it is not

Definition at line 2849 of file main/config.c.

References config_lock, config_maps, lock, map, ast_config_map::name, ast_config_map::next, and SCOPED_MUTEX.

Referenced by ast_named_acl_find(), and sorcery_realtime_open().

02850 {
02851    struct ast_config_map *map;
02852    SCOPED_MUTEX(lock, &config_lock);
02853 
02854    for (map = config_maps; map; map = map->next) {
02855       if (!strcasecmp(family, map->name)) {
02856          return 1;
02857       }
02858    }
02859 
02860    return 0;
02861 }

int ast_realtime_require_field ( const char *  family,
  ... 
)

Inform realtime what fields that may be stored.

Since:
1.6.1
Parameters:
family which family/config is referenced
This will inform builtin configuration backends that particular fields may be updated during the use of that configuration section. This is mainly to be used during startup routines, to ensure that various fields exist in the backend. The backends may take various actions, such as creating new fields in the data store or warning the administrator that new fields may need to be created, in order to ensure proper function.

The arguments are specified in groups of 3: column name, column type, and column size. The column types are specified as integer constants, defined by the enum require_type. Note that the size is specified as the number of equivalent character fields that a field may take up, even if a field is otherwise specified as an integer type. This is due to the fact that some fields have historically been specified as character types, even if they contained integer values.

A family should always specify its fields to the minimum necessary requirements to fulfill all possible values (within reason; for example, a timeout value may reasonably be specified as an INTEGER2, with size 5. Even though values above 32767 seconds are possible, they are unlikely to be useful, and we should not complain about that size).

Return values:
0 Required fields met specified standards
-1 One or more fields was missing or insufficient
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 3204 of file main/config.c.

References db, find_engine(), and ast_config_engine::require_func.

Referenced by ast_queue_log(), change_password_realtime(), conf_run(), load_module(), and logger_queue_rt_start().

03205 {
03206    struct ast_config_engine *eng;
03207    char db[256];
03208    char table[256];
03209    va_list ap;
03210    int res = -1, i;
03211 
03212    va_start(ap, family);
03213    for (i = 1; ; i++) {
03214       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03215          /* If the require succeeds, it returns 0. */
03216          if (eng->require_func && !(res = eng->require_func(db, table, ap))) {
03217             break;
03218          }
03219       } else {
03220          break;
03221       }
03222    }
03223    va_end(ap);
03224 
03225    return res;
03226 }

int ast_store_realtime ( const char *  family,
  ... 
)

Create realtime configuration.

Parameters:
family which family/config to be created
This function is used to create a parameter in realtime configuration space.

Returns:
Number of rows affected, or -1 on error.
Note:
On the MySQL engine only, for reasons of backwards compatibility, the return value is the insert ID. This value is nonportable and may be changed in a future version to match the other engines.

You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 3392 of file main/config.c.

References ast_store_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by ast_queue_log(), cli_realtime_store(), copy_plain_file(), function_realtime_store(), leave_voicemail(), and msg_create_from_file().

03393 {
03394    RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
03395    va_list ap;
03396 
03397    va_start(ap, family);
03398    realtime_arguments_to_fields(ap, &fields);
03399    va_end(ap);
03400 
03401    if (!fields) {
03402       return -1;
03403    }
03404 
03405    return ast_store_realtime_fields(family, fields);
03406 }

int ast_store_realtime_fields ( const char *  family,
const struct ast_variable fields 
)

Create realtime configuration.

Parameters:
family which family/config to be created
fields fields themselves
This function is used to create a parameter in realtime configuration space.

Returns:
Number of rows affected, or -1 on error.
Note:
On the MySQL engine only, for reasons of backwards compatibility, the return value is the insert ID. This value is nonportable and may be changed in a future version to match the other engines.

Definition at line 3371 of file main/config.c.

References db, find_engine(), and ast_config_engine::store_func.

Referenced by ast_store_realtime(), and sorcery_realtime_create().

03372 {
03373    struct ast_config_engine *eng;
03374    int res = -1, i;
03375    char db[256];
03376    char table[256];
03377 
03378    for (i = 1; ; i++) {
03379       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03380          /* If the store succeeds, it returns >= 0*/
03381          if (eng->store_func && ((res = eng->store_func(db, table, fields)) >= 0)) {
03382             break;
03383          }
03384       } else {
03385          break;
03386       }
03387    }
03388 
03389    return res;
03390 }

int ast_unload_realtime ( const char *  family  ) 

Release any resources cached for a realtime family.

Since:
1.6.1
Parameters:
family which family/config to destroy
Various backends may cache attributes about a realtime data storage facility; on reload, a front end resource may request to purge that cache.

Return values:
0 If any cache was purged
-1 If no cache was found

Definition at line 3228 of file main/config.c.

References db, find_engine(), and ast_config_engine::unload_func.

Referenced by __unload_module(), load_config(), logger_queue_init(), reload(), reload_config(), reload_logger(), and unload_module().

03229 {
03230    struct ast_config_engine *eng;
03231    char db[256];
03232    char table[256];
03233    int res = -1, i;
03234 
03235    for (i = 1; ; i++) {
03236       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03237          if (eng->unload_func) {
03238             /* Do this for ALL engines */
03239             res = eng->unload_func(db, table);
03240          }
03241       } else {
03242          break;
03243       }
03244    }
03245    return res;
03246 }

int ast_update2_realtime ( const char *  family,
  ... 
)

Update realtime configuration.

Parameters:
family which family/config to be updated
This function is used to update a parameter in realtime configuration space. It includes the ability to lookup a row based upon multiple key criteria. As a result, this function includes two sentinel values, one to terminate lookup values and the other to terminate the listing of fields to update.

Returns:
Number of rows affected, or -1 on error.
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 3347 of file main/config.c.

References ast_update2_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, realtime_arguments_to_fields, and realtime_arguments_to_fields2().

Referenced by change_password_realtime(), and cli_realtime_update2().

03348 {
03349    RAII_VAR(struct ast_variable *, lookup_fields, NULL, ast_variables_destroy);
03350    RAII_VAR(struct ast_variable *, update_fields, NULL, ast_variables_destroy);
03351    va_list ap;
03352 
03353    va_start(ap, family);
03354    /* XXX: If we wanted to pass no lookup fields (select all), we'd be
03355     * out of luck. realtime_arguments_to_fields expects at least one key
03356     * value pair. */
03357    realtime_arguments_to_fields(ap, &lookup_fields);
03358    va_end(ap);
03359 
03360    va_start(ap, family);
03361    realtime_arguments_to_fields2(ap, 1, &update_fields);
03362    va_end(ap);
03363 
03364    if (!lookup_fields || !update_fields) {
03365       return -1;
03366    }
03367 
03368    return ast_update2_realtime_fields(family, lookup_fields, update_fields);
03369 }

int ast_update2_realtime_fields ( const char *  family,
const struct ast_variable lookup_fields,
const struct ast_variable update_fields 
)

Update realtime configuration.

Parameters:
family which family/config to be updated
lookup_fields fields used to look up entries
update_fields fields to update
This function is used to update a parameter in realtime configuration space. It includes the ability to lookup a row based upon multiple key criteria. As a result, this function includes two sentinel values, one to terminate lookup values and the other to terminate the listing of fields to update.

Returns:
Number of rows affected, or -1 on error.

Definition at line 3327 of file main/config.c.

References db, find_engine(), and ast_config_engine::update2_func.

Referenced by ast_update2_realtime().

03328 {
03329    struct ast_config_engine *eng;
03330    int res = -1, i;
03331    char db[256];
03332    char table[256];
03333 
03334    for (i = 1; ; i++) {
03335       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03336          if (eng->update2_func && !(res = eng->update2_func(db, table, lookup_fields, update_fields))) {
03337             break;
03338          }
03339       } else {
03340          break;
03341       }
03342    }
03343 
03344    return res;
03345 }

int ast_update_realtime ( const char *  family,
const char *  keyfield,
const char *  lookup,
  ... 
)

Update realtime configuration.

Parameters:
family which family/config to be updated
keyfield which field to use as the key
lookup which value to look for in the key field to match the entry.
This function is used to update a parameter in realtime configuration space.

Returns:
Number of rows affected, or -1 on error.
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 3311 of file main/config.c.

References ast_update_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), handle_response_peerpoke(), leave_voicemail(), realtime_update_peer(), rename_file(), rt_extend_conf(), sip_poke_noanswer(), and update_realtime_member_field().

03312 {
03313    RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
03314    va_list ap;
03315 
03316    va_start(ap, lookup);
03317    realtime_arguments_to_fields(ap, &fields);
03318    va_end(ap);
03319 
03320    if (!fields) {
03321       return -1;
03322    }
03323 
03324    return ast_update_realtime_fields(family, keyfield, lookup, fields);
03325 }

int ast_update_realtime_fields ( const char *  family,
const char *  keyfield,
const char *  lookup,
const struct ast_variable fields 
)

Update realtime configuration.

Parameters:
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.
fields fields to update
This function is used to update a parameter in realtime configuration space.

Returns:
Number of rows affected, or -1 on error.

Definition at line 3290 of file main/config.c.

References db, find_engine(), and ast_config_engine::update_func.

Referenced by ast_update_realtime(), and sorcery_realtime_update().

03291 {
03292    struct ast_config_engine *eng;
03293    int res = -1, i;
03294    char db[256];
03295    char table[256];
03296 
03297    for (i = 1; ; i++) {
03298       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
03299          /* If the update succeeds, it returns >= 0. */
03300          if (eng->update_func && ((res = eng->update_func(db, table, keyfield, lookup, fields)) >= 0)) {
03301             break;
03302          }
03303       } else {
03304          break;
03305       }
03306    }
03307 
03308    return res;
03309 }

void ast_variable_append ( struct ast_category category,
struct ast_variable variable 
)

struct ast_variable* ast_variable_browse ( const struct ast_config config,
const char *  category 
) [read]

Definition at line 604 of file main/config.c.

References ast_category_get(), ast_config::last_browse, ast_category::name, NULL, and ast_category::root.

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_sorcery_apply_config(), __init_manager(), _dsp_init(), aco_process_category_options(), actual_load_config(), adsi_load(), ast_cli_perms_init(), ast_plc_reload(), ast_readconfig(), AST_TEST_DEFINE(), ast_variable_retrieve(), build_calendar(), build_device(), caldav_load_calendar(), conf_exec(), config_load(), config_module(), do_reload(), do_say(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), get_defaults(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), load_common(), load_config(), load_general_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), mbl_load_adapter(), mbl_load_config(), mbl_load_device(), misdn_cfg_init(), my_load_module(), new_realtime_sqlite3_db(), odbc_load_module(), osp_create_provider(), parse_config(), parse_tone_zone(), pbx_load_config(), process_my_load_module(), read_config_maps(), realtime_directory(), 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(), tds_load_module(), and test_config_validity().

00605 {
00606    struct ast_category *cat;
00607 
00608    if (config->last_browse && (config->last_browse->name == category)) {
00609       cat = config->last_browse;
00610    } else {
00611       cat = ast_category_get(config, category, NULL);
00612    }
00613 
00614    return (cat) ? cat->root : NULL;
00615 }

int ast_variable_delete ( struct ast_category category,
const char *  variable,
const char *  match,
const char *  line 
)

Definition at line 1273 of file main/config.c.

References ast_strlen_zero, ast_variable_destroy(), ast_category::last, ast_variable::name, ast_variable::next, NULL, ast_category::prev, ast_category::root, and ast_variable::value.

Referenced by handle_updates().

01274 {
01275    struct ast_variable *cur, *prev=NULL, *curn;
01276    int res = -1;
01277    int num_item = 0;
01278    int req_item;
01279 
01280    req_item = -1;
01281    if (!ast_strlen_zero(line)) {
01282       /* Requesting to delete by item number. */
01283       if (sscanf(line, "%30d", &req_item) != 1
01284          || req_item < 0) {
01285          /* Invalid item number to delete. */
01286          return -1;
01287       }
01288    }
01289 
01290    prev = NULL;
01291    cur = category->root;
01292    while (cur) {
01293       curn = cur->next;
01294       /* Delete by item number or by variable name with optional value. */
01295       if ((0 <= req_item && num_item == req_item)
01296          || (req_item < 0 && !strcasecmp(cur->name, variable)
01297             && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
01298          if (prev) {
01299             prev->next = cur->next;
01300             if (cur == category->last)
01301                category->last = prev;
01302          } else {
01303             category->root = cur->next;
01304             if (cur == category->last)
01305                category->last = NULL;
01306          }
01307          ast_variable_destroy(cur);
01308          res = 0;
01309       } else
01310          prev = cur;
01311 
01312       cur = curn;
01313       ++num_item;
01314    }
01315    return res;
01316 }

static void ast_variable_destroy ( struct ast_variable doomed  )  [static]

const char* ast_variable_find ( const struct ast_category category,
const char *  variable 
)

Gets a variable from a specific category structure.

Parameters:
category category structure under which the variable lies
variable which variable you wish to get the data for
Goes through a given category and searches for the given variable

Return values:
The variable value on success
NULL if unable to find it.

Definition at line 721 of file main/config.c.

References ast_variable_find_in_list(), and ast_category::root.

Referenced by AST_TEST_DEFINE(), and ast_variable_retrieve_filtered().

00722 {
00723    return ast_variable_find_in_list(category->root, variable);
00724 }

const char* ast_variable_find_in_list ( const struct ast_variable list,
const char *  variable 
)

Gets a variable from a variable list.

Parameters:
list variable list to search
variable which variable you wish to get the data for
Goes through a given variable list and searches for the given variable

Return values:
The variable value on success
NULL if unable to find it.

Definition at line 726 of file main/config.c.

References ast_variable::name, ast_variable::next, NULL, and ast_variable::value.

Referenced by ast_sorcery_changeset_create(), ast_variable_find(), handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), is_variable_true(), and wizard_apply_handler().

00727 {
00728    const struct ast_variable *v;
00729 
00730    for (v = list; v; v = v->next) {
00731       if (!strcasecmp(variable, v->name)) {
00732          return v->value;
00733       }
00734    }
00735    return NULL;
00736 }

void ast_variable_insert ( struct ast_category category,
struct ast_variable variable,
const char *  line 
)

Definition at line 503 of file main/config.c.

References ast_variable::next, and ast_category::root.

Referenced by AST_TEST_DEFINE(), and handle_updates().

00504 {
00505    struct ast_variable *cur = category->root;
00506    int lineno;
00507    int insertline;
00508 
00509    if (!variable || sscanf(line, "%30d", &insertline) != 1) {
00510       return;
00511    }
00512    if (!insertline) {
00513       variable->next = category->root;
00514       category->root = variable;
00515    } else {
00516       for (lineno = 1; lineno < insertline; lineno++) {
00517          cur = cur->next;
00518          if (!cur->next) {
00519             break;
00520          }
00521       }
00522       variable->next = cur->next;
00523       cur->next = variable;
00524    }
00525 }

struct ast_variable* ast_variable_list_append_hint ( struct ast_variable **  head,
struct ast_variable search_hint,
struct ast_variable new_var 
) [read]

Appends a variable list to the end of another list.

Parameters:
head A pointer to an ast_variable * of the existing variable list head. May NOT be NULL but the content may be to initialize a new list. If so, upon return, this parameter will be updated with a pointer to the new list head.
search_hint The place in the current list to start searching for the end of the list. Might help performance on longer lists. If NULL, it defaults to head.
new_var The head of the new variable list to be appended
Returns:
The tail of the resulting list.
Note:
If the existing *head is NULL, it will be updated to new_var. This allows you to call ast_variable_list_append in a loop or callback without initializing the list first.

Definition at line 650 of file main/config.c.

References ast_assert, ast_variable::next, and NULL.

Referenced by ast_sorcery_objectset_create2().

00651 {
00652    struct ast_variable *curr;
00653    ast_assert(head != NULL);
00654 
00655    if (!*head) {
00656       *head = newvar;
00657    } else {
00658       if (search_hint == NULL) {
00659          search_hint = *head;
00660       }
00661       for (curr = search_hint; curr->next; curr = curr->next);
00662       curr->next = newvar;
00663    }
00664 
00665    for (curr = newvar; curr->next; curr = curr->next);
00666 
00667    return curr;
00668 }

struct ast_variable* ast_variable_list_sort ( struct ast_variable head  )  [read]

Performs an in-place sort on the variable list by ascending name.

Parameters:
head The variable list head
Returns:
The new list head

Definition at line 624 of file main/config.c.

References ast_variable::name, ast_variable::next, NULL, and variable_list_switch().

Referenced by ast_sip_cli_print_sorcery_objectset().

00625 {
00626    struct ast_variable *p, *q;
00627    struct ast_variable top;
00628    int changed = 1;
00629    memset(&top, 0, sizeof(top));
00630    top.next = start;
00631    if (start != NULL && start->next != NULL) {
00632       while (changed) {
00633          changed = 0;
00634          q = &top;
00635          p = top.next;
00636          while (p->next != NULL) {
00637             if (p->next != NULL && strcmp(p->name, p->next->name) > 0) {
00638                q->next = variable_list_switch(p, p->next);
00639                changed = 1;
00640             }
00641             q = p;
00642             if (p->next != NULL)
00643                p = p->next;
00644          }
00645       }
00646    }
00647    return top.next;
00648 }

static void ast_variable_move ( struct ast_variable dst_var,
struct ast_variable src_var 
) [static]

Definition at line 326 of file main/config.c.

References ast_variable::blanklines, ast_variable::lineno, NULL, ast_variable::object, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.

Referenced by ast_include_rename(), and ast_variable_update().

00327 {
00328    dst_var->lineno = src_var->lineno;
00329    dst_var->object = src_var->object;
00330    dst_var->blanklines = src_var->blanklines;
00331    dst_var->precomments = src_var->precomments;
00332    src_var->precomments = NULL;
00333    dst_var->sameline = src_var->sameline;
00334    src_var->sameline = NULL;
00335    dst_var->trailing = src_var->trailing;
00336    src_var->trailing = NULL;
00337 }

struct ast_variable* ast_variable_new ( const char *  name,
const char *  value,
const char *  filename 
) [read]

Definition at line 285 of file main/config.c.

References __ast_calloc(), ast_calloc, ast_variable::file, MIN_VARIABLE_FNAME_SPACE, ast_variable::name, ast_variable::stuff, and ast_variable::value.

Referenced by __init_manager(), aco_set_defaults(), add_cfg_entry(), add_message_id(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), announce_to_dial(), append_row_to_cfg(), apply_outgoing(), ast_ari_invoke(), ast_channeltype_list(), ast_http_get_post_vars(), ast_include_rename(), ast_json_to_ast_variables(), ast_sorcery_changeset_create(), ast_sorcery_object_set_extended(), AST_TEST_DEFINE(), ast_variable_update(), ast_variables_dup(), build_calendar(), build_cfg(), build_user(), check_access(), config_curl(), config_ldap(), config_mysql(), config_odbc(), config_pgsql(), contact_to_var_list(), copy_vars(), create_vmaccount(), dup_vars(), fields_handler(), get_single_field_as_var_list(), handle_registrations(), handle_updates(), handle_uri(), http_request_headers_get(), iax_parse_ies(), jack_handler(), ldap_table_config_add_attribute(), localnet_to_vl(), man_do_variable_value(), manager_sipnotify(), match_to_var_list(), mkintf(), object_type_loaded_observer(), outbound_auths_to_var_list(), parse_cookies(), process_dahdi(), process_text_line(), realtime_arguments_to_fields(), realtime_arguments_to_fields2(), realtime_curl(), realtime_directory(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_multi_curl(), realtime_multi_mysql(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_mysql(), realtime_odbc(), realtime_pgsql(), realtime_sorcery_update(), resource_event_handler(), row_to_varlist(), set_var_handler(), sip_cli_notify(), sorcery_config_open(), sorcery_json_to_objectset(), sorcery_realtime_create(), sorcery_realtime_retrieve_id(), sorcery_realtime_retrieve_multiple(), sorcery_realtime_retrieve_regex(), static_realtime_cb(), test_sorcery_copy(), test_sorcery_diff(), test_sorcery_regex_fields(), test_sorcery_transform(), variable_clone(), variable_list_append(), verify_user_event_fields(), vm_change_password(), and write_password_to_file().

00287 {
00288    struct ast_variable *variable;
00289    int name_len = strlen(name) + 1;
00290    int val_len = strlen(value) + 1;
00291    int fn_len = strlen(filename) + 1;
00292 
00293    /* Ensure a minimum length in case the filename is changed later. */
00294    if (fn_len < MIN_VARIABLE_FNAME_SPACE) {
00295       fn_len = MIN_VARIABLE_FNAME_SPACE;
00296    }
00297 
00298    if (
00299 #ifdef MALLOC_DEBUG
00300       (variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable), file, lineno, func))
00301 #else
00302       (variable = ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable)))
00303 #endif
00304       ) {
00305       char *dst = variable->stuff;  /* writable space starts here */
00306 
00307       /* Put file first so ast_include_rename() can calculate space available. */
00308       variable->file = strcpy(dst, filename);
00309       dst += fn_len;
00310       variable->name = strcpy(dst, name);
00311       dst += name_len;
00312       variable->value = strcpy(dst, value);
00313    }
00314    return variable;
00315 }

const char* ast_variable_retrieve ( struct ast_config config,
const char *  category,
const char *  variable 
)

Definition at line 680 of file main/config.c.

References ast_variable_browse(), ast_variable::name, ast_category::next, ast_variable::next, NULL, ast_category::root, ast_config::root, and ast_variable::value.

Referenced by __init_manager(), actual_load_config(), advanced_options(), ast_config_option(), AST_TEST_DEFINE(), conf_exec(), config_module(), directory_exec(), festival_exec(), find_realtime(), forward_message(), get_defaults(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), iax_template_parse(), init_acf_query(), init_logger_chain(), initialize_cc_devstate_map_helper(), initialize_cc_max_requests(), internal_aco_type_find(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), load_mysql_config(), load_realtime_rules(), load_tech_calendars(), load_users(), make_email_file(), mbl_load_adapter(), mbl_load_device(), message_range_and_existence_check(), my_load_config_number(), my_load_config_string(), named_acl_find_realtime(), notify_new_message(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), process_my_load_module(), queue_rules_set_global_params(), queue_set_global_params(), read_password_from_file(), realtime_directory(), realtime_is_object_matching(), reload_config(), reload_followme(), reload_single_queue(), rt_handle_member_record(), rtp_reload(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), and vm_msg_snapshot_create().

00681 {
00682    struct ast_variable *v;
00683 
00684    if (category) {
00685       for (v = ast_variable_browse(config, category); v; v = v->next) {
00686          if (!strcasecmp(variable, v->name)) {
00687             return v->value;
00688          }
00689       }
00690    } else {
00691       struct ast_category *cat;
00692 
00693       for (cat = config->root; cat; cat = cat->next) {
00694          for (v = cat->root; v; v = v->next) {
00695             if (!strcasecmp(variable, v->name)) {
00696                return v->value;
00697             }
00698          }
00699       }
00700    }
00701 
00702    return NULL;
00703 }

const char* ast_variable_retrieve_filtered ( struct ast_config config,
const char *  category,
const char *  variable,
const char *  filter 
)

Gets a variable by context and variable names.

Parameters:
config which (opened) config to use
category category under which the variable lies
variable which variable you wish to get the data for
filter an optional comma-separated list of <name_regex>=<value_regex> pairs. Only categories with matching variables will be searched. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.
Return values:
The variable value on success
NULL if unable to find it.

Definition at line 705 of file main/config.c.

References ast_category_browse_filtered(), ast_variable_find(), and NULL.

00707 {
00708    struct ast_category *cat = NULL;
00709    const char *value;
00710 
00711    while ((cat = ast_category_browse_filtered(config, category, cat, filter))) {
00712       value = ast_variable_find(cat, variable);
00713       if (value) {
00714          return value;
00715       }
00716    }
00717 
00718    return NULL;
00719 }

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.

Parameters:
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
Returns:
0 on success or -1 on failure.

Definition at line 1318 of file main/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, NULL, ast_category::prev, ast_category::root, and ast_variable::value.

Referenced by handle_updates(), process_text_line(), vm_change_password(), and vm_forwardoptions().

01320 {
01321    struct ast_variable *cur, *prev=NULL, *newer=NULL;
01322 
01323    for (cur = category->root; cur; prev = cur, cur = cur->next) {
01324       if (strcasecmp(cur->name, variable) ||
01325          (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
01326          continue;
01327 
01328       if (!(newer = ast_variable_new(variable, value, cur->file)))
01329          return -1;
01330 
01331       ast_variable_move(newer, cur);
01332       newer->object = newer->object || object;
01333 
01334       /* Replace the old node in the list with the new node. */
01335       newer->next = cur->next;
01336       if (prev)
01337          prev->next = newer;
01338       else
01339          category->root = newer;
01340       if (category->last == cur)
01341          category->last = newer;
01342 
01343       ast_variable_destroy(cur);
01344 
01345       return 0;
01346    }
01347 
01348    /* Could not find variable to update */
01349    return -1;
01350 }

void ast_variables_destroy ( struct ast_variable v  ) 

Free variable list.

Parameters:
var the linked list of variables to free
This function frees a list of variables.

Definition at line 593 of file main/config.c.

References ast_variable_destroy(), free, and ast_variable::next.

Referenced by __init_manager(), __sip_destroy(), aco_set_defaults(), action_messagesend(), action_originate(), add_message_id(), announce_to_dial(), ast_ari_callback(), ast_ari_channels_originate(), ast_ari_channels_originate_with_id(), ast_ari_endpoints_send_message(), ast_ari_endpoints_send_message_to_endpoint(), ast_ari_invoke(), ast_category_destroy(), ast_category_empty(), ast_config_destroy(), ast_destroy_realtime(), ast_http_get_cookies(), ast_http_manid_from_vars(), ast_json_to_ast_variables(), ast_load_realtime(), ast_load_realtime_all(), ast_load_realtime_multientry(), ast_sip_cli_print_sorcery_objectset(), ast_sip_sorcery_object_to_ami(), ast_sorcery_changeset_create(), ast_sorcery_copy(), ast_sorcery_diff(), ast_sorcery_object_set_extended(), ast_sorcery_objectset_apply(), ast_sorcery_objectset_json_create(), ast_store_realtime(), AST_TEST_DEFINE(), ast_update2_realtime(), ast_update_realtime(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variables_dup(), auth_http_callback(), build_gateway(), build_peer(), calendar_destructor(), can_reuse_registration(), check_peer_ok(), cli_realtime_load(), conf_run(), copy_plain_file(), destroy_dahdi_pvt(), destroy_endpoint(), destroy_fast_originate_helper(), dup_vars(), endpoint_destructor(), fields_handler(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_realtime_gw(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), generic_http_callback(), get_insecure_variable_from_sipregs(), get_multiple_fields_as_var_list(), get_object_variables(), handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), handle_uri(), http_request_headers_get(), httpd_process_request(), httpstatus_callback(), ldap_loadentry(), leave_queue(), local_ast_moh_start(), manager_free_user(), manager_notify_endpoint(), manager_notify_uri(), manager_sipnotify(), mkintf(), notify_ami_data_destroy(), notify_ami_uri_data_destroy(), object_type_loaded_observer(), pjsip_aor_function_read(), pjsip_contact_function_read(), pjsip_endpoint_function_read(), process_dahdi(), publication_resource_destroy(), pvt_destructor(), queue_function_queuegetchannel(), queue_function_queuewaitingcount(), realtime_arguments_to_fields(), realtime_arguments_to_fields2(), realtime_canmatch(), realtime_common(), realtime_exec(), realtime_exists(), realtime_handler(), realtime_ldap_base(), 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(), realtimefield_read(), row_to_varlist(), rt_extend_conf(), session_destructor(), sip_aor_to_ami(), sip_destroy_peer(), socket_process_helper(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_regex(), sorcery_config_destructor(), sorcery_config_fields_cmp(), sorcery_function_read(), sorcery_is_criteria_met(), sorcery_json_to_objectset(), sorcery_memory_fields_cmp(), sorcery_object_destructor(), sorcery_realtime_create(), sorcery_realtime_filter_objectset(), sorcery_realtime_retrieve_fields(), sorcery_realtime_retrieve_id(), sorcery_realtime_retrieve_multiple(), sorcery_realtime_retrieve_regex(), sorcery_realtime_update(), table_configs_free(), test_sorcery_object_destroy(), test_sorcery_transform(), and user_destructor().

00594 {
00595    struct ast_variable *vn;
00596 
00597    while (v) {
00598       vn = v;
00599       v = v->next;
00600       ast_variable_destroy(vn);
00601    }
00602 }

struct ast_variable* ast_variables_dup ( struct ast_variable var  )  [read]

Duplicate variable list.

Parameters:
var the linked list of variables to clone
Returns:
A duplicated list which you'll need to free with ast_variables_destroy or NULL when out of memory.
Note:
Do not depend on this to copy more than just name, value and filename (the arguments to ast_variables_new).

Definition at line 547 of file main/config.c.

References ast_variable_new(), ast_variables_destroy(), ast_variable::file, ast_variable::name, ast_variable::next, NULL, tmp(), and ast_variable::value.

Referenced by action_originate(), ast_ari_callback(), ast_config_copy(), authenticate(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), handle_registrations(), jim_handler(), jim_vl(), realtime_sorcery(), realtime_sorcery_multi(), realtime_sorcery_store(), realtime_sorcery_update(), set_var_to_vl(), and sorcery_extended_fields_handler().

00548 {
00549    struct ast_variable *cloned;
00550    struct ast_variable *tmp;
00551 
00552    if (!(cloned = ast_variable_new(var->name, var->value, var->file))) {
00553       return NULL;
00554    }
00555 
00556    tmp = cloned;
00557 
00558    while ((var = var->next)) {
00559       if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) {
00560          ast_variables_destroy(cloned);
00561          return NULL;
00562       }
00563       tmp = tmp->next;
00564    }
00565 
00566    return cloned;
00567 }

struct ast_variable* ast_variables_reverse ( struct ast_variable var  )  [read]

Reverse a variable list.

Parameters:
var the linked list of variables to reverse
Returns:
The head of the reversed variable list
Note:
The variable list var is not preserved in this function and should not be used after reversing it.

Definition at line 569 of file main/config.c.

References ast_variable::next, and NULL.

Referenced by astman_get_variables_order().

00570 {
00571    struct ast_variable *var1, *var2;
00572 
00573    var1 = var;
00574 
00575    if (!var1 || !var1->next) {
00576       return var1;
00577    }
00578 
00579    var2 = var1->next;
00580    var1->next = NULL;
00581 
00582    while (var2) {
00583       struct ast_variable *next = var2->next;
00584 
00585       var2->next = var1;
00586       var1 = var2;
00587       var2 = next;
00588    }
00589 
00590    return var1;
00591 }

static void CB_ADD ( struct ast_str **  cb,
const char *  str 
) [static]

Definition at line 123 of file main/config.c.

References ast_str_append().

Referenced by config_text_file_load().

00124 {
00125    ast_str_append(cb, 0, "%s", str);
00126 }

static void CB_ADD_LEN ( struct ast_str **  cb,
const char *  str,
int  len 
) [static]

Definition at line 128 of file main/config.c.

References ast_alloca, and ast_str_append().

Referenced by config_text_file_load().

00129 {
00130    char *s = ast_alloca(len + 1);
00131 
00132    memcpy(s, str, len);
00133    s[len] = '\0';
00134    ast_str_append(cb, 0, "%s", s);
00135 }

static void CB_RESET ( struct ast_str cb,
struct ast_str llb 
) [static]

Definition at line 137 of file main/config.c.

References ast_str_reset().

Referenced by config_text_file_load(), and process_text_line().

00138 {
00139    if (cb) {
00140       ast_str_reset(cb);
00141    }
00142    if (llb) {
00143       ast_str_reset(llb);
00144    }
00145 }

static int cfmstat_cmp ( struct cache_file_mtime cfmtime,
struct stat *  statbuf 
) [static]

Definition at line 1492 of file main/config.c.

References cfmstat_save(), cache_file_mtime::stat_mtime, cache_file_mtime::stat_mtime_nsec, and cache_file_mtime::stat_size.

Referenced by config_text_file_load().

01493 {
01494    struct cache_file_mtime cfm_buf;
01495 
01496    cfmstat_save(&cfm_buf, statbuf);
01497 
01498    return cfmtime->stat_size != cfm_buf.stat_size
01499       || cfmtime->stat_mtime != cfm_buf.stat_mtime
01500       || cfmtime->stat_mtime_nsec != cfm_buf.stat_mtime_nsec;
01501 }

static void cfmstat_save ( struct cache_file_mtime cfmtime,
struct stat *  statbuf 
) [static]

Definition at line 1468 of file main/config.c.

References cache_file_mtime::stat_mtime, cache_file_mtime::stat_mtime_nsec, and cache_file_mtime::stat_size.

Referenced by cfmstat_cmp(), and config_text_file_load().

01469 {
01470    cfmtime->stat_size = statbuf->st_size;
01471 #if defined(HAVE_STRUCT_STAT_ST_MTIM)
01472    cfmtime->stat_mtime_nsec = statbuf->st_mtim.tv_nsec;
01473 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
01474    cfmtime->stat_mtime_nsec = statbuf->st_mtimensec;
01475 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
01476    cfmtime->stat_mtime_nsec = statbuf->st_mtimespec.tv_nsec;
01477 #else
01478    cfmtime->stat_mtime_nsec = 0;
01479 #endif
01480    cfmtime->stat_mtime = statbuf->st_mtime;
01481 }

static struct cache_file_mtime* cfmtime_new ( const char *  filename,
const char *  who_asked 
) [static, read]

Definition at line 1436 of file main/config.c.

References ast_calloc, cache_file_mtime::filename, NULL, and cache_file_mtime::who_asked.

Referenced by config_cache_attribute(), and config_text_file_load().

01437 {
01438    struct cache_file_mtime *cfmtime;
01439    char *dst;
01440 
01441    cfmtime = ast_calloc(1,
01442       sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
01443    if (!cfmtime) {
01444       return NULL;
01445    }
01446    dst = cfmtime->filename;   /* writable space starts here */
01447    strcpy(dst, filename); /* Safe */
01448    dst += strlen(dst) + 1;
01449    cfmtime->who_asked = strcpy(dst, who_asked); /* Safe */
01450 
01451    return cfmtime;
01452 }

static void clear_config_maps ( void   )  [static]

Definition at line 2681 of file main/config.c.

References ast_free, config_lock, config_maps, lock, map, ast_config_map::next, and SCOPED_MUTEX.

Referenced by read_config_maps().

02682 {
02683    struct ast_config_map *map;
02684 
02685    SCOPED_MUTEX(lock, &config_lock);
02686 
02687    while (config_maps) {
02688       map = config_maps;
02689       config_maps = config_maps->next;
02690       ast_free(map);
02691    }
02692 }

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 1564 of file main/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, and cache_file_mtime::who_asked.

Referenced by process_text_line().

01565 {
01566    struct cache_file_mtime *cfmtime;
01567    struct cache_file_include *cfinclude;
01568 
01569    /* Find our cached entry for this configuration file */
01570    AST_LIST_LOCK(&cfmtime_head);
01571    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
01572       if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
01573          break;
01574    }
01575    if (!cfmtime) {
01576       cfmtime = cfmtime_new(configfile, who_asked);
01577       if (!cfmtime) {
01578          AST_LIST_UNLOCK(&cfmtime_head);
01579          return;
01580       }
01581       /* Note that the file mtime is initialized to 0, i.e. 1970 */
01582       AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
01583    }
01584 
01585    switch (attrtype) {
01586    case ATTRIBUTE_INCLUDE:
01587       AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
01588          if (!strcmp(cfinclude->include, filename)) {
01589             AST_LIST_UNLOCK(&cfmtime_head);
01590             return;
01591          }
01592       }
01593       cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
01594       if (!cfinclude) {
01595          AST_LIST_UNLOCK(&cfmtime_head);
01596          return;
01597       }
01598       strcpy(cfinclude->include, filename); /* Safe */
01599       AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
01600       break;
01601    case ATTRIBUTE_EXEC:
01602       cfmtime->has_exec = 1;
01603       break;
01604    }
01605    AST_LIST_UNLOCK(&cfmtime_head);
01606 }

static void config_cache_destroy_entry ( struct cache_file_mtime cfmtime  )  [static]

Definition at line 1532 of file main/config.c.

References ast_free, and config_cache_flush_includes().

Referenced by config_cache_remove(), and config_shutdown().

01533 {
01534    config_cache_flush_includes(cfmtime);
01535    ast_free(cfmtime);
01536 }

static void config_cache_flush_includes ( struct cache_file_mtime cfmtime  )  [static]

Definition at line 1513 of file main/config.c.

References ast_free, AST_LIST_REMOVE_HEAD, and cache_file_mtime::includes.

Referenced by config_cache_destroy_entry(), and config_text_file_load().

01514 {
01515    struct cache_file_include *cfinclude;
01516 
01517    while ((cfinclude = AST_LIST_REMOVE_HEAD(&cfmtime->includes, list))) {
01518       ast_free(cfinclude);
01519    }
01520 }

static void config_cache_remove ( const char *  filename,
const char *  who_asked 
) [static]

static void config_hook_exec ( const char *  filename,
const char *  module,
const struct ast_config cfg 
) [static]

Definition at line 3882 of file main/config.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_config_copy(), copy(), cfg_hook::filename, cfg_hook::hook_cb, and cfg_hook::module.

Referenced by ast_config_internal_load(), and ast_config_text_file_save2().

03883 {
03884    struct ao2_iterator it;
03885    struct cfg_hook *hook;
03886    if (!(cfg_hooks)) {
03887       return;
03888    }
03889    it = ao2_iterator_init(cfg_hooks, 0);
03890    while ((hook = ao2_iterator_next(&it))) {
03891       if (!strcasecmp(hook->filename, filename) &&
03892             !strcasecmp(hook->module, module)) {
03893          struct ast_config *copy = ast_config_copy(cfg);
03894          hook->hook_cb(copy);
03895       }
03896       ao2_ref(hook, -1);
03897    }
03898    ao2_iterator_destroy(&it);
03899 }

static void config_shutdown ( void   )  [static]

static struct ast_config* config_text_file_load ( const char *  database,
const char *  table,
const char *  filename,
struct ast_config cfg,
struct ast_flags  flags,
const char *  suggested_include_file,
const char *  who_asked 
) [static, read]

Growable string buffer

< this will be a comment collector.

< A buffer for stuff behind the ;

Definition at line 1885 of file main/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, buf, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, cfmstat_cmp(), cfmstat_save(), cfmtime_new(), comment, comment_buffer, COMMENT_META, COMMENT_TAG, config_cache_flush_includes(), config_cache_remove(), 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, lline_buffer, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, MY_GLOB_FLAGS, NULL, process_text_line(), ast_variable::trailing, ast_category::trailing, and cache_file_mtime::who_asked.

01886 {
01887    char fn[256];
01888 #if defined(LOW_MEMORY)
01889    char buf[512];
01890 #else
01891    char buf[8192];
01892 #endif
01893    char *new_buf, *comment_p, *process_buf;
01894    FILE *f;
01895    int lineno=0;
01896    int comment = 0, nest[MAX_NESTED_COMMENTS];
01897    struct ast_category *cat = NULL;
01898    int count = 0;
01899    struct stat statbuf;
01900    struct cache_file_mtime *cfmtime = NULL;
01901    struct cache_file_include *cfinclude;
01902    struct ast_variable *last_var = 0;
01903    struct ast_category *last_cat = 0;
01904    /*! Growable string buffer */
01905    struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/
01906    struct ast_str *lline_buffer = NULL;   /*!< A buffer for stuff behind the ; */
01907 #ifdef AST_INCLUDE_GLOB
01908    int glob_ret;
01909    glob_t globbuf;
01910 #endif
01911 
01912    if (cfg) {
01913       cat = ast_config_get_current_category(cfg);
01914    }
01915 
01916    if (filename[0] == '/') {
01917       ast_copy_string(fn, filename, sizeof(fn));
01918    } else {
01919       snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
01920    }
01921 
01922    if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01923       comment_buffer = ast_str_create(CB_SIZE);
01924       if (comment_buffer) {
01925          lline_buffer = ast_str_create(CB_SIZE);
01926       }
01927       if (!lline_buffer) {
01928          ast_free(comment_buffer);
01929          ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
01930          return NULL;
01931       }
01932    }
01933 #ifdef AST_INCLUDE_GLOB
01934    globbuf.gl_offs = 0; /* initialize it to silence gcc */
01935    glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf);
01936    if (glob_ret == GLOB_NOSPACE) {
01937       ast_log(LOG_WARNING,
01938          "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
01939    } else if (glob_ret  == GLOB_ABORTED) {
01940       ast_log(LOG_WARNING,
01941          "Glob Expansion of pattern '%s' failed: Read error\n", fn);
01942    } else {
01943       /* loop over expanded files */
01944       int i;
01945 
01946       if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
01947          /*
01948           * We just want a file changed answer and since we cannot
01949           * tell if a file was deleted with wildcard matching we will
01950           * assume that something has always changed.  Also without
01951           * a lot of refactoring we couldn't check more than one file
01952           * for changes in the glob loop anyway.
01953           */
01954          globfree(&globbuf);
01955          ast_free(comment_buffer);
01956          ast_free(lline_buffer);
01957          return NULL;
01958       }
01959       for (i=0; i<globbuf.gl_pathc; i++) {
01960          ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
01961 #endif
01962          /*
01963           * The following is not a loop, but just a convenient way to define a block
01964           * (using do { } while(0) ), and be able to exit from it with 'continue'
01965           * or 'break' in case of errors. Nice trick.
01966           */
01967          do {
01968             if (stat(fn, &statbuf)) {
01969                if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01970                   config_cache_remove(fn, who_asked);
01971                }
01972                continue;
01973             }
01974 
01975             if (!S_ISREG(statbuf.st_mode)) {
01976                ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
01977                if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01978                   config_cache_remove(fn, who_asked);
01979                }
01980                continue;
01981             }
01982 
01983             if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01984                /* Find our cached entry for this configuration file */
01985                AST_LIST_LOCK(&cfmtime_head);
01986                AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
01987                   if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) {
01988                      break;
01989                   }
01990                }
01991                if (!cfmtime) {
01992                   cfmtime = cfmtime_new(fn, who_asked);
01993                   if (!cfmtime) {
01994                      AST_LIST_UNLOCK(&cfmtime_head);
01995                      continue;
01996                   }
01997                   /* Note that the file mtime is initialized to 0, i.e. 1970 */
01998                   AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
01999                }
02000             }
02001 
02002             if (cfmtime
02003                && !cfmtime->has_exec
02004                && !cfmstat_cmp(cfmtime, &statbuf)
02005                && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) {
02006                int unchanged = 1;
02007 
02008                /* File is unchanged, what about the (cached) includes (if any)? */
02009                AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
02010                   if (!config_text_file_load(NULL, NULL, cfinclude->include,
02011                      NULL, flags, "", who_asked)) {
02012                      /* One change is enough to short-circuit and reload the whole shebang */
02013                      unchanged = 0;
02014                      break;
02015                   }
02016                }
02017 
02018                if (unchanged) {
02019                   AST_LIST_UNLOCK(&cfmtime_head);
02020 #ifdef AST_INCLUDE_GLOB
02021                   globfree(&globbuf);
02022 #endif
02023                   ast_free(comment_buffer);
02024                   ast_free(lline_buffer);
02025                   return CONFIG_STATUS_FILEUNCHANGED;
02026                }
02027             }
02028 
02029             /* If cfg is NULL, then we just want a file changed answer. */
02030             if (cfg == NULL) {
02031                if (cfmtime) {
02032                   AST_LIST_UNLOCK(&cfmtime_head);
02033                }
02034                continue;
02035             }
02036 
02037             if (cfmtime) {
02038                /* Forget about what we thought we knew about this file's includes. */
02039                cfmtime->has_exec = 0;
02040                config_cache_flush_includes(cfmtime);
02041 
02042                cfmstat_save(cfmtime, &statbuf);
02043                AST_LIST_UNLOCK(&cfmtime_head);
02044             }
02045 
02046             if (!(f = fopen(fn, "r"))) {
02047                ast_debug(1, "No file to parse: %s\n", fn);
02048                ast_verb(2, "Parsing '%s': Not found (%s)\n", fn, strerror(errno));
02049                continue;
02050             }
02051             count++;
02052             /* If we get to this point, then we're loading regardless */
02053             ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED);
02054             ast_debug(1, "Parsing %s\n", fn);
02055             ast_verb(2, "Parsing '%s': Found\n", fn);
02056             while (!feof(f)) {
02057                lineno++;
02058                if (fgets(buf, sizeof(buf), f)) {
02059                   /* Skip lines that are too long */
02060                   if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 1] != '\n') {
02061                      ast_log(LOG_WARNING, "Line %d too long, skipping. It begins with: %.32s...\n", lineno, buf);
02062                      while (fgets(buf, sizeof(buf), f)) {
02063                         if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 1] == '\n') {
02064                            break;
02065                         }
02066                      }
02067                      continue;
02068                   }
02069 
02070                   if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)
02071                      && lline_buffer
02072                      && ast_str_strlen(lline_buffer)) {
02073                      CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
02074                      ast_str_reset(lline_buffer);        /* erase the lline buffer */
02075                   }
02076 
02077                   new_buf = buf;
02078                   if (comment) {
02079                      process_buf = NULL;
02080                   } else {
02081                      process_buf = buf;
02082                   }
02083 
02084                   if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)
02085                      && comment_buffer
02086                      && ast_str_strlen(comment_buffer)
02087                      && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) {
02088                      /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */
02089                      CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */
02090                      continue; /* go get a new line, then */
02091                   }
02092 
02093                   while ((comment_p = strchr(new_buf, COMMENT_META))) {
02094                      if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) {
02095                         /* Escaped semicolons aren't comments. */
02096                         new_buf = comment_p;
02097                         /* write over the \ and bring the null terminator with us */
02098                         memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
02099                      } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
02100                         /* Meta-Comment start detected ";--" */
02101                         if (comment < MAX_NESTED_COMMENTS) {
02102                            *comment_p = '\0';
02103                            new_buf = comment_p + 3;
02104                            comment++;
02105                            nest[comment-1] = lineno;
02106                         } else {
02107                            ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
02108                         }
02109                      } else if ((comment_p >= new_buf + 2) &&
02110                            (*(comment_p - 1) == COMMENT_TAG) &&
02111                            (*(comment_p - 2) == COMMENT_TAG)) {
02112                         /* Meta-Comment end detected "--;" */
02113                         comment--;
02114                         new_buf = comment_p + 1;
02115                         if (!comment) {
02116                            /* Back to non-comment now */
02117                            if (process_buf) {
02118                               /* Actually have to move what's left over the top, then continue */
02119                               char *oldptr;
02120 
02121                               oldptr = process_buf + strlen(process_buf);
02122                               if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
02123                                  CB_ADD(&comment_buffer, ";");
02124                                  CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
02125                               }
02126 
02127                               memmove(oldptr, new_buf, strlen(new_buf) + 1);
02128                               new_buf = oldptr;
02129                            } else {
02130                               process_buf = new_buf;
02131                            }
02132                         }
02133                      } else {
02134                         if (!comment) {
02135                            /* If ; is found, and we are not nested in a comment,
02136                               we immediately stop all comment processing */
02137                            if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
02138                               CB_ADD(&lline_buffer, comment_p);
02139                            }
02140                            *comment_p = '\0';
02141                            new_buf = comment_p;
02142                         } else {
02143                            new_buf = comment_p + 1;
02144                         }
02145                      }
02146                   }
02147                   if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) {
02148                      CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */
02149                   }
02150 
02151                   if (process_buf) {
02152                      char *buffer = ast_strip(process_buf);
02153 
02154                      if (!ast_strlen_zero(buffer)) {
02155                         if (process_text_line(cfg, &cat, buffer, lineno, fn,
02156                            flags, comment_buffer, lline_buffer,
02157                            suggested_include_file, &last_cat, &last_var,
02158                            who_asked)) {
02159                            cfg = CONFIG_STATUS_FILEINVALID;
02160                            break;
02161                         }
02162                      }
02163                   }
02164                }
02165             }
02166             /* end of file-- anything in a comment buffer? */
02167             if (last_cat) {
02168                if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
02169                   if (lline_buffer && ast_str_strlen(lline_buffer)) {
02170                      CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
02171                      ast_str_reset(lline_buffer); /* erase the lline buffer */
02172                   }
02173                   last_cat->trailing = ALLOC_COMMENT(comment_buffer);
02174                }
02175             } else if (last_var) {
02176                if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
02177                   if (lline_buffer && ast_str_strlen(lline_buffer)) {
02178                      CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
02179                      ast_str_reset(lline_buffer); /* erase the lline buffer */
02180                   }
02181                   last_var->trailing = ALLOC_COMMENT(comment_buffer);
02182                }
02183             } else {
02184                if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
02185                   ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer));
02186                }
02187             }
02188             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
02189                CB_RESET(comment_buffer, lline_buffer);
02190             }
02191 
02192             fclose(f);
02193          } while (0);
02194          if (comment) {
02195             ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
02196          }
02197 #ifdef AST_INCLUDE_GLOB
02198          if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
02199             break;
02200          }
02201       }
02202       globfree(&globbuf);
02203    }
02204 #endif
02205 
02206    ast_free(comment_buffer);
02207    ast_free(lline_buffer);
02208 
02209    if (count == 0) {
02210       return NULL;
02211    }
02212 
02213    return cfg;
02214 }

int config_text_file_save ( const char *  configfile,
const struct ast_config cfg,
const char *  generator 
)

static int count_linefeeds ( char *  str  )  [static]

Definition at line 2310 of file main/config.c.

Referenced by count_linefeeds_in_comments().

02311 {
02312    int count = 0;
02313 
02314    while (*str) {
02315       if (*str =='\n')
02316          count++;
02317       str++;
02318    }
02319    return count;
02320 }

static int count_linefeeds_in_comments ( struct ast_comment x  )  [static]

Definition at line 2322 of file main/config.c.

References ast_comment::cmt, count_linefeeds(), and ast_comment::next.

Referenced by insert_leading_blank_lines().

02323 {
02324    int count = 0;
02325 
02326    while (x) {
02327       count += count_linefeeds(x->cmt);
02328       x = x->next;
02329    }
02330    return count;
02331 }

static int does_category_match ( struct ast_category cat,
const char *  category_name,
const char *  match 
) [static]

Returns true if ALL of the regex expressions and category name match. Both can be NULL (I.E. no predicate) which results in a true return;.

Definition at line 764 of file main/config.c.

References ast_alloca, ast_log, ast_strdupa, ast_strlen_zero, ast_strsep(), AST_STRSEP_STRIP, ast_category::ignored, LOG_ERROR, ast_variable::name, ast_category::name, ast_variable::next, NULL, ast_category::root, and ast_variable::value.

Referenced by ast_category_get(), and next_available_category().

00765 {
00766    char *dupmatch;
00767    char *nvp = NULL;
00768    int match_found = 0, match_expressions = 0;
00769    int template_ok = 0;
00770 
00771    /* Only match on category name if it's not a NULL or empty string */
00772    if (!ast_strlen_zero(category_name) && strcasecmp(cat->name, category_name)) {
00773       return 0;
00774    }
00775 
00776    /* If match is NULL or empty, automatically match if not a template */
00777    if (ast_strlen_zero(match)) {
00778       return !cat->ignored;
00779    }
00780 
00781    dupmatch = ast_strdupa(match);
00782 
00783    while ((nvp = ast_strsep(&dupmatch, ',', AST_STRSEP_STRIP))) {
00784       struct ast_variable *v;
00785       char *match_name;
00786       char *match_value = NULL;
00787       char *regerr;
00788       int rc;
00789       regex_t r_name, r_value;
00790 
00791       match_expressions++;
00792 
00793       match_name = ast_strsep(&nvp, '=', AST_STRSEP_STRIP);
00794       match_value = ast_strsep(&nvp, '=', AST_STRSEP_STRIP);
00795 
00796       /* an empty match value is OK.  A NULL match value (no =) is NOT. */
00797       if (match_value == NULL) {
00798          break;
00799       }
00800 
00801       if (!strcmp("TEMPLATES", match_name)) {
00802          if (!strcasecmp("include", match_value)) {
00803             if (cat->ignored) {
00804                template_ok = 1;
00805             }
00806             match_found++;
00807          } else if (!strcasecmp("restrict", match_value)) {
00808             if (cat->ignored) {
00809                match_found++;
00810                template_ok = 1;
00811             } else {
00812                break;
00813             }
00814          }
00815          continue;
00816       }
00817 
00818       if ((rc = regcomp(&r_name, match_name, REG_EXTENDED | REG_NOSUB))) {
00819          regerr = ast_alloca(128);
00820          regerror(rc, &r_name, regerr, 128);
00821          ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n",
00822             match_name, regerr);
00823          regfree(&r_name);
00824          return 0;
00825       }
00826       if ((rc = regcomp(&r_value, match_value, REG_EXTENDED | REG_NOSUB))) {
00827          regerr = ast_alloca(128);
00828          regerror(rc, &r_value, regerr, 128);
00829          ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n",
00830             match_value, regerr);
00831          regfree(&r_name);
00832          regfree(&r_value);
00833          return 0;
00834       }
00835 
00836       for (v = cat->root; v; v = v->next) {
00837          if (!regexec(&r_name, v->name, 0, NULL, 0)
00838             && !regexec(&r_value, v->value, 0, NULL, 0)) {
00839             match_found++;
00840             break;
00841          }
00842       }
00843       regfree(&r_name);
00844       regfree(&r_value);
00845    }
00846    if (match_found == match_expressions && (!cat->ignored || template_ok)) {
00847       return 1;
00848    }
00849    return 0;
00850 }

static struct ast_config_engine* find_engine ( const char *  family,
int  priority,
char *  database,
int  dbsiz,
char *  table,
int  tabsiz 
) [static, read]

Find realtime engine for realtime family.

Definition at line 2864 of file main/config.c.

References ast_copy_string(), ast_log, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, lock, LOG_WARNING, map, ast_config_map::name, ast_config_engine::next, ast_config_map::next, NULL, ast_config_map::priority, SCOPED_MUTEX, and ast_config_map::table.

Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime_fields(), ast_load_realtime_all_fields(), ast_load_realtime_multientry_fields(), ast_realtime_require_field(), ast_speech_new(), ast_speech_register(), ast_store_realtime_fields(), ast_unload_realtime(), ast_update2_realtime_fields(), and ast_update_realtime_fields().

02865 {
02866    struct ast_config_engine *eng, *ret = NULL;
02867    struct ast_config_map *map;
02868 
02869    SCOPED_MUTEX(lock, &config_lock);
02870 
02871    for (map = config_maps; map; map = map->next) {
02872       if (!strcasecmp(family, map->name) && (priority == map->priority)) {
02873          if (database)
02874             ast_copy_string(database, map->database, dbsiz);
02875          if (table)
02876             ast_copy_string(table, map->table ? map->table : family, tabsiz);
02877          break;
02878       }
02879    }
02880 
02881    /* Check if the required driver (engine) exist */
02882    if (map) {
02883       for (eng = config_engine_list; !ret && eng; eng = eng->next) {
02884          if (!strcasecmp(eng->name, map->driver))
02885             ret = eng;
02886       }
02887    }
02888 
02889    /* if we found a mapping, but the engine is not available, then issue a warning */
02890    if (map && !ret)
02891       ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
02892 
02893    return ret;
02894 }

static void gen_header ( FILE *  f1,
const char *  configfile,
const char *  fn,
const char *  generator 
) [static]

Definition at line 2237 of file main/config.c.

References ast_copy_string().

Referenced by ast_config_text_file_save2(), and localized_config_text_file_save().

02238 {
02239    char date[256]="";
02240    time_t t;
02241 
02242    time(&t);
02243    ast_copy_string(date, ctime(&t), sizeof(date));
02244 
02245    fprintf(f1, ";!\n");
02246    fprintf(f1, ";! Automatically generated configuration file\n");
02247    if (strcmp(configfile, fn))
02248       fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
02249    else
02250       fprintf(f1, ";! Filename: %s\n", configfile);
02251    fprintf(f1, ";! Generator: %s\n", generator);
02252    fprintf(f1, ";! Creation Date: %s", date);
02253    fprintf(f1, ";!\n");
02254 }

static char* handle_cli_config_list ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3790 of file main/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, NULL, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.

03791 {
03792    struct cache_file_mtime *cfmtime;
03793 
03794    switch (cmd) {
03795    case CLI_INIT:
03796       e->command = "config list";
03797       e->usage =
03798          "Usage: config list\n"
03799          "   Show all modules that have loaded a configuration file\n";
03800       return NULL;
03801    case CLI_GENERATE:
03802       return NULL;
03803    }
03804 
03805    AST_LIST_LOCK(&cfmtime_head);
03806    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
03807       ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
03808    }
03809    AST_LIST_UNLOCK(&cfmtime_head);
03810 
03811    return CLI_SUCCESS;
03812 }

static char* handle_cli_config_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3728 of file main/config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_alloca, ast_cli_command, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strlen_zero, buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, ast_cli_args::n, NULL, ast_cli_args::pos, ast_category::prev, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.

03729 {
03730    struct cache_file_mtime *cfmtime;
03731    char *prev = "", *completion_value = NULL;
03732    int wordlen, which = 0;
03733 
03734    switch (cmd) {
03735    case CLI_INIT:
03736       e->command = "config reload";
03737       e->usage =
03738          "Usage: config reload <filename.conf>\n"
03739          "   Reloads all modules that reference <filename.conf>\n";
03740       return NULL;
03741    case CLI_GENERATE:
03742       if (a->pos > 2) {
03743          return NULL;
03744       }
03745 
03746       wordlen = strlen(a->word);
03747 
03748       AST_LIST_LOCK(&cfmtime_head);
03749       AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
03750          /* Skip duplicates - this only works because the list is sorted by filename */
03751          if (strcmp(cfmtime->filename, prev) == 0) {
03752             continue;
03753          }
03754 
03755          /* Core configs cannot be reloaded */
03756          if (ast_strlen_zero(cfmtime->who_asked)) {
03757             continue;
03758          }
03759 
03760          if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) {
03761             completion_value = ast_strdup(cfmtime->filename);
03762             break;
03763          }
03764 
03765          /* Otherwise save that we've seen this filename */
03766          prev = cfmtime->filename;
03767       }
03768       AST_LIST_UNLOCK(&cfmtime_head);
03769 
03770       return completion_value;
03771    }
03772 
03773    if (a->argc != 3) {
03774       return CLI_SHOWUSAGE;
03775    }
03776 
03777    AST_LIST_LOCK(&cfmtime_head);
03778    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
03779       if (!strcmp(cfmtime->filename, a->argv[2])) {
03780          char *buf = ast_alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
03781          sprintf(buf, "module reload %s", cfmtime->who_asked);
03782          ast_cli_command(a->fd, buf);
03783       }
03784    }
03785    AST_LIST_UNLOCK(&cfmtime_head);
03786 
03787    return CLI_SUCCESS;
03788 }

static char* handle_cli_core_show_config_mappings ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3691 of file main/config.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, ast_cli_args::fd, lock, map, ast_config_map::name, ast_config_engine::name, ast_config_map::next, ast_config_engine::next, NULL, SCOPED_MUTEX, ast_config_map::table, and ast_cli_entry::usage.

03692 {
03693    struct ast_config_engine *eng;
03694    struct ast_config_map *map;
03695 
03696    switch (cmd) {
03697    case CLI_INIT:
03698       e->command = "core show config mappings";
03699       e->usage =
03700          "Usage: core show config mappings\n"
03701          "  Shows the filenames to config engines.\n";
03702       return NULL;
03703    case CLI_GENERATE:
03704       return NULL;
03705    }
03706 
03707    {
03708       SCOPED_MUTEX(lock, &config_lock);
03709 
03710       if (!config_engine_list) {
03711          ast_cli(a->fd, "No config mappings found.\n");
03712       } else {
03713          for (eng = config_engine_list; eng; eng = eng->next) {
03714             ast_cli(a->fd, "Config Engine: %s\n", eng->name);
03715             for (map = config_maps; map; map = map->next) {
03716                if (!strcasecmp(map->driver, eng->name)) {
03717                   ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
03718                         map->table ? map->table : map->name);
03719                }
03720             }
03721          }
03722       }
03723    }
03724 
03725    return CLI_SUCCESS;
03726 }

static int hash_string ( const void *  obj,
const int  flags 
) [static]

Definition at line 167 of file main/config.c.

References str, tmp(), and total.

Referenced by ast_config_text_file_save2(), and AST_TEST_DEFINE().

00168 {
00169    char *str = ((struct inclfile *) obj)->fname;
00170    int total;
00171 
00172    for (total = 0; *str; str++) {
00173       unsigned int tmp = total;
00174       total <<= 1; /* multiply by 2 */
00175       total += tmp; /* multiply by 3 */
00176       total <<= 2; /* multiply by 12 */
00177       total += tmp; /* multiply by 13 */
00178 
00179       total += ((unsigned int) (*str));
00180    }
00181    if (total < 0) {
00182       total = -total;
00183    }
00184    return total;
00185 }

static int hashtab_compare_strings ( void *  a,
void *  b,
int  flags 
) [static]

Definition at line 187 of file main/config.c.

References be, CMP_MATCH, CMP_STOP, and inclfile::fname.

Referenced by ast_config_text_file_save2().

00188 {
00189    const struct inclfile *ae = a, *be = b;
00190    return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0;
00191 }

static int hook_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 3858 of file main/config.c.

References CMP_MATCH, CMP_STOP, and cfg_hook::name.

Referenced by ast_config_hook_register().

03859 {
03860    struct cfg_hook *hook1 = obj;
03861    struct cfg_hook *hook2 = arg;
03862 
03863    return !(strcasecmp(hook1->name, hook2->name)) ? CMP_MATCH | CMP_STOP : 0;
03864 }

static void hook_destroy ( void *  obj  )  [static]

Definition at line 3850 of file main/config.c.

References ast_free, cfg_hook::filename, cfg_hook::module, and cfg_hook::name.

Referenced by ast_config_hook_register().

03851 {
03852    struct cfg_hook *hook = obj;
03853    ast_free((void *) hook->name);
03854    ast_free((void *) hook->filename);
03855    ast_free((void *) hook->module);
03856 }

static int hook_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 3866 of file main/config.c.

References ast_str_hash(), and cfg_hook::name.

Referenced by ast_config_hook_register().

03867 {
03868    const struct cfg_hook *hook = obj;
03869 
03870    return ast_str_hash(hook->name);
03871 }

static void inclfile_destroy ( void *  obj  )  [static]

Definition at line 2256 of file main/config.c.

References ast_free, and inclfile::fname.

Referenced by set_fn().

02257 {
02258    const struct inclfile *o = obj;
02259 
02260    ast_free(o->fname);
02261 }

static int init_appendbuf ( void *  data  )  [static]

Definition at line 111 of file main/config.c.

References ast_str_create(), and str.

00112 {
00113    struct ast_str **str = data;
00114    *str = ast_str_create(16);
00115    return *str ? 0 : -1;
00116 }

static void insert_leading_blank_lines ( FILE *  fp,
struct inclfile fi,
struct ast_comment precomments,
int  lineno 
) [static]

Definition at line 2333 of file main/config.c.

References count_linefeeds_in_comments(), and inclfile::lineno.

Referenced by ast_config_text_file_save2().

02334 {
02335    int precomment_lines;
02336    int i;
02337 
02338    if (!fi) {
02339       /* No file scratch pad object so insert no blank lines. */
02340       return;
02341    }
02342 
02343    precomment_lines = count_linefeeds_in_comments(precomments);
02344 
02345    /* I don't have to worry about those ;! comments, they are
02346       stored in the precomments, but not printed back out.
02347       I did have to make sure that comments following
02348       the ;! header comments were not also deleted in the process */
02349    if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */
02350       return;
02351    } else if (lineno == 0) {
02352       /* Line replacements also mess things up */
02353       return;
02354    } else if (lineno - precomment_lines - fi->lineno < 5) {
02355       /* Only insert less than 5 blank lines; if anything more occurs,
02356        * it's probably due to context deletion. */
02357       for (i = fi->lineno; i < lineno - precomment_lines; i++) {
02358          fprintf(fp, "\n");
02359       }
02360    } else {
02361       /* Deletion occurred - insert a single blank line, for separation of
02362        * contexts. */
02363       fprintf(fp, "\n");
02364    }
02365 
02366    fi->lineno = lineno + 1; /* Advance the file lineno */
02367 }

static void make_fn ( char *  fn,
size_t  fn_size,
const char *  file,
const char *  configfile 
) [static]

Definition at line 2263 of file main/config.c.

References ast_config_AST_CONFIG_DIR, ast_copy_string(), and ast_strlen_zero.

Referenced by ast_config_text_file_save2(), and set_fn().

02264 {
02265    if (ast_strlen_zero(file)) {
02266       if (configfile[0] == '/') {
02267          ast_copy_string(fn, configfile, fn_size);
02268       } else {
02269          snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
02270       }
02271    } else if (file[0] == '/') {
02272       ast_copy_string(fn, file, fn_size);
02273    } else {
02274       snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
02275    }
02276 }

static void move_variables ( struct ast_category old,
struct ast_category new 
) [static]

Definition at line 752 of file main/config.c.

References ast_variable_append(), NULL, ast_category::root, and var.

Referenced by process_text_line().

00753 {
00754    struct ast_variable *var = old->root;
00755 
00756    old->root = NULL;
00757    /* we can just move the entire list in a single op */
00758    ast_variable_append(new, var);
00759 }

static struct ast_category* new_category ( const char *  name,
const char *  in_file,
int  lineno,
int  template 
) [static, read]

Definition at line 853 of file main/config.c.

References ast_calloc, ast_category_destroy(), ast_copy_string(), ast_strdup, ast_category::file, ast_category::ignored, ast_category::lineno, ast_category::name, and NULL.

Referenced by ast_category_new(), and ast_category_new_template().

00854 {
00855    struct ast_category *category;
00856 
00857    category = ast_calloc(1, sizeof(*category));
00858    if (!category) {
00859       return NULL;
00860    }
00861    category->file = ast_strdup(in_file);
00862    if (!category->file) {
00863       ast_category_destroy(category);
00864       return NULL;
00865    }
00866    ast_copy_string(category->name, name, sizeof(category->name));
00867    category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
00868    category->ignored = template;
00869    return category;
00870 }

static struct ast_category* next_available_category ( struct ast_category cat,
const char *  name,
const char *  filter 
) [static, read]

Definition at line 1022 of file main/config.c.

References does_category_match(), and ast_category::next.

Referenced by ast_category_browse(), and ast_category_browse_filtered().

01024 {
01025    for (; cat && !does_category_match(cat, name, filter); cat = cat->next);
01026 
01027    return cat;
01028 }

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 1615 of file main/config.c.

References ALLOC_COMMENT(), appendbuf, ast_category_append(), ast_category_destroy(), ast_category_first(), ast_category_get(), ast_category_inherit(), 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, c, CB_RESET(), config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, ast_config::include_level, ast_variable::lineno, LOG_ERROR, LOG_WARNING, move_variables(), ast_variable::name, ast_variable::next, NULL, ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), astconfigparser::try_include(), ast_variable::value, and var.

Referenced by config_text_file_load().

01621 {
01622    char *c;
01623    char *cur = buf;
01624    struct ast_variable *v;
01625    char cmd[512], exec_file[512];
01626 
01627    /* Actually parse the entry */
01628    if (cur[0] == '[') { /* A category header */
01629       /* format is one of the following:
01630        * [foo] define a new category named 'foo'
01631        * [foo](!) define a new template category named 'foo'
01632        * [foo](+) append to category 'foo', error if foo does not exist.
01633        * [foo](a) define a new category and inherit from category or template a.
01634        *    You can put a comma-separated list of categories and templates
01635        *    and '!' and '+' between parentheses, with obvious meaning.
01636        */
01637       struct ast_category *newcat = NULL;
01638       char *catname;
01639 
01640       c = strchr(cur, ']');
01641       if (!c) {
01642          ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
01643          return -1;
01644       }
01645       *c++ = '\0';
01646       cur++;
01647       if (*c++ != '(')
01648          c = NULL;
01649       catname = cur;
01650       if (!(*cat = newcat = ast_category_new(catname,
01651             S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile),
01652             lineno))) {
01653          return -1;
01654       }
01655       (*cat)->lineno = lineno;
01656       *last_var = 0;
01657       *last_cat = newcat;
01658 
01659       /* add comments */
01660       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01661          newcat->precomments = ALLOC_COMMENT(comment_buffer);
01662       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01663          newcat->sameline = ALLOC_COMMENT(lline_buffer);
01664       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01665          CB_RESET(comment_buffer, lline_buffer);
01666 
01667       /* If there are options or categories to inherit from, process them now */
01668       if (c) {
01669          if (!(cur = strchr(c, ')'))) {
01670             ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
01671             return -1;
01672          }
01673          *cur = '\0';
01674          while ((cur = strsep(&c, ","))) {
01675             if (!strcasecmp(cur, "!")) {
01676                (*cat)->ignored = 1;
01677             } else if (!strcasecmp(cur, "+")) {
01678                *cat = ast_category_get(cfg, catname, NULL);
01679                if (!(*cat)) {
01680                   if (newcat)
01681                      ast_category_destroy(newcat);
01682                   ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
01683                   return -1;
01684                }
01685                if (newcat) {
01686                   move_variables(newcat, *cat);
01687                   ast_category_destroy(newcat);
01688                   newcat = NULL;
01689                }
01690             } else {
01691                struct ast_category *base;
01692 
01693                base = ast_category_get(cfg, cur, "TEMPLATES=include");
01694                if (!base) {
01695                   ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
01696                   return -1;
01697                }
01698                if (ast_category_inherit(*cat, base)) {
01699                   ast_log(LOG_ERROR, "Inheritence requested, but allocation failed\n");
01700                   return -1;
01701                }
01702             }
01703          }
01704       }
01705       if (newcat)
01706          ast_category_append(cfg, *cat);
01707    } else if (cur[0] == '#') { /* A directive - #include or #exec */
01708       char *cur2;
01709       char real_inclusion_name[256];
01710       int do_include = 0;  /* otherwise, it is exec */
01711       int try_include = 0;
01712 
01713       cur++;
01714       c = cur;
01715       while (*c && (*c > 32)) {
01716          c++;
01717       }
01718 
01719       if (*c) {
01720          *c = '\0';
01721          /* Find real argument */
01722          c = ast_strip(c + 1);
01723          if (!(*c)) {
01724             c = NULL;
01725          }
01726       } else {
01727          c = NULL;
01728       }
01729       if (!strcasecmp(cur, "include")) {
01730          do_include = 1;
01731       } else if (!strcasecmp(cur, "tryinclude")) {
01732          do_include = 1;
01733          try_include = 1;
01734       } else if (!strcasecmp(cur, "exec")) {
01735          if (!ast_opt_exec_includes) {
01736             ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
01737             return 0;   /* XXX is this correct ? or we should return -1 ? */
01738          }
01739       } else {
01740          ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
01741          return 0;   /* XXX is this correct ? or we should return -1 ? */
01742       }
01743 
01744       if (c == NULL) {
01745          ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
01746                do_include ? "include / tryinclude" : "exec",
01747                do_include ? "filename" : "/path/to/executable",
01748                lineno,
01749                configfile);
01750          return 0;   /* XXX is this correct ? or we should return -1 ? */
01751       }
01752 
01753       cur = c;
01754       /* Strip off leading and trailing "'s and <>'s */
01755       /* Dequote */
01756       if ((*c == '"') || (*c == '<')) {
01757          char quote_char = *c;
01758          if (quote_char == '<') {
01759             quote_char = '>';
01760          }
01761 
01762          if (*(c + strlen(c) - 1) == quote_char) {
01763             cur++;
01764             *(c + strlen(c) - 1) = '\0';
01765          }
01766       }
01767       cur2 = cur;
01768 
01769       /* #exec </path/to/executable>
01770          We create a tmp file, then we #include it, then we delete it. */
01771       if (!do_include) {
01772          struct timeval now = ast_tvnow();
01773          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01774             config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked);
01775          snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self());
01776          snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
01777          ast_safe_system(cmd);
01778          cur = exec_file;
01779       } else {
01780          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01781             config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked);
01782          exec_file[0] = '\0';
01783       }
01784       /* A #include */
01785       /* record this inclusion */
01786       ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
01787 
01788       do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0;
01789       if (!ast_strlen_zero(exec_file))
01790          unlink(exec_file);
01791       if (!do_include && !try_include) {
01792          ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur);
01793          return -1;
01794       }
01795       /* XXX otherwise what ? the default return is 0 anyways */
01796 
01797    } else {
01798       /* Just a line (variable = value) */
01799       int object = 0;
01800       int is_escaped;
01801 
01802       if (!(*cat)) {
01803          ast_log(LOG_WARNING,
01804             "parse error: No category context for line %d of %s\n", lineno, configfile);
01805          return -1;
01806       }
01807 
01808       is_escaped = cur[0] == '\\';
01809       if (is_escaped) {
01810          /* First character is escaped. */
01811          ++cur;
01812          if (cur[0] < 33) {
01813             ast_log(LOG_ERROR, "Invalid escape in line %d of %s\n", lineno, configfile);
01814             return -1;
01815          }
01816       }
01817       c = strchr(cur + is_escaped, '=');
01818 
01819       if (c && c > cur + is_escaped && (*(c - 1) == '+')) {
01820          struct ast_variable *var, *replace = NULL;
01821          struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str));
01822 
01823          if (!str || !*str) {
01824             return -1;
01825          }
01826 
01827          *(c - 1) = '\0';
01828          c++;
01829          cur = ast_strip(cur);
01830 
01831          /* Must iterate through category until we find last variable of same name (since there could be multiple) */
01832          for (var = ast_category_first(*cat); var; var = var->next) {
01833             if (!strcmp(var->name, cur)) {
01834                replace = var;
01835             }
01836          }
01837 
01838          if (!replace) {
01839             /* Nothing to replace; just set a variable normally. */
01840             goto set_new_variable;
01841          }
01842 
01843          ast_str_set(str, 0, "%s", replace->value);
01844          ast_str_append(str, 0, "%s", c);
01845          ast_str_trim_blanks(*str);
01846          ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object);
01847       } else if (c) {
01848          *c = 0;
01849          c++;
01850          /* Ignore > in => */
01851          if (*c== '>') {
01852             object = 1;
01853             c++;
01854          }
01855          cur = ast_strip(cur);
01856 set_new_variable:
01857          if (ast_strlen_zero(cur)) {
01858             ast_log(LOG_WARNING, "No variable name in line %d of %s\n", lineno, configfile);
01859          } else if ((v = ast_variable_new(cur, ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) {
01860             v->lineno = lineno;
01861             v->object = object;
01862             *last_cat = 0;
01863             *last_var = v;
01864             /* Put and reset comments */
01865             v->blanklines = 0;
01866             ast_variable_append(*cat, v);
01867             /* add comments */
01868             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01869                v->precomments = ALLOC_COMMENT(comment_buffer);
01870             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01871                v->sameline = ALLOC_COMMENT(lline_buffer);
01872             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01873                CB_RESET(comment_buffer, lline_buffer);
01874 
01875          } else {
01876             return -1;
01877          }
01878       } else {
01879          ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
01880       }
01881    }
01882    return 0;
01883 }

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 2733 of file main/config.c.

References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log, ast_realtime_append_mapping(), ast_variable_browse(), buf, clear_config_maps(), CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, strsep(), tmp(), and ast_variable::value.

Referenced by main().

02734 {
02735    struct ast_config *config, *configtmp;
02736    struct ast_variable *v;
02737    char *driver, *table, *database, *textpri, *stringp, *tmp;
02738    struct ast_flags flags = { CONFIG_FLAG_NOREALTIME };
02739    int pri;
02740 
02741    clear_config_maps();
02742 
02743    configtmp = ast_config_new();
02744    if (!configtmp) {
02745       ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
02746       return -1;
02747    }
02748    config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
02749    if (config == CONFIG_STATUS_FILEINVALID) {
02750       return -1;
02751    } else if (!config) {
02752       ast_config_destroy(configtmp);
02753       return 0;
02754    }
02755 
02756    for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
02757       char buf[512];
02758       ast_copy_string(buf, v->value, sizeof(buf));
02759       stringp = buf;
02760       driver = strsep(&stringp, ",");
02761 
02762       if ((tmp = strchr(stringp, '\"')))
02763          stringp = tmp;
02764 
02765       /* check if the database text starts with a double quote */
02766       if (*stringp == '"') {
02767          stringp++;
02768          database = strsep(&stringp, "\"");
02769          strsep(&stringp, ",");
02770       } else {
02771          /* apparently this text has no quotes */
02772          database = strsep(&stringp, ",");
02773       }
02774 
02775       table = strsep(&stringp, ",");
02776       textpri = strsep(&stringp, ",");
02777       if (!textpri || !(pri = atoi(textpri))) {
02778          pri = 1;
02779       }
02780 
02781       if (!strcmp(v->name, extconfig_conf)) {
02782          ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
02783          continue;
02784       }
02785 
02786       if (!strcmp(v->name, "asterisk.conf")) {
02787          ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
02788          continue;
02789       }
02790 
02791       if (!strcmp(v->name, "logger.conf")) {
02792          ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
02793          continue;
02794       }
02795 
02796       if (!driver || !database)
02797          continue;
02798       if (!strcasecmp(v->name, "sipfriends")) {
02799          ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
02800          ast_realtime_append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
02801       } else if (!strcasecmp(v->name, "iaxfriends")) {
02802          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");
02803          ast_realtime_append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
02804          ast_realtime_append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
02805       } else
02806          ast_realtime_append_mapping(v->name, driver, database, table, pri);
02807    }
02808 
02809    ast_config_destroy(config);
02810    return 0;
02811 }

static int realtime_arguments_to_fields2 ( va_list  ap,
int  skip,
struct ast_variable **  result 
) [static]

Definition at line 3007 of file main/config.c.

References ast_variable_new(), ast_variables_destroy(), first, ast_variable::next, and NULL.

Referenced by ast_update2_realtime().

03008 {
03009    struct ast_variable *first, *fields = NULL;
03010    const char *newparam;
03011    const char *newval;
03012 
03013    /*
03014     * Previously we would do:
03015     *
03016     *     va_start(ap, last);
03017     *     x = realtime_arguments_to_fields(ap);
03018     *     y = realtime_arguments_to_fields(ap);
03019     *     va_end(ap);
03020     *
03021     * While this works on generic amd64 machines (2014), it doesn't on the
03022     * raspberry PI. The va_arg() manpage says:
03023     *
03024     *     If ap is passed to a function that uses va_arg(ap,type) then
03025     *     the value of ap is undefined after the return of that function.
03026     *
03027     * On the raspberry, ap seems to get reset after the call: the contents
03028     * of y would be equal to the contents of x.
03029     *
03030     * So, instead we allow the caller to skip past earlier argument sets
03031     * using the skip parameter:
03032     *
03033     *     va_start(ap, last);
03034     *     if (realtime_arguments_to_fields(ap, &x)) {
03035     *         // FAILURE CONDITIONS
03036     *     }
03037     *     va_end(ap);
03038     *     va_start(ap, last);
03039     *     if (realtime_arguments_to_fields2(ap, 1, &y)) {
03040     *         // FAILURE CONDITIONS
03041     *     }
03042     *     va_end(ap);
03043     */
03044    while (skip--) {
03045       /* There must be at least one argument. */
03046       newparam = va_arg(ap, const char *);
03047       newval = va_arg(ap, const char *);
03048       while ((newparam = va_arg(ap, const char *))) {
03049          newval = va_arg(ap, const char *);
03050       }
03051    }
03052 
03053    /* Load up the first vars. */
03054    newparam = va_arg(ap, const char *);
03055    if (!newparam) {
03056       *result = NULL;
03057       return 0;
03058    }
03059    newval = va_arg(ap, const char *);
03060 
03061    if (!(first = ast_variable_new(newparam, newval, ""))) {
03062       *result = NULL;
03063       return -1;
03064    }
03065 
03066    while ((newparam = va_arg(ap, const char *))) {
03067       struct ast_variable *field;
03068 
03069       newval = va_arg(ap, const char *);
03070       if (!(field = ast_variable_new(newparam, newval, ""))) {
03071          ast_variables_destroy(fields);
03072          ast_variables_destroy(first);
03073          *result = NULL;
03074          return -1;
03075       }
03076 
03077       field->next = fields;
03078       fields = field;
03079    }
03080 
03081    first->next = fields;
03082    fields = first;
03083 
03084    *result = fields;
03085    return 0;
03086 }

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 3836 of file main/config.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_register_cleanup(), and config_shutdown().

Referenced by main().

static struct inclfile* set_fn ( char *  fn,
size_t  fn_size,
const char *  file,
const char *  configfile,
struct ao2_container fileset 
) [static, read]

Definition at line 2278 of file main/config.c.

References ao2_alloc, ao2_find, ao2_link, ao2_ref, ast_strdup, inclfile::fname, inclfile_destroy(), inclfile::lineno, make_fn(), NULL, and OBJ_POINTER.

Referenced by ast_config_text_file_save2(), and localized_config_text_file_save().

02279 {
02280    struct inclfile lookup;
02281    struct inclfile *fi;
02282 
02283    make_fn(fn, fn_size, file, configfile);
02284    lookup.fname = fn;
02285    fi = ao2_find(fileset, &lookup, OBJ_POINTER);
02286    if (fi) {
02287       /* Found existing include file scratch pad. */
02288       return fi;
02289    }
02290 
02291    /* set up a file scratch pad */
02292    fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
02293    if (!fi) {
02294       /* Scratch pad creation failed. */
02295       return NULL;
02296    }
02297    fi->fname = ast_strdup(fn);
02298    if (!fi->fname) {
02299       /* Scratch pad creation failed. */
02300       ao2_ref(fi, -1);
02301       return NULL;
02302    }
02303    fi->lineno = 1;
02304 
02305    ao2_link(fileset, fi);
02306 
02307    return fi;
02308 }

static struct ast_variable* variable_clone ( const struct ast_variable old  )  [static, read]

Definition at line 738 of file main/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 ast_category_inherit(), and inherit_category().

00739 {
00740    struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
00741 
00742    if (new) {
00743       new->lineno = old->lineno;
00744       new->object = old->object;
00745       new->blanklines = old->blanklines;
00746       /* TODO: clone comments? */
00747    }
00748 
00749    return new;
00750 }

static struct ast_variable * variable_list_switch ( struct ast_variable l1,
struct ast_variable l2 
) [static, read]

Definition at line 617 of file main/config.c.

References ast_variable::next.

Referenced by ast_variable_list_sort().

00618 {
00619     l1->next = l2->next;
00620     l2->next = l1;
00621     return l2;
00622 }


Variable Documentation

struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , } [static]

Definition at line 118 of file main/config.c.

Referenced by process_text_line().

struct ao2_container* cfg_hooks [static]

Definition at line 72 of file main/config.c.

struct ast_cli_entry cli_config[] [static]

Initial value:

 {
   AST_CLI_DEFINE(handle_cli_core_show_config_mappings, "Display config mappings (file names to config engines)"),
   AST_CLI_DEFINE(handle_cli_config_reload, "Force a reload on modules using a particular configuration file"),
   AST_CLI_DEFINE(handle_cli_config_list, "Show all files that have loaded a configuration file"),
}

Definition at line 3814 of file main/config.c.

Definition at line 209 of file main/config.c.

ast_mutex_t config_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

struct ast_config_map * config_maps [static]

char* extconfig_conf = "extconfig.conf" [static]

Definition at line 70 of file main/config.c.

Initial value:

 {
   .name = "text",
   .load_func = config_text_file_load,
}

Definition at line 2896 of file main/config.c.


Generated on Thu Apr 16 06:30:25 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6