Wed Oct 28 13:32:27 2009

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 dependency graph for config.c:

Go to the source code of this file.

Data Structures

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

Defines

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

Enumerations

enum  config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0, ATTRIBUTE_EXEC = 1 }

Functions

static void __init_appendbuf (void)
static struct ast_commentALLOC_COMMENT (struct ast_str *buffer)
static int append_mapping (const char *name, const char *driver, const char *database, const char *table)
void ast_category_append (struct ast_config *config, struct ast_category *category)
char * ast_category_browse (struct ast_config *config, const char *prev)
 Goes through categories.
int ast_category_delete (struct ast_config *cfg, const char *category)
void ast_category_destroy (struct ast_category *cat)
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. This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get())
struct ast_categoryast_category_get (const struct ast_config *config, const char *category_name)
 Retrieve a category if it exists.
void ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match)
 Inserts new category.
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.
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. API for backend configuration engines while building a configuration set.
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. Retrieves the named variable var within category cat of configuration set cfg. If not found, attempts to retrieve the named variable var from within category general.
void ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat)
 Set the category within the configuration as being current. API for backend configuration engines while building a configuration set.
int ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator)
static void ast_destroy_comments (struct ast_category *cat)
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.
int ast_realtime_enabled ()
 Check if there's any realtime engines loaded.
int ast_realtime_require_field (const char *family,...)
 Inform realtime what fields that may be stored.
int ast_store_realtime (const char *family,...)
 Create realtime configuration.
int ast_unload_realtime (const char *family)
 Release any resources cached for a realtime family.
int ast_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 Somewhat similar in intent as the ast_category_browse. List variables of config file category.
int ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line)
void ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line)
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.
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 void clear_config_maps (void)
static void config_cache_attribute (const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked)
static struct ast_configconfig_text_file_load (const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
int config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator)
static int count_linefeeds (char *str)
static int count_linefeeds_in_comments (struct ast_comment *x)
static struct ast_config_enginefind_engine (const char *family, char *database, int dbsiz, char *table, int tabsiz)
 Find realtime engine for realtime family.
static void gen_header (FILE *f1, const char *configfile, const char *fn, const char *generator)
static char * handle_cli_config_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_config_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_core_show_config_mappings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int hash_string (const void *obj, const int flags)
static int hashtab_compare_strings (void *a, void *b, int flags)
static void inclfile_destroy (void *obj)
static void inherit_category (struct ast_category *new, const struct ast_category *base)
static int init_appendbuf (void *data)
static void insert_leading_blank_lines (FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
static void move_variables (struct ast_category *old, struct ast_category *new)
static struct ast_categorynext_available_category (struct ast_category *cat)
static int process_text_line (struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked)
 parse one line in the configuration.
int read_config_maps (void)
 Exposed re-initialization method for core process This method is intended for use only with the core re-initialization and is not designed to be called from any user applications.
int register_config_cli ()
 Exposed initialization method for core process This method is intended for use only with the core initialization and is not designed to be called from any user applications.
static void set_fn (char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset, struct inclfile **fi)
static struct ast_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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
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 doc/realtime.txt and doc/extconfig.txt

Definition in file config.c.


Define Documentation

#define AST_INCLUDE_GLOB   1

Definition at line 40 of file config.c.

#define CB_SIZE   250

Definition at line 93 of file config.c.

Referenced by config_text_file_load().

#define COMMENT_END   "--;"

Definition at line 53 of file config.c.

#define COMMENT_META   ';'

Definition at line 54 of file config.c.

Referenced by config_text_file_load().

#define COMMENT_START   ";--"

Definition at line 52 of file config.c.

#define COMMENT_TAG   '-'

Definition at line 55 of file config.c.

Referenced by config_text_file_load().

#define MAX_INCLUDE_LEVEL   10

Definition at line 175 of file config.c.

Referenced by ast_config_new().

#define MAX_NESTED_COMMENTS   128

Definition at line 51 of file config.c.

Referenced by config_text_file_load().


Enumeration Type Documentation

Enumerator:
ATTRIBUTE_INCLUDE 
ATTRIBUTE_EXEC 

Definition at line 868 of file config.c.

00868                                  {
00869    ATTRIBUTE_INCLUDE = 0,
00870    ATTRIBUTE_EXEC = 1,
00871 };


Function Documentation

static void __init_appendbuf ( void   )  [static]

Definition at line 90 of file config.c.

00096 {

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

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

00118 { 
00119    struct ast_comment *x = NULL;
00120    if (!buffer || !ast_str_strlen(buffer)) {
00121       return NULL;
00122    }
00123    if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
00124       strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
00125    }
00126    return x;
00127 }

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

Definition at line 1869 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::stuff, and ast_config_map::table.

Referenced by read_config_maps().

01870 {
01871    struct ast_config_map *map;
01872    int length;
01873 
01874    length = sizeof(*map);
01875    length += strlen(name) + 1;
01876    length += strlen(driver) + 1;
01877    length += strlen(database) + 1;
01878    if (table)
01879       length += strlen(table) + 1;
01880 
01881    if (!(map = ast_calloc(1, length)))
01882       return -1;
01883 
01884    map->name = map->stuff;
01885    strcpy(map->name, name);
01886    map->driver = map->name + strlen(map->name) + 1;
01887    strcpy(map->driver, driver);
01888    map->database = map->driver + strlen(map->driver) + 1;
01889    strcpy(map->database, database);
01890    if (table) {
01891       map->table = map->database + strlen(map->database) + 1;
01892       strcpy(map->table, table);
01893    }
01894    map->next = config_maps;
01895 
01896    ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
01897 
01898    config_maps = map;
01899    return 0;
01900 }

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 617 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(), aji_load_config(), ast_cli_perms_init(), complete_sipnotify(), config_load(), find_queue_by_name_rt(), find_realtime(), get_insecure_variable_from_config(), gtalk_load_config(), iax_provision_reload(), jingle_load_config(), load_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_tech_calendars(), misdn_cfg_init(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), search_directory(), search_directory_sub(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().

00618 {  
00619    struct ast_category *cat = NULL;
00620 
00621    if (prev && config->last_browse && (config->last_browse->name == prev))
00622       cat = config->last_browse->next;
00623    else if (!prev && config->root)
00624       cat = config->root;
00625    else if (prev) {
00626       for (cat = config->root; cat; cat = cat->next) {
00627          if (cat->name == prev) {
00628             cat = cat->next;
00629             break;
00630          }
00631       }
00632       if (!cat) {
00633          for (cat = config->root; cat; cat = cat->next) {
00634             if (!strcasecmp(cat->name, prev)) {
00635                cat = cat->next;
00636                break;
00637             }
00638          }
00639       }
00640    }
00641    
00642    if (cat)
00643       cat = next_available_category(cat);
00644 
00645    config->last_browse = cat;
00646    return (cat) ? cat->name : NULL;
00647 }

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

Definition at line 778 of file config.c.

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

Referenced by handle_updates().

00779 {
00780    struct ast_category *prev=NULL, *cat;
00781 
00782    cat = cfg->root;
00783    while (cat) {
00784       if (cat->name == category) {
00785          if (prev) {
00786             prev->next = cat->next;
00787             if (cat == cfg->last)
00788                cfg->last = prev;
00789          } else {
00790             cfg->root = cat->next;
00791             if (cat == cfg->last)
00792                cfg->last = NULL;
00793          }
00794          ast_category_destroy(cat);
00795          return 0;
00796       }
00797       prev = cat;
00798       cat = cat->next;
00799    }
00800 
00801    prev = NULL;
00802    cat = cfg->root;
00803    while (cat) {
00804       if (!strcasecmp(cat->name, category)) {
00805          if (prev) {
00806             prev->next = cat->next;
00807             if (cat == cfg->last)
00808                cfg->last = prev;
00809          } else {
00810             cfg->root = cat->next;
00811             if (cat == cfg->last)
00812                cfg->last = NULL;
00813          }
00814          ast_category_destroy(cat);
00815          return 0;
00816       }
00817       prev = cat;
00818       cat = cat->next;
00819    }
00820    return -1;
00821 }

void ast_category_destroy ( struct ast_category cat  ) 

Definition at line 567 of file config.c.

References ast_destroy_comments(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, free, and ast_category::root.

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

00568 {
00569    ast_variables_destroy(cat->root);
00570    if (cat->file) {
00571       free(cat->file);
00572       cat->file = 0;
00573    }
00574    ast_destroy_comments(cat);
00575    ast_destroy_template_list(cat);
00576    ast_free(cat);
00577 }

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

Definition at line 649 of file config.c.

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

Referenced by realtime_switch_common().

00650 {
00651    struct ast_variable *v;
00652 
00653    v = cat->root;
00654    cat->root = NULL;
00655    cat->last = NULL;
00656 
00657    return v;
00658 }

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

00824 {
00825    struct ast_category *cat;
00826 
00827    for (cat = cfg->root; cat; cat = cat->next) {
00828       if (!strcasecmp(cat->name, category))
00829          continue;
00830       ast_variables_destroy(cat->root);
00831       cat->root = NULL;
00832       cat->last = NULL;
00833       return 0;
00834    }
00835 
00836    return -1;
00837 }

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

References ast_category_get().

00503 {
00504    return !!ast_category_get(config, category_name);
00505 }

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

given a pointer to a category, return the root variable. This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get())

return the first var of a category

Definition at line 603 of file config.c.

References ast_category::root.

Referenced by process_text_line().

00604 {
00605    return (cat) ? cat->root : NULL;
00606 }

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

00498 {
00499    return category_get(config, category_name, 0);
00500 }

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

Inserts new category.

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

Definition at line 518 of file config.c.

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

Referenced by handle_updates().

00519 {
00520    struct ast_category *cur_category;
00521 
00522    if (!cat || !match)
00523       return;
00524    if (!strcasecmp(config->root->name, match)) {
00525       cat->next = config->root;
00526       config->root = cat;
00527       return;
00528    } 
00529    for (cur_category = config->root; cur_category; cur_category = cur_category->next) {
00530       if (!strcasecmp(cur_category->next->name, match)) {
00531          cat->next = cur_category->next;
00532          cur_category->next = cat;
00533          break;
00534       }
00535    }
00536 }

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

Create a category structure.

Definition at line 468 of file config.c.

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

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

00469 {
00470    struct ast_category *category;
00471 
00472    if ((category = ast_calloc(1, sizeof(*category))))
00473       ast_copy_string(category->name, name, sizeof(category->name));
00474    category->file = strdup(in_file);
00475    category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
00476    return category;
00477 }

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

Definition at line 660 of file config.c.

References ast_copy_string(), and ast_category::name.

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

00661 {
00662    ast_copy_string(cat->name, name, sizeof(cat->name));
00663 }

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

References ast_category_get(), and ast_category::root.

Referenced by get_insecure_variable_from_config().

00609 {
00610    struct ast_category *category = ast_category_get(config, cat);
00611 
00612    if (category)
00613       return category->root;
00614    return NULL;
00615 }

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 2166 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(), handle_response_peerpoke(), handle_voicemail_show_users(), leave_voicemail(), load_module(), local_ast_moh_start(), realtime_peer(), realtime_update_peer(), rename_file(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().

02167 {
02168    struct ast_config_engine *eng;
02169    if (!ast_realtime_enabled()) {
02170       return 0;   /* There are no engines at all so fail early */
02171    }
02172 
02173    eng = find_engine(family, NULL, 0, NULL, 0);
02174    if (eng)
02175       return 1;
02176    return 0;
02177 }

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 839 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_readconfig(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_realtime(), handle_cli_dialplan_save(), iax_provision_reload(), init_logger_chain(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_realtime_queue(), load_rpt_vars(), make_email_file(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), read_agent_config(), read_config_maps(), realtime_directory(), realtime_multi_handler(), realtime_peer(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), rtp_reload(), run_startup_commands(), set_config(), setup_dahdi(), show_users_realtime(), sla_load_config(), smdi_load(), store_config(), tds_load_module(), unload_module(), update_realtime_members(), and vm_forwardoptions().

00840 {
00841    struct ast_category *cat, *catn;
00842 
00843    if (!cfg)
00844       return;
00845 
00846    ast_includes_destroy(cfg->includes);
00847 
00848    cat = cfg->root;
00849    while (cat) {
00850       catn = cat;
00851       cat = cat->next;
00852       ast_category_destroy(catn);
00853    }
00854    ast_free(cfg);
00855 }

int ast_config_engine_deregister ( struct ast_config_engine del  ) 

Deregister config engine.

Return values:
0 Always

Definition at line 1992 of file config.c.

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

Referenced by unload_module().

01993 {
01994    struct ast_config_engine *ptr, *last=NULL;
01995 
01996    ast_mutex_lock(&config_lock);
01997 
01998    for (ptr = config_engine_list; ptr; ptr=ptr->next) {
01999       if (ptr == del) {
02000          if (last)
02001             last->next = ptr->next;
02002          else
02003             config_engine_list = ptr->next;
02004          break;
02005       }
02006       last = ptr;
02007    }
02008 
02009    ast_mutex_unlock(&config_lock);
02010 
02011    return 0;
02012 }

int ast_config_engine_register ( struct ast_config_engine newconfig  ) 

Register config engine.

Return values:
1 Always

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

01974 {
01975    struct ast_config_engine *ptr;
01976 
01977    ast_mutex_lock(&config_lock);
01978 
01979    if (!config_engine_list) {
01980       config_engine_list = new;
01981    } else {
01982       for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
01983       ptr->next = new;
01984    }
01985 
01986    ast_mutex_unlock(&config_lock);
01987    ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name);
01988 
01989    return 1;
01990 }

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

References ast_config::current.

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

00858 {
00859    return cfg->current;
00860 }

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

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

02055 {
02056    char db[256];
02057    char table[256];
02058    struct ast_config_engine *loader = &text_file_engine;
02059    struct ast_config *result; 
02060 
02061    /* The config file itself bumps include_level by 1 */
02062    if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
02063       ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
02064       return NULL;
02065    }
02066 
02067    cfg->include_level++;
02068 
02069    if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
02070       struct ast_config_engine *eng;
02071 
02072       eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
02073 
02074 
02075       if (eng && eng->load_func) {
02076          loader = eng;
02077       } else {
02078          eng = find_engine("global", db, sizeof(db), table, sizeof(table));
02079          if (eng && eng->load_func)
02080             loader = eng;
02081       }
02082    }
02083 
02084    result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
02085 
02086    if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED)
02087       result->include_level--;
02088    else if (result != CONFIG_STATUS_FILEINVALID)
02089       cfg->include_level--;
02090 
02091    return result;
02092 }

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 Create a config structure from a given configuration file.
who_asked The module which is making this request.
flags Optional flags: CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact; CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files).
Returns:
an ast_config data structure on success
Return values:
NULL on error

Definition at line 2094 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(), load_config(), load_indications(), load_modules(), misdn_cfg_init(), private_enum_init(), rtp_reload(), and run_startup_commands().

02095 {
02096    struct ast_config *cfg;
02097    struct ast_config *result;
02098 
02099    cfg = ast_config_new();
02100    if (!cfg)
02101       return NULL;
02102 
02103    result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
02104    if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID)
02105       ast_config_destroy(cfg);
02106 
02107    return result;
02108 }

struct ast_config* ast_config_new ( void   )  [read]

Create a new base configuration structure.

Definition at line 677 of file config.c.

References ast_calloc, config, MAX_INCLUDE_LEVEL, and ast_config::max_include_level.

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

00678 {
00679    struct ast_config *config;
00680 
00681    if ((config = ast_calloc(1, sizeof(*config))))
00682       config->max_include_level = MAX_INCLUDE_LEVEL;
00683    return config;
00684 }

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

References ast_variable_retrieve().

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

00410 {
00411    const char *tmp;
00412    tmp = ast_variable_retrieve(cfg, cat, var);
00413    if (!tmp) {
00414       tmp = ast_variable_retrieve(cfg, "general", var);
00415    }
00416    return tmp;
00417 }

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

References ast_config::current.

00863 {
00864    /* cast below is just to silence compiler warning about dropping "const" */
00865    cfg->current = (struct ast_category *) cat;
00866 }

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

Definition at line 1614 of file config.c.

References ao2_container_alloc, ao2_ref, ast_debug, AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, 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, 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().

01615 {
01616    FILE *f;
01617    char fn[256];
01618    struct ast_variable *var;
01619    struct ast_category *cat;
01620    struct ast_comment *cmt;
01621    struct ast_config_include *incl;
01622    int blanklines = 0;
01623    struct ao2_container *fileset = ao2_container_alloc(180000, hash_string, hashtab_compare_strings);
01624    struct inclfile *fi = 0;
01625 
01626    /* reset all the output flags, in case this isn't our first time saving this data */
01627 
01628    for (incl=cfg->includes; incl; incl = incl->next)
01629       incl->output = 0;
01630 
01631    /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
01632       are all truncated to zero bytes and have that nice header*/
01633 
01634    for (incl=cfg->includes; incl; incl = incl->next)
01635    {
01636       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*/
01637          FILE *f1;
01638 
01639          set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset, &fi); /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
01640          f1 = fopen(fn,"w");
01641          if (f1) {
01642             gen_header(f1, configfile, fn, generator);
01643             fclose(f1); /* this should zero out the file */
01644          } else {
01645             ast_debug(1, "Unable to open for writing: %s\n", fn);
01646             ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
01647          }
01648          ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01649          fi = 0;
01650       }
01651    }
01652 
01653    set_fn(fn, sizeof(fn), 0, configfile, fileset, &fi); /* just set fn to absolute ver of configfile */
01654 #ifdef __CYGWIN__ 
01655    if ((f = fopen(fn, "w+"))) {
01656 #else
01657    if ((f = fopen(fn, "w"))) {
01658 #endif       
01659       ast_verb(2, "Saving '%s': ", fn);
01660       gen_header(f, configfile, fn, generator);
01661       cat = cfg->root;
01662       fclose(f);
01663       ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01664       
01665       /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
01666       /* since each var, cat, and associated comments can come from any file, we have to be 
01667          mobile, and open each file, print, and close it on an entry-by-entry basis */
01668 
01669       while (cat) {
01670          set_fn(fn, sizeof(fn), cat->file, configfile, fileset, &fi);
01671          f = fopen(fn, "a");
01672          if (!f)
01673          {
01674             ast_debug(1, "Unable to open for writing: %s\n", fn);
01675             ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
01676             ao2_ref(fileset, -1);
01677             return -1;
01678          }
01679 
01680          /* dump any includes that happen before this category header */
01681          for (incl=cfg->includes; incl; incl = incl->next) {
01682             if (strcmp(incl->include_location_file, cat->file) == 0){
01683                if (cat->lineno > incl->include_location_lineno && !incl->output) {
01684                   if (incl->exec)
01685                      fprintf(f,"#exec \"%s\"\n", incl->exec_file);
01686                   else
01687                      fprintf(f,"#include \"%s\"\n", incl->included_file);
01688                   incl->output = 1;
01689                }
01690             }
01691          }
01692 
01693          insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno);
01694          /* Dump section with any appropriate comment */
01695          for (cmt = cat->precomments; cmt; cmt=cmt->next) {
01696             char *cmtp = cmt->cmt;
01697             while (*cmtp == ';' && *(cmtp+1) == '!') {
01698                char *cmtp2 = strchr(cmtp+1, '\n');
01699                if (cmtp2)
01700                   cmtp = cmtp2+1;
01701                else cmtp = 0;
01702             }
01703             if (cmtp)
01704                fprintf(f,"%s", cmtp);
01705          }
01706          fprintf(f, "[%s]", cat->name);
01707          if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
01708             fprintf(f, "(");
01709             if (cat->ignored) {
01710                fprintf(f, "!");
01711             }
01712             if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
01713                fprintf(f, ",");
01714             }
01715             if (!AST_LIST_EMPTY(&cat->template_instances)) {
01716                struct ast_category_template_instance *x;
01717                AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
01718                   fprintf(f,"%s",x->name);
01719                   if (x != AST_LIST_LAST(&cat->template_instances))
01720                      fprintf(f,",");
01721                }
01722             }
01723             fprintf(f, ")");
01724          }
01725          for(cmt = cat->sameline; cmt; cmt=cmt->next)
01726          {
01727             fprintf(f,"%s", cmt->cmt);
01728          }
01729          if (!cat->sameline)
01730             fprintf(f,"\n");
01731          for (cmt = cat->trailing; cmt; cmt=cmt->next) {
01732             if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
01733                fprintf(f,"%s", cmt->cmt);
01734          }
01735          fclose(f);
01736          ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01737          fi = 0;
01738          
01739          var = cat->root;
01740          while (var) {
01741             struct ast_category_template_instance *x;
01742             int found = 0;
01743             AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
01744                struct ast_variable *v;
01745                for (v = x->inst->root; v; v = v->next) {
01746                   if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
01747                      found = 1;
01748                      break;
01749                   }
01750                }
01751                if (found)
01752                   break;
01753             }
01754             if (found) {
01755                var = var->next;
01756                continue;
01757             }
01758             set_fn(fn, sizeof(fn), var->file, configfile, fileset, &fi);
01759             f = fopen(fn, "a");
01760             if (!f)
01761             {
01762                ast_debug(1, "Unable to open for writing: %s\n", fn);
01763                ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
01764                ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01765                fi = 0;
01766                ao2_ref(fileset, -1);
01767                return -1;
01768             }
01769             
01770             /* dump any includes that happen before this category header */
01771             for (incl=cfg->includes; incl; incl = incl->next) {
01772                if (strcmp(incl->include_location_file, var->file) == 0){
01773                   if (var->lineno > incl->include_location_lineno && !incl->output) {
01774                      if (incl->exec)
01775                         fprintf(f,"#exec \"%s\"\n", incl->exec_file);
01776                      else
01777                         fprintf(f,"#include \"%s\"\n", incl->included_file);
01778                      incl->output = 1;
01779                   }
01780                }
01781             }
01782             
01783             insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
01784             for (cmt = var->precomments; cmt; cmt=cmt->next) {
01785                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
01786                   fprintf(f,"%s", cmt->cmt);
01787             }
01788             if (var->sameline) 
01789                fprintf(f, "%s %s %s  %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
01790             else  
01791                fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
01792             for (cmt = var->trailing; cmt; cmt=cmt->next) {
01793                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
01794                   fprintf(f,"%s", cmt->cmt);
01795             }
01796             if (var->blanklines) {
01797                blanklines = var->blanklines;
01798                while (blanklines--)
01799                   fprintf(f, "\n");
01800             }
01801             
01802             fclose(f);
01803             ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01804             fi = 0;
01805             
01806             var = var->next;
01807          }
01808          cat = cat->next;
01809       }
01810       if (!option_debug)
01811          ast_verb(2, "Saved\n");
01812    } else {
01813       ast_debug(1, "Unable to open for writing: %s\n", fn);
01814       ast_verb(2, "Unable to write (%s)", strerror(errno));
01815       ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01816       ao2_ref(fileset, -1);
01817       return -1;
01818    }
01819 
01820    /* Now, for files with trailing #include/#exec statements,
01821       we have to make sure every entry is output */
01822 
01823    for (incl=cfg->includes; incl; incl = incl->next) {
01824       if (!incl->output) {
01825          /* open the respective file */
01826          set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset, &fi);
01827          f = fopen(fn, "a");
01828          if (!f)
01829          {
01830             ast_debug(1, "Unable to open for writing: %s\n", fn);
01831             ast_verb(2, "Unable to write %s (%s)", fn, strerror(errno));
01832             ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01833             fi = 0;
01834             ao2_ref(fileset, -1);
01835             return -1;
01836          }
01837          
01838          /* output the respective include */
01839          if (incl->exec)
01840             fprintf(f,"#exec \"%s\"\n", incl->exec_file);
01841          else
01842             fprintf(f,"#include \"%s\"\n", incl->included_file);
01843          fclose(f);
01844          incl->output = 1;
01845          ao2_ref(fi,-1); /* we are giving up this reference to the object ptd to by fi */
01846          fi = 0;
01847       }
01848    }
01849    ao2_ref(fileset, -1); /* this should destroy the hash container */
01850             
01851    return 0;
01852 }

static void ast_destroy_comments ( struct ast_category cat  )  [static]

Definition at line 538 of file config.c.

References free, ast_comment::next, ast_category::precomments, ast_category::sameline, and ast_category::trailing.

Referenced by ast_category_destroy().

00539 {
00540    struct ast_comment *n, *p;
00541 
00542    for (p=cat->precomments; p; p=n) {
00543       n = p->next;
00544       free(p);
00545    }
00546    for (p=cat->sameline; p; p=n) {
00547       n = p->next;
00548       free(p);
00549    }
00550    for (p=cat->trailing; p; p=n) {
00551       n = p->next;
00552       free(p);
00553    }
00554    cat->precomments = NULL;
00555    cat->sameline = NULL;
00556    cat->trailing = NULL;
00557 }

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 that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

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

02286 {
02287    struct ast_config_engine *eng;
02288    int res = -1;
02289    char db[256];
02290    char table[256];
02291    va_list ap;
02292 
02293    va_start(ap, lookup);
02294    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02295    if (eng && eng->destroy_func) 
02296       res = eng->destroy_func(db, table, keyfield, lookup, ap);
02297    va_end(ap);
02298 
02299    return res;
02300 }

static void ast_destroy_template_list ( struct ast_category cat  )  [static]

Definition at line 559 of file config.c.

References AST_LIST_REMOVE_HEAD, free, and ast_category::template_instances.

Referenced by ast_category_destroy().

00560 {
00561    struct ast_category_template_instance *x;
00562 
00563    while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
00564       free(x);
00565 }

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

Definition at line 337 of file config.c.

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

Referenced by ast_include_new().

00338 {
00339    struct ast_config_include *x;
00340    for (x=conf->includes;x;x=x->next) {
00341       if (strcmp(x->included_file,included_file) == 0)
00342          return x;
00343    }
00344    return 0;
00345 }

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

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

Referenced by process_text_line().

00247 {
00248    /* a file should be included ONCE. Otherwise, if one of the instances is changed,
00249     * then all be changed. -- how do we know to include it? -- Handling modified 
00250     * instances is possible, I'd have
00251     * to create a new master for each instance. */
00252    struct ast_config_include *inc;
00253    struct stat statbuf;
00254    
00255    inc = ast_include_find(conf, included_file);
00256    if (inc) {
00257       do {
00258          inc->inclusion_count++;
00259          snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
00260       } while (stat(real_included_file_name, &statbuf) == 0);
00261       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);
00262    } else
00263       *real_included_file_name = 0;
00264    
00265    inc = ast_calloc(1,sizeof(struct ast_config_include));
00266    inc->include_location_file = ast_strdup(from_file);
00267    inc->include_location_lineno = from_lineno;
00268    if (!ast_strlen_zero(real_included_file_name))
00269       inc->included_file = ast_strdup(real_included_file_name);
00270    else
00271       inc->included_file = ast_strdup(included_file);
00272    
00273    inc->exec = is_exec;
00274    if (is_exec)
00275       inc->exec_file = ast_strdup(exec_file);
00276    
00277    /* attach this new struct to the conf struct */
00278    inc->next = conf->includes;
00279    conf->includes = inc;
00280    
00281    return inc;
00282 }

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

Definition at line 284 of file config.c.

References ast_variable::file, ast_category::file, free, ast_config_include::include_location_file, ast_config::includes, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, ast_config::root, and strdup.

Referenced by action_updateconfig().

00285 {
00286    struct ast_config_include *incl;
00287    struct ast_category *cat;
00288    struct ast_variable *v;
00289    
00290    int from_len = strlen(from_file);
00291    int to_len = strlen(to_file);
00292    
00293    if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
00294       return;
00295    
00296    /* the manager code allows you to read in one config file, then
00297     * write it back out under a different name. But, the new arrangement
00298     * ties output lines to the file name. So, before you try to write
00299     * the config file to disk, better riffle thru the data and make sure
00300     * the file names are changed.
00301     */
00302    /* file names are on categories, includes (of course), and on variables. So,
00303     * traverse all this and swap names */
00304 
00305    for (incl = conf->includes; incl; incl=incl->next) {
00306       if (strcmp(incl->include_location_file,from_file) == 0) {
00307          if (from_len >= to_len)
00308             strcpy(incl->include_location_file, to_file);
00309          else {
00310             free(incl->include_location_file);
00311             incl->include_location_file = strdup(to_file);
00312          }
00313       }
00314    }
00315    for (cat = conf->root; cat; cat = cat->next) {
00316       if (strcmp(cat->file,from_file) == 0) {
00317          if (from_len >= to_len)
00318             strcpy(cat->file, to_file);
00319          else {
00320             free(cat->file);
00321             cat->file = strdup(to_file);
00322          }
00323       }
00324       for (v = cat->root; v; v = v->next) {
00325          if (strcmp(v->file,from_file) == 0) {
00326             if (from_len >= to_len)
00327                strcpy(v->file, to_file);
00328             else {
00329                free(v->file);
00330                v->file = strdup(to_file);
00331             }
00332          }
00333       }
00334    }
00335 }

static void ast_includes_destroy ( struct ast_config_include incls  )  [static]

Definition at line 579 of file config.c.

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

Referenced by ast_config_destroy().

00580 {
00581    struct ast_config_include *incl,*inclnext;
00582    
00583    for (incl=incls; incl; incl = inclnext) {
00584       inclnext = incl->next;
00585       if (incl->include_location_file)
00586          free(incl->include_location_file);
00587       if (incl->exec_file)
00588          free(incl->exec_file);
00589       if (incl->included_file)
00590          free(incl->included_file);
00591       free(incl);
00592    }
00593 }

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

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

Definition at line 2136 of file config.c.

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

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

02137 {
02138    struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL;
02139    va_list ap;
02140 
02141    va_start(ap, family);
02142    res = ast_load_realtime_helper(family, ap);
02143    va_end(ap);
02144 
02145    /* Eliminate blank entries */
02146    for (cur = res; cur; cur = cur->next) {
02147       if (freeme) {
02148          ast_free(freeme);
02149          freeme = NULL;
02150       }
02151 
02152       if (ast_strlen_zero(cur->value)) {
02153          if (prev)
02154             prev->next = cur->next;
02155          else
02156             res = cur->next;
02157          freeme = cur;
02158       } else {
02159          prev = cur;
02160       }
02161    }
02162    return res;
02163 }

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

Definition at line 2124 of file config.c.

References ast_load_realtime_helper().

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

02125 {
02126    struct ast_variable *res;
02127    va_list ap;
02128 
02129    va_start(ap, family);
02130    res = ast_load_realtime_helper(family, ap);
02131    va_end(ap);
02132 
02133    return res;
02134 }

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

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

02111 {
02112    struct ast_config_engine *eng;
02113    char db[256];
02114    char table[256];
02115    struct ast_variable *res=NULL;
02116 
02117    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02118    if (eng && eng->realtime_func) 
02119       res = eng->realtime_func(db, table, ap);
02120 
02121    return res;
02122 }

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.

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

Definition at line 2217 of file config.c.

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

Referenced by __queues_show(), find_realtime(), load_realtime_queue(), realtime_directory(), realtime_peer(), realtime_switch_common(), show_users_realtime(), and update_realtime_members().

02218 {
02219    struct ast_config_engine *eng;
02220    char db[256];
02221    char table[256];
02222    struct ast_config *res = NULL;
02223    va_list ap;
02224 
02225    va_start(ap, family);
02226    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02227    if (eng && eng->realtime_multi_func) 
02228       res = eng->realtime_multi_func(db, table, ap);
02229    va_end(ap);
02230 
02231    return res;
02232 }

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

References ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_strdupa, buf, hp, PARSE_DEFAULT, PARSE_DOUBLE, PARSE_IN_RANGE, PARSE_INADDR, PARSE_INT32, PARSE_OUT_RANGE, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, PARSE_PORT_REQUIRE, PARSE_TYPE, PARSE_UINT32, and strsep().

Referenced by ast_sip_ouraddrfor(), ast_tls_read_conf(), check_via_response(), multicast_rtp_request(), and reload_config().

02307 {
02308    va_list ap;
02309    int error = 0;
02310 
02311    va_start(ap, p_result);
02312    switch (flags & PARSE_TYPE) {
02313    case PARSE_INT32:
02314        {
02315       int32_t *result = p_result;
02316       int32_t x, def = result ? *result : 0,
02317          high = (int32_t)0x7fffffff,
02318          low  = (int32_t)0x80000000;
02319       /* optional argument: first default value, then range */
02320       if (flags & PARSE_DEFAULT)
02321          def = va_arg(ap, int32_t);
02322       if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
02323          /* range requested, update bounds */
02324          low = va_arg(ap, int32_t);
02325          high = va_arg(ap, int32_t);
02326       }
02327       x = strtol(arg, NULL, 0);
02328       error = (x < low) || (x > high);
02329       if (flags & PARSE_OUT_RANGE)
02330          error = !error;
02331       if (result)
02332          *result  = error ? def : x;
02333       ast_debug(3,
02334          "extract int from [%s] in [%d, %d] gives [%d](%d)\n",
02335          arg, low, high,
02336          result ? *result : x, error);
02337       break;
02338        }
02339 
02340    case PARSE_UINT32:
02341        {
02342       uint32_t *result = p_result;
02343       uint32_t x, def = result ? *result : 0,
02344          low = 0, high = (uint32_t)~0;
02345       /* optional argument: first default value, then range */
02346       if (flags & PARSE_DEFAULT)
02347          def = va_arg(ap, uint32_t);
02348       if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
02349          /* range requested, update bounds */
02350          low = va_arg(ap, uint32_t);
02351          high = va_arg(ap, uint32_t);
02352       }
02353       x = strtoul(arg, NULL, 0);
02354       error = (x < low) || (x > high);
02355       if (flags & PARSE_OUT_RANGE)
02356          error = !error;
02357       if (result)
02358          *result  = error ? def : x;
02359       ast_debug(3,
02360          "extract uint from [%s] in [%u, %u] gives [%u](%d)\n",
02361          arg, low, high,
02362          result ? *result : x, error);
02363       break;
02364        }
02365 
02366    case PARSE_DOUBLE:
02367        {
02368       double *result = p_result;
02369       double x, def = result ? *result : 0,
02370          low = -HUGE_VAL, high = HUGE_VAL;
02371 
02372       /* optional argument: first default value, then range */
02373       if (flags & PARSE_DEFAULT)
02374          def = va_arg(ap, double);
02375       if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
02376          /* range requested, update bounds */
02377          low = va_arg(ap, double);
02378          high = va_arg(ap, double);
02379       }
02380       x = strtod(arg, NULL);
02381       error = (x < low) || (x > high);
02382       if (flags & PARSE_OUT_RANGE)
02383          error = !error;
02384       if (result)
02385          *result  = error ? def : x;
02386       ast_debug(3,
02387          "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
02388          arg, low, high,
02389          result ? *result : x, error);
02390       break;
02391        }
02392    case PARSE_INADDR:
02393        {
02394       char *port, *buf;
02395       struct sockaddr_in _sa_buf;   /* buffer for the result */
02396       struct sockaddr_in *sa = p_result ?
02397          (struct sockaddr_in *)p_result : &_sa_buf;
02398       /* default is either the supplied value or the result itself */
02399       struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
02400          va_arg(ap, struct sockaddr_in *) : sa;
02401       struct hostent *hp;
02402       struct ast_hostent ahp;
02403 
02404       memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
02405       /* duplicate the string to strip away the :port */
02406       port = ast_strdupa(arg);
02407       buf = strsep(&port, ":");
02408       sa->sin_family = AF_INET;  /* assign family */
02409       /*
02410        * honor the ports flag setting, assign default value
02411        * in case of errors or field unset.
02412        */
02413       flags &= PARSE_PORT_MASK; /* the only flags left to process */
02414       if (port) {
02415          if (flags == PARSE_PORT_FORBID) {
02416             error = 1;  /* port was forbidden */
02417             sa->sin_port = def->sin_port;
02418          } else if (flags == PARSE_PORT_IGNORE)
02419             sa->sin_port = def->sin_port;
02420          else /* accept or require */
02421             sa->sin_port = htons(strtol(port, NULL, 0));
02422       } else {
02423          sa->sin_port = def->sin_port;
02424          if (flags == PARSE_PORT_REQUIRE)
02425             error = 1;
02426       }
02427       /* Now deal with host part, even if we have errors before. */
02428       hp = ast_gethostbyname(buf, &ahp);
02429       if (hp)  /* resolved successfully */
02430          memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
02431       else {
02432          error = 1;
02433          sa->sin_addr = def->sin_addr;
02434       }
02435       ast_debug(3,
02436          "extract inaddr from [%s] gives [%s:%d](%d)\n",
02437          arg, ast_inet_ntoa(sa->sin_addr),
02438          ntohs(sa->sin_port), error);
02439          break;
02440        }
02441    }
02442    va_end(ap);
02443    return error;
02444 }

int ast_realtime_enabled ( void   ) 

Check if there's any realtime engines loaded.

Definition at line 2180 of file config.c.

References config_maps.

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

02181 {
02182    return config_maps ? 1 : 0;
02183 }

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

Inform realtime what fields that may be stored.

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 that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Since:
1.6.1

Definition at line 2185 of file config.c.

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

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

02186 {
02187    struct ast_config_engine *eng;
02188    char db[256];
02189    char table[256];
02190    va_list ap;
02191    int res = -1;
02192 
02193    va_start(ap, family);
02194    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02195    if (eng && eng->require_func) {
02196       res = eng->require_func(db, table, ap);
02197    }
02198    va_end(ap);
02199 
02200    return res;
02201 }

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. 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.
Note that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

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

02269 {
02270    struct ast_config_engine *eng;
02271    int res = -1;
02272    char db[256];
02273    char table[256];
02274    va_list ap;
02275 
02276    va_start(ap, family);
02277    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02278    if (eng && eng->store_func) 
02279       res = eng->store_func(db, table, ap);
02280    va_end(ap);
02281 
02282    return res;
02283 }

int ast_unload_realtime ( const char *  family  ) 

Release any resources cached for a realtime family.

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
Since:
1.6.1

Definition at line 2203 of file config.c.

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

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

02204 {
02205    struct ast_config_engine *eng;
02206    char db[256];
02207    char table[256];
02208    int res = -1;
02209 
02210    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02211    if (eng && eng->unload_func) {
02212       res = eng->unload_func(db, table);
02213    }
02214    return res;
02215 }

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 that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 2251 of file config.c.

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

Referenced by change_password_realtime(), and cli_realtime_update2().

02252 {
02253    struct ast_config_engine *eng;
02254    int res = -1;
02255    char db[256];
02256    char table[256];
02257    va_list ap;
02258 
02259    va_start(ap, family);
02260    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02261    if (eng && eng->update2_func) 
02262       res = eng->update2_func(db, table, ap);
02263    va_end(ap);
02264 
02265    return res;
02266 }

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 that you should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

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

02235 {
02236    struct ast_config_engine *eng;
02237    int res = -1;
02238    char db[256];
02239    char table[256];
02240    va_list ap;
02241 
02242    va_start(ap, lookup);
02243    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
02244    if (eng && eng->update_func) 
02245       res = eng->update_func(db, table, keyfield, lookup, ap);
02246    va_end(ap);
02247 
02248    return res;
02249 }

void ast_variable_append ( struct ast_category category,
struct ast_variable variable 
)

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

00349 {
00350    if (!variable)
00351       return;
00352    if (category->last)
00353       category->last->next = variable;
00354    else
00355       category->root = variable;
00356    category->last = variable;
00357    while (category->last->next)
00358       category->last = category->last->next;
00359 }

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 396 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(), action_getconfig(), action_getconfigjson(), adsi_load(), aji_load_config(), ast_cli_perms_init(), ast_readconfig(), ast_variable_retrieve(), build_calendar(), build_device(), build_event_channel(), caldav_load_calendar(), check_tx_freq(), collect_function_digits(), conf_exec(), config_load(), config_module(), do_say(), do_scheduler(), 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_rpt_vars(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_create_provider(), parse_config(), parse_tone_zone(), pbx_load_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_single_queue(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().

00397 {
00398    struct ast_category *cat = NULL;
00399 
00400    if (category && config->last_browse && (config->last_browse->name == category)) {
00401       cat = config->last_browse;
00402    } else {
00403       cat = ast_category_get(config, category);
00404    }
00405 
00406    return (cat) ? cat->root : NULL;
00407 }

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

Definition at line 686 of file config.c.

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

Referenced by handle_updates().

00687 {
00688    struct ast_variable *cur, *prev=NULL, *curn;
00689    int res = -1;
00690    int lineno = 0;
00691 
00692    cur = category->root;
00693    while (cur) {
00694       if (cur->name == variable) {
00695          if (prev) {
00696             prev->next = cur->next;
00697             if (cur == category->last)
00698                category->last = prev;
00699          } else {
00700             category->root = cur->next;
00701             if (cur == category->last)
00702                category->last = NULL;
00703          }
00704          cur->next = NULL;
00705          ast_variables_destroy(cur);
00706          return 0;
00707       }
00708       prev = cur;
00709       cur = cur->next;
00710    }
00711 
00712    prev = NULL;
00713    cur = category->root;
00714    while (cur) {
00715       curn = cur->next;
00716       if ((!ast_strlen_zero(line) && lineno == atoi(line)) || (ast_strlen_zero(line) && !strcasecmp(cur->name, variable) && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
00717          if (prev) {
00718             prev->next = cur->next;
00719             if (cur == category->last)
00720                category->last = prev;
00721          } else {
00722             category->root = cur->next;
00723             if (cur == category->last)
00724                category->last = NULL;
00725          }
00726          cur->next = NULL;
00727          ast_variables_destroy(cur);
00728          res = 0;
00729       } else
00730          prev = cur;
00731 
00732       cur = curn;
00733       lineno++;
00734    }
00735    return res;
00736 }

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

Definition at line 361 of file config.c.

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

Referenced by handle_updates().

00362 {
00363    struct ast_variable *cur = category->root;
00364    int lineno;
00365    int insertline;
00366 
00367    if (!variable || sscanf(line, "%30d", &insertline) != 1) {
00368       return;
00369    }
00370    if (!insertline) {
00371       variable->next = category->root;
00372       category->root = variable;
00373    } else {
00374       for (lineno = 1; lineno < insertline; lineno++) {
00375          cur = cur->next;
00376          if (!cur->next) {
00377             break;
00378          }
00379       }
00380       variable->next = cur->next;
00381       cur->next = variable;
00382    }
00383 }

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

Definition at line 223 of file config.c.

References __ast_calloc(), ast_calloc, ast_variable::file, 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_variable_update(), astman_get_variables(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), 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().

00225 {
00226    struct ast_variable *variable;
00227    int name_len = strlen(name) + 1; 
00228    int val_len = strlen(value) + 1; 
00229    int fn_len = strlen(filename) + 1;  
00230 
00231 #ifdef MALLOC_DEBUG
00232    if ((variable = __ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable), file, lineno, func))) {
00233 #else
00234    if ((variable = ast_calloc(1, name_len + val_len + fn_len + sizeof(*variable)))) {
00235 #endif
00236       char *dst = variable->stuff;  /* writable space starts here */
00237       variable->name = strcpy(dst, name);
00238       dst += name_len;
00239       variable->value = strcpy(dst, value);
00240       dst += val_len;
00241       variable->file = strcpy(dst, filename);
00242    }
00243    return variable;
00244 }

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 420 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(), _dsp_init(), advanced_options(), aji_load_config(), ast_config_option(), build_extension(), config_function_read(), config_module(), directory_exec(), do_reload(), do_scheduler(), festival_exec(), find_queue_by_name_rt(), find_realtime(), function_macro(), get_insecure_variable_from_config(), get_wait_interval(), gtalk_load_config(), iax_template_parse(), init_acf_query(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), load_rpt_vars(), load_tech_calendars(), make_email_file(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queue_set_global_params(), read_agent_config(), read_password_from_file(), realtime_directory(), reload_config(), reload_followme(), reload_single_queue(), retreive_memory(), retrieve_astcfgint(), rpt(), rpt_master(), rpt_tele_thread(), rpt_telemetry(), rtp_reload(), saynode(), search_directory(), search_directory_sub(), set_config(), setup_dahdi(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), telem_lookup(), update_realtime_members(), vm_change_password(), and vm_forwardoptions().

00421 {
00422    struct ast_variable *v;
00423 
00424    if (category) {
00425       for (v = ast_variable_browse(config, category); v; v = v->next) {
00426          if (!strcasecmp(variable, v->name)) {
00427             return v->value;
00428          }
00429       }
00430    } else {
00431       struct ast_category *cat;
00432 
00433       for (cat = config->root; cat; cat = cat->next) {
00434          for (v = cat->root; v; v = v->next) {
00435             if (!strcasecmp(variable, v->name)) {
00436                return v->value;
00437             }
00438          }
00439       }
00440    }
00441 
00442    return NULL;
00443 }

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

References ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), ast_variable::blanklines, ast_variable::file, ast_category::last, ast_variable::lineno, ast_variable::name, ast_variable::next, ast_variable::object, ast_variable::precomments, ast_category::root, ast_variable::sameline, ast_variable::trailing, and ast_variable::value.

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

00740 {
00741    struct ast_variable *cur, *prev=NULL, *newer=NULL;
00742 
00743    for (cur = category->root; cur; prev = cur, cur = cur->next) {
00744       if (strcasecmp(cur->name, variable) ||
00745          (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
00746          continue;
00747 
00748       if (!(newer = ast_variable_new(variable, value, cur->file)))
00749          return -1;
00750    
00751       newer->next = cur->next;
00752       newer->object = cur->object || object;
00753 
00754       /* Preserve everything */
00755       newer->lineno = cur->lineno;
00756       newer->blanklines = cur->blanklines;
00757       newer->precomments = cur->precomments; cur->precomments = NULL;
00758       newer->sameline = cur->sameline; cur->sameline = NULL;
00759       newer->trailing = cur->trailing; cur->trailing = NULL;
00760 
00761       if (prev)
00762          prev->next = newer;
00763       else
00764          category->root = newer;
00765       if (category->last == cur)
00766          category->last = newer;
00767 
00768       cur->next = NULL;
00769       ast_variables_destroy(cur);
00770 
00771       return 0;
00772    }
00773 
00774    /* Could not find variable to update */
00775    return -1;
00776 }

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

References ast_free, and ast_variable::next.

Referenced by __sip_destroy(), 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_variable_delete(), ast_variable_update(), auth_http_callback(), build_gateway(), build_peer(), build_user(), cli_realtime_load(), conf_run(), copy_plain_file(), destroy_dahdi_pvt(), destroy_endpoint(), find_conf_realtime(), find_realtime(), find_user_realtime(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), generic_http_callback(), handle_uri(), http_post_callback(), httpd_helper_thread(), httpstatus_callback(), ldap_loadentry(), leave_queue(), load_realtime_queue(), local_ast_moh_start(), manager_sipnotify(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_exec(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_user(), realtimefield_read(), rt_extend_conf(), sip_destroy_peer(), socket_process(), table_configs_free(), and user_destructor().

00386 {
00387    struct ast_variable *vn;
00388 
00389    while (v) {
00390       vn = v;
00391       v = v->next;
00392       ast_free(vn);
00393    }
00394 }

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

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

00480 {
00481    struct ast_category *cat;
00482 
00483    /* try exact match first, then case-insensitive match */
00484    for (cat = config->root; cat; cat = cat->next) {
00485       if (cat->name == category_name && (ignored || !cat->ignored))
00486          return cat;
00487    }
00488 
00489    for (cat = config->root; cat; cat = cat->next) {
00490       if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
00491          return cat;
00492    }
00493 
00494    return NULL;
00495 }

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

Definition at line 95 of file config.c.

References ast_str_append().

Referenced by config_text_file_load().

00096 {
00097    ast_str_append(cb, 0, "%s", str);
00098 }

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

Definition at line 100 of file config.c.

References ast_copy_string(), ast_str_append(), and s.

Referenced by config_text_file_load().

00101 {
00102    char *s = alloca(len + 1);
00103    ast_copy_string(s, str, len);
00104    ast_str_append(cb, 0, "%s", str);
00105 }

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

Definition at line 107 of file config.c.

References ast_str_reset().

Referenced by config_text_file_load(), and process_text_line().

00108 { 
00109    if (cb) {
00110       ast_str_reset(cb);
00111    }
00112    if (llb) {
00113       ast_str_reset(llb);
00114    }
00115 }

static void clear_config_maps ( void   )  [static]

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

01855 {
01856    struct ast_config_map *map;
01857 
01858    ast_mutex_lock(&config_lock);
01859 
01860    while (config_maps) {
01861       map = config_maps;
01862       config_maps = config_maps->next;
01863       ast_free(map);
01864    }
01865       
01866    ast_mutex_unlock(&config_lock);
01867 }

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

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

Referenced by process_text_line().

00874 {
00875    struct cache_file_mtime *cfmtime;
00876    struct cache_file_include *cfinclude;
00877    struct stat statbuf = { 0, };
00878 
00879    /* Find our cached entry for this configuration file */
00880    AST_LIST_LOCK(&cfmtime_head);
00881    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
00882       if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
00883          break;
00884    }
00885    if (!cfmtime) {
00886       cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(configfile) + 1 + strlen(who_asked) + 1);
00887       if (!cfmtime) {
00888          AST_LIST_UNLOCK(&cfmtime_head);
00889          return;
00890       }
00891       AST_LIST_HEAD_INIT(&cfmtime->includes);
00892       strcpy(cfmtime->filename, configfile);
00893       cfmtime->who_asked = cfmtime->filename + strlen(configfile) + 1;
00894       strcpy(cfmtime->who_asked, who_asked);
00895       /* Note that the file mtime is initialized to 0, i.e. 1970 */
00896       AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
00897    }
00898 
00899    if (!stat(configfile, &statbuf))
00900       cfmtime->mtime = 0;
00901    else
00902       cfmtime->mtime = statbuf.st_mtime;
00903 
00904    switch (attrtype) {
00905    case ATTRIBUTE_INCLUDE:
00906       AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
00907          if (!strcmp(cfinclude->include, filename)) {
00908             AST_LIST_UNLOCK(&cfmtime_head);
00909             return;
00910          }
00911       }
00912       cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
00913       if (!cfinclude) {
00914          AST_LIST_UNLOCK(&cfmtime_head);
00915          return;
00916       }
00917       strcpy(cfinclude->include, filename);
00918       AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
00919       break;
00920    case ATTRIBUTE_EXEC:
00921       cfmtime->has_exec = 1;
00922       break;
00923    }
00924    AST_LIST_UNLOCK(&cfmtime_head);
00925 }

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

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

01189 {
01190    char fn[256];
01191 #if defined(LOW_MEMORY)
01192    char buf[512];
01193 #else
01194    char buf[8192];
01195 #endif
01196    char *new_buf, *comment_p, *process_buf;
01197    FILE *f;
01198    int lineno=0;
01199    int comment = 0, nest[MAX_NESTED_COMMENTS];
01200    struct ast_category *cat = NULL;
01201    int count = 0;
01202    struct stat statbuf;
01203    struct cache_file_mtime *cfmtime = NULL;
01204    struct cache_file_include *cfinclude;
01205    struct ast_variable *last_var = 0;
01206    struct ast_category *last_cat = 0;
01207    /*! Growable string buffer */
01208    struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/
01209    struct ast_str *lline_buffer = NULL;   /*!< A buffer for stuff behind the ; */
01210 
01211    if (cfg)
01212       cat = ast_config_get_current_category(cfg);
01213 
01214    if (filename[0] == '/') {
01215       ast_copy_string(fn, filename, sizeof(fn));
01216    } else {
01217       snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
01218    }
01219 
01220    if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01221       comment_buffer = ast_str_create(CB_SIZE);
01222       if (comment_buffer)
01223          lline_buffer = ast_str_create(CB_SIZE);
01224       if (!lline_buffer) {
01225          if (comment_buffer)
01226             ast_free(comment_buffer);
01227          ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
01228          return NULL;
01229       }
01230    }
01231 #ifdef AST_INCLUDE_GLOB
01232    {
01233       int glob_ret;
01234       glob_t globbuf;
01235       globbuf.gl_offs = 0; /* initialize it to silence gcc */
01236       glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf);
01237       if (glob_ret == GLOB_NOSPACE)
01238          ast_log(LOG_WARNING,
01239             "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
01240       else if (glob_ret  == GLOB_ABORTED)
01241          ast_log(LOG_WARNING,
01242             "Glob Expansion of pattern '%s' failed: Read error\n", fn);
01243       else  {
01244          /* loop over expanded files */
01245          int i;
01246          for (i=0; i<globbuf.gl_pathc; i++) {
01247             ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
01248 #endif
01249    /*
01250     * The following is not a loop, but just a convenient way to define a block
01251     * (using do { } while(0) ), and be able to exit from it with 'continue'
01252     * or 'break' in case of errors. Nice trick.
01253     */
01254    do {
01255       if (stat(fn, &statbuf))
01256          continue;
01257 
01258       if (!S_ISREG(statbuf.st_mode)) {
01259          ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
01260          continue;
01261       }
01262 
01263       if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
01264          /* Find our cached entry for this configuration file */
01265          AST_LIST_LOCK(&cfmtime_head);
01266          AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
01267             if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked))
01268                break;
01269          }
01270          if (!cfmtime) {
01271             cfmtime = ast_calloc(1, sizeof(*cfmtime) + strlen(fn) + 1 + strlen(who_asked) + 1);
01272             if (!cfmtime)
01273                continue;
01274             AST_LIST_HEAD_INIT(&cfmtime->includes);
01275             strcpy(cfmtime->filename, fn);
01276             cfmtime->who_asked = cfmtime->filename + strlen(fn) + 1;
01277             strcpy(cfmtime->who_asked, who_asked);
01278             /* Note that the file mtime is initialized to 0, i.e. 1970 */
01279             AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
01280          }
01281       }
01282 
01283       if (cfmtime && (!cfmtime->has_exec) && (cfmtime->mtime == statbuf.st_mtime) && ast_test_flag(&flags, CONFIG_FLAG_FILEUNCHANGED)) {
01284          /* File is unchanged, what about the (cached) includes (if any)? */
01285          int unchanged = 1;
01286          AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
01287             /* We must glob here, because if we did not, then adding a file to globbed directory would
01288              * incorrectly cause no reload to be necessary. */
01289             char fn2[256];
01290 #ifdef AST_INCLUDE_GLOB
01291             int glob_return;
01292             glob_t glob_buf = { .gl_offs = 0 };
01293             glob_return = glob(cfinclude->include, MY_GLOB_FLAGS, NULL, &glob_buf);
01294             /* On error, we reparse */
01295             if (glob_return == GLOB_NOSPACE || glob_return  == GLOB_ABORTED)
01296                unchanged = 0;
01297             else  {
01298                /* loop over expanded files */
01299                int j;
01300                for (j = 0; j < glob_buf.gl_pathc; j++) {
01301                   ast_copy_string(fn2, glob_buf.gl_pathv[j], sizeof(fn2));
01302 #else
01303                   ast_copy_string(fn2, cfinclude->include);
01304 #endif
01305                   if (config_text_file_load(NULL, NULL, fn2, NULL, flags, "", who_asked) == NULL) {
01306                      /* that second-to-last field needs to be looked at in this case... TODO */
01307                      unchanged = 0;
01308                      /* One change is enough to short-circuit and reload the whole shebang */
01309                      break;
01310                   }
01311 #ifdef AST_INCLUDE_GLOB
01312                }
01313             }
01314 #endif
01315          }
01316 
01317          if (unchanged) {
01318             AST_LIST_UNLOCK(&cfmtime_head);
01319             return CONFIG_STATUS_FILEUNCHANGED;
01320          }
01321       }
01322       if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01323          AST_LIST_UNLOCK(&cfmtime_head);
01324 
01325       /* If cfg is NULL, then we just want an answer */
01326       if (cfg == NULL)
01327          return NULL;
01328 
01329       if (cfmtime)
01330          cfmtime->mtime = statbuf.st_mtime;
01331 
01332       ast_verb(2, "Parsing '%s': ", fn);
01333          fflush(stdout);
01334       if (!(f = fopen(fn, "r"))) {
01335          ast_debug(1, "No file to parse: %s\n", fn);
01336          ast_verb(2, "Not found (%s)\n", strerror(errno));
01337          continue;
01338       }
01339       count++;
01340       /* If we get to this point, then we're loading regardless */
01341       ast_clear_flag(&flags, CONFIG_FLAG_FILEUNCHANGED);
01342       ast_debug(1, "Parsing %s\n", fn);
01343       ast_verb(2, "Found\n");
01344       while (!feof(f)) {
01345          lineno++;
01346          if (fgets(buf, sizeof(buf), f)) {
01347             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && lline_buffer && ast_str_strlen(lline_buffer)) {
01348                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01349                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01350             }
01351             
01352             new_buf = buf;
01353             if (comment) 
01354                process_buf = NULL;
01355             else
01356                process_buf = buf;
01357             
01358             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"))) {
01359                /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */
01360                CB_ADD(&comment_buffer, "\n");       /* add a newline to the comment buffer */
01361                continue; /* go get a new line, then */
01362             }
01363             
01364             while ((comment_p = strchr(new_buf, COMMENT_META))) {
01365                if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) {
01366                   /* Escaped semicolons aren't comments. */
01367                   new_buf = comment_p + 1;
01368                } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
01369                   /* Meta-Comment start detected ";--" */
01370                   if (comment < MAX_NESTED_COMMENTS) {
01371                      *comment_p = '\0';
01372                      new_buf = comment_p + 3;
01373                      comment++;
01374                      nest[comment-1] = lineno;
01375                   } else {
01376                      ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
01377                   }
01378                } else if ((comment_p >= new_buf + 2) &&
01379                      (*(comment_p - 1) == COMMENT_TAG) &&
01380                      (*(comment_p - 2) == COMMENT_TAG)) {
01381                   /* Meta-Comment end detected */
01382                   comment--;
01383                   new_buf = comment_p + 1;
01384                   if (!comment) {
01385                      /* Back to non-comment now */
01386                      if (process_buf) {
01387                         /* Actually have to move what's left over the top, then continue */
01388                         char *oldptr;
01389                         oldptr = process_buf + strlen(process_buf);
01390                         if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01391                            CB_ADD(&comment_buffer, ";");
01392                            CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
01393                         }
01394                         
01395                         memmove(oldptr, new_buf, strlen(new_buf) + 1);
01396                         new_buf = oldptr;
01397                      } else
01398                         process_buf = new_buf;
01399                   }
01400                } else {
01401                   if (!comment) {
01402                      /* If ; is found, and we are not nested in a comment, 
01403                         we immediately stop all comment processing */
01404                      if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01405                         CB_ADD(&lline_buffer, comment_p);
01406                      }
01407                      *comment_p = '\0'; 
01408                      new_buf = comment_p;
01409                   } else
01410                      new_buf = comment_p + 1;
01411                }
01412             }
01413             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) {
01414                CB_ADD(&comment_buffer, buf);  /* the whole line is a comment, store it */
01415             }
01416             
01417             if (process_buf) {
01418                char *buffer = ast_strip(process_buf);
01419                if (!ast_strlen_zero(buffer)) {
01420                   if (process_text_line(cfg, &cat, buffer, lineno, fn, flags, comment_buffer, lline_buffer, suggested_include_file, &last_cat, &last_var, who_asked)) {
01421                      cfg = CONFIG_STATUS_FILEINVALID;
01422                      break;
01423                   }
01424                }
01425             }
01426          }
01427       }
01428       /* end of file-- anything in a comment buffer? */
01429       if (last_cat) {
01430          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01431             if (lline_buffer && ast_str_strlen(lline_buffer)) {
01432                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01433                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01434             }
01435             last_cat->trailing = ALLOC_COMMENT(comment_buffer);
01436          }
01437       } else if (last_var) {
01438          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01439             if (lline_buffer && ast_str_strlen(lline_buffer)) {
01440                CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer));       /* add the current lline buffer to the comment buffer */
01441                ast_str_reset(lline_buffer);        /* erase the lline buffer */
01442             }
01443             last_var->trailing = ALLOC_COMMENT(comment_buffer);
01444          }
01445       } else {
01446          if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
01447             ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer));
01448          }
01449       }
01450       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01451          CB_RESET(comment_buffer, lline_buffer);
01452 
01453       fclose(f);
01454    } while (0);
01455    if (comment) {
01456       ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
01457    }
01458 #ifdef AST_INCLUDE_GLOB
01459                if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
01460                   break;
01461                }
01462             }
01463             globfree(&globbuf);
01464          }
01465       }
01466 #endif
01467 
01468    if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
01469       if (comment_buffer)
01470          ast_free(comment_buffer);
01471       if (lline_buffer)
01472          ast_free(lline_buffer);
01473       comment_buffer = NULL;
01474       lline_buffer = NULL;
01475    }
01476    
01477    if (count == 0)
01478       return NULL;
01479 
01480    return cfg;
01481 }

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

Definition at line 1609 of file config.c.

References ast_config_text_file_save().

01610 {
01611    return ast_config_text_file_save(configfile, cfg, generator);
01612 }

static int count_linefeeds ( char *  str  )  [static]

Definition at line 1557 of file config.c.

Referenced by count_linefeeds_in_comments().

01558 {
01559    int count = 0;
01560 
01561    while (*str) {
01562       if (*str =='\n')
01563          count++;
01564       str++;
01565    }
01566    return count;
01567 }

static int count_linefeeds_in_comments ( struct ast_comment x  )  [static]

Definition at line 1569 of file config.c.

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

Referenced by insert_leading_blank_lines().

01570 {
01571    int count = 0;
01572 
01573    while (x) {
01574       count += count_linefeeds(x->cmt);
01575       x = x->next;
01576    }
01577    return count;
01578 }

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

Find realtime engine for realtime family.

Definition at line 2015 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, 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_speech_new(), ast_speech_register(), ast_store_realtime(), ast_unload_realtime(), ast_update2_realtime(), and ast_update_realtime().

02016 {
02017    struct ast_config_engine *eng, *ret = NULL;
02018    struct ast_config_map *map;
02019 
02020    ast_mutex_lock(&config_lock);
02021 
02022    for (map = config_maps; map; map = map->next) {
02023       if (!strcasecmp(family, map->name)) {
02024          if (database)
02025             ast_copy_string(database, map->database, dbsiz);
02026          if (table)
02027             ast_copy_string(table, map->table ? map->table : family, tabsiz);
02028          break;
02029       }
02030    }
02031 
02032    /* Check if the required driver (engine) exist */
02033    if (map) {
02034       for (eng = config_engine_list; !ret && eng; eng = eng->next) {
02035          if (!strcasecmp(eng->name, map->driver))
02036             ret = eng;
02037       }
02038    }
02039 
02040    ast_mutex_unlock(&config_lock);
02041    
02042    /* if we found a mapping, but the engine is not available, then issue a warning */
02043    if (map && !ret)
02044       ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
02045 
02046    return ret;
02047 }

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

Definition at line 1504 of file config.c.

References ast_copy_string().

Referenced by ast_config_text_file_save().

01505 {
01506    char date[256]="";
01507    time_t t;
01508 
01509    time(&t);
01510    ast_copy_string(date, ctime(&t), sizeof(date));
01511 
01512    fprintf(f1, ";!\n");
01513    fprintf(f1, ";! Automatically generated configuration file\n");
01514    if (strcmp(configfile, fn))
01515       fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
01516    else
01517       fprintf(f1, ";! Filename: %s\n", configfile);
01518    fprintf(f1, ";! Generator: %s\n", generator);
01519    fprintf(f1, ";! Creation Date: %s", date);
01520    fprintf(f1, ";!\n");
01521 }

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

Definition at line 2547 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.

02548 {
02549    struct cache_file_mtime *cfmtime;
02550 
02551    switch (cmd) {
02552    case CLI_INIT:
02553       e->command = "config list";
02554       e->usage =
02555          "Usage: config list\n"
02556          "   Show all modules that have loaded a configuration file\n";
02557       return NULL;
02558    case CLI_GENERATE:
02559       return NULL;
02560    }
02561 
02562    AST_LIST_LOCK(&cfmtime_head);
02563    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
02564       ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
02565    }
02566    AST_LIST_UNLOCK(&cfmtime_head);
02567 
02568    return CLI_SUCCESS;
02569 }

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

Definition at line 2485 of file config.c.

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

02486 {
02487    struct cache_file_mtime *cfmtime;
02488    char *prev = "", *completion_value = NULL;
02489    int wordlen, which = 0;
02490 
02491    switch (cmd) {
02492    case CLI_INIT:
02493       e->command = "config reload";
02494       e->usage =
02495          "Usage: config reload <filename.conf>\n"
02496          "   Reloads all modules that reference <filename.conf>\n";
02497       return NULL;
02498    case CLI_GENERATE:
02499       if (a->pos > 2) {
02500          return NULL;
02501       }
02502 
02503       wordlen = strlen(a->word);
02504 
02505       AST_LIST_LOCK(&cfmtime_head);
02506       AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
02507          /* Skip duplicates - this only works because the list is sorted by filename */
02508          if (strcmp(cfmtime->filename, prev) == 0) {
02509             continue;
02510          }
02511 
02512          /* Core configs cannot be reloaded */
02513          if (ast_strlen_zero(cfmtime->who_asked)) {
02514             continue;
02515          }
02516 
02517          if (++which > a->n && strncmp(cfmtime->filename, a->word, wordlen) == 0) {
02518             completion_value = ast_strdup(cfmtime->filename);
02519             break;
02520          }
02521 
02522          /* Otherwise save that we've seen this filename */
02523          prev = cfmtime->filename;
02524       }
02525       AST_LIST_UNLOCK(&cfmtime_head);
02526 
02527       return completion_value;
02528    }
02529 
02530    if (a->argc != 3) {
02531       return CLI_SHOWUSAGE;
02532    }
02533 
02534    AST_LIST_LOCK(&cfmtime_head);
02535    AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
02536       if (!strcmp(cfmtime->filename, a->argv[2])) {
02537          char *buf = alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
02538          sprintf(buf, "module reload %s", cfmtime->who_asked);
02539          ast_cli_command(a->fd, buf);
02540       }
02541    }
02542    AST_LIST_UNLOCK(&cfmtime_head);
02543 
02544    return CLI_SUCCESS;
02545 }

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

Definition at line 2446 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.

02447 {
02448    struct ast_config_engine *eng;
02449    struct ast_config_map *map;
02450 
02451    switch (cmd) {
02452    case CLI_INIT:
02453       e->command = "core show config mappings";
02454       e->usage =
02455          "Usage: core show config mappings\n"
02456          "  Shows the filenames to config engines.\n";
02457       return NULL;
02458    case CLI_GENERATE:
02459       return NULL;
02460    }
02461    
02462    ast_mutex_lock(&config_lock);
02463 
02464    if (!config_engine_list) {
02465       ast_cli(a->fd, "No config mappings found.\n");
02466    } else {
02467       ast_cli(a->fd, "\n\n");
02468       for (eng = config_engine_list; eng; eng = eng->next) {
02469          ast_cli(a->fd, "\nConfig Engine: %s\n", eng->name);
02470          for (map = config_maps; map; map = map->next) {
02471             if (!strcasecmp(map->driver, eng->name)) {
02472                ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
02473                      map->table ? map->table : map->name);
02474             }
02475          }
02476       }
02477       ast_cli(a->fd,"\n\n");
02478    }
02479    
02480    ast_mutex_unlock(&config_lock);
02481 
02482    return CLI_SUCCESS;
02483 }

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

Definition at line 137 of file config.c.

References str, and total.

Referenced by ast_config_text_file_save().

00138 {
00139    char *str = ((struct inclfile *) obj)->fname;
00140    int total;
00141 
00142    for (total = 0; *str; str++) {
00143       unsigned int tmp = total;
00144       total <<= 1; /* multiply by 2 */
00145       total += tmp; /* multiply by 3 */
00146       total <<= 2; /* multiply by 12 */
00147       total += tmp; /* multiply by 13 */
00148 
00149       total += ((unsigned int) (*str));
00150    }
00151    if (total < 0) {
00152       total = -total;
00153    }
00154    return total;
00155 }

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

Definition at line 157 of file config.c.

References CMP_MATCH, CMP_STOP, and inclfile::fname.

Referenced by ast_config_text_file_save().

00158 {
00159    const struct inclfile *ae = a, *be = b;
00160    return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0;
00161 }

static void inclfile_destroy ( void *  obj  )  [static]

Definition at line 1523 of file config.c.

References inclfile::fname, and free.

Referenced by set_fn().

01524 {
01525    const struct inclfile *o = obj;
01526 
01527    if (o->fname)
01528       free(o->fname);
01529 }

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

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

00666 {
00667    struct ast_variable *var;
00668    struct ast_category_template_instance *x = ast_calloc(1,sizeof(struct ast_category_template_instance));
00669 
00670    strcpy(x->name, base->name);
00671    x->inst = base;
00672    AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
00673    for (var = base->root; var; var = var->next)
00674       ast_variable_append(new, variable_clone(var));
00675 }

static int init_appendbuf ( void *  data  )  [static]

Definition at line 83 of file config.c.

References ast_str_create(), and str.

00084 {
00085    struct ast_str **str = data;
00086    *str = ast_str_create(16);
00087    return *str ? 0 : -1;
00088 }

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

Definition at line 1580 of file config.c.

References count_linefeeds_in_comments(), and inclfile::lineno.

Referenced by ast_config_text_file_save().

01581 {
01582    int precomment_lines = count_linefeeds_in_comments(precomments);
01583    int i;
01584 
01585    /* I don't have to worry about those ;! comments, they are
01586       stored in the precomments, but not printed back out.
01587       I did have to make sure that comments following
01588       the ;! header comments were not also deleted in the process */
01589    if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */
01590       return;
01591    } else if (lineno == 0) {
01592       /* Line replacements also mess things up */
01593       return;
01594    } else if (lineno - precomment_lines - fi->lineno < 5) {
01595       /* Only insert less than 5 blank lines; if anything more occurs,
01596        * it's probably due to context deletion. */
01597       for (i = fi->lineno; i < lineno - precomment_lines; i++) {
01598          fprintf(fp, "\n");
01599       }
01600    } else {
01601       /* Deletion occurred - insert a single blank line, for separation of
01602        * contexts. */
01603       fprintf(fp, "\n");
01604    }
01605  
01606    fi->lineno = lineno + 1; /* Advance the file lineno */
01607 }

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

Definition at line 459 of file config.c.

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

Referenced by process_text_line().

00460 {
00461    struct ast_variable *var = old->root;
00462 
00463    old->root = NULL;
00464    /* we can just move the entire list in a single op */
00465    ast_variable_append(new, var);
00466 }

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

Definition at line 595 of file config.c.

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

Referenced by ast_category_browse().

00596 {
00597    for (; cat && cat->ignored; cat = cat->next);
00598 
00599    return cat;
00600 }

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 934 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, S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), ast_variable::value, and var.

Referenced by config_text_file_load().

00940 {
00941    char *c;
00942    char *cur = buf;
00943    struct ast_variable *v;
00944    char cmd[512], exec_file[512];
00945 
00946    /* Actually parse the entry */
00947    if (cur[0] == '[') { /* A category header */
00948       /* format is one of the following:
00949        * [foo] define a new category named 'foo'
00950        * [foo](!) define a new template category named 'foo'
00951        * [foo](+) append to category 'foo', error if foo does not exist.
00952        * [foo](a) define a new category and inherit from template a.
00953        *    You can put a comma-separated list of templates and '!' and '+'
00954        *    between parentheses, with obvious meaning.
00955        */
00956       struct ast_category *newcat = NULL;
00957       char *catname;
00958 
00959       c = strchr(cur, ']');
00960       if (!c) {
00961          ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
00962          return -1;
00963       }
00964       *c++ = '\0';
00965       cur++;
00966       if (*c++ != '(')
00967          c = NULL;
00968       catname = cur;
00969       if (!(*cat = newcat = ast_category_new(catname,
00970             S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile),
00971             lineno))) {
00972          return -1;
00973       }
00974       (*cat)->lineno = lineno;
00975       *last_var = 0;
00976       *last_cat = newcat;
00977       
00978       /* add comments */
00979       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
00980          newcat->precomments = ALLOC_COMMENT(comment_buffer);
00981       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
00982          newcat->sameline = ALLOC_COMMENT(lline_buffer);
00983       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
00984          CB_RESET(comment_buffer, lline_buffer);
00985       
00986       /* If there are options or categories to inherit from, process them now */
00987       if (c) {
00988          if (!(cur = strchr(c, ')'))) {
00989             ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
00990             return -1;
00991          }
00992          *cur = '\0';
00993          while ((cur = strsep(&c, ","))) {
00994             if (!strcasecmp(cur, "!")) {
00995                (*cat)->ignored = 1;
00996             } else if (!strcasecmp(cur, "+")) {
00997                *cat = category_get(cfg, catname, 1);
00998                if (!(*cat)) {
00999                   if (newcat)
01000                      ast_category_destroy(newcat);
01001                   ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
01002                   return -1;
01003                }
01004                if (newcat) {
01005                   move_variables(newcat, *cat);
01006                   ast_category_destroy(newcat);
01007                   newcat = NULL;
01008                }
01009             } else {
01010                struct ast_category *base;
01011             
01012                base = category_get(cfg, cur, 1);
01013                if (!base) {
01014                   ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
01015                   return -1;
01016                }
01017                inherit_category(*cat, base);
01018             }
01019          }
01020       }
01021       if (newcat)
01022          ast_category_append(cfg, *cat);
01023    } else if (cur[0] == '#') { /* A directive - #include or #exec */
01024       char *cur2;
01025       char real_inclusion_name[256];
01026       struct ast_config_include *inclu;
01027       int do_include = 0;  /* otherwise, it is exec */
01028 
01029       cur++;
01030       c = cur;
01031       while (*c && (*c > 32)) {
01032          c++;
01033       }
01034 
01035       if (*c) {
01036          *c = '\0';
01037          /* Find real argument */
01038          c = ast_skip_blanks(c + 1);
01039          if (!(*c)) {
01040             c = NULL;
01041          }
01042       } else 
01043          c = NULL;
01044       if (!strcasecmp(cur, "include")) {
01045          do_include = 1;
01046       } else if (!strcasecmp(cur, "exec")) {
01047          if (!ast_opt_exec_includes) {
01048             ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
01049             return 0;   /* XXX is this correct ? or we should return -1 ? */
01050          }
01051       } else {
01052          ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
01053          return 0;   /* XXX is this correct ? or we should return -1 ? */
01054       }
01055 
01056       if (c == NULL) {
01057          ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 
01058                do_include ? "include" : "exec",
01059                do_include ? "filename" : "/path/to/executable",
01060                lineno,
01061                configfile);
01062          return 0;   /* XXX is this correct ? or we should return -1 ? */
01063       }
01064 
01065       cur = c;
01066       /* Strip off leading and trailing "'s and <>'s */
01067       if (*c == '"') {
01068          /* Dequote */
01069          while (*c) {
01070             if (*c == '"') {
01071                strcpy(c, c + 1); /* SAFE */
01072                c--;
01073             } else if (*c == '\\') {
01074                strcpy(c, c + 1); /* SAFE */
01075             }
01076             c++;
01077          }
01078       } else if (*c == '<') {
01079          /* C-style include */
01080          if (*(c + strlen(c) - 1) == '>') {
01081             cur++;
01082             *(c + strlen(c) - 1) = '\0';
01083          }
01084       }
01085       cur2 = cur;
01086 
01087       /* #exec </path/to/executable>
01088          We create a tmp file, then we #include it, then we delete it. */
01089       if (!do_include) {
01090          struct timeval now = ast_tvnow();
01091          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01092             config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked);
01093          snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self());
01094          snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
01095          ast_safe_system(cmd);
01096          cur = exec_file;
01097       } else {
01098          if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
01099             config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked);
01100          exec_file[0] = '\0';
01101       }
01102       /* A #include */
01103       /* record this inclusion */
01104       inclu = ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
01105 
01106       do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0;
01107       if (!ast_strlen_zero(exec_file))
01108          unlink(exec_file);
01109       if (!do_include) {
01110          ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur);
01111          return -1;
01112       }
01113       /* XXX otherwise what ? the default return is 0 anyways */
01114 
01115    } else {
01116       /* Just a line (variable = value) */
01117       int object = 0;
01118       if (!(*cat)) {
01119          ast_log(LOG_WARNING,
01120             "parse error: No category context for line %d of %s\n", lineno, configfile);
01121          return -1;
01122       }
01123       c = strchr(cur, '=');
01124 
01125       if (c && c > cur && (*(c - 1) == '+')) {
01126          struct ast_variable *var, *replace = NULL;
01127          struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str));
01128 
01129          if (!str || !*str) {
01130             return -1;
01131          }
01132 
01133          *(c - 1) = '\0';
01134          c++;
01135          cur = ast_strip(cur);
01136 
01137          /* Must iterate through category until we find last variable of same name (since there could be multiple) */
01138          for (var = ast_category_first(*cat); var; var = var->next) {
01139             if (!strcmp(var->name, cur)) {
01140                replace = var;
01141             }
01142          }
01143 
01144          if (!replace) {
01145             /* Nothing to replace; just set a variable normally. */
01146             goto set_new_variable;
01147          }
01148 
01149          ast_str_set(str, 0, "%s", replace->value);
01150          ast_str_append(str, 0, "%s", c);
01151          ast_str_trim_blanks(*str);
01152          ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object);
01153       } else if (c) {
01154          *c = 0;
01155          c++;
01156          /* Ignore > in => */
01157          if (*c== '>') {
01158             object = 1;
01159             c++;
01160          }
01161 set_new_variable:
01162          if ((v = ast_variable_new(ast_strip(cur), ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) {
01163             v->lineno = lineno;
01164             v->object = object;
01165             *last_cat = 0;
01166             *last_var = v;
01167             /* Put and reset comments */
01168             v->blanklines = 0;
01169             ast_variable_append(*cat, v);
01170             /* add comments */
01171             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01172                v->precomments = ALLOC_COMMENT(comment_buffer);
01173             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01174                v->sameline = ALLOC_COMMENT(lline_buffer);
01175             if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS))
01176                CB_RESET(comment_buffer, lline_buffer);
01177             
01178          } else {
01179             return -1;
01180          }
01181       } else {
01182          ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
01183       }
01184    }
01185    return 0;
01186 }

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

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

Referenced by main().

01903 {
01904    struct ast_config *config, *configtmp;
01905    struct ast_variable *v;
01906    char *driver, *table, *database, *stringp, *tmp;
01907    struct ast_flags flags = { 0 };
01908 
01909    clear_config_maps();
01910 
01911    configtmp = ast_config_new();
01912    configtmp->max_include_level = 1;
01913    config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
01914    if (!config) {
01915       ast_config_destroy(configtmp);
01916       return 0;
01917    }
01918 
01919    for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
01920       char buf[512];
01921       ast_copy_string(buf, v->value, sizeof(buf));
01922       stringp = buf;
01923       driver = strsep(&stringp, ",");
01924 
01925       if ((tmp = strchr(stringp, '\"')))
01926          stringp = tmp;
01927 
01928       /* check if the database text starts with a double quote */
01929       if (*stringp == '"') {
01930          stringp++;
01931          database = strsep(&stringp, "\"");
01932          strsep(&stringp, ",");
01933       } else {
01934          /* apparently this text has no quotes */
01935          database = strsep(&stringp, ",");
01936       }
01937 
01938       table = strsep(&stringp, ",");
01939 
01940       if (!strcmp(v->name, extconfig_conf)) {
01941          ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
01942          continue;
01943       }
01944 
01945       if (!strcmp(v->name, "asterisk.conf")) {
01946          ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
01947          continue;
01948       }
01949 
01950       if (!strcmp(v->name, "logger.conf")) {
01951          ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
01952          continue;
01953       }
01954 
01955       if (!driver || !database)
01956          continue;
01957       if (!strcasecmp(v->name, "sipfriends")) {
01958          ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sipusers and sippeers, though they can point to the same table.\n");
01959          append_mapping("sipusers", driver, database, table ? table : "sipfriends");
01960          append_mapping("sippeers", driver, database, table ? table : "sipfriends");
01961       } else if (!strcasecmp(v->name, "iaxfriends")) {
01962          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");
01963          append_mapping("iaxusers", driver, database, table ? table : "iaxfriends");
01964          append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends");
01965       } else 
01966          append_mapping(v->name, driver, database, table);
01967    }
01968       
01969    ast_config_destroy(config);
01970    return 0;
01971 }

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

References ARRAY_LEN, and ast_cli_register_multiple().

Referenced by main().

02578 {
02579    ast_cli_register_multiple(cli_config, ARRAY_LEN(cli_config));
02580    return 0;
02581 }

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

Definition at line 1532 of file config.c.

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

Referenced by ast_config_text_file_save().

01533 {
01534    struct inclfile lookup;
01535    
01536    if (!file || file[0] == 0) {
01537       if (configfile[0] == '/')
01538          ast_copy_string(fn, configfile, fn_size);
01539       else
01540          snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
01541    } else if (file[0] == '/') 
01542       ast_copy_string(fn, file, fn_size);
01543    else
01544       snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
01545    lookup.fname = fn;
01546    *fi = ao2_find(fileset, &lookup, OBJ_POINTER);
01547    if (!(*fi)) {
01548       /* set up a file scratch pad */
01549       struct inclfile *fx = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
01550       fx->fname = ast_strdup(fn);
01551       fx->lineno = 1;
01552       *fi = fx;
01553       ao2_link(fileset, fx);
01554    }
01555 }

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

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

00446 {
00447    struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
00448 
00449    if (new) {
00450       new->lineno = old->lineno;
00451       new->object = old->object;
00452       new->blanklines = old->blanklines;
00453       /* TODO: clone comments? */
00454    }
00455 
00456    return new;
00457 }


Variable Documentation

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

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

Definition at line 173 of file config.c.

ast_mutex_t config_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

struct ast_config_map * config_maps [static]

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

Definition at line 57 of file config.c.

Initial value:

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

Definition at line 2049 of file config.c.


Generated on Wed Oct 28 13:32:28 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6