Mon Oct 8 12:39:21 2012

Asterisk developer's documentation


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 "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/netsock2.h"

Go to the source code of this file.

Data Structures

struct  ast_category
struct  ast_category::template_instance_list
struct  ast_category_template_instance
struct  ast_comment
 Structure to keep comments for rewriting configuration files. More...
struct  ast_config
struct  ast_config_include
struct  ast_config_map
struct  cache_file_include
 Hold the mtime for config files, so if we don't need to reread our config, don't. More...
struct  cache_file_mtime
struct  cache_file_mtime::includes
struct  cfmtime_head
struct  inclfile

Defines

#define AST_INCLUDE_GLOB   1
#define CB_SIZE   250
#define COMMENT_END   "--;"
#define COMMENT_META   ';'
#define COMMENT_START   ";--"
#define COMMENT_TAG   '-'
#define MAX_INCLUDE_LEVEL   10
#define MAX_NESTED_COMMENTS   128
#define MIN_VARIABLE_FNAME_SPACE   40

Enumerations

enum  config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0, ATTRIBUTE_EXEC = 1 }

Functions

static void __init_appendbuf (void)
static struct ast_commentALLOC_COMMENT (struct ast_str *buffer)
static int append_mapping (const char *name, const char *driver, const char *database, const char *table, int priority)
void ast_category_append (struct ast_config *config, struct ast_category *category)
char * ast_category_browse (struct ast_config *config, const char *prev)
 Goes through categories.
int ast_category_delete (struct ast_config *cfg, const char *category)
void ast_category_destroy (struct ast_category *cat)
ast_variableast_category_detach_variables (struct ast_category *cat)
int ast_category_empty (struct ast_config *cfg, const char *category)
 Removes and destroys all variables within a category.
int ast_category_exist (const struct ast_config *config, const char *category_name)
 Check for category duplicates.
ast_variableast_category_first (struct ast_category *cat)
 given a pointer to a category, return the root variable.
ast_categoryast_category_get (const struct ast_config *config, const char *category_name)
 Retrieve a category if it exists.
void ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match)
 Inserts new category.
ast_categoryast_category_new (const char *name, const char *in_file, int lineno)
 Create a category structure.
void ast_category_rename (struct ast_category *cat, const char *name)
ast_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)
void ast_config_destroy (struct ast_config *cfg)
 Destroys a config.
int ast_config_engine_deregister (struct ast_config_engine *del)
 Deregister config engine.
int ast_config_engine_register (struct ast_config_engine *new)
 Register config engine.
ast_categoryast_config_get_current_category (const struct ast_config *cfg)
 Retrieve the current category name being built.
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)
ast_configast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags)
 Load a config file.
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.
int ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator)
int ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...)
 Destroy realtime configuration.
static void ast_destroy_template_list (struct ast_category *cat)
ast_config_includeast_include_find (struct ast_config *conf, const char *included_file)
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)
ast_variableast_load_realtime (const char *family,...)
 Retrieve realtime configuration.
ast_variableast_load_realtime_all (const char *family,...)
static struct ast_variableast_load_realtime_helper (const char *family, va_list ap)
ast_configast_load_realtime_multientry (const char *family,...)
 Retrieve realtime configuration.
int ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *p_result,...)
 The argument parsing routine.
char * ast_realtime_decode_chunk (char *chunk)
 Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values.
int ast_realtime_enabled (void)
 Check if there's any realtime engines loaded.
char * ast_realtime_encode_chunk (struct ast_str **dest, ssize_t maxlen, const char *chunk)
 Encodes a chunk of data for realtime.
int ast_realtime_require_field (const char *family,...)
 Inform realtime what fields that may be stored.
int ast_store_realtime (const char *family,...)
 Create realtime configuration.
int ast_unload_realtime (const char *family)
 Release any resources cached for a realtime family.
int ast_update2_realtime (const char *family,...)
 Update realtime configuration.
int ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...)
 Update realtime configuration.
void ast_variable_append (struct ast_category *category, struct ast_variable *variable)
ast_variableast_variable_browse (const struct ast_config *config, const char *category)
 Goes through variables.
int ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line)
static void ast_variable_destroy (struct ast_variable *doomed)
void ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line)
static void ast_variable_move (struct ast_variable *dst_var, struct ast_variable *src_var)
ast_variableast_variable_new (const char *name, const char *value, const char *filename)
const char * ast_variable_retrieve (const struct ast_config *config, const char *category, const char *variable)
 Gets a variable.
int ast_variable_update (struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
 Update variable value within a config.
void ast_variables_destroy (struct ast_variable *v)
 Free variable list.
ast_variableast_variables_dup (struct ast_variable *var)
 Duplicate variable list.
static struct ast_categorycategory_get (const struct ast_config *config, const char *category_name, int ignored)
static void CB_ADD (struct ast_str **cb, const char *str)
static void CB_ADD_LEN (struct ast_str **cb, const char *str, int len)
static void CB_RESET (struct ast_str *cb, struct ast_str *llb)
static struct cache_file_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 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 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 void inclfile_destroy (void *obj)
static void inherit_category (struct ast_category *new, const struct ast_category *base)
static int init_appendbuf (void *data)
static void insert_leading_blank_lines (FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
static void move_variables (struct ast_category *old, struct ast_category *new)
static struct ast_categorynext_available_category (struct ast_category *cat)
static int process_text_line (struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked)
 parse one line in the configuration.
int read_config_maps (void)
 Exposed re-initialization method for core process.
int register_config_cli (void)
 Exposed initialization method for core process.
static struct inclfileset_fn (char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
static struct ast_variablevariable_clone (const struct ast_variable *old)

Variables

static struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , }
static struct ast_cli_entry cli_config []
static struct ast_config_engineconfig_engine_list
static ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , 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 config.c.


Define Documentation

#define AST_INCLUDE_GLOB   1

Definition at line 44 of file config.c.

#define CB_SIZE   250

Definition at line 110 of file config.c.

Referenced by config_text_file_load().

#define COMMENT_END   "--;"

Definition at line 58 of file config.c.

#define COMMENT_META   ';'

Definition at line 59 of file config.c.

Referenced by config_text_file_load().

#define COMMENT_START   ";--"

Definition at line 57 of file config.c.

#define COMMENT_TAG   '-'

Definition at line 60 of file config.c.

Referenced by config_text_file_load().

#define MAX_INCLUDE_LEVEL   10

Definition at line 198 of file config.c.

Referenced by ast_config_new().

#define MAX_NESTED_COMMENTS   128

Definition at line 56 of file 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 67 of file config.c.

Referenced by ast_variable_new().


Enumeration Type Documentation

enum config_cache_attribute_enum

Enumerator:
ATTRIBUTE_INCLUDE 
ATTRIBUTE_EXEC 

Definition at line 1058 of file config.c.

01058                                  {
01059    ATTRIBUTE_INCLUDE = 0,
01060    ATTRIBUTE_EXEC = 1,
01061 };


Function Documentation

static void __init_appendbuf ( void   )  [static]

Definition at line 107 of file config.c.

00113 {

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

Definition at line 134 of file config.c.

References ast_calloc, ast_str_buffer(), and ast_str_strlen().

Referenced by config_text_file_load(), and process_text_line().

00135 { 
00136    struct ast_comment *x = NULL;
00137    if (!buffer || !ast_str_strlen(buffer)) {
00138       return NULL;
00139    }
00140    if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
00141       strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
00142    }
00143    return x;
00144 }

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

Definition at line 2085 of file config.c.

References ast_calloc, ast_verb, config_maps, and map.

Referenced by read_config_maps().

02086 {
02087    struct ast_config_map *map;
02088    char *dst;
02089    int length;
02090 
02091    length = sizeof(*map);
02092    length += strlen(name) + 1;
02093    length += strlen(driver) + 1;
02094    length += strlen(database) + 1;
02095    if (table)
02096       length += strlen(table) + 1;
02097 
02098    if (!(map = ast_calloc(1, length)))
02099       return -1;
02100 
02101    dst = map->stuff; /* writable space starts here */
02102    map->name = strcpy(dst, name);
02103    dst += strlen(dst) + 1;
02104    map->driver = strcpy(dst, driver);
02105    dst += strlen(dst) + 1;
02106    map->database = strcpy(dst, database);
02107    if (table) {
02108       dst += strlen(dst) + 1;
02109       map->table = strcpy(dst, table);
02110    }
02111    map->priority = priority;
02112    map->next = config_maps;
02113    config_maps = map;
02114 
02115    ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
02116 
02117    return 0;
02118 }

void ast_category_append ( struct ast_config config,
struct ast_category category 
)

Definition at line 687 of file config.c.

References config, and ast_category::include_level.

Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), and write_password_to_file().

00688 {
00689    if (config->last)
00690       config->last->next = category;
00691    else
00692       config->root = category;
00693    category->include_level = config->include_level;
00694    config->last = category;
00695    config->current = category;
00696 }

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

Goes through categories.

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

Return values:
a category on success
NULL on failure/no-more-categories

Definition at line 774 of file config.c.

References config, ast_category::name, ast_category::next, and next_available_category().

Referenced by __queues_show(), action_getconfig(), action_getconfigjson(), action_listcategories(), actual_load_config(), aji_load_config(), ast_cli_perms_init(), complete_sipnotify(), conf_exec(), config_load(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), gtalk_load_config(), iax_provision_reload(), jingle_load_config(), load_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_tech_calendars(), misdn_cfg_init(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), queues_data_provider_get(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().

00775 {  
00776    struct ast_category *cat;
00777 
00778    if (!prev) {
00779       /* First time browse. */
00780       cat = config->root;
00781    } else if (config->last_browse && (config->last_browse->name == prev)) {
00782       /* Simple last browse found. */
00783       cat = config->last_browse->next;
00784    } else {
00785       /*
00786        * Config changed since last browse.
00787        *
00788        * First try cheap last browse search. (Rebrowsing a different
00789        * previous category?)
00790        */
00791       for (cat = config->root; cat; cat = cat->next) {
00792          if (cat->name == prev) {
00793             /* Found it. */
00794             cat = cat->next;
00795             break;
00796          }
00797       }
00798       if (!cat) {
00799          /*
00800           * Have to do it the hard way. (Last category was deleted and
00801           * re-added?)
00802           */
00803          for (cat = config->root; cat; cat = cat->next) {
00804             if (!strcasecmp(cat->name, prev)) {
00805                /* Found it. */
00806                cat = cat->next;
00807                break;
00808             }
00809          }
00810       }
00811    }
00812    
00813    if (cat)
00814       cat = next_available_category(cat);
00815 
00816    config->last_browse = cat;
00817    return (cat) ? cat->name : NULL;
00818 }

int ast_category_delete ( struct ast_config cfg,
const char *  category 
)

Definition at line 940 of file config.c.

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

Referenced by handle_updates().

00941 {
00942    struct ast_category *prev=NULL, *cat;
00943 
00944    cat = cfg->root;
00945    while (cat) {
00946       if (cat->name == category) {
00947          if (prev) {
00948             prev->next = cat->next;
00949             if (cat == cfg->last)
00950                cfg->last = prev;
00951          } else {
00952             cfg->root = cat->next;
00953             if (cat == cfg->last)
00954                cfg->last = NULL;
00955          }
00956          ast_category_destroy(cat);
00957          return 0;
00958       }
00959       prev = cat;
00960       cat = cat->next;
00961    }
00962 
00963    prev = NULL;
00964    cat = cfg->root;
00965    while (cat) {
00966       if (!strcasecmp(cat->name, category)) {
00967          if (prev) {
00968             prev->next = cat->next;
00969             if (cat == cfg->last)
00970                cfg->last = prev;
00971          } else {
00972             cfg->root = cat->next;
00973             if (cat == cfg->last)
00974                cfg->last = NULL;
00975          }
00976          ast_category_destroy(cat);
00977          return 0;
00978       }
00979       prev = cat;
00980       cat = cat->next;
00981    }
00982    return -1;
00983 }

void ast_category_destroy ( struct ast_category cat  ) 

Definition at line 726 of file config.c.

References ast_comment_destroy(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, ast_category::last, ast_category::precomments, ast_category::root, ast_category::sameline, and ast_category::trailing.

Referenced by add_cfg_entry(), ast_category_delete(), ast_category_new(), ast_config_destroy(), process_text_line(), realtime_multi_odbc(), and write_password_to_file().

00727 {
00728    ast_variables_destroy(cat->root);
00729    cat->root = NULL;
00730    cat->last = NULL;
00731    ast_comment_destroy(&cat->precomments);
00732    ast_comment_destroy(&cat->sameline);
00733    ast_comment_destroy(&cat->trailing);
00734    ast_destroy_template_list(cat);
00735    ast_free(cat->file);
00736    ast_free(cat);
00737 }

struct ast_variable* ast_category_detach_variables ( struct ast_category cat  ) 

Definition at line 820 of file config.c.

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

Referenced by realtime_switch_common().

00821 {
00822    struct ast_variable *v;
00823 
00824    v = cat->root;
00825    cat->root = NULL;
00826    cat->last = NULL;
00827 
00828    return v;
00829 }

int ast_category_empty ( struct ast_config cfg,
const char *  category 
)

Removes and destroys all variables within a category.

Return values:
0 if the category was found and emptied
-1 if the category was not found

Definition at line 985 of file config.c.

References ast_variables_destroy(), ast_category::last, ast_category::name, ast_category::next, ast_category::root, and ast_config::root.

Referenced by handle_updates().

00986 {
00987    struct ast_category *cat;
00988 
00989    for (cat = cfg->root; cat; cat = cat->next) {
00990       if (!strcasecmp(cat->name, category))
00991          continue;
00992       ast_variables_destroy(cat->root);
00993       cat->root = NULL;
00994       cat->last = NULL;
00995       return 0;
00996    }
00997 
00998    return -1;
00999 }

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

Check for category duplicates.

Parameters:
config which config to use
category_name name of the category you're looking for
This will search through the categories within a given config file for a match.

Returns:
non-zero if found

Definition at line 682 of file config.c.

References ast_category_get(), and config.

00683 {
00684    return !!ast_category_get(config, category_name);
00685 }

struct ast_variable* ast_category_first ( struct ast_category cat  ) 

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

return the first var of a category

Definition at line 760 of file config.c.

References ast_category::root.

Referenced by process_text_line().

00761 {
00762    return (cat) ? cat->root : NULL;
00763 }

struct ast_category* ast_category_get ( const struct ast_config config,
const char *  category_name 
)

Retrieve a category if it exists.

Parameters:
config which config to use
category_name name of the category you're looking for
This will search through the categories within a given config file for a match.

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

Definition at line 677 of file config.c.

References category_get(), and config.

Referenced by ast_category_exist(), ast_category_root(), ast_variable_browse(), handle_updates(), realtime_directory(), realtime_switch_common(), vm_change_password(), and vm_forwardoptions().

00678 {
00679    return category_get(config, category_name, 0);
00680 }

void 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.

Definition at line 698 of file config.c.

References config, ast_category::name, and ast_category::next.

Referenced by handle_updates().

00699 {
00700    struct ast_category *cur_category;
00701 
00702    if (!cat || !match)
00703       return;
00704    if (!strcasecmp(config->root->name, match)) {
00705       cat->next = config->root;
00706       config->root = cat;
00707       return;
00708    } 
00709    for (cur_category = config->root; cur_category; cur_category = cur_category->next) {
00710       if (!strcasecmp(cur_category->next->name, match)) {
00711          cat->next = cur_category->next;
00712          cur_category->next = cat;
00713          break;
00714       }
00715    }
00716 }

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

Create a category structure.

Definition at line 641 of file config.c.

References ast_calloc, ast_category_destroy(), ast_copy_string(), and ast_strdup.

Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), and write_password_to_file().

00642 {
00643    struct ast_category *category;
00644 
00645    category = ast_calloc(1, sizeof(*category));
00646    if (!category) {
00647       return NULL;
00648    }
00649    category->file = ast_strdup(in_file);
00650    if (!category->file) {
00651       ast_category_destroy(category);
00652       return NULL;
00653    }
00654    ast_copy_string(category->name, name, sizeof(category->name));
00655    category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
00656    return category;
00657 }

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

Definition at line 831 of file config.c.

References ast_copy_string(), and ast_category::name.

Referenced by handle_updates(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), and realtime_multi_pgsql().

00832 {
00833    ast_copy_string(cat->name, name, sizeof(cat->name));
00834 }

struct ast_variable* ast_category_root ( struct ast_config config,
char *  cat 
)

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 765 of file config.c.

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

Referenced by get_insecure_variable_from_config(), and get_insecure_variable_from_sipregs().

00766 {
00767    struct ast_category *category = ast_category_get(config, cat);
00768 
00769    if (category)
00770       return category->root;
00771    return NULL;
00772 }

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 2410 of file config.c.

References ast_realtime_enabled(), and find_engine().

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

02411 {
02412    struct ast_config_engine *eng;
02413    if (!ast_realtime_enabled()) {
02414       return 0;   /* There are no engines at all so fail early */
02415    }
02416 
02417    eng = find_engine(family, 1, NULL, 0, NULL, 0);
02418    if (eng)
02419       return 1;
02420    return 0;
02421 }

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

Definition at line 512 of file config.c.

References ast_free, comment, and ast_comment::next.

Referenced by ast_category_destroy(), and ast_variable_destroy().

00513 {
00514    struct ast_comment *n, *p;
00515 
00516    for (p = *comment; p; p = n) {
00517       n = p->next;
00518       ast_free(p);
00519    }
00520 
00521    *comment = NULL;
00522 }

void ast_config_destroy ( struct ast_config config  ) 

Destroys a config.

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

Definition at line 1001 of file config.c.

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

Referenced by __ast_http_post_load(), __ast_udptl_reload(), __queues_show(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), advanced_options(), ast_config_load2(), ast_load_realtime_multientry(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), handle_cli_dialplan_save(), iax_provision_reload(), initialize_cc_max_requests(), load_config(), load_config_meetme(), load_indications(), load_module(), load_realtime_queue(), make_email_file(), misdn_cfg_init(), odbc_load_module(), osp_load(), parse_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queues_data_provider_get(), read_agent_config(), read_config_maps(), read_password_from_file(), realtime_directory(), realtime_multi_handler(), realtime_multi_pgsql(), realtime_switch_common(), 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(), tds_load_module(), unload_module(), update_realtime_members(), vm_forwardoptions(), and write_password_to_file().

01002 {
01003    struct ast_category *cat, *catn;
01004 
01005    if (!cfg)
01006       return;
01007 
01008    ast_includes_destroy(cfg->includes);
01009 
01010    cat = cfg->root;
01011    while (cat) {
01012       catn = cat;
01013       cat = cat->next;
01014       ast_category_destroy(catn);
01015    }
01016    ast_free(cfg);
01017 }

int ast_config_engine_deregister ( struct ast_config_engine del  ) 

Deregister config engine.

Return values:
0 Always

Definition at line 2220 of file config.c.

References ast_mutex_lock, ast_mutex_unlock, config_engine_list, config_lock, last, and ast_config_engine::next.

Referenced by unload_module().

02221 {
02222    struct ast_config_engine *ptr, *last=NULL;
02223 
02224    ast_mutex_lock(&config_lock);
02225 
02226    for (ptr = config_engine_list; ptr; ptr=ptr->next) {
02227       if (ptr == del) {
02228          if (last)
02229             last->next = ptr->next;
02230          else
02231             config_engine_list = ptr->next;
02232          break;
02233       }
02234       last = ptr;
02235    }
02236 
02237    ast_mutex_unlock(&config_lock);
02238 
02239    return 0;
02240 }

int ast_config_engine_register ( struct ast_config_engine newconfig  ) 

Register config engine.

Return values:
1 Always

Definition at line 2201 of file config.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, config_engine_list, config_lock, LOG_NOTICE, ast_config_engine::name, and ast_config_engine::next.

Referenced by load_module().

02202 {
02203    struct ast_config_engine *ptr;
02204 
02205    ast_mutex_lock(&config_lock);
02206 
02207    if (!config_engine_list) {
02208       config_engine_list = new;
02209    } else {
02210       for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
02211       ptr->next = new;
02212    }
02213 
02214    ast_mutex_unlock(&config_lock);
02215    ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name);
02216 
02217    return 1;
02218 }

struct ast_category* ast_config_get_current_category ( const struct ast_config cfg  ) 

Retrieve the current category name being built.

API for backend configuration engines while building a configuration set.

Definition at line 1019 of file config.c.

References ast_config::current.

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

01020 {
01021    return cfg->current;
01022 }

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

Definition at line 2282 of file config.c.

References ast_log(), ast_test_flag, config_engine_list, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, db, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, table, and text_file_engine.

Referenced by add_cfg_entry(), ast_config_load2(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), process_text_line(), and read_config_maps().

02283 {
02284    char db[256];
02285    char table[256];
02286    struct ast_config_engine *loader = &text_file_engine;
02287    struct ast_config *result; 
02288 
02289    /* The config file itself bumps include_level by 1 */
02290    if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
02291       ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
02292       return NULL;
02293    }
02294 
02295    cfg->include_level++;
02296 
02297    if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) {
02298       struct ast_config_engine *eng;
02299 
02300       eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
02301 
02302 
02303       if (eng && eng->load_func) {
02304          loader = eng;
02305       } else {
02306          eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
02307          if (eng && eng->load_func)
02308             loader = eng;
02309       }
02310    }
02311 
02312    result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
02313 
02314    if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED)
02315       result->include_level--;
02316    else if (result != CONFIG_STATUS_FILEINVALID)
02317       cfg->include_level--;
02318 
02319    return result;
02320 }

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

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 2322 of file config.c.

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

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

02323 {
02324    struct ast_config *cfg;
02325    struct ast_config *result;
02326 
02327    cfg = ast_config_new();
02328    if (!cfg)
02329       return NULL;
02330 
02331    result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
02332    if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID)
02333       ast_config_destroy(cfg);
02334 
02335    return result;
02336 }

struct ast_config* ast_config_new ( void   ) 

Create a new base configuration structure.

Definition at line 852 of file config.c.

References ast_calloc, config, and MAX_INCLUDE_LEVEL.

Referenced by ast_config_load2(), load_realtime_queue(), read_config_maps(), realtime_multi_curl(), realtime_multi_handler(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), setup_dahdi_int(), and write_password_to_file().

00853 {
00854    struct ast_config *config;
00855 
00856    if ((config = ast_calloc(1, sizeof(*config))))
00857       config->max_include_level = MAX_INCLUDE_LEVEL;
00858    return config;
00859 }

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 582 of file config.c.

References ast_variable_retrieve().

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

00583 {
00584    const char *tmp;
00585    tmp = ast_variable_retrieve(cfg, cat, var);
00586    if (!tmp) {
00587       tmp = ast_variable_retrieve(cfg, "general", var);
00588    }
00589    return tmp;
00590 }

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 1024 of file config.c.

References ast_config::current.

01025 {
01026    /* cast below is just to silence compiler warning about dropping "const" */
01027    cfg->current = (struct ast_category *) cat;
01028 }

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

Definition at line 1815 of file config.c.

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

Referenced by action_updateconfig(), config_text_file_save(), vm_change_password(), vm_forwardoptions(), and write_password_to_file().

01816 {
01817    FILE *f;
01818    char fn[PATH_MAX];
01819    struct ast_variable *var;
01820    struct ast_category *cat;
01821    struct ast_comment *cmt;
01822    struct ast_config_include *incl;
01823    int blanklines = 0;
01824    struct ao2_container *fileset;
01825    struct inclfile *fi;
01826 
01827    fileset = ao2_container_alloc(1023, hash_string, hashtab_compare_strings);
01828    if (!fileset) {
01829       /* Container creation failed. */
01830       return -1;
01831    }
01832 
01833    /* reset all the output flags, in case this isn't our first time saving this data */
01834    for (incl = cfg->includes; incl; incl = incl->next) {
01835       incl->output = 0;
01836    }
01837 
01838    /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
01839       are all truncated to zero bytes and have that nice header*/
01840    for (incl = cfg->includes; incl; incl = incl->next) {
01841       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*/
01842          /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
01843          fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
01844          f = fopen(fn, "w");
01845          if (f) {
01846             gen_header(f, configfile, fn, generator);
01847             fclose(f); /* this should zero out the file */
01848          } else {
01849             ast_debug(1, "Unable to open for writing: %s\n", fn);
01850             ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
01851          }
01852          if (fi) {
01853             ao2_ref(fi, -1);
01854          }
01855       }
01856    }
01857 
01858    /* just set fn to absolute ver of configfile */
01859    fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
01860    if (
01861 #ifdef __CYGWIN__
01862       (f = fopen(fn, "w+"))
01863 #else
01864       (f = fopen(fn, "w"))
01865 #endif
01866       ) {
01867       ast_verb(2, "Saving '%s': ", fn);
01868       gen_header(f, configfile, fn, generator);
01869       cat = cfg->root;
01870       fclose(f);
01871       if (fi) {
01872          ao2_ref(fi, -1);
01873       }
01874 
01875       /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
01876       /* since each var, cat, and associated comments can come from any file, we have to be
01877          mobile, and open each file, print, and close it on an entry-by-entry basis */
01878 
01879       while (cat) {
01880          fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
01881          f = fopen(fn, "a");
01882          if (!f) {
01883             ast_debug(1, "Unable to open for writing: %s\n", fn);
01884             ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
01885             if (fi) {
01886                ao2_ref(fi, -1);
01887             }
01888             ao2_ref(fileset, -1);
01889             return -1;
01890          }
01891 
01892          /* dump any includes that happen before this category header */
01893          for (incl=cfg->includes; incl; incl = incl->next) {
01894             if (strcmp(incl->include_location_file, cat->file) == 0){
01895                if (cat->lineno > incl->include_location_lineno && !incl->output) {
01896                   if (incl->exec)
01897                      fprintf(f,"#exec \"%s\"\n", incl->exec_file);
01898                   else
01899                      fprintf(f,"#include \"%s\"\n", incl->included_file);
01900                   incl->output = 1;
01901                }
01902             }
01903          }
01904 
01905          insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno);
01906          /* Dump section with any appropriate comment */
01907          for (cmt = cat->precomments; cmt; cmt=cmt->next) {
01908             char *cmtp = cmt->cmt;
01909             while (cmtp && *cmtp == ';' && *(cmtp+1) == '!') {
01910                char *cmtp2 = strchr(cmtp+1, '\n');
01911                if (cmtp2)
01912                   cmtp = cmtp2+1;
01913                else cmtp = 0;
01914             }
01915             if (cmtp)
01916                fprintf(f,"%s", cmtp);
01917          }
01918          fprintf(f, "[%s]", cat->name);
01919          if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
01920             fprintf(f, "(");
01921             if (cat->ignored) {
01922                fprintf(f, "!");
01923             }
01924             if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
01925                fprintf(f, ",");
01926             }
01927             if (!AST_LIST_EMPTY(&cat->template_instances)) {
01928                struct ast_category_template_instance *x;
01929                AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
01930                   fprintf(f,"%s",x->name);
01931                   if (x != AST_LIST_LAST(&cat->template_instances))
01932                      fprintf(f,",");
01933                }
01934             }
01935             fprintf(f, ")");
01936          }
01937          for(cmt = cat->sameline; cmt; cmt=cmt->next)
01938          {
01939             fprintf(f,"%s", cmt->cmt);
01940          }
01941          if (!cat->sameline)
01942             fprintf(f,"\n");
01943          for (cmt = cat->trailing; cmt; cmt=cmt->next) {
01944             if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
01945                fprintf(f,"%s", cmt->cmt);
01946          }
01947          fclose(f);
01948          if (fi) {
01949             ao2_ref(fi, -1);
01950          }
01951 
01952          var = cat->root;
01953          while (var) {
01954             struct ast_category_template_instance *x;
01955             int found = 0;
01956             AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
01957                struct ast_variable *v;
01958                for (v = x->inst->root; v; v = v->next) {
01959                   if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
01960                      found = 1;
01961                      break;
01962                   }
01963                }
01964                if (found)
01965                   break;
01966             }
01967             if (found) {
01968                var = var->next;
01969                continue;
01970             }
01971             fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
01972             f = fopen(fn, "a");
01973             if (!f) {
01974                ast_debug(1, "Unable to open for writing: %s\n", fn);
01975                ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
01976                if (fi) {
01977                   ao2_ref(fi, -1);
01978                }
01979                ao2_ref(fileset, -1);
01980                return -1;
01981             }
01982 
01983             /* dump any includes that happen before this category header */
01984             for (incl=cfg->includes; incl; incl = incl->next) {
01985                if (strcmp(incl->include_location_file, var->file) == 0){
01986                   if (var->lineno > incl->include_location_lineno && !incl->output) {
01987                      if (incl->exec)
01988                         fprintf(f,"#exec \"%s\"\n", incl->exec_file);
01989                      else
01990                         fprintf(f,"#include \"%s\"\n", incl->included_file);
01991                      incl->output = 1;
01992                   }
01993                }
01994             }
01995 
01996             insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
01997             for (cmt = var->precomments; cmt; cmt=cmt->next) {
01998                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
01999                   fprintf(f,"%s", cmt->cmt);
02000             }
02001             if (var->sameline)
02002                fprintf(f, "%s %s %s  %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
02003             else
02004                fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
02005             for (cmt = var->trailing; cmt; cmt=cmt->next) {
02006                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
02007                   fprintf(f,"%s", cmt->cmt);
02008             }
02009             if (var->blanklines) {
02010                blanklines = var->blanklines;
02011                while (blanklines--)
02012                   fprintf(f, "\n");
02013             }
02014 
02015             fclose(f);
02016             if (fi) {
02017                ao2_ref(fi, -1);
02018             }
02019 
02020             var = var->next;
02021          }
02022          cat = cat->next;
02023       }
02024       if (!option_debug)
02025          ast_verb(2, "Saved\n");
02026    } else {
02027       ast_debug(1, "Unable to open for writing: %s\n", fn);
02028       ast_verb(2, "Unable to write (%s)", strerror(errno));
02029       if (fi) {
02030          ao2_ref(fi, -1);
02031       }
02032       ao2_ref(fileset, -1);
02033       return -1;
02034    }
02035 
02036    /* Now, for files with trailing #include/#exec statements,
02037       we have to make sure every entry is output */
02038    for (incl=cfg->includes; incl; incl = incl->next) {
02039       if (!incl->output) {
02040          /* open the respective file */
02041          fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
02042          f = fopen(fn, "a");
02043          if (!f) {
02044             ast_debug(1, "Unable to open for writing: %s\n", fn);
02045             ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
02046             if (fi) {
02047                ao2_ref(fi, -1);
02048             }
02049             ao2_ref(fileset, -1);
02050             return -1;
02051          }
02052 
02053          /* output the respective include */
02054          if (incl->exec)
02055             fprintf(f,"#exec \"%s\"\n", incl->exec_file);
02056          else
02057             fprintf(f,"#include \"%s\"\n", incl->included_file);
02058          fclose(f);
02059          incl->output = 1;
02060          if (fi) {
02061             ao2_ref(fi, -1);
02062          }
02063       }
02064    }
02065    ao2_ref(fileset, -1); /* this should destroy the hash container */
02066 
02067    return 0;
02068 }

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 2573 of file config.c.

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

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

02574 {
02575    struct ast_config_engine *eng;
02576    int res = -1, i;
02577    char db[256];
02578    char table[256];
02579    va_list ap;
02580 
02581    va_start(ap, lookup);
02582    for (i = 1; ; i++) {
02583       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02584          if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, ap))) {
02585             break;
02586          }
02587       } else {
02588          break;
02589       }
02590    }
02591    va_end(ap);
02592 
02593    return res;
02594 }

static void ast_destroy_template_list ( struct ast_category cat  )  [static]

Definition at line 718 of file config.c.

References ast_free, AST_LIST_REMOVE_HEAD, ast_category_template_instance::next, and ast_category::template_instances.

Referenced by ast_category_destroy().

00719 {
00720    struct ast_category_template_instance *x;
00721 
00722    while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
00723       ast_free(x);
00724 }

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

Definition at line 464 of file config.c.

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

Referenced by ast_include_new().

00465 {
00466    struct ast_config_include *x;
00467    for (x=conf->includes;x;x=x->next) {
00468       if (strcmp(x->included_file,included_file) == 0)
00469          return x;
00470    }
00471    return 0;
00472 }

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

Definition at line 324 of file config.c.

References ast_calloc, ast_include_find(), ast_includes_destroy(), ast_log(), ast_strdup, ast_strlen_zero(), ast_config::includes, and LOG_WARNING.

Referenced by process_text_line().

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

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

Definition at line 372 of file config.c.

References ast_free, ast_strdup, ast_variable_destroy(), ast_variable_move(), ast_variable_new(), ast_variable::file, ast_category::file, ast_config_include::include_location_file, ast_config::includes, ast_category::last, ast_variable::name, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, ast_config::root, str, and ast_variable::value.

Referenced by action_updateconfig().

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

static void ast_includes_destroy ( struct ast_config_include incls  )  [static]

Definition at line 739 of file config.c.

References ast_free, ast_config_include::exec_file, ast_config_include::include_location_file, ast_config_include::included_file, and ast_config_include::next.

Referenced by ast_config_destroy(), and ast_include_new().

00740 {
00741    struct ast_config_include *incl,*inclnext;
00742    
00743    for (incl=incls; incl; incl = inclnext) {
00744       inclnext = incl->next;
00745       ast_free(incl->include_location_file);
00746       ast_free(incl->exec_file);
00747       ast_free(incl->included_file);
00748       ast_free(incl);
00749    }
00750 }

struct ast_variable* ast_load_realtime ( const char *  family,
  ... 
)

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 2371 of file config.c.

References ast_load_realtime_helper(), ast_strlen_zero(), ast_variable_destroy(), ast_variable::next, and ast_variable::value.

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

02372 {
02373    struct ast_variable *res;
02374    struct ast_variable *cur;
02375    struct ast_variable **prev;
02376    va_list ap;
02377 
02378    va_start(ap, family);
02379    res = ast_load_realtime_helper(family, ap);
02380    va_end(ap);
02381 
02382    /* Filter the list. */
02383    prev = &res;
02384    cur = res;
02385    while (cur) {
02386       if (ast_strlen_zero(cur->value)) {
02387          /* Eliminate empty entries */
02388          struct ast_variable *next;
02389 
02390          next = cur->next;
02391          *prev = next;
02392          ast_variable_destroy(cur);
02393          cur = next;
02394       } else {
02395          /* Make blank entries empty and keep them. */
02396          if (cur->value[0] == ' ' && cur->value[1] == '\0') {
02397             char *vptr = (char *) cur->value;
02398 
02399             vptr[0] = '\0';
02400          }
02401 
02402          prev = &cur->next;
02403          cur = cur->next;
02404       }
02405    }
02406    return res;
02407 }

struct ast_variable* ast_load_realtime_all ( const char *  family,
  ... 
)

Definition at line 2359 of file config.c.

References ast_load_realtime_helper().

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

02360 {
02361    struct ast_variable *res;
02362    va_list ap;
02363 
02364    va_start(ap, family);
02365    res = ast_load_realtime_helper(family, ap);
02366    va_end(ap);
02367 
02368    return res;
02369 }

static struct ast_variable* ast_load_realtime_helper ( const char *  family,
va_list  ap 
) [static]

Definition at line 2338 of file config.c.

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

Referenced by ast_load_realtime(), and ast_load_realtime_all().

02339 {
02340    struct ast_config_engine *eng;
02341    char db[256];
02342    char table[256];
02343    struct ast_variable *res=NULL;
02344    int i;
02345 
02346    for (i = 1; ; i++) {
02347       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02348          if (eng->realtime_func && (res = eng->realtime_func(db, table, ap))) {
02349             return res;
02350          }
02351       } else {
02352          return NULL;
02353       }
02354    }
02355 
02356    return res;
02357 }

struct ast_config* ast_load_realtime_multientry ( const char *  family,
  ... 
)

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 2473 of file config.c.

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

Referenced by __queues_show(), conf_exec(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), load_realtime_queue(), queues_data_provider_get(), realtime_directory(), realtime_switch_common(), show_users_realtime(), and update_realtime_members().

02474 {
02475    struct ast_config_engine *eng;
02476    char db[256];
02477    char table[256];
02478    struct ast_config *res = NULL;
02479    va_list ap;
02480    int i;
02481 
02482    va_start(ap, family);
02483    for (i = 1; ; i++) {
02484       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02485          if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, ap))) {
02486             /* If we were returned an empty cfg, destroy it and return NULL */
02487             if (!res->root) {
02488                ast_config_destroy(res);
02489                res = NULL;
02490             }
02491             break;
02492          }
02493       } else {
02494          break;
02495       }
02496    }
02497    va_end(ap);
02498 
02499    return res;
02500 }

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

The argument parsing routine.

Parameters:
arg the string to parse. It is not modified.
flags combination of ast_parse_flags to specify the return type and additional checks.
result pointer to the result. NULL is valid here, and can be used to perform only the validity checks.
... extra arguments are required according to flags.
Return values:
0 in case of success, != 0 otherwise.
result returns the parsed value in case of success, the default value in case of error, or it is left unchanged in case of error and no default specified. Note that in certain cases (e.g. sockaddr_in, with multi-field return values) some of the fields in result may be changed even if an error occurs.
Examples of use: ast_parse_arg("223", PARSE_INT32|PARSE_IN_RANGE, &a, -1000, 1000); returns 0, a = 223 ast_parse_arg("22345", PARSE_INT32|PARSE_IN_RANGE|PARSE_DEFAULT, &a, 9999, 10, 100); returns 1, a = 9999 ast_parse_arg("22345ssf", PARSE_UINT32|PARSE_IN_RANGE, &b, 10, 100); returns 1, b unchanged ast_parse_arg("www.foo.biz:44", PARSE_INADDR, &sa); returns 0, sa contains address and port ast_parse_arg("www.foo.biz", PARSE_INADDR|PARSE_PORT_REQUIRE, &sa); returns 1 because port is missing, sa contains address

Definition at line 2628 of file 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(), errno, hp, INT32_MAX, INT32_MIN, PARSE_ADDR, PARSE_DEFAULT, PARSE_DOUBLE, PARSE_IN_RANGE, PARSE_INADDR, PARSE_INT32, PARSE_OUT_RANGE, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, PARSE_PORT_REQUIRE, PARSE_TYPE, PARSE_UINT32, strsep(), and UINT32_MAX.

Referenced by ast_tls_read_conf(), and check_via_response().

02630 {
02631    va_list ap;
02632    int error = 0;
02633 
02634    va_start(ap, p_result);
02635    switch (flags & PARSE_TYPE) {
02636    case PARSE_INT32:
02637    {
02638       long int x = 0;
02639       int32_t *result = p_result;
02640       int32_t def = result ? *result : 0, high = INT32_MAX, low = INT32_MIN;
02641       char *endptr = NULL;
02642 
02643       /* optional arguments: default value and/or (low, high) */
02644       if (flags & PARSE_DEFAULT) {
02645          def = va_arg(ap, int32_t);
02646       }
02647       if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
02648          low = va_arg(ap, int32_t);
02649          high = va_arg(ap, int32_t);
02650       }
02651       if (ast_strlen_zero(arg)) {
02652          error = 1;
02653          goto int32_done;
02654       }
02655       x = strtol(arg, &endptr, 0);
02656       if (*endptr || x < INT32_MIN || x > INT32_MAX) {
02657          /* Parse error, or type out of int32_t bounds */
02658          error = 1;
02659          goto int32_done;
02660       }
02661       error = (x < low) || (x > high);
02662       if (flags & PARSE_OUT_RANGE) {
02663          error = !error;
02664       }
02665 int32_done:
02666       if (result) {
02667          *result  = error ? def : x;
02668       }
02669 
02670       ast_debug(3, "extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
02671             arg, low, high, result ? *result : x, error);
02672       break;
02673    }
02674 
02675    case PARSE_UINT32:
02676    {
02677       unsigned long int x = 0;
02678       uint32_t *result = p_result;
02679       uint32_t def = result ? *result : 0, low = 0, high = UINT32_MAX;
02680       char *endptr = NULL;
02681 
02682       /* optional argument: first default value, then range */
02683       if (flags & PARSE_DEFAULT) {
02684          def = va_arg(ap, uint32_t);
02685       }
02686       if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
02687          /* range requested, update bounds */
02688          low = va_arg(ap, uint32_t);
02689          high = va_arg(ap, uint32_t);
02690       }
02691 
02692       if (ast_strlen_zero(arg)) {
02693          error = 1;
02694          goto uint32_done;
02695       }
02696       /* strtoul will happilly and silently negate negative numbers */
02697       arg = ast_skip_blanks(arg);
02698       if (*arg == '-') {
02699          error = 1;
02700          goto uint32_done;
02701       }
02702       x = strtoul(arg, &endptr, 0);
02703       if (*endptr || x > UINT32_MAX) {
02704          error = 1;
02705          goto uint32_done;
02706       }
02707       error = (x < low) || (x > high);
02708       if (flags & PARSE_OUT_RANGE) {
02709          error = !error;
02710       }
02711 uint32_done:
02712       if (result) {
02713          *result  = error ? def : x;
02714       }
02715       ast_debug(3, "extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
02716             arg, low, high, result ? *result : x, error);
02717       break;
02718    }
02719 
02720    case PARSE_DOUBLE:
02721    {
02722       double *result = p_result;
02723       double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
02724       char *endptr = NULL;
02725 
02726       /* optional argument: first default value, then range */
02727       if (flags & PARSE_DEFAULT) {
02728          def = va_arg(ap, double);
02729       }
02730       if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
02731          /* range requested, update bounds */
02732          low = va_arg(ap, double);
02733          high = va_arg(ap, double);
02734       }
02735       if (ast_strlen_zero(arg)) {
02736          error = 1;
02737          goto double_done;
02738       }
02739       errno = 0;
02740       x = strtod(arg, &endptr);
02741       if (*endptr || errno == ERANGE) {
02742          error = 1;
02743          goto double_done;
02744       }
02745       error = (x < low) || (x > high);
02746       if (flags & PARSE_OUT_RANGE) {
02747          error = !error;
02748       }
02749 double_done:
02750       if (result) {
02751          *result = error ? def : x;
02752       }
02753       ast_debug(3, "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
02754             arg, low, high, result ? *result : x, error);
02755       break;
02756    }
02757    case PARSE_ADDR:
02758        {
02759       struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result;
02760 
02761       if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) {
02762          error = 1;
02763       }
02764 
02765       ast_debug(3, "extract addr from %s gives %s(%d)\n",
02766            arg, ast_sockaddr_stringify(addr), error);
02767 
02768       break;
02769        }
02770    case PARSE_INADDR:   /* TODO Remove this (use PARSE_ADDR instead). */
02771        {
02772       char *port, *buf;
02773       struct sockaddr_in _sa_buf;   /* buffer for the result */
02774       struct sockaddr_in *sa = p_result ?
02775          (struct sockaddr_in *)p_result : &_sa_buf;
02776       /* default is either the supplied value or the result itself */
02777       struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
02778          va_arg(ap, struct sockaddr_in *) : sa;
02779       struct hostent *hp;
02780       struct ast_hostent ahp;
02781 
02782       memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
02783       /* duplicate the string to strip away the :port */
02784       port = ast_strdupa(arg);
02785       buf = strsep(&port, ":");
02786       sa->sin_family = AF_INET;  /* assign family */
02787       /*
02788        * honor the ports flag setting, assign default value
02789        * in case of errors or field unset.
02790        */
02791       flags &= PARSE_PORT_MASK; /* the only flags left to process */
02792       if (port) {
02793          if (flags == PARSE_PORT_FORBID) {
02794             error = 1;  /* port was forbidden */
02795             sa->sin_port = def->sin_port;
02796          } else if (flags == PARSE_PORT_IGNORE)
02797             sa->sin_port = def->sin_port;
02798          else /* accept or require */
02799             sa->sin_port = htons(strtol(port, NULL, 0));
02800       } else {
02801          sa->sin_port = def->sin_port;
02802          if (flags == PARSE_PORT_REQUIRE)
02803             error = 1;
02804       }
02805       /* Now deal with host part, even if we have errors before. */
02806       hp = ast_gethostbyname(buf, &ahp);
02807       if (hp)  /* resolved successfully */
02808          memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
02809       else {
02810          error = 1;
02811          sa->sin_addr = def->sin_addr;
02812       }
02813       ast_debug(3,
02814          "extract inaddr from [%s] gives [%s:%d](%d)\n",
02815          arg, ast_inet_ntoa(sa->sin_addr),
02816          ntohs(sa->sin_port), error);
02817          break;
02818        }
02819    }
02820    va_end(ap);
02821    return error;
02822 }

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 This function modifies the original buffer

Definition at line 2596 of file config.c.

Referenced by realtime_multi_pgsql(), and realtime_pgsql().

02597 {
02598    char *orig = chunk;
02599    for (; *chunk; chunk++) {
02600       if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
02601          sscanf(chunk + 1, "%02hhX", chunk);
02602          memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
02603       }
02604    }
02605    return orig;
02606 }

int ast_realtime_enabled ( void   ) 

Check if there's any realtime engines loaded.

Definition at line 2424 of file config.c.

References config_maps.

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

02425 {
02426    return config_maps ? 1 : 0;
02427 }

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 2608 of file config.c.

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

02609 {
02610    if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
02611       ast_str_set(dest, maxlen, "%s", chunk);
02612    } else {
02613       ast_str_reset(*dest);
02614       for (; *chunk; chunk++) {
02615          if (strchr(";^", *chunk)) {
02616             ast_str_append(dest, maxlen, "^%02hhX", *chunk);
02617          } else {
02618             ast_str_append(dest, maxlen, "%c", *chunk);
02619          }
02620       }
02621    }
02622    return ast_str_buffer(*dest);
02623 }

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 2429 of file config.c.

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

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

02430 {
02431    struct ast_config_engine *eng;
02432    char db[256];
02433    char table[256];
02434    va_list ap;
02435    int res = -1, i;
02436 
02437    va_start(ap, family);
02438    for (i = 1; ; i++) {
02439       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02440          /* If the require succeeds, it returns 0. */
02441          if (eng->require_func && !(res = eng->require_func(db, table, ap))) {
02442             break;
02443          }
02444       } else {
02445          break;
02446       }
02447    }
02448    va_end(ap);
02449 
02450    return res;
02451 }

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 2549 of file config.c.

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

Referenced by ast_queue_log(), cli_realtime_store(), and function_realtime_store().

02550 {
02551    struct ast_config_engine *eng;
02552    int res = -1, i;
02553    char db[256];
02554    char table[256];
02555    va_list ap;
02556 
02557    va_start(ap, family);
02558    for (i = 1; ; i++) {
02559       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02560          /* If the store succeeds, it returns 0. */
02561          if (eng->store_func && !(res = eng->store_func(db, table, ap))) {
02562             break;
02563          }
02564       } else {
02565          break;
02566       }
02567    }
02568    va_end(ap);
02569 
02570    return res;
02571 }

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 2453 of file config.c.

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

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

02454 {
02455    struct ast_config_engine *eng;
02456    char db[256];
02457    char table[256];
02458    int res = -1, i;
02459 
02460    for (i = 1; ; i++) {
02461       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02462          if (eng->unload_func) {
02463             /* Do this for ALL engines */
02464             res = eng->unload_func(db, table);
02465          }
02466       } else {
02467          break;
02468       }
02469    }
02470    return res;
02471 }

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 2526 of file config.c.

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

Referenced by change_password_realtime(), and cli_realtime_update2().

02527 {
02528    struct ast_config_engine *eng;
02529    int res = -1, i;
02530    char db[256];
02531    char table[256];
02532    va_list ap;
02533 
02534    va_start(ap, family);
02535    for (i = 1; ; i++) {
02536       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02537          if (eng->update2_func && !(res = eng->update2_func(db, table, ap))) {
02538             break;
02539          }
02540       } else {
02541          break;
02542       }
02543    }
02544    va_end(ap);
02545 
02546    return res;
02547 }

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 2502 of file config.c.

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

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

02503 {
02504    struct ast_config_engine *eng;
02505    int res = -1, i;
02506    char db[256];
02507    char table[256];
02508    va_list ap;
02509 
02510    va_start(ap, lookup);
02511    for (i = 1; ; i++) {
02512       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02513          /* If the update succeeds, it returns 0. */
02514          if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, ap))) {
02515             break;
02516          }
02517       } else {
02518          break;
02519       }
02520    }
02521    va_end(ap);
02522 
02523    return res;
02524 }

void ast_variable_append ( struct ast_category category,
struct ast_variable variable 
)

Definition at line 475 of file config.c.

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

Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), handle_updates(), inherit_category(), move_variables(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_odbc(), realtime_multi_pgsql(), vm_change_password(), and write_password_to_file().

00476 {
00477    if (!variable)
00478       return;
00479    if (category->last)
00480       category->last->next = variable;
00481    else
00482       category->root = variable;
00483    category->last = variable;
00484    while (category->last->next)
00485       category->last = category->last->next;
00486 }

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

Goes through variables.

Somewhat similar in intent as the ast_category_browse. List variables of config file category

Return values:
ast_variable list on success
NULL on failure

Definition at line 565 of file config.c.

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

Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), action_getconfig(), action_getconfigjson(), actual_load_config(), adsi_load(), aji_load_config(), ast_cli_perms_init(), ast_plc_reload(), ast_readconfig(), ast_variable_retrieve(), build_calendar(), build_device(), build_event_channel(), caldav_load_calendar(), conf_exec(), config_load(), config_module(), do_say(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), jingle_load_config(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), misdn_cfg_init(), odbc_load_module(), osp_create_provider(), parse_config(), parse_tone_zone(), pbx_load_config(), process_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_single_queue(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().

00566 {
00567    struct ast_category *cat = NULL;
00568 
00569    if (!category) {
00570       return NULL;
00571    }
00572 
00573    if (config->last_browse && (config->last_browse->name == category)) {
00574       cat = config->last_browse;
00575    } else {
00576       cat = ast_category_get(config, category);
00577    }
00578 
00579    return (cat) ? cat->root : NULL;
00580 }

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

Definition at line 861 of file config.c.

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

Referenced by handle_updates().

00862 {
00863    struct ast_variable *cur, *prev=NULL, *curn;
00864    int res = -1;
00865    int num_item = 0;
00866    int req_item;
00867 
00868    req_item = -1;
00869    if (!ast_strlen_zero(line)) {
00870       /* Requesting to delete by item number. */
00871       if (sscanf(line, "%30d", &req_item) != 1
00872          || req_item < 0) {
00873          /* Invalid item number to delete. */
00874          return -1;
00875       }
00876    }
00877 
00878    prev = NULL;
00879    cur = category->root;
00880    while (cur) {
00881       curn = cur->next;
00882       /* Delete by item number or by variable name with optional value. */
00883       if ((0 <= req_item && num_item == req_item)
00884          || (req_item < 0 && !strcasecmp(cur->name, variable)
00885             && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
00886          if (prev) {
00887             prev->next = cur->next;
00888             if (cur == category->last)
00889                category->last = prev;
00890          } else {
00891             category->root = cur->next;
00892             if (cur == category->last)
00893                category->last = NULL;
00894          }
00895          ast_variable_destroy(cur);
00896          res = 0;
00897       } else
00898          prev = cur;
00899 
00900       cur = curn;
00901       ++num_item;
00902    }
00903    return res;
00904 }

static void ast_variable_destroy ( struct ast_variable doomed  )  [static]

Definition at line 524 of file config.c.

References ast_comment_destroy(), ast_free, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.

Referenced by ast_include_rename(), ast_load_realtime(), ast_variable_delete(), ast_variable_update(), and ast_variables_destroy().

00525 {
00526    ast_comment_destroy(&doomed->precomments);
00527    ast_comment_destroy(&doomed->sameline);
00528    ast_comment_destroy(&doomed->trailing);
00529    ast_free(doomed);
00530 }

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

Definition at line 488 of file config.c.

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

Referenced by handle_updates().

00489 {
00490    struct ast_variable *cur = category->root;
00491    int lineno;
00492    int insertline;
00493 
00494    if (!variable || sscanf(line, "%30d", &insertline) != 1) {
00495       return;
00496    }
00497    if (!insertline) {
00498       variable->next = category->root;
00499       category->root = variable;
00500    } else {
00501       for (lineno = 1; lineno < insertline; lineno++) {
00502          cur = cur->next;
00503          if (!cur->next) {
00504             break;
00505          }
00506       }
00507       variable->next = cur->next;
00508       cur->next = variable;
00509    }
00510 }

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

Definition at line 311 of file config.c.

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

Referenced by ast_include_rename(), and ast_variable_update().

00312 {
00313    dst_var->lineno = src_var->lineno;
00314    dst_var->object = src_var->object;
00315    dst_var->blanklines = src_var->blanklines;
00316    dst_var->precomments = src_var->precomments;
00317    src_var->precomments = NULL;
00318    dst_var->sameline = src_var->sameline;
00319    src_var->sameline = NULL;
00320    dst_var->trailing = src_var->trailing;
00321    src_var->trailing = NULL;
00322 }

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

Definition at line 270 of file config.c.

References __ast_calloc(), ast_calloc, and MIN_VARIABLE_FNAME_SPACE.

Referenced by add_cfg_entry(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), apply_outgoing(), ast_channeltype_list(), ast_include_rename(), ast_variable_update(), ast_variables_dup(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), dup_vars(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), man_do_variable_value(), manager_sipnotify(), parkandannounce_exec(), parse_cookies(), process_text_line(), realtime_curl(), realtime_directory(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_multi_curl(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_odbc(), realtime_pgsql(), sip_cli_notify(), variable_clone(), vm_change_password(), and write_password_to_file().

00272 {
00273    struct ast_variable *variable;
00274    int name_len = strlen(name) + 1;
00275    int val_len = strlen(value) + 1;
00276    int fn_len = strlen(filename) + 1;
00277 
00278    /* Ensure a minimum length in case the filename is changed later. */
00279    if (fn_len < MIN_VARIABLE_FNAME_SPACE) {
00280       fn_len = MIN_VARIABLE_FNAME_SPACE;
00281    }
00282 
00283    if (
00284 #ifdef MALLOC_DEBUG
00285       (variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable), file, lineno, func))
00286 #else
00287       (variable = ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable)))
00288 #endif
00289       ) {
00290       char *dst = variable->stuff;  /* writable space starts here */
00291 
00292       /* Put file first so ast_include_rename() can calculate space available. */
00293       variable->file = strcpy(dst, filename);
00294       dst += fn_len;
00295       variable->name = strcpy(dst, name);
00296       dst += name_len;
00297       variable->value = strcpy(dst, value);
00298    }
00299    return variable;
00300 }

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

Gets a variable.

Parameters:
config which (opened) config to use
category category under which the variable lies
variable which variable you wish to get the data for
Goes through a given config file in the given category and searches for the given variable

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

Definition at line 593 of file config.c.

References ast_variable_browse(), config, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __ast_udptl_reload(), _dsp_init(), actual_load_config(), advanced_options(), aji_load_config(), ast_config_option(), build_extension(), conf_exec(), config_function_read(), config_module(), directory_exec(), do_reload(), festival_exec(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), gtalk_load_config(), iax_template_parse(), init_acf_query(), init_logger_chain(), initialize_cc_max_requests(), jingle_load_config(), load_config(), load_config_meetme(), load_indications(), load_module(), load_tech_calendars(), make_email_file(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queue_set_global_params(), read_agent_config(), read_password_from_file(), realtime_directory(), reload_config(), reload_followme(), reload_single_queue(), rtp_reload(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), update_realtime_members(), vm_change_password(), and vm_forwardoptions().

00594 {
00595    struct ast_variable *v;
00596 
00597    if (category) {
00598       for (v = ast_variable_browse(config, category); v; v = v->next) {
00599          if (!strcasecmp(variable, v->name)) {
00600             return v->value;
00601          }
00602       }
00603    } else {
00604       struct ast_category *cat;
00605 
00606       for (cat = config->root; cat; cat = cat->next) {
00607          for (v = cat->root; v; v = v->next) {
00608             if (!strcasecmp(variable, v->name)) {
00609                return v->value;
00610             }
00611          }
00612       }
00613    }
00614 
00615    return NULL;
00616 }

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 906 of file config.c.

References ast_strlen_zero(), ast_variable_destroy(), ast_variable_move(), ast_variable_new(), ast_variable::file, ast_category::last, ast_variable::name, ast_variable::next, ast_category::root, and ast_variable::value.

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

00908 {
00909    struct ast_variable *cur, *prev=NULL, *newer=NULL;
00910 
00911    for (cur = category->root; cur; prev = cur, cur = cur->next) {
00912       if (strcasecmp(cur->name, variable) ||
00913          (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
00914          continue;
00915 
00916       if (!(newer = ast_variable_new(variable, value, cur->file)))
00917          return -1;
00918 
00919       ast_variable_move(newer, cur);
00920       newer->object = newer->object || object;
00921 
00922       /* Replace the old node in the list with the new node. */
00923       newer->next = cur->next;
00924       if (prev)
00925          prev->next = newer;
00926       else
00927          category->root = newer;
00928       if (category->last == cur)
00929          category->last = newer;
00930 
00931       ast_variable_destroy(cur);
00932 
00933       return 0;
00934    }
00935 
00936    /* Could not find variable to update */
00937    return -1;
00938 }

void ast_variables_destroy ( struct ast_variable var  ) 

Free variable list.

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

Definition at line 554 of file config.c.

References ast_variable_destroy(), and ast_variable::next.

Referenced by __sip_destroy(), action_originate(), ast_category_destroy(), ast_category_empty(), ast_http_get_cookies(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variables_dup(), build_peer(), build_user(), check_peer_ok(), cli_realtime_load(), conf_run(), destroy_dahdi_pvt(), destroy_fast_originate_helper(), dup_vars(), find_conf_realtime(), find_realtime(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), get_insecure_variable_from_sipregs(), handle_uri(), httpd_helper_thread(), httpstatus_callback(), ldap_loadentry(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), parkandannounce_exec(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_common(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_user(), rt_extend_conf(), sip_destroy_peer(), socket_process(), table_configs_free(), and user_destructor().

00555 {
00556    struct ast_variable *vn;
00557 
00558    while (v) {
00559       vn = v;
00560       v = v->next;
00561       ast_variable_destroy(vn);
00562    }
00563 }

struct ast_variable* ast_variables_dup ( struct ast_variable var  ) 

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 532 of file config.c.

References ast_variable_new(), ast_variables_destroy(), ast_variable::next, and var.

Referenced by get_insecure_variable_from_sippeers(), and get_insecure_variable_from_sipregs().

00533 {
00534    struct ast_variable *cloned;
00535    struct ast_variable *tmp;
00536 
00537    if (!(cloned = ast_variable_new(var->name, var->value, var->file))) {
00538       return NULL;
00539    }
00540 
00541    tmp = cloned;
00542 
00543    while ((var = var->next)) {
00544       if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) {
00545          ast_variables_destroy(cloned);
00546          return NULL;
00547       }
00548       tmp = tmp->next;
00549    }
00550 
00551    return cloned;
00552 }

static struct ast_category* category_get ( const struct ast_config config,
const char *  category_name,
int  ignored 
) [static]

Definition at line 659 of file config.c.

References config, ast_category::ignored, ast_category::name, and ast_category::next.

Referenced by ast_category_get(), and process_text_line().

00660 {
00661    struct ast_category *cat;
00662 
00663    /* try exact match first, then case-insensitive match */
00664    for (cat = config->root; cat; cat = cat->next) {
00665       if (cat->name == category_name && (ignored || !cat->ignored))
00666          return cat;
00667    }
00668 
00669    for (cat = config->root; cat; cat = cat->next) {
00670       if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
00671          return cat;
00672    }
00673 
00674    return NULL;
00675 }

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

Definition at line 112 of file config.c.

References ast_str_append().

Referenced by config_text_file_load().

00113 {
00114    ast_str_append(cb, 0, "%s", str);
00115 }

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

Definition at line 117 of file config.c.

References ast_copy_string(), and ast_str_append().

Referenced by config_text_file_load().

00118 {
00119    char *s = alloca(len + 1);
00120    ast_copy_string(s, str, len);
00121    ast_str_append(cb, 0, "%s", str);
00122 }

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

Definition at line 124 of file config.c.

References ast_str_reset().

Referenced by config_text_file_load(), and process_text_line().

00125 { 
00126    if (cb) {
00127       ast_str_reset(cb);
00128    }
00129    if (llb) {
00130       ast_str_reset(llb);
00131    }
00132 }

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

Definition at line 1040 of file config.c.

References ast_calloc.

Referenced by config_cache_attribute(), and config_text_file_load().

01041 {
01042    struct cache_file_mtime *cfmtime;
01043    char *dst;
01044 
01045    cfmtime = ast_calloc(1,
01046       sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
01047    if (!cfmtime) {
01048       return NULL;
01049    }
01050    dst = cfmtime->filename;   /* writable space starts here */
01051    strcpy(dst, filename);
01052    dst += strlen(dst) + 1;
01053    cfmtime->who_asked = strcpy(dst, who_asked);
01054 
01055    return cfmtime;
01056 }

static void clear_config_maps ( void   )  [static]

Definition at line 2070 of file config.c.

References ast_free, ast_mutex_lock, ast_mutex_unlock, config_lock, config_maps, map, and ast_config_map::next.

Referenced by read_config_maps().

02071 {
02072    struct ast_config_map *map;
02073 
02074    ast_mutex_lock(&config_lock);
02075 
02076    while (config_maps) {
02077       map = config_maps;
02078       config_maps = config_maps->next;
02079       ast_free(map);
02080    }
02081       
02082    ast_mutex_unlock(&config_lock);
02083 }

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 1063 of file config.c.

References ast_calloc, AST_LIST_INSERT_SORTALPHA, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, cfmtime_new(), cache_file_mtime::filename, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, cache_file_mtime::mtime, and cache_file_mtime::who_asked.

Referenced by process_text_line().

01064 {
01065    struct cache_file_mtime *cfmtime;
01066    struct cache_file_include *cfinclude;
01067    struct stat statbuf = { 0, };
01068 
01069    /* Find our cached entry for this configuration file */
01070    AST_LIST_LOCK(&cfmtime_head);
01071    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
01072       if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
01073          break;
01074    }
01075    if (!cfmtime) {
01076       cfmtime = cfmtime_new(configfile, who_asked);
01077       if (!cfmtime) {
01078          AST_LIST_UNLOCK(&cfmtime_head);
01079          return;
01080       }
01081       /* Note that the file mtime is initialized to 0, i.e. 1970 */
01082       AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
01083    }
01084 
01085    if (!stat(configfile, &statbuf))
01086       cfmtime->mtime = 0;
01087    else
01088       cfmtime->mtime = statbuf.st_mtime;
01089 
01090    switch (attrtype) {
01091    case ATTRIBUTE_INCLUDE:
01092       AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
01093          if (!strcmp(cfinclude->include, filename)) {
01094             AST_LIST_UNLOCK(&cfmtime_head);
01095             return;
01096          }
01097       }
01098       cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
01099       if (!cfinclude) {
01100          AST_LIST_UNLOCK(&cfmtime_head);
01101          return;
01102       }
01103       strcpy(cfinclude->include, filename);
01104       AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
01105       break;
01106    case ATTRIBUTE_EXEC:
01107       cfmtime->has_exec = 1;
01108       break;
01109    }
01110    AST_LIST_UNLOCK(&cfmtime_head);
01111 }

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

Definition at line 1368 of file config.c.

References ALLOC_COMMENT(), ast_clear_flag, ast_config_AST_CONFIG_DIR, ast_config_get_current_category(), ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_SORTALPHA, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_strlen(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, cfmtime_new(), comment, COMMENT_META, COMMENT_TAG, CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, GLOB_ABORTED, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, cache_file_mtime::mtime, MY_GLOB_FLAGS, process_text_line(), ast_variable::trailing, ast_category::trailing, and cache_file_mtime::who_asked.

01369 {
01370    char fn[256];
01371 #if defined(LOW_MEMORY)
01372    char buf[512];
01373 #else
01374    char buf[8192];
01375 #endif
01376    char *new_buf, *comment_p, *process_buf;
01377    FILE *f;
01378    int lineno=0;
01379    int comment = 0, nest[MAX_NESTED_COMMENTS];
01380    struct ast_category *cat = NULL;
01381    int count = 0;
01382    struct stat statbuf;
01383    struct cache_file_mtime *cfmtime = NULL;
01384    struct cache_file_include *cfinclude;
01385    struct ast_variable *last_var = 0;
01386    struct ast_category *last_cat = 0;
01387    /*! Growable string buffer */
01388    struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/
01389    struct ast_str *lline_buffer = NULL;   /*!< A buffer for stuff behind the ; */
01390 
01391    if (cfg)
01392       cat = ast_config_get_current_category(cfg);
01393 
01394    if (filename[0] == '/') {
01395       ast_copy_string(fn, filename, sizeof(fn));
01396    } else {
01397       snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
01398    }
01399 
01400    if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01401       comment_buffer = ast_str_create(CB_SIZE);
01402       if (comment_buffer)
01403          lline_buffer = ast_str_create(CB_SIZE);
01404       if (!lline_buffer) {
01405          ast_free(comment_buffer);
01406          ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
01407          return NULL;
01408       }
01409    }
01410 #ifdef AST_INCLUDE_GLOB
01411    {
01412       int glob_ret;
01413       glob_t globbuf;
01414       globbuf.gl_offs = 0; /* initialize it to silence gcc */
01415       glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf);
01416       if (glob_ret == GLOB_NOSPACE)
01417          ast_log(LOG_WARNING,
01418             "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
01419       else if (glob_ret  == GLOB_ABORTED)
01420          ast_log(LOG_WARNING,
01421             "Glob Expansion of pattern '%s' failed: Read error\n", fn);
01422       else  {
01423          /* loop over expanded files */
01424          int i;
01425          for (i=0; i<globbuf.gl_pathc; i++) {
01426             ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
01427 #endif
01428    /*
01429     * The following is not a loop, but just a convenient way to define a block
01430     * (using do { } while(0) ), and be able to exit from it with 'continue'
01431     * or 'break' in case of errors. Nice trick.
01432     */
01433    do {
01434       if (stat(fn, &statbuf))
01435          continue;
01436 
01437       if (!S_ISREG(statbuf.st_mode)) {
01438          ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
01439          continue;
01440       }
01441 
01442       if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01443          /* Find our cached entry for this configuration file */
01444          AST_LIST_LOCK(&cfmtime_head);
01445          AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
01446             if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked))
01447                break;
01448          }
01449          if (!cfmtime) {
01450             cfmtime = cfmtime_new(fn, who_asked);
01451             if (!cfmtime)
01452                continue;
01453             /* Note that the file mtime is initialized to 0, i.e. 1970 */
01454             AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
01455          }
01456       }
01457 
01458       if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) {
01459          /* File is unchanged, what about the (cached) includes (if any)? */
01460          int unchanged = 1;
01461          AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
01462             /* We must glob here, because if we did not, then adding a file to globbed directory would
01463              * incorrectly cause no reload to be necessary. */
01464             char fn2[256];
01465 #ifdef AST_INCLUDE_GLOB
01466             int glob_return;
01467             glob_t glob_buf = { .gl_offs = 0 };
01468             glob_return = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &glob_buf);
01469             /* On error, we reparse */
01470             if (glob_return == GLOB_NOSPACE || glob_return  == GLOB_ABORTED)
01471                unchanged = 0;
01472             else  {
01473                /* loop over expanded files */
01474                int j;
01475                for (j = 0; j < glob_buf.gl_pathc; j++) {
01476                   ast_copy_string(fn2, glob_buf.gl_pathv[j], sizeof(fn2));
01477 #else
01478                   ast_copy_string(fn2, cfinclude->include);
01479 #endif
01480                   if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) {
01481                      /* that second-to-last field needs to be looked at in this case... TODO */
01482                      unchanged = 0;
01483                      /* One change is enough to short-circuit and reload the whole shebang */
01484                      break;
01485                   }
01486 #ifdef AST_INCLUDE_GLOB
01487                }
01488             }
01489 #endif
01490          }
01491 
01492          if (unchanged) {
01493             AST_LIST_UNLOCK(&cfmtime_head);
01494             ast_free(comment_buffer);
01495             ast_free(lline_buffer);
01496             return CONFIG_STATUS_FILEUNCHANGED;
01497          }
01498       }
01499       if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01500          AST_LIST_UNLOCK(&cfmtime_head);
01501 
01502       /* If cfg is NULL, then we just want an answer */
01503       if (cfg == NULL) {
01504          ast_free(comment_buffer);
01505          ast_free(lline_buffer);
01506          return NULL;
01507       }
01508 
01509       if (cfmtime)
01510          cfmtime->mtime = statbuf.st_mtime;
01511 
01512       ast_verb(2, "Parsing '%s': ", fn);
01513          fflush(stdout);
01514       if (!(f = fopen(fn, "r"))) {
01515          ast_debug(1, "No file to parse: %s\n", fn);
01516          ast_verb(2, "Not found (%s)\n", strerror(errno));
01517          continue;
01518       }
01519       count++;
01520       /* If we get to this point, then we're loading regardless */
01521       ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED);
01522       ast_debug(1, "Parsing %s\n", fn);
01523       ast_verb(2, "Found\n");
01524       while (!feof(f)) {
01525          lineno++;
01526          if (fgets(buf, sizeof(buf), f)) {
01527             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && ast_str_strlen(lline_buffer)) {
01528                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01529                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01530             }
01531             
01532             new_buf = buf;
01533             if (comment) 
01534                process_buf = NULL;
01535             else
01536                process_buf = buf;
01537             
01538             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer) && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) {
01539                /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */
01540                CB_ADD(&comment_buffer, "\n");       /* add a newline to the comment buffer */
01541                continue; /* go get a new line, then */
01542             }
01543             
01544             while ((comment_p = strchr(new_buf, COMMENT_META))) {
01545                if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) {
01546                   /* Escaped semicolons aren't comments. */
01547                   new_buf = comment_p;
01548                   /* write over the \ and bring the null terminator with us */
01549                   memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
01550                } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
01551                   /* Meta-Comment start detected ";--" */
01552                   if (comment < MAX_NESTED_COMMENTS) {
01553                      *comment_p = '\0';
01554                      new_buf = comment_p + 3;
01555                      comment++;
01556                      nest[comment-1] = lineno;
01557                   } else {
01558                      ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
01559                   }
01560                } else if ((comment_p >= new_buf + 2) &&
01561                      (*(comment_p - 1) == COMMENT_TAG) &&
01562                      (*(comment_p - 2) == COMMENT_TAG)) {
01563                   /* Meta-Comment end detected */
01564                   comment--;
01565                   new_buf = comment_p + 1;
01566                   if (!comment) {
01567                      /* Back to non-comment now */
01568                      if (process_buf) {
01569                         /* Actually have to move what's left over the top, then continue */
01570                         char *oldptr;
01571                         oldptr = process_buf + strlen(process_buf);
01572                         if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01573                            CB_ADD(&comment_buffer, ";");
01574                            CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
01575                         }
01576                         
01577                         memmove(oldptr, new_buf, strlen(new_buf) + 1);
01578                         new_buf = oldptr;
01579                      } else
01580                         process_buf = new_buf;
01581                   }
01582                } else {
01583                   if (!comment) {
01584                      /* If ; is found, and we are not nested in a comment, 
01585                         we immediately stop all comment processing */
01586                      if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01587                         CB_ADD(&lline_buffer, comment_p);
01588                      }
01589                      *comment_p = '\0'; 
01590                      new_buf = comment_p;
01591                   } else
01592                      new_buf = comment_p + 1;
01593                }
01594             }
01595             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) {
01596                CB_ADD(&comment_buffer, buf);  /* the whole line is a comment, store it */
01597             }
01598             
01599             if (process_buf) {
01600                char *buffer = ast_strip(process_buf);
01601                if (!ast_strlen_zero(buffer)) {
01602                   if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) {
01603                      cfg = CONFIG_STATUS_FILEINVALID;
01604                      break;
01605                   }
01606                }
01607             }
01608          }
01609       }
01610       /* end of file-- anything in a comment buffer? */
01611       if (last_cat) {
01612          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01613             if (lline_buffer && ast_str_strlen(lline_buffer)) {
01614                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01615                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01616             }
01617             last_cat->trailing = ALLOC_COMMENT(comment_buffer);
01618          }
01619       } else if (last_var) {
01620          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01621             if (lline_buffer && ast_str_strlen(lline_buffer)) {
01622                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01623                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01624             }
01625             last_var->trailing = ALLOC_COMMENT(comment_buffer);
01626          }
01627       } else {
01628          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01629             ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer));
01630          }
01631       }
01632       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01633          CB_RESET(comment_buffer, lline_buffer);
01634 
01635       fclose(f);
01636    } while (0);
01637    if (comment) {
01638       ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
01639    }
01640 #ifdef AST_INCLUDE_GLOB
01641                if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
01642                   break;
01643                }
01644             }
01645             globfree(&globbuf);
01646          }
01647       }
01648 #endif
01649 
01650    if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01651       ast_free(comment_buffer);
01652       ast_free(lline_buffer);
01653       comment_buffer = NULL;
01654       lline_buffer = NULL;
01655    }
01656 
01657    if (count == 0)
01658       return NULL;
01659 
01660    return cfg;
01661 }

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

Definition at line 1810 of file config.c.

References ast_config_text_file_save().

01811 {
01812    return ast_config_text_file_save(configfile, cfg, generator);
01813 }

static int count_linefeeds ( char *  str  )  [static]

Definition at line 1751 of file config.c.

Referenced by count_linefeeds_in_comments().

01752 {
01753    int count = 0;
01754 
01755    while (*str) {
01756       if (*str =='\n')
01757          count++;
01758       str++;
01759    }
01760    return count;
01761 }

static int count_linefeeds_in_comments ( struct ast_comment x  )  [static]

Definition at line 1763 of file config.c.

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

Referenced by insert_leading_blank_lines().

01764 {
01765    int count = 0;
01766 
01767    while (x) {
01768       count += count_linefeeds(x->cmt);
01769       x = x->next;
01770    }
01771    return count;
01772 }

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

Find realtime engine for realtime family.

Definition at line 2243 of file config.c.

References ast_copy_string(), ast_mutex_lock, config_lock, config_maps, and map.

Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime(), ast_load_realtime_helper(), ast_load_realtime_multientry(), ast_realtime_require_field(), ast_speech_new(), ast_speech_register(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), and ast_update_realtime().

02244 {
02245    struct ast_config_engine *eng, *ret = NULL;
02246    struct ast_config_map *map;
02247 
02248    ast_mutex_lock(&config_lock);
02249 
02250    for (map = config_maps; map; map = map->next) {
02251       if (!strcasecmp(family, map->name) && (priority == map->priority)) {
02252          if (database)
02253             ast_copy_string(database, map->database, dbsiz);
02254          if (table)
02255             ast_copy_string(table, map->table ? map->table : family, tabsiz);
02256          break;
02257       }
02258    }
02259 
02260    /* Check if the required driver (engine) exist */
02261    if (map) {
02262       for (eng = config_engine_list; !ret && eng; eng = eng->next) {
02263          if (!strcasecmp(eng->name, map->driver))
02264             ret = eng;
02265       }
02266    }
02267 
02268    ast_mutex_unlock(&config_lock);
02269    
02270    /* if we found a mapping, but the engine is not available, then issue a warning */
02271    if (map && !ret)
02272       ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
02273 
02274    return ret;
02275 }

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

Definition at line 1684 of file config.c.

References ast_copy_string().

Referenced by ast_config_text_file_save().

01685 {
01686    char date[256]="";
01687    time_t t;
01688 
01689    time(&t);
01690    ast_copy_string(date, ctime(&t), sizeof(date));
01691 
01692    fprintf(f1, ";!\n");
01693    fprintf(f1, ";! Automatically generated configuration file\n");
01694    if (strcmp(configfile, fn))
01695       fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
01696    else
01697       fprintf(f1, ";! Filename: %s\n", configfile);
01698    fprintf(f1, ";! Generator: %s\n", generator);
01699    fprintf(f1, ";! Creation Date: %s", date);
01700    fprintf(f1, ";!\n");
01701 }

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

Definition at line 2923 of file config.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, cache_file_mtime::list, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.

02924 {
02925    struct cache_file_mtime *cfmtime;
02926 
02927    switch (cmd) {
02928    case CLI_INIT:
02929       e->command = "config list";
02930       e->usage =
02931          "Usage: config list\n"
02932          "   Show all modules that have loaded a configuration file\n";
02933       return NULL;
02934    case CLI_GENERATE:
02935       return NULL;
02936    }
02937 
02938    AST_LIST_LOCK(&cfmtime_head);
02939    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
02940       ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
02941    }
02942    AST_LIST_UNLOCK(&cfmtime_head);
02943 
02944    return CLI_SUCCESS;
02945 }

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

Definition at line 2861 of file config.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli_command, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, cache_file_mtime::filename, cache_file_mtime::list, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.

02862 {
02863    struct cache_file_mtime *cfmtime;
02864    char *prev = "", *completion_value = NULL;
02865    int wordlen, which = 0;
02866 
02867    switch (cmd) {
02868    case CLI_INIT:
02869       e->command = "config reload";
02870       e->usage =
02871          "Usage: config reload <filename.conf>\n"
02872          "   Reloads all modules that reference <filename.conf>\n";
02873       return NULL;
02874    case CLI_GENERATE:
02875       if (a->pos > 2) {
02876          return NULL;
02877       }
02878 
02879       wordlen = strlen(a->word);
02880 
02881       AST_LIST_LOCK(&cfmtime_head);
02882       AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
02883          /* Skip duplicates - this only works because the list is sorted by filename */
02884          if (strcmp(cfmtime->filename, prev) == 0) {
02885             continue;
02886          }
02887 
02888          /* Core configs cannot be reloaded */
02889          if (ast_strlen_zero(cfmtime->who_asked)) {
02890             continue;
02891          }
02892 
02893          if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) {
02894             completion_value = ast_strdup(cfmtime->filename);
02895             break;
02896          }
02897 
02898          /* Otherwise save that we've seen this filename */
02899          prev = cfmtime->filename;
02900       }
02901       AST_LIST_UNLOCK(&cfmtime_head);
02902 
02903       return completion_value;
02904    }
02905 
02906    if (a->argc != 3) {
02907       return CLI_SHOWUSAGE;
02908    }
02909 
02910    AST_LIST_LOCK(&cfmtime_head);
02911    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
02912       if (!strcmp(cfmtime->filename, a->argv[2])) {
02913          char *buf = alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
02914          sprintf(buf, "module reload %s", cfmtime->who_asked);
02915          ast_cli_command(a->fd, buf);
02916       }
02917    }
02918    AST_LIST_UNLOCK(&cfmtime_head);
02919 
02920    return CLI_SUCCESS;
02921 }

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

Definition at line 2824 of file config.c.

References ast_cli(), ast_mutex_lock, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, config_engine_list, config_lock, config_maps, ast_cli_args::fd, map, ast_config_engine::name, ast_config_engine::next, and ast_cli_entry::usage.

02825 {
02826    struct ast_config_engine *eng;
02827    struct ast_config_map *map;
02828 
02829    switch (cmd) {
02830    case CLI_INIT:
02831       e->command = "core show config mappings";
02832       e->usage =
02833          "Usage: core show config mappings\n"
02834          "  Shows the filenames to config engines.\n";
02835       return NULL;
02836    case CLI_GENERATE:
02837       return NULL;
02838    }
02839    
02840    ast_mutex_lock(&config_lock);
02841 
02842    if (!config_engine_list) {
02843       ast_cli(a->fd, "No config mappings found.\n");
02844    } else {
02845       for (eng = config_engine_list; eng; eng = eng->next) {
02846          ast_cli(a->fd, "Config Engine: %s\n", eng->name);
02847          for (map = config_maps; map; map = map->next) {
02848             if (!strcasecmp(map->driver, eng->name)) {
02849                ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
02850                      map->table ? map->table : map->name);
02851             }
02852          }
02853       }
02854    }
02855    
02856    ast_mutex_unlock(&config_lock);
02857 
02858    return CLI_SUCCESS;
02859 }

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

Definition at line 154 of file config.c.

References str, and total.

Referenced by ast_config_text_file_save().

00155 {
00156    char *str = ((struct inclfile *) obj)->fname;
00157    int total;
00158 
00159    for (total = 0; *str; str++) {
00160       unsigned int tmp = total;
00161       total <<= 1; /* multiply by 2 */
00162       total += tmp; /* multiply by 3 */
00163       total <<= 2; /* multiply by 12 */
00164       total += tmp; /* multiply by 13 */
00165 
00166       total += ((unsigned int) (*str));
00167    }
00168    if (total < 0) {
00169       total = -total;
00170    }
00171    return total;
00172 }

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

Definition at line 174 of file config.c.

References CMP_MATCH, CMP_STOP, and inclfile::fname.

Referenced by ast_config_text_file_save().

00175 {
00176    const struct inclfile *ae = a, *be = b;
00177    return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0;
00178 }

static void inclfile_destroy ( void *  obj  )  [static]

Definition at line 1703 of file config.c.

References ast_free, and inclfile::fname.

Referenced by set_fn().

01704 {
01705    const struct inclfile *o = obj;
01706 
01707    ast_free(o->fname);
01708 }

static void inherit_category ( struct ast_category new,
const struct ast_category base 
) [static]

Definition at line 836 of file config.c.

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

Referenced by process_text_line().

00837 {
00838    struct ast_variable *var;
00839    struct ast_category_template_instance *x;
00840 
00841    x = ast_calloc(1, sizeof(*x));
00842    if (!x) {
00843       return;
00844    }
00845    strcpy(x->name, base->name);
00846    x->inst = base;
00847    AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
00848    for (var = base->root; var; var = var->next)
00849       ast_variable_append(new, variable_clone(var));
00850 }

static int init_appendbuf ( void *  data  )  [static]

Definition at line 100 of file config.c.

References ast_str_create(), and str.

00101 {
00102    struct ast_str **str = data;
00103    *str = ast_str_create(16);
00104    return *str ? 0 : -1;
00105 }

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

Definition at line 1774 of file config.c.

References count_linefeeds_in_comments(), and inclfile::lineno.

Referenced by ast_config_text_file_save().

01775 {
01776    int precomment_lines;
01777    int i;
01778 
01779    if (!fi) {
01780       /* No file scratch pad object so insert no blank lines. */
01781       return;
01782    }
01783 
01784    precomment_lines = count_linefeeds_in_comments(precomments);
01785 
01786    /* I don't have to worry about those ;! comments, they are
01787       stored in the precomments, but not printed back out.
01788       I did have to make sure that comments following
01789       the ;! header comments were not also deleted in the process */
01790    if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */
01791       return;
01792    } else if (lineno == 0) {
01793       /* Line replacements also mess things up */
01794       return;
01795    } else if (lineno - precomment_lines - fi->lineno < 5) {
01796       /* Only insert less than 5 blank lines; if anything more occurs,
01797        * it's probably due to context deletion. */
01798       for (i = fi->lineno; i < lineno - precomment_lines; i++) {
01799          fprintf(fp, "\n");
01800       }
01801    } else {
01802       /* Deletion occurred - insert a single blank line, for separation of
01803        * contexts. */
01804       fprintf(fp, "\n");
01805    }
01806  
01807    fi->lineno = lineno + 1; /* Advance the file lineno */
01808 }

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

Definition at line 632 of file config.c.

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

Referenced by process_text_line().

00633 {
00634    struct ast_variable *var = old->root;
00635 
00636    old->root = NULL;
00637    /* we can just move the entire list in a single op */
00638    ast_variable_append(new, var);
00639 }

static struct ast_category* next_available_category ( struct ast_category cat  )  [static]

Definition at line 752 of file config.c.

References ast_category::ignored, and ast_category::next.

Referenced by ast_category_browse().

00753 {
00754    for (; cat && cat->ignored; cat = cat->next);
00755 
00756    return cat;
00757 }

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 1120 of file config.c.

References ALLOC_COMMENT(), appendbuf, ast_category_append(), ast_category_destroy(), ast_category_first(), ast_category_new(), ast_config_internal_load(), ast_include_new(), ast_log(), ast_opt_exec_includes, ast_safe_system(), ast_skip_blanks(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_trim_blanks(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_tvnow(), ast_variable_append(), ast_variable_new(), ast_variable_update(), ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, ast_variable::blanklines, category_get(), CB_RESET(), config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, ast_config::include_level, inherit_category(), ast_variable::lineno, LOG_ERROR, LOG_WARNING, move_variables(), ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), and var.

Referenced by config_text_file_load().

01126 {
01127    char *c;
01128    char *cur = buf;
01129    struct ast_variable *v;
01130    char cmd[512], exec_file[512];
01131 
01132    /* Actually parse the entry */
01133    if (cur[0] == '[') { /* A category header */
01134       /* format is one of the following:
01135        * [foo] define a new category named 'foo'
01136        * [foo](!) define a new template category named 'foo'
01137        * [foo](+) append to category 'foo', error if foo does not exist.
01138        * [foo](a) define a new category and inherit from template a.
01139        *    You can put a comma-separated list of templates and '!' and '+'
01140        *    between parentheses, with obvious meaning.
01141        */
01142       struct ast_category *newcat = NULL;
01143       char *catname;
01144 
01145       c = strchr(cur, ']');
01146       if (!c) {
01147          ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
01148          return -1;
01149       }
01150       *c++ = '\0';
01151       cur++;
01152       if (*c++ != '(')
01153          c = NULL;
01154       catname = cur;
01155       if (!(*cat = newcat = ast_category_new(catname,
01156             S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile),
01157             lineno))) {
01158          return -1;
01159       }
01160       (*cat)->lineno = lineno;
01161       *last_var = 0;
01162       *last_cat = newcat;
01163       
01164       /* add comments */
01165       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01166          newcat->precomments = ALLOC_COMMENT(comment_buffer);
01167       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01168          newcat->sameline = ALLOC_COMMENT(lline_buffer);
01169       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01170          CB_RESET(comment_buffer, lline_buffer);
01171       
01172       /* If there are options or categories to inherit from, process them now */
01173       if (c) {
01174          if (!(cur = strchr(c, ')'))) {
01175             ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
01176             return -1;
01177          }
01178          *cur = '\0';
01179          while ((cur = strsep(&c, ","))) {
01180             if (!strcasecmp(cur, "!")) {
01181                (*cat)->ignored = 1;
01182             } else if (!strcasecmp(cur, "+")) {
01183                *cat = category_get(cfg, catname, 1);
01184                if (!(*cat)) {
01185                   if (newcat)
01186                      ast_category_destroy(newcat);
01187                   ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
01188                   return -1;
01189                }
01190                if (newcat) {
01191                   move_variables(newcat, *cat);
01192                   ast_category_destroy(newcat);
01193                   newcat = NULL;
01194                }
01195             } else {
01196                struct ast_category *base;
01197             
01198                base = category_get(cfg, cur, 1);
01199                if (!base) {
01200                   ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
01201                   return -1;
01202                }
01203                inherit_category(*cat, base);
01204             }
01205          }
01206       }
01207       if (newcat)
01208          ast_category_append(cfg, *cat);
01209    } else if (cur[0] == '#') { /* A directive - #include or #exec */
01210       char *cur2;
01211       char real_inclusion_name[256];
01212       int do_include = 0;  /* otherwise, it is exec */
01213 
01214       cur++;
01215       c = cur;
01216       while (*c && (*c > 32)) {
01217          c++;
01218       }
01219 
01220       if (*c) {
01221          *c = '\0';
01222          /* Find real argument */
01223          c = ast_strip(c + 1);
01224          if (!(*c)) {
01225             c = NULL;
01226          }
01227       } else {
01228          c = NULL;
01229       }
01230       if (!strcasecmp(cur, "include")) {
01231          do_include = 1;
01232       } else if (!strcasecmp(cur, "exec")) {
01233          if (!ast_opt_exec_includes) {
01234             ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
01235             return 0;   /* XXX is this correct ? or we should return -1 ? */
01236          }
01237       } else {
01238          ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
01239          return 0;   /* XXX is this correct ? or we should return -1 ? */
01240       }
01241 
01242       if (c == NULL) {
01243          ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 
01244                do_include ? "include" : "exec",
01245                do_include ? "filename" : "/path/to/executable",
01246                lineno,
01247                configfile);
01248          return 0;   /* XXX is this correct ? or we should return -1 ? */
01249       }
01250 
01251       cur = c;
01252       /* Strip off leading and trailing "'s and <>'s */
01253       /* Dequote */
01254       if ((*c == '"') || (*c == '<')) {
01255          char quote_char = *c;
01256          if (quote_char == '<') {
01257             quote_char = '>';
01258          }
01259 
01260          if (*(c + strlen(c) - 1) == quote_char) {
01261             cur++;
01262             *(c + strlen(c) - 1) = '\0';
01263          }
01264       }
01265       cur2 = cur;
01266 
01267       /* #exec </path/to/executable>
01268          We create a tmp file, then we #include it, then we delete it. */
01269       if (!do_include) {
01270          struct timeval now = ast_tvnow();
01271          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01272             config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked);
01273          snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self());
01274          snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
01275          ast_safe_system(cmd);
01276          cur = exec_file;
01277       } else {
01278          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01279             config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked);
01280          exec_file[0] = '\0';
01281       }
01282       /* A #include */
01283       /* record this inclusion */
01284       ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
01285 
01286       do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0;
01287       if (!ast_strlen_zero(exec_file))
01288          unlink(exec_file);
01289       if (!do_include) {
01290          ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur);
01291          return -1;
01292       }
01293       /* XXX otherwise what ? the default return is 0 anyways */
01294 
01295    } else {
01296       /* Just a line (variable = value) */
01297       int object = 0;
01298       if (!(*cat)) {
01299          ast_log(LOG_WARNING,
01300             "parse error: No category context for line %d of %s\n", lineno, configfile);
01301          return -1;
01302       }
01303       c = strchr(cur, '=');
01304 
01305       if (c && c > cur && (*(c - 1) == '+')) {
01306          struct ast_variable *var, *replace = NULL;
01307          struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str));
01308 
01309          if (!str || !*str) {
01310             return -1;
01311          }
01312 
01313          *(c - 1) = '\0';
01314          c++;
01315          cur = ast_strip(cur);
01316 
01317          /* Must iterate through category until we find last variable of same name (since there could be multiple) */
01318          for (var = ast_category_first(*cat); var; var = var->next) {
01319             if (!strcmp(var->name, cur)) {
01320                replace = var;
01321             }
01322          }
01323 
01324          if (!replace) {
01325             /* Nothing to replace; just set a variable normally. */
01326             goto set_new_variable;
01327          }
01328 
01329          ast_str_set(str, 0, "%s", replace->value);
01330          ast_str_append(str, 0, "%s", c);
01331          ast_str_trim_blanks(*str);
01332          ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object);
01333       } else if (c) {
01334          *c = 0;
01335          c++;
01336          /* Ignore > in => */
01337          if (*c== '>') {
01338             object = 1;
01339             c++;
01340          }
01341 set_new_variable:
01342          if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) {
01343             v->lineno = lineno;
01344             v->object = object;
01345             *last_cat = 0;
01346             *last_var = v;
01347             /* Put and reset comments */
01348             v->blanklines = 0;
01349             ast_variable_append(*cat, v);
01350             /* add comments */
01351             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01352                v->precomments = ALLOC_COMMENT(comment_buffer);
01353             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01354                v->sameline = ALLOC_COMMENT(lline_buffer);
01355             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01356                CB_RESET(comment_buffer, lline_buffer);
01357             
01358          } else {
01359             return -1;
01360          }
01361       } else {
01362          ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
01363       }
01364    }
01365    return 0;
01366 }

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 2120 of file config.c.

References append_mapping(), ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log(), ast_variable_browse(), clear_config_maps(), config, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, ast_flags::flags, LOG_ERROR, LOG_WARNING, ast_config::max_include_level, ast_variable::name, ast_variable::next, strsep(), table, and ast_variable::value.

Referenced by main().

02121 {
02122    struct ast_config *config, *configtmp;
02123    struct ast_variable *v;
02124    char *driver, *table, *database, *textpri, *stringp, *tmp;
02125    struct ast_flags flags = { CONFIG_FLAG_NOREALTIME };
02126    int pri;
02127 
02128    clear_config_maps();
02129 
02130    configtmp = ast_config_new();
02131    if (!configtmp) {
02132       ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
02133       return -1;
02134    }
02135    configtmp->max_include_level = 1;
02136    config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
02137    if (config == CONFIG_STATUS_FILEINVALID) {
02138       return -1;
02139    } else if (!config) {
02140       ast_config_destroy(configtmp);
02141       return 0;
02142    }
02143 
02144    for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
02145       char buf[512];
02146       ast_copy_string(buf, v->value, sizeof(buf));
02147       stringp = buf;
02148       driver = strsep(&stringp, ",");
02149 
02150       if ((tmp = strchr(stringp, '\"')))
02151          stringp = tmp;
02152 
02153       /* check if the database text starts with a double quote */
02154       if (*stringp == '"') {
02155          stringp++;
02156          database = strsep(&stringp, "\"");
02157          strsep(&stringp, ",");
02158       } else {
02159          /* apparently this text has no quotes */
02160          database = strsep(&stringp, ",");
02161       }
02162 
02163       table = strsep(&stringp, ",");
02164       textpri = strsep(&stringp, ",");
02165       if (!textpri || !(pri = atoi(textpri))) {
02166          pri = 1;
02167       }
02168 
02169       if (!strcmp(v->name, extconfig_conf)) {
02170          ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
02171          continue;
02172       }
02173 
02174       if (!strcmp(v->name, "asterisk.conf")) {
02175          ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
02176          continue;
02177       }
02178 
02179       if (!strcmp(v->name, "logger.conf")) {
02180          ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
02181          continue;
02182       }
02183 
02184       if (!driver || !database)
02185          continue;
02186       if (!strcasecmp(v->name, "sipfriends")) {
02187          ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
02188          append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
02189       } else if (!strcasecmp(v->name, "iaxfriends")) {
02190          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");
02191          append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
02192          append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
02193       } else 
02194          append_mapping(v->name, driver, database, table, pri);
02195    }
02196       
02197    ast_config_destroy(config);
02198    return 0;
02199 }

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 2953 of file config.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_config.

Referenced by main().

02954 {
02955    ast_cli_register_multiple(cli_config, ARRAY_LEN(cli_config));
02956    return 0;
02957 }

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

Definition at line 1711 of file config.c.

References ao2_alloc, ao2_find, ao2_link, ao2_ref, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_strdup, ast_strlen_zero(), inclfile::fname, inclfile_destroy(), inclfile::lineno, and OBJ_POINTER.

Referenced by ast_config_text_file_save().

01712 {
01713    struct inclfile lookup;
01714    struct inclfile *fi;
01715 
01716    if (ast_strlen_zero(file)) {
01717       if (configfile[0] == '/')
01718          ast_copy_string(fn, configfile, fn_size);
01719       else
01720          snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
01721    } else if (file[0] == '/')
01722       ast_copy_string(fn, file, fn_size);
01723    else
01724       snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
01725    lookup.fname = fn;
01726    fi = ao2_find(fileset, &lookup, OBJ_POINTER);
01727    if (fi) {
01728       /* Found existing include file scratch pad. */
01729       return fi;
01730    }
01731 
01732    /* set up a file scratch pad */
01733    fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
01734    if (!fi) {
01735       /* Scratch pad creation failed. */
01736       return NULL;
01737    }
01738    fi->fname = ast_strdup(fn);
01739    if (!fi->fname) {
01740       /* Scratch pad creation failed. */
01741       ao2_ref(fi, -1);
01742       return NULL;
01743    }
01744    fi->lineno = 1;
01745 
01746    ao2_link(fileset, fi);
01747 
01748    return fi;
01749 }

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

Definition at line 618 of file config.c.

References ast_variable_new(), ast_variable::blanklines, ast_variable::file, ast_variable::lineno, ast_variable::name, ast_variable::object, and ast_variable::value.

Referenced by inherit_category().

00619 {
00620    struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
00621 
00622    if (new) {
00623       new->lineno = old->lineno;
00624       new->object = old->object;
00625       new->blanklines = old->blanklines;
00626       /* TODO: clone comments? */
00627    }
00628 
00629    return new;
00630 }


Variable Documentation

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

Definition at line 107 of file config.c.

Referenced by process_text_line().

struct ast_cli_entry cli_config[] [static]

Initial value:

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

Definition at line 2947 of file config.c.

Referenced by register_config_cli().

struct ast_config_engine* config_engine_list [static]

Definition at line 196 of file config.c.

Referenced by ast_config_engine_deregister(), ast_config_engine_register(), ast_config_internal_load(), and handle_cli_core_show_config_mappings().

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

Definition at line 195 of file config.c.

Referenced by ast_calendar_config_release(), ast_config_engine_deregister(), ast_config_engine_register(), clear_config_maps(), find_engine(), handle_cli_core_show_config_mappings(), load_config(), and load_tech_calendars().

struct ast_config_map * config_maps [static]

Referenced by append_mapping(), ast_realtime_enabled(), clear_config_maps(), find_engine(), and handle_cli_core_show_config_mappings().

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

Definition at line 69 of file config.c.

struct ast_config_engine text_file_engine [static]

Initial value:

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

Definition at line 2277 of file config.c.

Referenced by ast_config_internal_load().


Generated on Mon Oct 8 12:39:21 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7