Wed Jan 27 20:02:36 2016

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
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  cfmtime_head
struct  inclfile
struct  includes
struct  template_instance_list

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)
struct 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.
struct ast_variableast_category_first (struct ast_category *cat)
 given a pointer to a category, return the root variable.
struct ast_categoryast_category_get (const struct ast_config *config, const char *category_name)
 Retrieve a category if it exists.
int ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match)
 Inserts new category.
struct 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)
struct ast_variableast_category_root (struct ast_config *config, char *cat)
 returns the root ast_variable of a config
int ast_check_realtime (const char *family)
 Check if realtime engine is configured for family.
static void ast_comment_destroy (struct ast_comment **comment)
void ast_config_destroy (struct ast_config *cfg)
 Destroys a config.
int ast_config_engine_deregister (struct ast_config_engine *del)
 Deregister config engine.
int ast_config_engine_register (struct ast_config_engine *new)
 Register config engine.
struct ast_categoryast_config_get_current_category (const struct ast_config *cfg)
 Retrieve the current category name being built.
struct ast_configast_config_internal_load (const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
struct ast_configast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags)
 Load a config file.
struct ast_configast_config_new (void)
 Create a new base configuration structure.
const char * ast_config_option (struct ast_config *cfg, const char *cat, const char *var)
 Retrieve a configuration variable within the configuration set.
void ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat)
 Set the category within the configuration as being current.
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)
struct ast_config_includeast_include_find (struct ast_config *conf, const char *included_file)
struct ast_config_includeast_include_new (struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
void ast_include_rename (struct ast_config *conf, const char *from_file, const char *to_file)
static void ast_includes_destroy (struct ast_config_include *incls)
struct ast_variableast_load_realtime (const char *family,...)
 Retrieve realtime configuration.
struct ast_variableast_load_realtime_all (const char *family,...)
static struct ast_variableast_load_realtime_helper (const char *family, va_list ap)
struct 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,...)
 Helper function to parse arguments See documentation in config.h.
char * ast_realtime_decode_chunk (char *chunk)
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)
struct 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)
struct 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.
struct ast_variableast_variables_dup (struct ast_variable *var)
 Duplicate variable list.
struct ast_variableast_variables_reverse (struct ast_variable *var)
 Reverse a variable list.
static 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 int cfmstat_cmp (struct cache_file_mtime *cfmtime, struct stat *statbuf)
static void cfmstat_save (struct cache_file_mtime *cfmtime, struct stat *statbuf)
static struct cache_file_mtimecfmtime_new (const char *filename, const char *who_asked)
static void clear_config_maps (void)
static void config_cache_attribute (const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked)
static void config_cache_destroy_entry (struct cache_file_mtime *cfmtime)
static void config_cache_flush_includes (struct cache_file_mtime *cfmtime)
static void config_cache_remove (const char *filename, const char *who_asked)
static void config_shutdown (void)
static struct ast_configconfig_text_file_load (const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
int config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator)
static int count_linefeeds (char *str)
static int count_linefeeds_in_comments (struct ast_comment *x)
static 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 make_fn (char *fn, size_t fn_size, const char *file, const char *configfile)
static void move_variables (struct ast_category *old, struct ast_category *new)
static struct ast_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, size_t 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 116 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 206 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

Enumerator:
ATTRIBUTE_INCLUDE 
ATTRIBUTE_EXEC 

Definition at line 1094 of file config.c.

01094                                  {
01095    ATTRIBUTE_INCLUDE = 0,
01096    ATTRIBUTE_EXEC = 1,
01097 };


Function Documentation

static void __init_appendbuf ( void   )  [static]

Definition at line 113 of file config.c.

00119 {

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

Definition at line 142 of file config.c.

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

Referenced by config_text_file_load(), and process_text_line().

00143 { 
00144    struct ast_comment *x = NULL;
00145    if (!buffer || !ast_str_strlen(buffer)) {
00146       return NULL;
00147    }
00148    if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
00149       strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
00150    }
00151    return x;
00152 }

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

Definition at line 2263 of file config.c.

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

Referenced by read_config_maps().

02264 {
02265    struct ast_config_map *map;
02266    char *dst;
02267    int length;
02268 
02269    length = sizeof(*map);
02270    length += strlen(name) + 1;
02271    length += strlen(driver) + 1;
02272    length += strlen(database) + 1;
02273    if (table)
02274       length += strlen(table) + 1;
02275 
02276    if (!(map = ast_calloc(1, length)))
02277       return -1;
02278 
02279    dst = map->stuff; /* writable space starts here */
02280    map->name = strcpy(dst, name);
02281    dst += strlen(dst) + 1;
02282    map->driver = strcpy(dst, driver);
02283    dst += strlen(dst) + 1;
02284    map->database = strcpy(dst, database);
02285    if (table) {
02286       dst += strlen(dst) + 1;
02287       map->table = strcpy(dst, table);
02288    }
02289    map->priority = priority;
02290    map->next = config_maps;
02291    config_maps = map;
02292 
02293    ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
02294 
02295    return 0;
02296 }

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.

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

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

Referenced by __init_manager(), __queues_show(), action_getconfig(), action_getconfigjson(), action_listcategories(), actual_load_config(), aji_load_config(), ast_cli_perms_init(), AST_LIST_HEAD_NOLOCK(), complete_sipnotify(), conf_exec(), config_load(), find_queue_by_name_rt(), find_realtime(), 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(), process_config(), queues_data_provider_get(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), search_directory(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().

00811 {  
00812    struct ast_category *cat;
00813 
00814    if (!prev) {
00815       /* First time browse. */
00816       cat = config->root;
00817    } else if (config->last_browse && (config->last_browse->name == prev)) {
00818       /* Simple last browse found. */
00819       cat = config->last_browse->next;
00820    } else {
00821       /*
00822        * Config changed since last browse.
00823        *
00824        * First try cheap last browse search. (Rebrowsing a different
00825        * previous category?)
00826        */
00827       for (cat = config->root; cat; cat = cat->next) {
00828          if (cat->name == prev) {
00829             /* Found it. */
00830             cat = cat->next;
00831             break;
00832          }
00833       }
00834       if (!cat) {
00835          /*
00836           * Have to do it the hard way. (Last category was deleted and
00837           * re-added?)
00838           */
00839          for (cat = config->root; cat; cat = cat->next) {
00840             if (!strcasecmp(cat->name, prev)) {
00841                /* Found it. */
00842                cat = cat->next;
00843                break;
00844             }
00845          }
00846       }
00847    }
00848    
00849    if (cat)
00850       cat = next_available_category(cat);
00851 
00852    config->last_browse = cat;
00853    return (cat) ? cat->name : NULL;
00854 }

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

Definition at line 976 of file config.c.

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

Referenced by handle_updates().

00977 {
00978    struct ast_category *prev=NULL, *cat;
00979 
00980    cat = cfg->root;
00981    while (cat) {
00982       if (cat->name == category) {
00983          if (prev) {
00984             prev->next = cat->next;
00985             if (cat == cfg->last)
00986                cfg->last = prev;
00987          } else {
00988             cfg->root = cat->next;
00989             if (cat == cfg->last)
00990                cfg->last = NULL;
00991          }
00992          ast_category_destroy(cat);
00993          return 0;
00994       }
00995       prev = cat;
00996       cat = cat->next;
00997    }
00998 
00999    prev = NULL;
01000    cat = cfg->root;
01001    while (cat) {
01002       if (!strcasecmp(cat->name, category)) {
01003          if (prev) {
01004             prev->next = cat->next;
01005             if (cat == cfg->last)
01006                cfg->last = prev;
01007          } else {
01008             cfg->root = cat->next;
01009             if (cat == cfg->last)
01010                cfg->last = NULL;
01011          }
01012          ast_category_destroy(cat);
01013          return 0;
01014       }
01015       prev = cat;
01016       cat = cat->next;
01017    }
01018    return -1;
01019 }

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

Definition at line 856 of file config.c.

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

Referenced by realtime_switch_common().

00857 {
00858    struct ast_variable *v;
00859 
00860    v = cat->root;
00861    cat->root = NULL;
00862    cat->last = NULL;
00863 
00864    return v;
00865 }

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 1021 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().

01022 {
01023    struct ast_category *cat;
01024 
01025    for (cat = cfg->root; cat; cat = cat->next) {
01026       if (strcasecmp(cat->name, category))
01027          continue;
01028       ast_variables_destroy(cat->root);
01029       cat->root = NULL;
01030       cat->last = NULL;
01031       return 0;
01032    }
01033 
01034    return -1;
01035 }

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

References ast_category_get().

00715 {
00716    return !!ast_category_get(config, category_name);
00717 }

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

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

return the first var of a category

Definition at line 796 of file config.c.

References ast_category::root.

Referenced by process_text_line().

00797 {
00798    return (cat) ? cat->root : NULL;
00799 }

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

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

References category_get().

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

00710 {
00711    return category_get(config, category_name, 0);
00712 }

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

Inserts new category.

Parameters:
config which config to use
cat newly created category to insert
match which category to insert above

This function is used to insert a new category above another category matching the match parameter.

Return values:
0 if succeeded
-1 if NULL parameters or match category was not found

Definition at line 730 of file config.c.

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

Referenced by handle_updates().

00731 {
00732    struct ast_category *cur_category;
00733 
00734    if (!config || !cat || !match) {
00735       return -1;
00736    }
00737    if (!strcasecmp(config->root->name, match)) {
00738       cat->next = config->root;
00739       config->root = cat;
00740       return 0;
00741    }
00742    for (cur_category = config->root; cur_category && cur_category->next;
00743       cur_category = cur_category->next) {
00744       if (!strcasecmp(cur_category->next->name, match)) {
00745          cat->next = cur_category->next;
00746          cur_category->next = cat;
00747          return 0;
00748       }
00749    }
00750 
00751    return -1;
00752 }

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

Create a category structure.

Definition at line 673 of file config.c.

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

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().

00674 {
00675    struct ast_category *category;
00676 
00677    category = ast_calloc(1, sizeof(*category));
00678    if (!category) {
00679       return NULL;
00680    }
00681    category->file = ast_strdup(in_file);
00682    if (!category->file) {
00683       ast_category_destroy(category);
00684       return NULL;
00685    }
00686    ast_copy_string(category->name, name, sizeof(category->name));
00687    category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
00688    return category;
00689 }

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

Definition at line 867 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().

00868 {
00869    ast_copy_string(cat->name, name, sizeof(cat->name));
00870 }

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

returns the root ast_variable of a config

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

Definition at line 801 of file config.c.

References ast_category_get(), and ast_category::root.

Referenced by get_insecure_variable_from_config(), and get_insecure_variable_from_sipregs().

00802 {
00803    struct ast_category *category = ast_category_get(config, cat);
00804 
00805    if (category)
00806       return category->root;
00807    return NULL;
00808 }

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 2587 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(), leave_voicemail(), 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().

02588 {
02589    struct ast_config_engine *eng;
02590    if (!ast_realtime_enabled()) {
02591       return 0;   /* There are no engines at all so fail early */
02592    }
02593 
02594    eng = find_engine(family, 1, NULL, 0, NULL, 0);
02595    if (eng)
02596       return 1;
02597    return 0;
02598 }

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

Definition at line 520 of file config.c.

References ast_free, and ast_comment::next.

Referenced by ast_category_destroy(), and ast_variable_destroy().

00521 {
00522    struct ast_comment *n, *p;
00523 
00524    for (p = *comment; p; p = n) {
00525       n = p->next;
00526       ast_free(p);
00527    }
00528 
00529    *comment = NULL;
00530 }

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 1037 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_load(), __ast_http_post_load(), __ast_udptl_reload(), __init_manager(), __queues_show(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), aji_load_config(), ast_cli_perms_init(), ast_config_load2(), ast_load_realtime_multientry(), ast_plc_reload(), ast_readconfig(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_realtime(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), gtalk_load_config(), handle_cli_dialplan_save(), iax_provision_reload(), init_logger_chain(), initialize_cc_max_requests(), jingle_load_config(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_realtime_queue(), make_email_file(), misdn_cfg_init(), odbc_load_module(), osp_load(), parse_config(), pbx_load_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(), smdi_load(), tds_load_module(), unload_module(), update_realtime_members(), vm_change_password(), vm_forwardoptions(), and write_password_to_file().

01038 {
01039    struct ast_category *cat, *catn;
01040 
01041    if (!cfg)
01042       return;
01043 
01044    ast_includes_destroy(cfg->includes);
01045 
01046    cat = cfg->root;
01047    while (cat) {
01048       catn = cat;
01049       cat = cat->next;
01050       ast_category_destroy(catn);
01051    }
01052    ast_free(cfg);
01053 }

int ast_config_engine_deregister ( struct ast_config_engine del  ) 

Deregister config engine.

Return values:
0 Always

Definition at line 2397 of file config.c.

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

Referenced by unload_module().

02398 {
02399    struct ast_config_engine *ptr, *last=NULL;
02400 
02401    ast_mutex_lock(&config_lock);
02402 
02403    for (ptr = config_engine_list; ptr; ptr=ptr->next) {
02404       if (ptr == del) {
02405          if (last)
02406             last->next = ptr->next;
02407          else
02408             config_engine_list = ptr->next;
02409          break;
02410       }
02411       last = ptr;
02412    }
02413 
02414    ast_mutex_unlock(&config_lock);
02415 
02416    return 0;
02417 }

int ast_config_engine_register ( struct ast_config_engine newconfig  ) 

Register config engine.

Return values:
1 Always

Definition at line 2378 of file config.c.

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

Referenced by load_module().

02379 {
02380    struct ast_config_engine *ptr;
02381 
02382    ast_mutex_lock(&config_lock);
02383 
02384    if (!config_engine_list) {
02385       config_engine_list = new;
02386    } else {
02387       for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
02388       ptr->next = new;
02389    }
02390 
02391    ast_mutex_unlock(&config_lock);
02392    ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name);
02393 
02394    return 1;
02395 }

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

Retrieve the current category name being built.

API for backend configuration engines while building a configuration set.

Definition at line 1055 of file config.c.

References ast_config::current.

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

01056 {
01057    return cfg->current;
01058 }

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

Definition at line 2459 of file config.c.

References ast_log(), ast_test_flag, 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, and table.

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

02460 {
02461    char db[256];
02462    char table[256];
02463    struct ast_config_engine *loader = &text_file_engine;
02464    struct ast_config *result; 
02465 
02466    /* The config file itself bumps include_level by 1 */
02467    if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
02468       ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
02469       return NULL;
02470    }
02471 
02472    cfg->include_level++;
02473 
02474    if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) {
02475       struct ast_config_engine *eng;
02476 
02477       eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
02478 
02479 
02480       if (eng && eng->load_func) {
02481          loader = eng;
02482       } else {
02483          eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
02484          if (eng && eng->load_func)
02485             loader = eng;
02486       }
02487    }
02488 
02489    result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
02490 
02491    if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED)
02492       result->include_level--;
02493    else if (result != CONFIG_STATUS_FILEINVALID)
02494       cfg->include_level--;
02495 
02496    return result;
02497 }

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

Load a config file.

Parameters:
filename path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR
who_asked The module which is making this request.
flags Optional flags: CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact; CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files).

Create a config structure from a given configuration file.

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

Definition at line 2499 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().

02500 {
02501    struct ast_config *cfg;
02502    struct ast_config *result;
02503 
02504    cfg = ast_config_new();
02505    if (!cfg)
02506       return NULL;
02507 
02508    result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
02509    if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID)
02510       ast_config_destroy(cfg);
02511 
02512    return result;
02513 }

struct ast_config* ast_config_new ( void   )  [read]

Create a new base configuration structure.

Definition at line 888 of file config.c.

References ast_calloc, config, MAX_INCLUDE_LEVEL, and ast_config::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().

00889 {
00890    struct ast_config *config;
00891 
00892    if ((config = ast_calloc(1, sizeof(*config))))
00893       config->max_include_level = MAX_INCLUDE_LEVEL;
00894    return config;
00895 }

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

References ast_variable_retrieve().

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

00615 {
00616    const char *tmp;
00617    tmp = ast_variable_retrieve(cfg, cat, var);
00618    if (!tmp) {
00619       tmp = ast_variable_retrieve(cfg, "general", var);
00620    }
00621    return tmp;
00622 }

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

References ast_config::current.

01061 {
01062    /* cast below is just to silence compiler warning about dropping "const" */
01063    cfg->current = (struct ast_category *) cat;
01064 }

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

Definition at line 1977 of file config.c.

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

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

01978 {
01979    FILE *f;
01980    char fn[PATH_MAX];
01981    struct ast_variable *var;
01982    struct ast_category *cat;
01983    struct ast_comment *cmt;
01984    struct ast_config_include *incl;
01985    int blanklines = 0;
01986    struct ao2_container *fileset;
01987    struct inclfile *fi;
01988 
01989    fileset = ao2_container_alloc(1023, hash_string, hashtab_compare_strings);
01990    if (!fileset) {
01991       /* Container creation failed. */
01992       return -1;
01993    }
01994 
01995    /* Check all the files for write access before attempting to modify any of them */
01996    for (incl = cfg->includes; incl; incl = incl->next) {
01997       /* reset all the output flags in case this isn't our first time saving this data */
01998       incl->output = 0;
01999       /* now make sure we have write access */
02000       if (!incl->exec) {
02001          make_fn(fn, sizeof(fn), incl->included_file, configfile);
02002          if (access(fn, R_OK | W_OK)) {
02003             ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02004             return -1;
02005          }
02006       }
02007    }
02008 
02009    /* now make sure we have write access to the main config file */
02010    make_fn(fn, sizeof(fn), 0, configfile);
02011    if (access(fn, R_OK | W_OK)) {
02012       ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02013       return -1;
02014    }
02015 
02016    /* Now that we know we have write access to all files, it's safe to start truncating them */
02017 
02018    /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
02019       are all truncated to zero bytes and have that nice header*/
02020    for (incl = cfg->includes; incl; incl = incl->next) {
02021       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*/
02022          /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
02023          fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
02024          f = fopen(fn, "w");
02025          if (f) {
02026             gen_header(f, configfile, fn, generator);
02027             fclose(f); /* this should zero out the file */
02028          } else {
02029             ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02030          }
02031          if (fi) {
02032             ao2_ref(fi, -1);
02033          }
02034       }
02035    }
02036 
02037    /* just set fn to absolute ver of configfile */
02038    fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
02039    if (
02040 #ifdef __CYGWIN__
02041       (f = fopen(fn, "w+"))
02042 #else
02043       (f = fopen(fn, "w"))
02044 #endif
02045       ) {
02046       ast_verb(2, "Saving '%s': ", fn);
02047       gen_header(f, configfile, fn, generator);
02048       cat = cfg->root;
02049       fclose(f);
02050       if (fi) {
02051          ao2_ref(fi, -1);
02052       }
02053 
02054       /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
02055       /* since each var, cat, and associated comments can come from any file, we have to be
02056          mobile, and open each file, print, and close it on an entry-by-entry basis */
02057 
02058       while (cat) {
02059          fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
02060          f = fopen(fn, "a");
02061          if (!f) {
02062             ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
02063             if (fi) {
02064                ao2_ref(fi, -1);
02065             }
02066             ao2_ref(fileset, -1);
02067             return -1;
02068          }
02069 
02070          /* dump any includes that happen before this category header */
02071          for (incl=cfg->includes; incl; incl = incl->next) {
02072             if (strcmp(incl->include_location_file, cat->file) == 0){
02073                if (cat->lineno > incl->include_location_lineno && !incl->output) {
02074                   if (incl->exec)
02075                      fprintf(f,"#exec \"%s\"\n", incl->exec_file);
02076                   else
02077                      fprintf(f,"#include \"%s\"\n", incl->included_file);
02078                   incl->output = 1;
02079                }
02080             }
02081          }
02082 
02083          insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno);
02084          /* Dump section with any appropriate comment */
02085          for (cmt = cat->precomments; cmt; cmt=cmt->next) {
02086             char *cmtp = cmt->cmt;
02087             while (cmtp && *cmtp == ';' && *(cmtp+1) == '!') {
02088                char *cmtp2 = strchr(cmtp+1, '\n');
02089                if (cmtp2)
02090                   cmtp = cmtp2+1;
02091                else cmtp = 0;
02092             }
02093             if (cmtp)
02094                fprintf(f,"%s", cmtp);
02095          }
02096          fprintf(f, "[%s]", cat->name);
02097          if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
02098             fprintf(f, "(");
02099             if (cat->ignored) {
02100                fprintf(f, "!");
02101             }
02102             if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
02103                fprintf(f, ",");
02104             }
02105             if (!AST_LIST_EMPTY(&cat->template_instances)) {
02106                struct ast_category_template_instance *x;
02107                AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
02108                   fprintf(f,"%s",x->name);
02109                   if (x != AST_LIST_LAST(&cat->template_instances))
02110                      fprintf(f,",");
02111                }
02112             }
02113             fprintf(f, ")");
02114          }
02115          for(cmt = cat->sameline; cmt; cmt=cmt->next)
02116          {
02117             fprintf(f,"%s", cmt->cmt);
02118          }
02119          if (!cat->sameline)
02120             fprintf(f,"\n");
02121          for (cmt = cat->trailing; cmt; cmt=cmt->next) {
02122             if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
02123                fprintf(f,"%s", cmt->cmt);
02124          }
02125          fclose(f);
02126          if (fi) {
02127             ao2_ref(fi, -1);
02128          }
02129 
02130          var = cat->root;
02131          while (var) {
02132             struct ast_category_template_instance *x;
02133             int found = 0;
02134             AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
02135                struct ast_variable *v;
02136                for (v = x->inst->root; v; v = v->next) {
02137                   if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
02138                      found = 1;
02139                      break;
02140                   }
02141                }
02142                if (found)
02143                   break;
02144             }
02145             if (found) {
02146                var = var->next;
02147                continue;
02148             }
02149             fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
02150             f = fopen(fn, "a");
02151             if (!f) {
02152                ast_debug(1, "Unable to open for writing: %s\n", fn);
02153                ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
02154                if (fi) {
02155                   ao2_ref(fi, -1);
02156                }
02157                ao2_ref(fileset, -1);
02158                return -1;
02159             }
02160 
02161             /* dump any includes that happen before this category header */
02162             for (incl=cfg->includes; incl; incl = incl->next) {
02163                if (strcmp(incl->include_location_file, var->file) == 0){
02164                   if (var->lineno > incl->include_location_lineno && !incl->output) {
02165                      if (incl->exec)
02166                         fprintf(f,"#exec \"%s\"\n", incl->exec_file);
02167                      else
02168                         fprintf(f,"#include \"%s\"\n", incl->included_file);
02169                      incl->output = 1;
02170                   }
02171                }
02172             }
02173 
02174             insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
02175             for (cmt = var->precomments; cmt; cmt=cmt->next) {
02176                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
02177                   fprintf(f,"%s", cmt->cmt);
02178             }
02179             if (var->sameline)
02180                fprintf(f, "%s %s %s  %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
02181             else
02182                fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
02183             for (cmt = var->trailing; cmt; cmt=cmt->next) {
02184                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
02185                   fprintf(f,"%s", cmt->cmt);
02186             }
02187             if (var->blanklines) {
02188                blanklines = var->blanklines;
02189                while (blanklines--)
02190                   fprintf(f, "\n");
02191             }
02192 
02193             fclose(f);
02194             if (fi) {
02195                ao2_ref(fi, -1);
02196             }
02197 
02198             var = var->next;
02199          }
02200          cat = cat->next;
02201       }
02202       if (!option_debug)
02203          ast_verb(2, "Saved\n");
02204    } else {
02205       ast_debug(1, "Unable to open for writing: %s\n", fn);
02206       ast_verb(2, "Unable to write (%s)", strerror(errno));
02207       if (fi) {
02208          ao2_ref(fi, -1);
02209       }
02210       ao2_ref(fileset, -1);
02211       return -1;
02212    }
02213 
02214    /* Now, for files with trailing #include/#exec statements,
02215       we have to make sure every entry is output */
02216    for (incl=cfg->includes; incl; incl = incl->next) {
02217       if (!incl->output) {
02218          /* open the respective file */
02219          fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
02220          f = fopen(fn, "a");
02221          if (!f) {
02222             ast_debug(1, "Unable to open for writing: %s\n", fn);
02223             ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
02224             if (fi) {
02225                ao2_ref(fi, -1);
02226             }
02227             ao2_ref(fileset, -1);
02228             return -1;
02229          }
02230 
02231          /* output the respective include */
02232          if (incl->exec)
02233             fprintf(f,"#exec \"%s\"\n", incl->exec_file);
02234          else
02235             fprintf(f,"#include \"%s\"\n", incl->included_file);
02236          fclose(f);
02237          incl->output = 1;
02238          if (fi) {
02239             ao2_ref(fi, -1);
02240          }
02241       }
02242    }
02243    ao2_ref(fileset, -1); /* this should destroy the hash container */
02244 
02245    return 0;
02246 }

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

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

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

02751 {
02752    struct ast_config_engine *eng;
02753    int res = -1, i;
02754    char db[256];
02755    char table[256];
02756    va_list ap;
02757 
02758    va_start(ap, lookup);
02759    for (i = 1; ; i++) {
02760       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02761          if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, ap))) {
02762             break;
02763          }
02764       } else {
02765          break;
02766       }
02767    }
02768    va_end(ap);
02769 
02770    return res;
02771 }

static void ast_destroy_template_list ( struct ast_category cat  )  [static]

Definition at line 754 of file config.c.

References ast_free, AST_LIST_REMOVE_HEAD, and ast_category::template_instances.

Referenced by ast_category_destroy().

00755 {
00756    struct ast_category_template_instance *x;
00757 
00758    while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
00759       ast_free(x);
00760 }

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

Definition at line 472 of file config.c.

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

Referenced by ast_include_new().

00473 {
00474    struct ast_config_include *x;
00475    for (x=conf->includes;x;x=x->next) {
00476       if (strcmp(x->included_file,included_file) == 0)
00477          return x;
00478    }
00479    return 0;
00480 }

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

Definition at line 332 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().

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

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

Definition at line 380 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().

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

static void ast_includes_destroy ( struct ast_config_include incls  )  [static]

Definition at line 775 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().

00776 {
00777    struct ast_config_include *incl,*inclnext;
00778    
00779    for (incl=incls; incl; incl = inclnext) {
00780       inclnext = incl->next;
00781       ast_free(incl->include_location_file);
00782       ast_free(incl->exec_file);
00783       ast_free(incl->included_file);
00784       ast_free(incl);
00785    }
00786 }

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

Retrieve realtime configuration.

Parameters:
family which family/config to lookup

This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters.

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 2548 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().

02549 {
02550    struct ast_variable *res;
02551    struct ast_variable *cur;
02552    struct ast_variable **prev;
02553    va_list ap;
02554 
02555    va_start(ap, family);
02556    res = ast_load_realtime_helper(family, ap);
02557    va_end(ap);
02558 
02559    /* Filter the list. */
02560    prev = &res;
02561    cur = res;
02562    while (cur) {
02563       if (ast_strlen_zero(cur->value)) {
02564          /* Eliminate empty entries */
02565          struct ast_variable *next;
02566 
02567          next = cur->next;
02568          *prev = next;
02569          ast_variable_destroy(cur);
02570          cur = next;
02571       } else {
02572          /* Make blank entries empty and keep them. */
02573          if (cur->value[0] == ' ' && cur->value[1] == '\0') {
02574             char *vptr = (char *) cur->value;
02575 
02576             vptr[0] = '\0';
02577          }
02578 
02579          prev = &cur->next;
02580          cur = cur->next;
02581       }
02582    }
02583    return res;
02584 }

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

Definition at line 2536 of file config.c.

References ast_load_realtime_helper().

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

02537 {
02538    struct ast_variable *res;
02539    va_list ap;
02540 
02541    va_start(ap, family);
02542    res = ast_load_realtime_helper(family, ap);
02543    va_end(ap);
02544 
02545    return res;
02546 }

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

Definition at line 2515 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().

02516 {
02517    struct ast_config_engine *eng;
02518    char db[256];
02519    char table[256];
02520    struct ast_variable *res=NULL;
02521    int i;
02522 
02523    for (i = 1; ; i++) {
02524       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02525          if (eng->realtime_func && (res = eng->realtime_func(db, table, ap))) {
02526             return res;
02527          }
02528       } else {
02529          return NULL;
02530       }
02531    }
02532 
02533    return res;
02534 }

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

Retrieve realtime configuration.

Parameters:
family which family/config to lookup

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

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

Definition at line 2650 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(), find_realtime(), 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().

02651 {
02652    struct ast_config_engine *eng;
02653    char db[256];
02654    char table[256];
02655    struct ast_config *res = NULL;
02656    va_list ap;
02657    int i;
02658 
02659    va_start(ap, family);
02660    for (i = 1; ; i++) {
02661       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02662          if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, ap))) {
02663             /* If we were returned an empty cfg, destroy it and return NULL */
02664             if (!res->root) {
02665                ast_config_destroy(res);
02666                res = NULL;
02667             }
02668             break;
02669          }
02670       } else {
02671          break;
02672       }
02673    }
02674    va_end(ap);
02675 
02676    return res;
02677 }

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

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

The argument parsing routine.

Definition at line 2805 of file config.c.

References 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, and UINT32_MAX.

Referenced by __ast_http_load(), ast_tls_read_conf(), check_via_response(), gtalk_load_config(), and reload_config().

02807 {
02808    va_list ap;
02809    int error = 0;
02810 
02811    va_start(ap, p_result);
02812    switch (flags & PARSE_TYPE) {
02813    case PARSE_INT32:
02814    {
02815       long int x = 0;
02816       int32_t *result = p_result;
02817       int32_t def = result ? *result : 0, high = INT32_MAX, low = INT32_MIN;
02818       char *endptr = NULL;
02819 
02820       /* optional arguments: default value and/or (low, high) */
02821       if (flags & PARSE_DEFAULT) {
02822          def = va_arg(ap, int32_t);
02823       }
02824       if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
02825          low = va_arg(ap, int32_t);
02826          high = va_arg(ap, int32_t);
02827       }
02828       if (ast_strlen_zero(arg)) {
02829          error = 1;
02830          goto int32_done;
02831       }
02832       errno = 0;
02833       x = strtol(arg, &endptr, 0);
02834       if (*endptr || errno || x < INT32_MIN || x > INT32_MAX) {
02835          /* Parse error, or type out of int32_t bounds */
02836          error = 1;
02837          goto int32_done;
02838       }
02839       error = (x < low) || (x > high);
02840       if (flags & PARSE_OUT_RANGE) {
02841          error = !error;
02842       }
02843 int32_done:
02844       if (result) {
02845          *result  = error ? def : x;
02846       }
02847 
02848       ast_debug(3, "extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
02849             arg, low, high, result ? *result : x, error);
02850       break;
02851    }
02852 
02853    case PARSE_UINT32:
02854    {
02855       unsigned long int x = 0;
02856       uint32_t *result = p_result;
02857       uint32_t def = result ? *result : 0, low = 0, high = UINT32_MAX;
02858       char *endptr = NULL;
02859 
02860       /* optional argument: first default value, then range */
02861       if (flags & PARSE_DEFAULT) {
02862          def = va_arg(ap, uint32_t);
02863       }
02864       if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
02865          /* range requested, update bounds */
02866          low = va_arg(ap, uint32_t);
02867          high = va_arg(ap, uint32_t);
02868       }
02869 
02870       if (ast_strlen_zero(arg)) {
02871          error = 1;
02872          goto uint32_done;
02873       }
02874       /* strtoul will happilly and silently negate negative numbers */
02875       arg = ast_skip_blanks(arg);
02876       if (*arg == '-') {
02877          error = 1;
02878          goto uint32_done;
02879       }
02880       errno = 0;
02881       x = strtoul(arg, &endptr, 0);
02882       if (*endptr || errno || x > UINT32_MAX) {
02883          error = 1;
02884          goto uint32_done;
02885       }
02886       error = (x < low) || (x > high);
02887       if (flags & PARSE_OUT_RANGE) {
02888          error = !error;
02889       }
02890 uint32_done:
02891       if (result) {
02892          *result  = error ? def : x;
02893       }
02894       ast_debug(3, "extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
02895             arg, low, high, result ? *result : x, error);
02896       break;
02897    }
02898 
02899    case PARSE_DOUBLE:
02900    {
02901       double *result = p_result;
02902       double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
02903       char *endptr = NULL;
02904 
02905       /* optional argument: first default value, then range */
02906       if (flags & PARSE_DEFAULT) {
02907          def = va_arg(ap, double);
02908       }
02909       if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
02910          /* range requested, update bounds */
02911          low = va_arg(ap, double);
02912          high = va_arg(ap, double);
02913       }
02914       if (ast_strlen_zero(arg)) {
02915          error = 1;
02916          goto double_done;
02917       }
02918       errno = 0;
02919       x = strtod(arg, &endptr);
02920       if (*endptr || errno == ERANGE) {
02921          error = 1;
02922          goto double_done;
02923       }
02924       error = (x < low) || (x > high);
02925       if (flags & PARSE_OUT_RANGE) {
02926          error = !error;
02927       }
02928 double_done:
02929       if (result) {
02930          *result = error ? def : x;
02931       }
02932       ast_debug(3, "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
02933             arg, low, high, result ? *result : x, error);
02934       break;
02935    }
02936    case PARSE_ADDR:
02937        {
02938       struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result;
02939 
02940       if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) {
02941          error = 1;
02942       }
02943 
02944       ast_debug(3, "extract addr from %s gives %s(%d)\n",
02945            arg, ast_sockaddr_stringify(addr), error);
02946 
02947       break;
02948        }
02949    case PARSE_INADDR:   /* TODO Remove this (use PARSE_ADDR instead). */
02950        {
02951       char *port, *buf;
02952       struct sockaddr_in _sa_buf;   /* buffer for the result */
02953       struct sockaddr_in *sa = p_result ?
02954          (struct sockaddr_in *)p_result : &_sa_buf;
02955       /* default is either the supplied value or the result itself */
02956       struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
02957          va_arg(ap, struct sockaddr_in *) : sa;
02958       struct hostent *hp;
02959       struct ast_hostent ahp;
02960 
02961       memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
02962       /* duplicate the string to strip away the :port */
02963       port = ast_strdupa(arg);
02964       buf = strsep(&port, ":");
02965       sa->sin_family = AF_INET;  /* assign family */
02966       /*
02967        * honor the ports flag setting, assign default value
02968        * in case of errors or field unset.
02969        */
02970       flags &= PARSE_PORT_MASK; /* the only flags left to process */
02971       if (port) {
02972          if (flags == PARSE_PORT_FORBID) {
02973             error = 1;  /* port was forbidden */
02974             sa->sin_port = def->sin_port;
02975          } else if (flags == PARSE_PORT_IGNORE)
02976             sa->sin_port = def->sin_port;
02977          else /* accept or require */
02978             sa->sin_port = htons(strtol(port, NULL, 0));
02979       } else {
02980          sa->sin_port = def->sin_port;
02981          if (flags == PARSE_PORT_REQUIRE)
02982             error = 1;
02983       }
02984       /* Now deal with host part, even if we have errors before. */
02985       hp = ast_gethostbyname(buf, &ahp);
02986       if (hp)  /* resolved successfully */
02987          memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
02988       else {
02989          error = 1;
02990          sa->sin_addr = def->sin_addr;
02991       }
02992       ast_debug(3,
02993          "extract inaddr from [%s] gives [%s:%d](%d)\n",
02994          arg, ast_inet_ntoa(sa->sin_addr),
02995          ntohs(sa->sin_port), error);
02996          break;
02997        }
02998    }
02999    va_end(ap);
03000    return error;
03001 }

char* ast_realtime_decode_chunk ( char *  chunk  ) 

Definition at line 2773 of file config.c.

Referenced by realtime_multi_pgsql(), and realtime_pgsql().

02774 {
02775    char *orig = chunk;
02776    for (; *chunk; chunk++) {
02777       if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
02778          sscanf(chunk + 1, "%02hhX", (unsigned char *)chunk);
02779          memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
02780       }
02781    }
02782    return orig;
02783 }

int ast_realtime_enabled ( void   ) 

Check if there's any realtime engines loaded.

Definition at line 2601 of file config.c.

References config_maps.

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

02602 {
02603    return config_maps ? 1 : 0;
02604 }

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

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

02786 {
02787    if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
02788       ast_str_set(dest, maxlen, "%s", chunk);
02789    } else {
02790       ast_str_reset(*dest);
02791       for (; *chunk; chunk++) {
02792          if (strchr(";^", *chunk)) {
02793             ast_str_append(dest, maxlen, "^%02hhX", *chunk);
02794          } else {
02795             ast_str_append(dest, maxlen, "%c", *chunk);
02796          }
02797       }
02798    }
02799    return ast_str_buffer(*dest);
02800 }

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 2606 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().

02607 {
02608    struct ast_config_engine *eng;
02609    char db[256];
02610    char table[256];
02611    va_list ap;
02612    int res = -1, i;
02613 
02614    va_start(ap, family);
02615    for (i = 1; ; i++) {
02616       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02617          /* If the require succeeds, it returns 0. */
02618          if (eng->require_func && !(res = eng->require_func(db, table, ap))) {
02619             break;
02620          }
02621       } else {
02622          break;
02623       }
02624    }
02625    va_end(ap);
02626 
02627    return res;
02628 }

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

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

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

02727 {
02728    struct ast_config_engine *eng;
02729    int res = -1, i;
02730    char db[256];
02731    char table[256];
02732    va_list ap;
02733 
02734    va_start(ap, family);
02735    for (i = 1; ; i++) {
02736       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02737          /* If the store succeeds, it returns 0. */
02738          if (eng->store_func && !(res = eng->store_func(db, table, ap))) {
02739             break;
02740          }
02741       } else {
02742          break;
02743       }
02744    }
02745    va_end(ap);
02746 
02747    return res;
02748 }

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 2630 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().

02631 {
02632    struct ast_config_engine *eng;
02633    char db[256];
02634    char table[256];
02635    int res = -1, i;
02636 
02637    for (i = 1; ; i++) {
02638       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02639          if (eng->unload_func) {
02640             /* Do this for ALL engines */
02641             res = eng->unload_func(db, table);
02642          }
02643       } else {
02644          break;
02645       }
02646    }
02647    return res;
02648 }

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

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

Referenced by change_password_realtime(), and cli_realtime_update2().

02704 {
02705    struct ast_config_engine *eng;
02706    int res = -1, i;
02707    char db[256];
02708    char table[256];
02709    va_list ap;
02710 
02711    va_start(ap, family);
02712    for (i = 1; ; i++) {
02713       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02714          if (eng->update2_func && !(res = eng->update2_func(db, table, ap))) {
02715             break;
02716          }
02717       } else {
02718          break;
02719       }
02720    }
02721    va_end(ap);
02722 
02723    return res;
02724 }

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 2679 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(), leave_voicemail(), realtime_update_peer(), rename_file(), rt_extend_conf(), sip_poke_noanswer(), and update_realtime_member_field().

02680 {
02681    struct ast_config_engine *eng;
02682    int res = -1, i;
02683    char db[256];
02684    char table[256];
02685    va_list ap;
02686 
02687    va_start(ap, lookup);
02688    for (i = 1; ; i++) {
02689       if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
02690          /* If the update succeeds, it returns 0. */
02691          if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, ap))) {
02692             break;
02693          }
02694       } else {
02695          break;
02696       }
02697    }
02698    va_end(ap);
02699 
02700    return res;
02701 }

void ast_variable_append ( struct ast_category category,
struct ast_variable variable 
)

Definition at line 483 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().

00484 {
00485    if (!variable)
00486       return;
00487    if (category->last)
00488       category->last->next = variable;
00489    else
00490       category->root = variable;
00491    category->last = variable;
00492    while (category->last->next)
00493       category->last = category->last->next;
00494 }

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

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

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

Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), actual_load_config(), adsi_load(), aji_load_config(), ast_cli_perms_init(), AST_LIST_HEAD_NOLOCK(), 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(), 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().

00598 {
00599    struct ast_category *cat = NULL;
00600 
00601    if (!category) {
00602       return NULL;
00603    }
00604 
00605    if (config->last_browse && (config->last_browse->name == category)) {
00606       cat = config->last_browse;
00607    } else {
00608       cat = ast_category_get(config, category);
00609    }
00610 
00611    return (cat) ? cat->root : NULL;
00612 }

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

Definition at line 897 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().

00898 {
00899    struct ast_variable *cur, *prev=NULL, *curn;
00900    int res = -1;
00901    int num_item = 0;
00902    int req_item;
00903 
00904    req_item = -1;
00905    if (!ast_strlen_zero(line)) {
00906       /* Requesting to delete by item number. */
00907       if (sscanf(line, "%30d", &req_item) != 1
00908          || req_item < 0) {
00909          /* Invalid item number to delete. */
00910          return -1;
00911       }
00912    }
00913 
00914    prev = NULL;
00915    cur = category->root;
00916    while (cur) {
00917       curn = cur->next;
00918       /* Delete by item number or by variable name with optional value. */
00919       if ((0 <= req_item && num_item == req_item)
00920          || (req_item < 0 && !strcasecmp(cur->name, variable)
00921             && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
00922          if (prev) {
00923             prev->next = cur->next;
00924             if (cur == category->last)
00925                category->last = prev;
00926          } else {
00927             category->root = cur->next;
00928             if (cur == category->last)
00929                category->last = NULL;
00930          }
00931          ast_variable_destroy(cur);
00932          res = 0;
00933       } else
00934          prev = cur;
00935 
00936       cur = curn;
00937       ++num_item;
00938    }
00939    return res;
00940 }

static void ast_variable_destroy ( struct ast_variable doomed  )  [static]
void ast_variable_insert ( struct ast_category category,
struct ast_variable variable,
const char *  line 
)

Definition at line 496 of file config.c.

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

Referenced by handle_updates().

00497 {
00498    struct ast_variable *cur = category->root;
00499    int lineno;
00500    int insertline;
00501 
00502    if (!variable || sscanf(line, "%30d", &insertline) != 1) {
00503       return;
00504    }
00505    if (!insertline) {
00506       variable->next = category->root;
00507       category->root = variable;
00508    } else {
00509       for (lineno = 1; lineno < insertline; lineno++) {
00510          cur = cur->next;
00511          if (!cur->next) {
00512             break;
00513          }
00514       }
00515       variable->next = cur->next;
00516       cur->next = variable;
00517    }
00518 }

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

Definition at line 319 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().

00320 {
00321    dst_var->lineno = src_var->lineno;
00322    dst_var->object = src_var->object;
00323    dst_var->blanklines = src_var->blanklines;
00324    dst_var->precomments = src_var->precomments;
00325    src_var->precomments = NULL;
00326    dst_var->sameline = src_var->sameline;
00327    src_var->sameline = NULL;
00328    dst_var->trailing = src_var->trailing;
00329    src_var->trailing = NULL;
00330 }

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

Definition at line 278 of file config.c.

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

Referenced by add_cfg_entry(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), apply_outgoing(), ast_channeltype_list(), ast_http_get_post_vars(), 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(), mkintf(), parkandannounce_exec(), parse_cookies(), process_dahdi(), 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().

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

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

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

Referenced by __ast_udptl_reload(), __init_manager(), actual_load_config(), advanced_options(), aji_load_config(), ast_config_option(), AST_LIST_HEAD_NOLOCK(), build_extension(), conf_exec(), config_function_read(), config_module(), directory_exec(), do_reload(), festival_exec(), find_queue_by_name_rt(), find_realtime(), 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_modules(), 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(), 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().

00626 {
00627    struct ast_variable *v;
00628 
00629    if (category) {
00630       for (v = ast_variable_browse(config, category); v; v = v->next) {
00631          if (!strcasecmp(variable, v->name)) {
00632             return v->value;
00633          }
00634       }
00635    } else {
00636       struct ast_category *cat;
00637 
00638       for (cat = config->root; cat; cat = cat->next) {
00639          for (v = cat->root; v; v = v->next) {
00640             if (!strcasecmp(variable, v->name)) {
00641                return v->value;
00642             }
00643          }
00644       }
00645    }
00646 
00647    return NULL;
00648 }

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 942 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().

00944 {
00945    struct ast_variable *cur, *prev=NULL, *newer=NULL;
00946 
00947    for (cur = category->root; cur; prev = cur, cur = cur->next) {
00948       if (strcasecmp(cur->name, variable) ||
00949          (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
00950          continue;
00951 
00952       if (!(newer = ast_variable_new(variable, value, cur->file)))
00953          return -1;
00954 
00955       ast_variable_move(newer, cur);
00956       newer->object = newer->object || object;
00957 
00958       /* Replace the old node in the list with the new node. */
00959       newer->next = cur->next;
00960       if (prev)
00961          prev->next = newer;
00962       else
00963          category->root = newer;
00964       if (category->last == cur)
00965          category->last = newer;
00966 
00967       ast_variable_destroy(cur);
00968 
00969       return 0;
00970    }
00971 
00972    /* Could not find variable to update */
00973    return -1;
00974 }

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 586 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_http_manid_from_vars(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variables_dup(), auth_http_callback(), build_gateway(), build_peer(), build_user(), check_peer_ok(), cli_realtime_load(), conf_run(), copy_plain_file(), destroy_dahdi_pvt(), destroy_endpoint(), destroy_fast_originate_helper(), dup_vars(), find_conf_realtime(), find_realtime(), find_realtime_gw(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), generic_http_callback(), get_insecure_variable_from_sipregs(), handle_uri(), http_post_callback(), httpd_helper_thread(), httpstatus_callback(), ldap_loadentry(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), manager_sipnotify(), mkintf(), parkandannounce_exec(), process_dahdi(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_common(), realtime_exec(), 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(), realtimefield_read(), rt_extend_conf(), sip_destroy_peer(), socket_process(), table_configs_free(), and user_destructor().

00587 {
00588    struct ast_variable *vn;
00589 
00590    while (v) {
00591       vn = v;
00592       v = v->next;
00593       ast_variable_destroy(vn);
00594    }
00595 }

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

Duplicate variable list.

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

Definition at line 540 of file config.c.

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

Referenced by get_insecure_variable_from_sippeers(), and get_insecure_variable_from_sipregs().

00541 {
00542    struct ast_variable *cloned;
00543    struct ast_variable *tmp;
00544 
00545    if (!(cloned = ast_variable_new(var->name, var->value, var->file))) {
00546       return NULL;
00547    }
00548 
00549    tmp = cloned;
00550 
00551    while ((var = var->next)) {
00552       if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) {
00553          ast_variables_destroy(cloned);
00554          return NULL;
00555       }
00556       tmp = tmp->next;
00557    }
00558 
00559    return cloned;
00560 }

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

Reverse a variable list.

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

Definition at line 562 of file config.c.

References ast_variable::next.

Referenced by astman_get_variables_order().

00563 {
00564    struct ast_variable *var1, *var2;
00565 
00566    var1 = var;
00567 
00568    if (!var1 || !var1->next) {
00569       return var1;
00570    }
00571 
00572    var2 = var1->next;
00573    var1->next = NULL;
00574 
00575    while (var2) {
00576       struct ast_variable *next = var2->next;
00577 
00578       var2->next = var1;
00579       var1 = var2;
00580       var2 = next;
00581    }
00582 
00583    return var1;
00584 }

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

Definition at line 691 of file config.c.

References ast_category::ignored, ast_category::name, ast_category::next, and ast_config::root.

Referenced by ast_category_get(), and process_text_line().

00692 {
00693    struct ast_category *cat;
00694 
00695    /* try exact match first, then case-insensitive match */
00696    for (cat = config->root; cat; cat = cat->next) {
00697       if (cat->name == category_name && (ignored || !cat->ignored))
00698          return cat;
00699    }
00700 
00701    for (cat = config->root; cat; cat = cat->next) {
00702       if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
00703          return cat;
00704    }
00705 
00706    return NULL;
00707 }

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

Definition at line 118 of file config.c.

References ast_str_append().

Referenced by config_text_file_load().

00119 {
00120    ast_str_append(cb, 0, "%s", str);
00121 }

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

Definition at line 123 of file config.c.

References ast_alloca, and ast_str_append().

Referenced by config_text_file_load().

00124 {
00125    char *s = ast_alloca(len + 1);
00126 
00127    memcpy(s, str, len);
00128    s[len] = '\0';
00129    ast_str_append(cb, 0, "%s", s);
00130 }

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

Definition at line 132 of file config.c.

References ast_str_reset().

Referenced by config_text_file_load(), and process_text_line().

00133 { 
00134    if (cb) {
00135       ast_str_reset(cb);
00136    }
00137    if (llb) {
00138       ast_str_reset(llb);
00139    }
00140 }

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

Definition at line 1132 of file config.c.

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

Referenced by config_text_file_load().

01133 {
01134    struct cache_file_mtime cfm_buf;
01135 
01136    cfmstat_save(&cfm_buf, statbuf);
01137 
01138    return cfmtime->stat_size != cfm_buf.stat_size
01139       || cfmtime->stat_mtime != cfm_buf.stat_mtime
01140       || cfmtime->stat_mtime_nsec != cfm_buf.stat_mtime_nsec;
01141 }

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

Definition at line 1108 of file config.c.

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

Referenced by cfmstat_cmp(), and config_text_file_load().

01109 {
01110    cfmtime->stat_size = statbuf->st_size;
01111 #if defined(HAVE_STRUCT_STAT_ST_MTIM)
01112    cfmtime->stat_mtime_nsec = statbuf->st_mtim.tv_nsec;
01113 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
01114    cfmtime->stat_mtime_nsec = statbuf->st_mtimensec;
01115 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
01116    cfmtime->stat_mtime_nsec = statbuf->st_mtimespec.tv_nsec;
01117 #else
01118    cfmtime->stat_mtime_nsec = 0;
01119 #endif
01120    cfmtime->stat_mtime = statbuf->st_mtime;
01121 }

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

Definition at line 1076 of file config.c.

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

Referenced by config_cache_attribute(), and config_text_file_load().

01077 {
01078    struct cache_file_mtime *cfmtime;
01079    char *dst;
01080 
01081    cfmtime = ast_calloc(1,
01082       sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
01083    if (!cfmtime) {
01084       return NULL;
01085    }
01086    dst = cfmtime->filename;   /* writable space starts here */
01087    strcpy(dst, filename); /* Safe */
01088    dst += strlen(dst) + 1;
01089    cfmtime->who_asked = strcpy(dst, who_asked); /* Safe */
01090 
01091    return cfmtime;
01092 }

static void clear_config_maps ( void   )  [static]

Definition at line 2248 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().

02249 {
02250    struct ast_config_map *map;
02251 
02252    ast_mutex_lock(&config_lock);
02253 
02254    while (config_maps) {
02255       map = config_maps;
02256       config_maps = config_maps->next;
02257       ast_free(map);
02258    }
02259       
02260    ast_mutex_unlock(&config_lock);
02261 }

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 1204 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, and cache_file_mtime::who_asked.

Referenced by process_text_line().

01205 {
01206    struct cache_file_mtime *cfmtime;
01207    struct cache_file_include *cfinclude;
01208 
01209    /* Find our cached entry for this configuration file */
01210    AST_LIST_LOCK(&cfmtime_head);
01211    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
01212       if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
01213          break;
01214    }
01215    if (!cfmtime) {
01216       cfmtime = cfmtime_new(configfile, who_asked);
01217       if (!cfmtime) {
01218          AST_LIST_UNLOCK(&cfmtime_head);
01219          return;
01220       }
01221       /* Note that the file mtime is initialized to 0, i.e. 1970 */
01222       AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
01223    }
01224 
01225    switch (attrtype) {
01226    case ATTRIBUTE_INCLUDE:
01227       AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
01228          if (!strcmp(cfinclude->include, filename)) {
01229             AST_LIST_UNLOCK(&cfmtime_head);
01230             return;
01231          }
01232       }
01233       cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
01234       if (!cfinclude) {
01235          AST_LIST_UNLOCK(&cfmtime_head);
01236          return;
01237       }
01238       strcpy(cfinclude->include, filename); /* Safe */
01239       AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
01240       break;
01241    case ATTRIBUTE_EXEC:
01242       cfmtime->has_exec = 1;
01243       break;
01244    }
01245    AST_LIST_UNLOCK(&cfmtime_head);
01246 }

static void config_cache_destroy_entry ( struct cache_file_mtime cfmtime  )  [static]

Definition at line 1172 of file config.c.

References ast_free, and config_cache_flush_includes().

Referenced by config_cache_remove(), and config_shutdown().

01173 {
01174    config_cache_flush_includes(cfmtime);
01175    ast_free(cfmtime);
01176 }

static void config_cache_flush_includes ( struct cache_file_mtime cfmtime  )  [static]

Definition at line 1153 of file config.c.

References ast_free, AST_LIST_REMOVE_HEAD, and cache_file_mtime::includes.

Referenced by config_cache_destroy_entry(), and config_text_file_load().

01154 {
01155    struct cache_file_include *cfinclude;
01156 
01157    while ((cfinclude = AST_LIST_REMOVE_HEAD(&cfmtime->includes, list))) {
01158       ast_free(cfinclude);
01159    }
01160 }

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

Growable string buffer

< this will be a comment collector.

< A buffer for stuff behind the ;

Definition at line 1503 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, cfmstat_cmp(), cfmstat_save(), cfmtime_new(), comment, COMMENT_META, COMMENT_TAG, config_cache_flush_includes(), config_cache_remove(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, errno, f, cache_file_mtime::filename, GLOB_ABORTED, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, MY_GLOB_FLAGS, process_text_line(), ast_variable::trailing, ast_category::trailing, and cache_file_mtime::who_asked.

01504 {
01505    char fn[256];
01506 #if defined(LOW_MEMORY)
01507    char buf[512];
01508 #else
01509    char buf[8192];
01510 #endif
01511    char *new_buf, *comment_p, *process_buf;
01512    FILE *f;
01513    int lineno=0;
01514    int comment = 0, nest[MAX_NESTED_COMMENTS];
01515    struct ast_category *cat = NULL;
01516    int count = 0;
01517    struct stat statbuf;
01518    struct cache_file_mtime *cfmtime = NULL;
01519    struct cache_file_include *cfinclude;
01520    struct ast_variable *last_var = 0;
01521    struct ast_category *last_cat = 0;
01522    /*! Growable string buffer */
01523    struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/
01524    struct ast_str *lline_buffer = NULL;   /*!< A buffer for stuff behind the ; */
01525 
01526    if (cfg)
01527       cat = ast_config_get_current_category(cfg);
01528 
01529    if (filename[0] == '/') {
01530       ast_copy_string(fn, filename, sizeof(fn));
01531    } else {
01532       snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
01533    }
01534 
01535    if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01536       comment_buffer = ast_str_create(CB_SIZE);
01537       if (comment_buffer)
01538          lline_buffer = ast_str_create(CB_SIZE);
01539       if (!lline_buffer) {
01540          ast_free(comment_buffer);
01541          ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
01542          return NULL;
01543       }
01544    }
01545 #ifdef AST_INCLUDE_GLOB
01546    {
01547       int glob_ret;
01548       glob_t globbuf;
01549 
01550       globbuf.gl_offs = 0; /* initialize it to silence gcc */
01551       glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf);
01552       if (glob_ret == GLOB_NOSPACE) {
01553          ast_log(LOG_WARNING,
01554             "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
01555       } else if (glob_ret  == GLOB_ABORTED) {
01556          ast_log(LOG_WARNING,
01557             "Glob Expansion of pattern '%s' failed: Read error\n", fn);
01558       } else {
01559          /* loop over expanded files */
01560          int i;
01561 
01562          if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
01563             /*
01564              * We just want a file changed answer and since we cannot
01565              * tell if a file was deleted with wildcard matching we will
01566              * assume that something has always changed.  Also without
01567              * a lot of refactoring we couldn't check more than one file
01568              * for changes in the glob loop anyway.
01569              */
01570             globfree(&globbuf);
01571             ast_free(comment_buffer);
01572             ast_free(lline_buffer);
01573             return NULL;
01574          }
01575          for (i=0; i<globbuf.gl_pathc; i++) {
01576             ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
01577 #endif
01578    /*
01579     * The following is not a loop, but just a convenient way to define a block
01580     * (using do { } while(0) ), and be able to exit from it with 'continue'
01581     * or 'break' in case of errors. Nice trick.
01582     */
01583    do {
01584       if (stat(fn, &statbuf)) {
01585          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01586             config_cache_remove(fn, who_asked);
01587          }
01588          continue;
01589       }
01590 
01591       if (!S_ISREG(statbuf.st_mode)) {
01592          ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
01593          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01594             config_cache_remove(fn, who_asked);
01595          }
01596          continue;
01597       }
01598 
01599       if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01600          /* Find our cached entry for this configuration file */
01601          AST_LIST_LOCK(&cfmtime_head);
01602          AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
01603             if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked))
01604                break;
01605          }
01606          if (!cfmtime) {
01607             cfmtime = cfmtime_new(fn, who_asked);
01608             if (!cfmtime) {
01609                AST_LIST_UNLOCK(&cfmtime_head);
01610                continue;
01611             }
01612             /* Note that the file mtime is initialized to 0, i.e. 1970 */
01613             AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
01614          }
01615       }
01616 
01617       if (cfmtime
01618          && !cfmtime->has_exec
01619          && !cfmstat_cmp(cfmtime, &statbuf)
01620          && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) {
01621          int unchanged = 1;
01622 
01623          /* File is unchanged, what about the (cached) includes (if any)? */
01624          AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
01625             if (!config_text_file_load(NULL, NULL, cfinclude->include,
01626                NULL, flags, "", who_asked)) {
01627                /* One change is enough to short-circuit and reload the whole shebang */
01628                unchanged = 0;
01629                break;
01630             }
01631          }
01632 
01633          if (unchanged) {
01634             AST_LIST_UNLOCK(&cfmtime_head);
01635 #ifdef AST_INCLUDE_GLOB
01636             globfree(&globbuf);
01637 #endif
01638             ast_free(comment_buffer);
01639             ast_free(lline_buffer);
01640             return CONFIG_STATUS_FILEUNCHANGED;
01641          }
01642       }
01643 
01644       /* If cfg is NULL, then we just want a file changed answer. */
01645       if (cfg == NULL) {
01646          if (cfmtime) {
01647             AST_LIST_UNLOCK(&cfmtime_head);
01648          }
01649          continue;
01650       }
01651 
01652       if (cfmtime) {
01653          /* Forget about what we thought we knew about this file's includes. */
01654          cfmtime->has_exec = 0;
01655          config_cache_flush_includes(cfmtime);
01656 
01657          cfmstat_save(cfmtime, &statbuf);
01658          AST_LIST_UNLOCK(&cfmtime_head);
01659       }
01660 
01661       ast_verb(2, "Parsing '%s': ", fn);
01662          fflush(stdout);
01663       if (!(f = fopen(fn, "r"))) {
01664          ast_debug(1, "No file to parse: %s\n", fn);
01665          ast_verb(2, "Not found (%s)\n", strerror(errno));
01666          continue;
01667       }
01668       count++;
01669       /* If we get to this point, then we're loading regardless */
01670       ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED);
01671       ast_debug(1, "Parsing %s\n", fn);
01672       ast_verb(2, "Found\n");
01673       while (!feof(f)) {
01674          lineno++;
01675          if (fgets(buf, sizeof(buf), f)) {
01676             /* Skip lines that are too long */
01677             if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 1] != '\n') {
01678                ast_log(LOG_WARNING, "Line %d too long, skipping. It begins with: %.32s...\n", lineno, buf);
01679                while (fgets(buf, sizeof(buf), f)) {
01680                   if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 1] == '\n') {
01681                      break;
01682                   }
01683                }
01684                continue;
01685             }
01686 
01687             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && ast_str_strlen(lline_buffer)) {
01688                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01689                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01690             }
01691             
01692             new_buf = buf;
01693             if (comment) 
01694                process_buf = NULL;
01695             else
01696                process_buf = buf;
01697             
01698             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"))) {
01699                /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */
01700                CB_ADD(&comment_buffer, "\n");       /* add a newline to the comment buffer */
01701                continue; /* go get a new line, then */
01702             }
01703             
01704             while ((comment_p = strchr(new_buf, COMMENT_META))) {
01705                if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) {
01706                   /* Escaped semicolons aren't comments. */
01707                   new_buf = comment_p;
01708                   /* write over the \ and bring the null terminator with us */
01709                   memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
01710                } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
01711                   /* Meta-Comment start detected ";--" */
01712                   if (comment < MAX_NESTED_COMMENTS) {
01713                      *comment_p = '\0';
01714                      new_buf = comment_p + 3;
01715                      comment++;
01716                      nest[comment-1] = lineno;
01717                   } else {
01718                      ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
01719                   }
01720                } else if ((comment_p >= new_buf + 2) &&
01721                      (*(comment_p - 1) == COMMENT_TAG) &&
01722                      (*(comment_p - 2) == COMMENT_TAG)) {
01723                   /* Meta-Comment end detected "--;" */
01724                   comment--;
01725                   new_buf = comment_p + 1;
01726                   if (!comment) {
01727                      /* Back to non-comment now */
01728                      if (process_buf) {
01729                         /* Actually have to move what's left over the top, then continue */
01730                         char *oldptr;
01731                         oldptr = process_buf + strlen(process_buf);
01732                         if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01733                            CB_ADD(&comment_buffer, ";");
01734                            CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
01735                         }
01736                         
01737                         memmove(oldptr, new_buf, strlen(new_buf) + 1);
01738                         new_buf = oldptr;
01739                      } else
01740                         process_buf = new_buf;
01741                   }
01742                } else {
01743                   if (!comment) {
01744                      /* If ; is found, and we are not nested in a comment, 
01745                         we immediately stop all comment processing */
01746                      if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01747                         CB_ADD(&lline_buffer, comment_p);
01748                      }
01749                      *comment_p = '\0'; 
01750                      new_buf = comment_p;
01751                   } else
01752                      new_buf = comment_p + 1;
01753                }
01754             }
01755             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) {
01756                CB_ADD(&comment_buffer, buf);  /* the whole line is a comment, store it */
01757             }
01758             
01759             if (process_buf) {
01760                char *buffer = ast_strip(process_buf);
01761                if (!ast_strlen_zero(buffer)) {
01762                   if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) {
01763                      cfg = CONFIG_STATUS_FILEINVALID;
01764                      break;
01765                   }
01766                }
01767             }
01768          }
01769       }
01770       /* end of file-- anything in a comment buffer? */
01771       if (last_cat) {
01772          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01773             if (lline_buffer && ast_str_strlen(lline_buffer)) {
01774                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01775                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01776             }
01777             last_cat->trailing = ALLOC_COMMENT(comment_buffer);
01778          }
01779       } else if (last_var) {
01780          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01781             if (lline_buffer && ast_str_strlen(lline_buffer)) {
01782                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01783                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01784             }
01785             last_var->trailing = ALLOC_COMMENT(comment_buffer);
01786          }
01787       } else {
01788          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01789             ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer));
01790          }
01791       }
01792       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01793          CB_RESET(comment_buffer, lline_buffer);
01794 
01795       fclose(f);
01796    } while (0);
01797    if (comment) {
01798       ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
01799    }
01800 #ifdef AST_INCLUDE_GLOB
01801                if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
01802                   break;
01803                }
01804             }
01805             globfree(&globbuf);
01806          }
01807       }
01808 #endif
01809 
01810    ast_free(comment_buffer);
01811    ast_free(lline_buffer);
01812 
01813    if (count == 0)
01814       return NULL;
01815 
01816    return cfg;
01817 }

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

Definition at line 1972 of file config.c.

References ast_config_text_file_save().

01973 {
01974    return ast_config_text_file_save(configfile, cfg, generator);
01975 }

static int count_linefeeds ( char *  str  )  [static]

Definition at line 1913 of file config.c.

Referenced by count_linefeeds_in_comments().

01914 {
01915    int count = 0;
01916 
01917    while (*str) {
01918       if (*str =='\n')
01919          count++;
01920       str++;
01921    }
01922    return count;
01923 }

static int count_linefeeds_in_comments ( struct ast_comment x  )  [static]

Definition at line 1925 of file config.c.

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

Referenced by insert_leading_blank_lines().

01926 {
01927    int count = 0;
01928 
01929    while (x) {
01930       count += count_linefeeds(x->cmt);
01931       x = x->next;
01932    }
01933    return count;
01934 }

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

Find realtime engine for realtime family.

Definition at line 2420 of file config.c.

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

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_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), and ast_update_realtime().

02421 {
02422    struct ast_config_engine *eng, *ret = NULL;
02423    struct ast_config_map *map;
02424 
02425    ast_mutex_lock(&config_lock);
02426 
02427    for (map = config_maps; map; map = map->next) {
02428       if (!strcasecmp(family, map->name) && (priority == map->priority)) {
02429          if (database)
02430             ast_copy_string(database, map->database, dbsiz);
02431          if (table)
02432             ast_copy_string(table, map->table ? map->table : family, tabsiz);
02433          break;
02434       }
02435    }
02436 
02437    /* Check if the required driver (engine) exist */
02438    if (map) {
02439       for (eng = config_engine_list; !ret && eng; eng = eng->next) {
02440          if (!strcasecmp(eng->name, map->driver))
02441             ret = eng;
02442       }
02443    }
02444 
02445    ast_mutex_unlock(&config_lock);
02446    
02447    /* if we found a mapping, but the engine is not available, then issue a warning */
02448    if (map && !ret)
02449       ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
02450 
02451    return ret;
02452 }

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

Definition at line 1840 of file config.c.

References ast_copy_string().

Referenced by ast_config_text_file_save().

01841 {
01842    char date[256]="";
01843    time_t t;
01844 
01845    time(&t);
01846    ast_copy_string(date, ctime(&t), sizeof(date));
01847 
01848    fprintf(f1, ";!\n");
01849    fprintf(f1, ";! Automatically generated configuration file\n");
01850    if (strcmp(configfile, fn))
01851       fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
01852    else
01853       fprintf(f1, ";! Filename: %s\n", configfile);
01854    fprintf(f1, ";! Generator: %s\n", generator);
01855    fprintf(f1, ";! Creation Date: %s", date);
01856    fprintf(f1, ";!\n");
01857 }

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

Definition at line 3102 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, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.

03103 {
03104    struct cache_file_mtime *cfmtime;
03105 
03106    switch (cmd) {
03107    case CLI_INIT:
03108       e->command = "config list";
03109       e->usage =
03110          "Usage: config list\n"
03111          "   Show all modules that have loaded a configuration file\n";
03112       return NULL;
03113    case CLI_GENERATE:
03114       return NULL;
03115    }
03116 
03117    AST_LIST_LOCK(&cfmtime_head);
03118    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
03119       ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
03120    }
03121    AST_LIST_UNLOCK(&cfmtime_head);
03122 
03123    return CLI_SUCCESS;
03124 }

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

Definition at line 3040 of file config.c.

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

03041 {
03042    struct cache_file_mtime *cfmtime;
03043    char *prev = "", *completion_value = NULL;
03044    int wordlen, which = 0;
03045 
03046    switch (cmd) {
03047    case CLI_INIT:
03048       e->command = "config reload";
03049       e->usage =
03050          "Usage: config reload <filename.conf>\n"
03051          "   Reloads all modules that reference <filename.conf>\n";
03052       return NULL;
03053    case CLI_GENERATE:
03054       if (a->pos > 2) {
03055          return NULL;
03056       }
03057 
03058       wordlen = strlen(a->word);
03059 
03060       AST_LIST_LOCK(&cfmtime_head);
03061       AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
03062          /* Skip duplicates - this only works because the list is sorted by filename */
03063          if (strcmp(cfmtime->filename, prev) == 0) {
03064             continue;
03065          }
03066 
03067          /* Core configs cannot be reloaded */
03068          if (ast_strlen_zero(cfmtime->who_asked)) {
03069             continue;
03070          }
03071 
03072          if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) {
03073             completion_value = ast_strdup(cfmtime->filename);
03074             break;
03075          }
03076 
03077          /* Otherwise save that we've seen this filename */
03078          prev = cfmtime->filename;
03079       }
03080       AST_LIST_UNLOCK(&cfmtime_head);
03081 
03082       return completion_value;
03083    }
03084 
03085    if (a->argc != 3) {
03086       return CLI_SHOWUSAGE;
03087    }
03088 
03089    AST_LIST_LOCK(&cfmtime_head);
03090    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
03091       if (!strcmp(cfmtime->filename, a->argv[2])) {
03092          char *buf = ast_alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
03093          sprintf(buf, "module reload %s", cfmtime->who_asked);
03094          ast_cli_command(a->fd, buf);
03095       }
03096    }
03097    AST_LIST_UNLOCK(&cfmtime_head);
03098 
03099    return CLI_SUCCESS;
03100 }

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

Definition at line 3003 of file config.c.

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

03004 {
03005    struct ast_config_engine *eng;
03006    struct ast_config_map *map;
03007 
03008    switch (cmd) {
03009    case CLI_INIT:
03010       e->command = "core show config mappings";
03011       e->usage =
03012          "Usage: core show config mappings\n"
03013          "  Shows the filenames to config engines.\n";
03014       return NULL;
03015    case CLI_GENERATE:
03016       return NULL;
03017    }
03018    
03019    ast_mutex_lock(&config_lock);
03020 
03021    if (!config_engine_list) {
03022       ast_cli(a->fd, "No config mappings found.\n");
03023    } else {
03024       for (eng = config_engine_list; eng; eng = eng->next) {
03025          ast_cli(a->fd, "Config Engine: %s\n", eng->name);
03026          for (map = config_maps; map; map = map->next) {
03027             if (!strcasecmp(map->driver, eng->name)) {
03028                ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
03029                      map->table ? map->table : map->name);
03030             }
03031          }
03032       }
03033    }
03034    
03035    ast_mutex_unlock(&config_lock);
03036 
03037    return CLI_SUCCESS;
03038 }

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

Definition at line 162 of file config.c.

References str, and total.

Referenced by ast_config_text_file_save().

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

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

Definition at line 182 of file config.c.

References CMP_MATCH, CMP_STOP, and inclfile::fname.

Referenced by ast_config_text_file_save().

00183 {
00184    const struct inclfile *ae = a, *be = b;
00185    return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0;
00186 }

static void inclfile_destroy ( void *  obj  )  [static]

Definition at line 1859 of file config.c.

References ast_free, and inclfile::fname.

Referenced by set_fn().

01860 {
01861    const struct inclfile *o = obj;
01862 
01863    ast_free(o->fname);
01864 }

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

Definition at line 872 of file config.c.

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

Referenced by process_text_line().

00873 {
00874    struct ast_variable *var;
00875    struct ast_category_template_instance *x;
00876 
00877    x = ast_calloc(1, sizeof(*x));
00878    if (!x) {
00879       return;
00880    }
00881    strcpy(x->name, base->name);
00882    x->inst = base;
00883    AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
00884    for (var = base->root; var; var = var->next)
00885       ast_variable_append(new, variable_clone(var));
00886 }

static int init_appendbuf ( void *  data  )  [static]

Definition at line 106 of file config.c.

References ast_str_create(), and str.

00107 {
00108    struct ast_str **str = data;
00109    *str = ast_str_create(16);
00110    return *str ? 0 : -1;
00111 }

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

Definition at line 1936 of file config.c.

References count_linefeeds_in_comments(), and inclfile::lineno.

Referenced by ast_config_text_file_save().

01937 {
01938    int precomment_lines;
01939    int i;
01940 
01941    if (!fi) {
01942       /* No file scratch pad object so insert no blank lines. */
01943       return;
01944    }
01945 
01946    precomment_lines = count_linefeeds_in_comments(precomments);
01947 
01948    /* I don't have to worry about those ;! comments, they are
01949       stored in the precomments, but not printed back out.
01950       I did have to make sure that comments following
01951       the ;! header comments were not also deleted in the process */
01952    if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */
01953       return;
01954    } else if (lineno == 0) {
01955       /* Line replacements also mess things up */
01956       return;
01957    } else if (lineno - precomment_lines - fi->lineno < 5) {
01958       /* Only insert less than 5 blank lines; if anything more occurs,
01959        * it's probably due to context deletion. */
01960       for (i = fi->lineno; i < lineno - precomment_lines; i++) {
01961          fprintf(fp, "\n");
01962       }
01963    } else {
01964       /* Deletion occurred - insert a single blank line, for separation of
01965        * contexts. */
01966       fprintf(fp, "\n");
01967    }
01968  
01969    fi->lineno = lineno + 1; /* Advance the file lineno */
01970 }

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

Definition at line 1866 of file config.c.

References ast_config_AST_CONFIG_DIR, ast_copy_string(), and ast_strlen_zero().

Referenced by ast_config_text_file_save(), and set_fn().

01867 {
01868    if (ast_strlen_zero(file)) {
01869       if (configfile[0] == '/') {
01870          ast_copy_string(fn, configfile, fn_size);
01871       } else {
01872          snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
01873       }
01874    } else if (file[0] == '/') {
01875       ast_copy_string(fn, file, fn_size);
01876    } else {
01877       snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
01878    }
01879 }

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

Definition at line 664 of file config.c.

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

Referenced by process_text_line().

00665 {
00666    struct ast_variable *var = old->root;
00667 
00668    old->root = NULL;
00669    /* we can just move the entire list in a single op */
00670    ast_variable_append(new, var);
00671 }

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

Definition at line 788 of file config.c.

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

Referenced by ast_category_browse().

00789 {
00790    for (; cat && cat->ignored; cat = cat->next);
00791 
00792    return cat;
00793 }

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 1255 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::name, ast_variable::next, ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, ast_variable::value, and var.

Referenced by config_text_file_load().

01261 {
01262    char *c;
01263    char *cur = buf;
01264    struct ast_variable *v;
01265    char cmd[512], exec_file[512];
01266 
01267    /* Actually parse the entry */
01268    if (cur[0] == '[') { /* A category header */
01269       /* format is one of the following:
01270        * [foo] define a new category named 'foo'
01271        * [foo](!) define a new template category named 'foo'
01272        * [foo](+) append to category 'foo', error if foo does not exist.
01273        * [foo](a) define a new category and inherit from template a.
01274        *    You can put a comma-separated list of templates and '!' and '+'
01275        *    between parentheses, with obvious meaning.
01276        */
01277       struct ast_category *newcat = NULL;
01278       char *catname;
01279 
01280       c = strchr(cur, ']');
01281       if (!c) {
01282          ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
01283          return -1;
01284       }
01285       *c++ = '\0';
01286       cur++;
01287       if (*c++ != '(')
01288          c = NULL;
01289       catname = cur;
01290       if (!(*cat = newcat = ast_category_new(catname,
01291             S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile),
01292             lineno))) {
01293          return -1;
01294       }
01295       (*cat)->lineno = lineno;
01296       *last_var = 0;
01297       *last_cat = newcat;
01298       
01299       /* add comments */
01300       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01301          newcat->precomments = ALLOC_COMMENT(comment_buffer);
01302       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01303          newcat->sameline = ALLOC_COMMENT(lline_buffer);
01304       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01305          CB_RESET(comment_buffer, lline_buffer);
01306       
01307       /* If there are options or categories to inherit from, process them now */
01308       if (c) {
01309          if (!(cur = strchr(c, ')'))) {
01310             ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
01311             return -1;
01312          }
01313          *cur = '\0';
01314          while ((cur = strsep(&c, ","))) {
01315             if (!strcasecmp(cur, "!")) {
01316                (*cat)->ignored = 1;
01317             } else if (!strcasecmp(cur, "+")) {
01318                *cat = category_get(cfg, catname, 1);
01319                if (!(*cat)) {
01320                   if (newcat)
01321                      ast_category_destroy(newcat);
01322                   ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
01323                   return -1;
01324                }
01325                if (newcat) {
01326                   move_variables(newcat, *cat);
01327                   ast_category_destroy(newcat);
01328                   newcat = NULL;
01329                }
01330             } else {
01331                struct ast_category *base;
01332             
01333                base = category_get(cfg, cur, 1);
01334                if (!base) {
01335                   ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
01336                   return -1;
01337                }
01338                inherit_category(*cat, base);
01339             }
01340          }
01341       }
01342       if (newcat)
01343          ast_category_append(cfg, *cat);
01344    } else if (cur[0] == '#') { /* A directive - #include or #exec */
01345       char *cur2;
01346       char real_inclusion_name[256];
01347       int do_include = 0;  /* otherwise, it is exec */
01348 
01349       cur++;
01350       c = cur;
01351       while (*c && (*c > 32)) {
01352          c++;
01353       }
01354 
01355       if (*c) {
01356          *c = '\0';
01357          /* Find real argument */
01358          c = ast_strip(c + 1);
01359          if (!(*c)) {
01360             c = NULL;
01361          }
01362       } else {
01363          c = NULL;
01364       }
01365       if (!strcasecmp(cur, "include")) {
01366          do_include = 1;
01367       } else if (!strcasecmp(cur, "exec")) {
01368          if (!ast_opt_exec_includes) {
01369             ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
01370             return 0;   /* XXX is this correct ? or we should return -1 ? */
01371          }
01372       } else {
01373          ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
01374          return 0;   /* XXX is this correct ? or we should return -1 ? */
01375       }
01376 
01377       if (c == NULL) {
01378          ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 
01379                do_include ? "include" : "exec",
01380                do_include ? "filename" : "/path/to/executable",
01381                lineno,
01382                configfile);
01383          return 0;   /* XXX is this correct ? or we should return -1 ? */
01384       }
01385 
01386       cur = c;
01387       /* Strip off leading and trailing "'s and <>'s */
01388       /* Dequote */
01389       if ((*c == '"') || (*c == '<')) {
01390          char quote_char = *c;
01391          if (quote_char == '<') {
01392             quote_char = '>';
01393          }
01394 
01395          if (*(c + strlen(c) - 1) == quote_char) {
01396             cur++;
01397             *(c + strlen(c) - 1) = '\0';
01398          }
01399       }
01400       cur2 = cur;
01401 
01402       /* #exec </path/to/executable>
01403          We create a tmp file, then we #include it, then we delete it. */
01404       if (!do_include) {
01405          struct timeval now = ast_tvnow();
01406          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01407             config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked);
01408          snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self());
01409          snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
01410          ast_safe_system(cmd);
01411          cur = exec_file;
01412       } else {
01413          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01414             config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked);
01415          exec_file[0] = '\0';
01416       }
01417       /* A #include */
01418       /* record this inclusion */
01419       ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
01420 
01421       do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0;
01422       if (!ast_strlen_zero(exec_file))
01423          unlink(exec_file);
01424       if (!do_include) {
01425          ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur);
01426          return -1;
01427       }
01428       /* XXX otherwise what ? the default return is 0 anyways */
01429 
01430    } else {
01431       /* Just a line (variable = value) */
01432       int object = 0;
01433       if (!(*cat)) {
01434          ast_log(LOG_WARNING,
01435             "parse error: No category context for line %d of %s\n", lineno, configfile);
01436          return -1;
01437       }
01438       c = strchr(cur, '=');
01439 
01440       if (c && c > cur && (*(c - 1) == '+')) {
01441          struct ast_variable *var, *replace = NULL;
01442          struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str));
01443 
01444          if (!str || !*str) {
01445             return -1;
01446          }
01447 
01448          *(c - 1) = '\0';
01449          c++;
01450          cur = ast_strip(cur);
01451 
01452          /* Must iterate through category until we find last variable of same name (since there could be multiple) */
01453          for (var = ast_category_first(*cat); var; var = var->next) {
01454             if (!strcmp(var->name, cur)) {
01455                replace = var;
01456             }
01457          }
01458 
01459          if (!replace) {
01460             /* Nothing to replace; just set a variable normally. */
01461             goto set_new_variable;
01462          }
01463 
01464          ast_str_set(str, 0, "%s", replace->value);
01465          ast_str_append(str, 0, "%s", c);
01466          ast_str_trim_blanks(*str);
01467          ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object);
01468       } else if (c) {
01469          *c = 0;
01470          c++;
01471          /* Ignore > in => */
01472          if (*c== '>') {
01473             object = 1;
01474             c++;
01475          }
01476 set_new_variable:
01477          if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) {
01478             v->lineno = lineno;
01479             v->object = object;
01480             *last_cat = 0;
01481             *last_var = v;
01482             /* Put and reset comments */
01483             v->blanklines = 0;
01484             ast_variable_append(*cat, v);
01485             /* add comments */
01486             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01487                v->precomments = ALLOC_COMMENT(comment_buffer);
01488             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01489                v->sameline = ALLOC_COMMENT(lline_buffer);
01490             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01491                CB_RESET(comment_buffer, lline_buffer);
01492             
01493          } else {
01494             return -1;
01495          }
01496       } else {
01497          ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
01498       }
01499    }
01500    return 0;
01501 }

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 2298 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, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, table, and ast_variable::value.

Referenced by main().

02299 {
02300    struct ast_config *config, *configtmp;
02301    struct ast_variable *v;
02302    char *driver, *table, *database, *textpri, *stringp, *tmp;
02303    struct ast_flags flags = { CONFIG_FLAG_NOREALTIME };
02304    int pri;
02305 
02306    clear_config_maps();
02307 
02308    configtmp = ast_config_new();
02309    if (!configtmp) {
02310       ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
02311       return -1;
02312    }
02313    config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
02314    if (config == CONFIG_STATUS_FILEINVALID) {
02315       return -1;
02316    } else if (!config) {
02317       ast_config_destroy(configtmp);
02318       return 0;
02319    }
02320 
02321    for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
02322       char buf[512];
02323       ast_copy_string(buf, v->value, sizeof(buf));
02324       stringp = buf;
02325       driver = strsep(&stringp, ",");
02326 
02327       if ((tmp = strchr(stringp, '\"')))
02328          stringp = tmp;
02329 
02330       /* check if the database text starts with a double quote */
02331       if (*stringp == '"') {
02332          stringp++;
02333          database = strsep(&stringp, "\"");
02334          strsep(&stringp, ",");
02335       } else {
02336          /* apparently this text has no quotes */
02337          database = strsep(&stringp, ",");
02338       }
02339 
02340       table = strsep(&stringp, ",");
02341       textpri = strsep(&stringp, ",");
02342       if (!textpri || !(pri = atoi(textpri))) {
02343          pri = 1;
02344       }
02345 
02346       if (!strcmp(v->name, extconfig_conf)) {
02347          ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
02348          continue;
02349       }
02350 
02351       if (!strcmp(v->name, "asterisk.conf")) {
02352          ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
02353          continue;
02354       }
02355 
02356       if (!strcmp(v->name, "logger.conf")) {
02357          ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
02358          continue;
02359       }
02360 
02361       if (!driver || !database)
02362          continue;
02363       if (!strcasecmp(v->name, "sipfriends")) {
02364          ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
02365          append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
02366       } else if (!strcasecmp(v->name, "iaxfriends")) {
02367          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");
02368          append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
02369          append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
02370       } else 
02371          append_mapping(v->name, driver, database, table, pri);
02372    }
02373       
02374    ast_config_destroy(config);
02375    return 0;
02376 }

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

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

Referenced by main().

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

Definition at line 1881 of file config.c.

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

Referenced by ast_config_text_file_save().

01882 {
01883    struct inclfile lookup;
01884    struct inclfile *fi;
01885 
01886    make_fn(fn, fn_size, file, configfile);
01887    lookup.fname = fn;
01888    fi = ao2_find(fileset, &lookup, OBJ_POINTER);
01889    if (fi) {
01890       /* Found existing include file scratch pad. */
01891       return fi;
01892    }
01893 
01894    /* set up a file scratch pad */
01895    fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
01896    if (!fi) {
01897       /* Scratch pad creation failed. */
01898       return NULL;
01899    }
01900    fi->fname = ast_strdup(fn);
01901    if (!fi->fname) {
01902       /* Scratch pad creation failed. */
01903       ao2_ref(fi, -1);
01904       return NULL;
01905    }
01906    fi->lineno = 1;
01907 
01908    ao2_link(fileset, fi);
01909 
01910    return fi;
01911 }

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

Definition at line 650 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().

00651 {
00652    struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
00653 
00654    if (new) {
00655       new->lineno = old->lineno;
00656       new->object = old->object;
00657       new->blanklines = old->blanklines;
00658       /* TODO: clone comments? */
00659    }
00660 
00661    return new;
00662 }


Variable Documentation

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

Definition at line 113 of file config.c.

Referenced by process_text_line().

struct ast_cli_entry cli_config[] [static]
Initial value:
 {
   AST_CLI_DEFINE(handle_cli_core_show_config_mappings, "Display config mappings (file names to config engines)"),
   AST_CLI_DEFINE(handle_cli_config_reload, "Force a reload on modules using a particular configuration file"),
   AST_CLI_DEFINE(handle_cli_config_list, "Show all files that have loaded a configuration file"),
}

Definition at line 3126 of file config.c.

Definition at line 204 of file config.c.

ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]
struct ast_config_map * config_maps [static]
char* extconfig_conf = "extconfig.conf" [static]

Definition at line 69 of file config.c.

Initial value:
 {
   .name = "text",
   .load_func = config_text_file_load,
}

Definition at line 2454 of file config.c.


Generated on 27 Jan 2016 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1