Mon Apr 30 07:41:44 2007

Asterisk developer's documentation


config.c File Reference

Configuration File Parser. More...

#include "asterisk.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include <glob.h>
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"

Include dependency graph for config.c:

Go to the source code of this file.

Data Structures

struct  ast_category
struct  ast_comment
 Structure to keep comments for rewriting configuration files. More...
struct  ast_config
struct  ast_config_map

Defines

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

Functions

static struct ast_commentALLOC_COMMENT (const char *buffer)
static int append_mapping (char *name, char *driver, char *database, 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, char *category)
void ast_category_destroy (struct ast_category *cat)
ast_variableast_category_detach_variables (struct ast_category *cat)
int ast_category_exist (const struct ast_config *config, const char *category_name)
 Check for category duplicates.
ast_categoryast_category_get (const struct ast_config *config, const char *category_name)
 Retrieve a category if it exists.
ast_categoryast_category_new (const char *name)
void ast_category_rename (struct ast_category *cat, const char *name)
int ast_check_realtime (const char *family)
 Check if realtime engine is configured for family returns 1 if family is configured in realtime and engine exists.
void ast_config_destroy (struct ast_config *cfg)
 Destroys a config.
int ast_config_engine_deregister (struct ast_config_engine *del)
 Deegister config engine.
int ast_config_engine_register (struct ast_config_engine *new)
 Register config engine.
ast_categoryast_config_get_current_category (const struct ast_config *cfg)
ast_configast_config_internal_load (const char *filename, struct ast_config *cfg, int withcomments)
ast_configast_config_load (const char *filename)
 Load a config file.
ast_configast_config_load_with_comments (const char *filename)
ast_configast_config_new (void)
const char * ast_config_option (struct ast_config *cfg, const char *cat, const char *var)
void ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat)
ast_variableast_load_realtime (const char *family,...)
 Retrieve realtime configuration.
ast_configast_load_realtime_multientry (const char *family,...)
 Retrieve realtime configuration.
 AST_MUTEX_DEFINE_STATIC (config_lock)
int ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...)
 Update realtime configuration.
void ast_variable_append (struct ast_category *category, struct ast_variable *variable)
ast_variableast_variable_browse (const struct ast_config *config, const char *category)
 Goes through variables Somewhat similar in intent as the ast_category_browse. List variables of config file category.
int ast_variable_delete (struct ast_category *category, char *variable, char *match)
ast_variableast_variable_new (const char *name, const char *value)
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)
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 (char **comment_buffer, int *comment_buffer_size, char *str)
static void CB_ADD_LEN (char **comment_buffer, int *comment_buffer_size, char *str, int len)
static void CB_INIT (char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size)
static void CB_RESET (char **comment_buffer, char **lline_buffer)
static void clear_config_maps (void)
static int config_command (int fd, int argc, char **argv)
static struct ast_configconfig_text_file_load (const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments)
int config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator)
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 inherit_category (struct ast_category *new, const struct ast_category *base)
static void LLB_ADD (char **lline_buffer, int *lline_buffer_size, char *str)
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, int withcomments, char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size)
int read_config_maps (void)
int register_config_cli ()
static struct ast_variablevariable_clone (const struct ast_variable *old)

Variables

static struct ast_cli_entry cli_config []
static struct ast_cli_entry cli_show_config_mappings_deprecated
static struct ast_config_engineconfig_engine_list
static struct ast_config_mapconfig_maps
static char * extconfig_conf = "extconfig.conf"
static char show_config_help []
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_INCR   250

Definition at line 72 of file config.c.

Referenced by CB_ADD(), CB_ADD_LEN(), CB_INIT(), and LLB_ADD().

#define COMMENT_END   "--;"

Definition at line 59 of file config.c.

#define COMMENT_META   ';'

Definition at line 60 of file config.c.

Referenced by config_text_file_load().

#define COMMENT_START   ";--"

Definition at line 58 of file config.c.

#define COMMENT_TAG   '-'

Definition at line 61 of file config.c.

Referenced by config_text_file_load().

#define MAX_INCLUDE_LEVEL   10

Definition at line 160 of file config.c.

Referenced by ast_config_new().

#define MAX_NESTED_COMMENTS   128

Definition at line 57 of file config.c.

Referenced by config_text_file_load().


Function Documentation

static struct ast_comment* ALLOC_COMMENT ( const char *  buffer  )  [static]

Definition at line 140 of file config.c.

References ast_calloc, and ast_comment::cmt.

Referenced by process_text_line().

00141 { 
00142    struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
00143    strcpy(x->cmt, buffer);
00144    return x;
00145 }

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

Definition at line 1055 of file config.c.

References ast_calloc, ast_verbose(), config_maps, map, option_verbose, and VERBOSE_PREFIX_2.

Referenced by read_config_maps().

01056 {
01057    struct ast_config_map *map;
01058    int length;
01059 
01060    length = sizeof(*map);
01061    length += strlen(name) + 1;
01062    length += strlen(driver) + 1;
01063    length += strlen(database) + 1;
01064    if (table)
01065       length += strlen(table) + 1;
01066 
01067    if (!(map = ast_calloc(1, length)))
01068       return -1;
01069 
01070    map->name = map->stuff;
01071    strcpy(map->name, name);
01072    map->driver = map->name + strlen(map->name) + 1;
01073    strcpy(map->driver, driver);
01074    map->database = map->driver + strlen(map->driver) + 1;
01075    strcpy(map->database, database);
01076    if (table) {
01077       map->table = map->database + strlen(map->database) + 1;
01078       strcpy(map->table, table);
01079    }
01080    map->next = config_maps;
01081 
01082    if (option_verbose > 1)
01083       ast_verbose(VERBOSE_PREFIX_2 "Binding %s to %s/%s/%s\n",
01084              map->name, map->driver, map->database, map->table ? map->table : map->name);
01085 
01086    config_maps = map;
01087    return 0;
01088 }

void ast_category_append ( struct ast_config config,
struct ast_category category 
)

Definition at line 332 of file config.c.

References config, and ast_category::include_level.

Referenced by config_mysql(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_mysql(), realtime_multi_odbc(), and realtime_multi_pgsql().

00333 {
00334    if (config->last)
00335       config->last->next = category;
00336    else
00337       config->root = category;
00338    category->include_level = config->include_level;
00339    config->last = category;
00340    config->current = category;
00341 }

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 funtion is kind of non-intuitive in it's use. To begin, one passes NULL as the second arguement. 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.
Returns a category on success, or NULL on failure/no-more-categories

Definition at line 356 of file config.c.

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

Referenced by action_getconfig(), aji_load_config(), authenticate(), complete_sipnotify(), do_directory(), gtalk_load_config(), iax_provision_reload(), ind_load_module(), init_manager(), load_config(), load_module(), load_moh_classes(), load_odbc_config(), loadconfigurationfile(), misdn_cfg_init(), osp_load(), pbx_load_config(), pbx_load_users(), read_agent_config(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queues(), rpt_master(), set_config(), setup_zap(), sla_load_config(), and vm_change_password().

00357 {  
00358    struct ast_category *cat = NULL;
00359 
00360    if (prev && config->last_browse && (config->last_browse->name == prev))
00361       cat = config->last_browse->next;
00362    else if (!prev && config->root)
00363       cat = config->root;
00364    else if (prev) {
00365       for (cat = config->root; cat; cat = cat->next) {
00366          if (cat->name == prev) {
00367             cat = cat->next;
00368             break;
00369          }
00370       }
00371       if (!cat) {
00372          for (cat = config->root; cat; cat = cat->next) {
00373             if (!strcasecmp(cat->name, prev)) {
00374                cat = cat->next;
00375                break;
00376             }
00377          }
00378       }
00379    }
00380    
00381    if (cat)
00382       cat = next_available_category(cat);
00383 
00384    config->last_browse = cat;
00385    return (cat) ? cat->name : NULL;
00386 }

int ast_category_delete ( struct ast_config cfg,
char *  category 
)

Definition at line 508 of file config.c.

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

Referenced by handle_updates().

00509 {
00510    struct ast_category *prev=NULL, *cat;
00511    cat = cfg->root;
00512    while(cat) {
00513       if (cat->name == category) {
00514          ast_variables_destroy(cat->root);
00515          if (prev) {
00516             prev->next = cat->next;
00517             if (cat == cfg->last)
00518                cfg->last = prev;
00519          } else {
00520             cfg->root = cat->next;
00521             if (cat == cfg->last)
00522                cfg->last = NULL;
00523          }
00524          free(cat);
00525          return 0;
00526       }
00527       prev = cat;
00528       cat = cat->next;
00529    }
00530 
00531    prev = NULL;
00532    cat = cfg->root;
00533    while(cat) {
00534       if (!strcasecmp(cat->name, category)) {
00535          ast_variables_destroy(cat->root);
00536          if (prev) {
00537             prev->next = cat->next;
00538             if (cat == cfg->last)
00539                cfg->last = prev;
00540          } else {
00541             cfg->root = cat->next;
00542             if (cat == cfg->last)
00543                cfg->last = NULL;
00544          }
00545          free(cat);
00546          return 0;
00547       }
00548       prev = cat;
00549       cat = cat->next;
00550    }
00551    return -1;
00552 }

void ast_category_destroy ( struct ast_category cat  ) 

Definition at line 343 of file config.c.

References ast_variables_destroy(), free, and ast_category::root.

Referenced by process_text_line(), and realtime_multi_odbc().

00344 {
00345    ast_variables_destroy(cat->root);
00346    free(cat);
00347 }

struct ast_variable* ast_category_detach_variables ( struct ast_category cat  ) 

Definition at line 388 of file config.c.

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

Referenced by realtime_switch_common().

00389 {
00390    struct ast_variable *v;
00391 
00392    v = cat->root;
00393    cat->root = NULL;
00394    cat->last = NULL;
00395 
00396    return v;
00397 }

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.
Return non-zero if found

Definition at line 327 of file config.c.

References ast_category_get(), and config.

00328 {
00329    return !!ast_category_get(config, category_name);
00330 }

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

Retrieve a category if it exists.

Parameters:
config which config to use
category_name name of the category you're looking for This will search through the categories within a given config file for a match.
Returns pointer to category if found, NULL if not.

Definition at line 322 of file config.c.

References category_get(), and config.

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

00323 {
00324    return category_get(config, category_name, 0);
00325 }

struct ast_category* ast_category_new ( const char *  name  ) 

Definition at line 295 of file config.c.

References ast_calloc.

Referenced by config_mysql(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_mysql(), realtime_multi_odbc(), and realtime_multi_pgsql().

00296 {
00297    struct ast_category *category;
00298 
00299    if ((category = ast_calloc(1, sizeof(*category))))
00300       ast_copy_string(category->name, name, sizeof(category->name));
00301    return category;
00302 }

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

Definition at line 399 of file config.c.

References ast_category::name.

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

00400 {
00401    ast_copy_string(cat->name, name, sizeof(cat->name));
00402 }

int ast_check_realtime ( const char *  family  ) 

Check if realtime engine is configured for family returns 1 if family is configured in realtime and engine exists.

Parameters:
family which family/config to be checked

Definition at line 1328 of file config.c.

References find_engine().

Referenced by _sip_show_peer(), _sip_show_peers(), and sip_show_settings().

01329 {
01330    struct ast_config_engine *eng;
01331 
01332    eng = find_engine(family, NULL, 0, NULL, 0);
01333    if (eng)
01334       return 1;
01335    return 0;
01336 
01337 }

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

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

Referenced by __ast_http_load(), action_getconfig(), action_updateconfig(), adsi_load(), advanced_options(), ast_config_load(), ast_config_load_with_comments(), ast_enum_init(), ast_rtp_reload(), ast_udptl_reload(), authenticate(), conf_exec(), directory_exec(), do_reload(), festival_exec(), find_conf(), handle_save_dialplan(), iax_provision_reload(), ind_load_module(), init_logger_chain(), init_manager(), load_config(), load_config_meetme(), load_module(), load_moh_classes(), load_realtime_queue(), load_rpt_vars(), loadconfigurationfile(), my_load_module(), odbc_load_module(), osp_load(), parse_config(), pbx_load_users(), play_message(), privacy_exec(), process_text_line(), read_agent_config(), read_config_maps(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), rpt_master(), set_config(), setup_zap(), sla_load_config(), tds_load_module(), unload_module(), and vm_forwardoptions().

00555 {
00556    struct ast_category *cat, *catn;
00557 
00558    if (!cfg)
00559       return;
00560 
00561    cat = cfg->root;
00562    while(cat) {
00563       ast_variables_destroy(cat->root);
00564       catn = cat;
00565       cat = cat->next;
00566       free(catn);
00567    }
00568    free(cfg);
00569 }

int ast_config_engine_deregister ( struct ast_config_engine del  ) 

Deegister config engine.

Definition at line 1177 of file config.c.

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

Referenced by unload_module().

01178 {
01179    struct ast_config_engine *ptr, *last=NULL;
01180 
01181    ast_mutex_lock(&config_lock);
01182 
01183    for (ptr = config_engine_list; ptr; ptr=ptr->next) {
01184       if (ptr == del) {
01185          if (last)
01186             last->next = ptr->next;
01187          else
01188             config_engine_list = ptr->next;
01189          break;
01190       }
01191       last = ptr;
01192    }
01193 
01194    ast_mutex_unlock(&config_lock);
01195 
01196    return 0;
01197 }

int ast_config_engine_register ( struct ast_config_engine new  ) 

Register config engine.

Definition at line 1158 of file config.c.

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

Referenced by load_module().

01159 {
01160    struct ast_config_engine *ptr;
01161 
01162    ast_mutex_lock(&config_lock);
01163 
01164    if (!config_engine_list) {
01165       config_engine_list = new;
01166    } else {
01167       for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
01168       ptr->next = new;
01169    }
01170 
01171    ast_mutex_unlock(&config_lock);
01172    ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name);
01173 
01174    return 1;
01175 }

struct ast_category* ast_config_get_current_category ( const struct ast_config cfg  ) 

Definition at line 571 of file config.c.

References ast_config::current.

Referenced by config_odbc(), and config_text_file_load().

00572 {
00573    return cfg->current;
00574 }

struct ast_config* ast_config_internal_load ( const char *  filename,
struct ast_config cfg,
int  withcomments 
)

Definition at line 1239 of file config.c.

References ast_log(), config_engine_list, db, extconfig_conf, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, result, table, and text_file_engine.

Referenced by ast_config_load(), ast_config_load_with_comments(), config_mysql(), config_odbc(), config_pgsql(), process_text_line(), and read_config_maps().

01240 {
01241    char db[256];
01242    char table[256];
01243    struct ast_config_engine *loader = &text_file_engine;
01244    struct ast_config *result; 
01245 
01246    if (cfg->include_level == cfg->max_include_level) {
01247       ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
01248       return NULL;
01249    }
01250 
01251    cfg->include_level++;
01252 
01253    if (strcmp(filename, extconfig_conf) && strcmp(filename, "asterisk.conf") && config_engine_list) {
01254       struct ast_config_engine *eng;
01255 
01256       eng = find_engine(filename, db, sizeof(db), table, sizeof(table));
01257 
01258 
01259       if (eng && eng->load_func) {
01260          loader = eng;
01261       } else {
01262          eng = find_engine("global", db, sizeof(db), table, sizeof(table));
01263          if (eng && eng->load_func)
01264             loader = eng;
01265       }
01266    }
01267 
01268    result = loader->load_func(db, table, filename, cfg, withcomments);
01269 
01270    if (result)
01271       result->include_level--;
01272    else
01273       cfg->include_level--;
01274 
01275    return result;
01276 }

struct ast_config* ast_config_load ( const char *  filename  ) 

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.
Returns NULL on error, or an ast_config data structure on success

Definition at line 1278 of file config.c.

References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), and result.

Referenced by __ast_http_load(), __say_init(), adsi_load(), advanced_options(), aji_load_config(), ast_enum_init(), ast_readconfig(), ast_rtp_reload(), ast_udptl_reload(), authenticate(), conf_exec(), directory_exec(), do_reload(), festival_exec(), find_conf(), gtalk_load_config(), handle_save_dialplan(), iax_provision_reload(), ind_load_module(), init_logger_chain(), init_manager(), load_config(), load_config_meetme(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_rpt_vars(), loadconfigurationfile(), my_load_module(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), privacy_exec(), read_agent_config(), realtime_directory(), reload(), reload_config(), reload_followme(), reload_queues(), set_config(), setup_zap(), sla_load_config(), smdi_load(), tds_load_module(), and vm_forwardoptions().

01279 {
01280    struct ast_config *cfg;
01281    struct ast_config *result;
01282 
01283    cfg = ast_config_new();
01284    if (!cfg)
01285       return NULL;
01286 
01287    result = ast_config_internal_load(filename, cfg, 0);
01288    if (!result)
01289       ast_config_destroy(cfg);
01290 
01291    return result;
01292 }

struct ast_config* ast_config_load_with_comments ( const char *  filename  ) 

Definition at line 1294 of file config.c.

References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), and result.

Referenced by action_getconfig(), action_updateconfig(), and vm_change_password().

01295 {
01296    struct ast_config *cfg;
01297    struct ast_config *result;
01298 
01299    cfg = ast_config_new();
01300    if (!cfg)
01301       return NULL;
01302 
01303    result = ast_config_internal_load(filename, cfg, 1);
01304    if (!result)
01305       ast_config_destroy(cfg);
01306 
01307    return result;
01308 }

struct ast_config* ast_config_new ( void   ) 

Definition at line 412 of file config.c.

References ast_calloc, config, and MAX_INCLUDE_LEVEL.

Referenced by ast_config_load(), ast_config_load_with_comments(), read_config_maps(), realtime_multi_mysql(), realtime_multi_odbc(), and realtime_multi_pgsql().

00413 {
00414    struct ast_config *config;
00415 
00416    if ((config = ast_calloc(1, sizeof(*config))))
00417       config->max_include_level = MAX_INCLUDE_LEVEL;
00418    return config;
00419 }

const char* ast_config_option ( struct ast_config cfg,
const char *  cat,
const char *  var 
)

Definition at line 233 of file config.c.

References ast_variable_retrieve().

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

00234 {
00235    const char *tmp;
00236    tmp = ast_variable_retrieve(cfg, cat, var);
00237    if (!tmp)
00238       tmp = ast_variable_retrieve(cfg, "general", var);
00239    return tmp;
00240 }

void ast_config_set_current_category ( struct ast_config cfg,
const struct ast_category cat 
)

Definition at line 576 of file config.c.

References ast_config::current.

00577 {
00578    /* cast below is just to silence compiler warning about dropping "const" */
00579    cfg->current = (struct ast_category *) cat;
00580 }

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

Retrieve realtime configuration.

Parameters:
family which family/config to lookup This will use builtin configuration backends to look up a particular entity in realtime and return a variable list of its parameters. Note that unlike the variables in ast_config, the resulting list of variables MUST be freed with ast_variables_destroy() as there is no container.

Definition at line 1310 of file config.c.

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

Referenced by cli_realtime_load(), find_conf_realtime(), find_user_realtime(), function_realtime_read(), load_realtime_queue(), realtime_alias(), realtime_exec(), realtime_peer(), realtime_switch_common(), and realtime_user().

01311 {
01312    struct ast_config_engine *eng;
01313    char db[256]="";
01314    char table[256]="";
01315    struct ast_variable *res=NULL;
01316    va_list ap;
01317 
01318    va_start(ap, family);
01319    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01320    if (eng && eng->realtime_func) 
01321       res = eng->realtime_func(db, table, ap);
01322    va_end(ap);
01323 
01324    return res;
01325 }

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

Retrieve realtime configuration.

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

Definition at line 1339 of file config.c.

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

Referenced by load_realtime_queue(), realtime_directory(), and realtime_switch_common().

01340 {
01341    struct ast_config_engine *eng;
01342    char db[256]="";
01343    char table[256]="";
01344    struct ast_config *res=NULL;
01345    va_list ap;
01346 
01347    va_start(ap, family);
01348    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01349    if (eng && eng->realtime_multi_func) 
01350       res = eng->realtime_multi_func(db, table, ap);
01351    va_end(ap);
01352 
01353    return res;
01354 }

AST_MUTEX_DEFINE_STATIC ( config_lock   ) 

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.

Definition at line 1356 of file config.c.

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

Referenced by change_password_realtime(), cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), realtime_update_exec(), and realtime_update_peer().

01357 {
01358    struct ast_config_engine *eng;
01359    int res = -1;
01360    char db[256]="";
01361    char table[256]="";
01362    va_list ap;
01363 
01364    va_start(ap, lookup);
01365    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01366    if (eng && eng->update_func) 
01367       res = eng->update_func(db, table, keyfield, lookup, ap);
01368    va_end(ap);
01369 
01370    return res;
01371 }

void ast_variable_append ( struct ast_category category,
struct ast_variable variable 
)

Definition at line 197 of file config.c.

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

Referenced by config_mysql(), config_odbc(), config_pgsql(), handle_updates(), inherit_category(), move_variables(), process_text_line(), realtime_directory(), realtime_multi_mysql(), realtime_multi_odbc(), realtime_multi_pgsql(), and vm_change_password().

00198 {
00199    if (!variable)
00200       return;
00201    if (category->last)
00202       category->last->next = variable;
00203    else
00204       category->root = variable;
00205    category->last = variable;
00206    while (category->last->next)
00207       category->last = category->last->next;
00208 }

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

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

Returns ast_variable list on success, or NULL on failure

Definition at line 221 of file config.c.

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

Referenced by __ast_http_load(), action_getconfig(), adsi_load(), aji_load_config(), ast_enum_init(), ast_readconfig(), ast_variable_retrieve(), authenticate(), collect_function_digits(), conf_exec(), database_first_connect(), do_directory(), do_say(), find_conf(), gtalk_load_config(), handle_save_dialplan(), iax_template_parse(), ind_load_module(), init_logger_chain(), init_manager(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_rpt_vars(), loadconfigurationfile(), misdn_cfg_init(), my_load_module(), odbc_load_module(), osp_create_provider(), parse_config(), pbx_load_config(), process_my_load_module(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_queues(), set_config(), setup_zap(), sip_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().

00222 {
00223    struct ast_category *cat = NULL;
00224 
00225    if (category && config->last_browse && (config->last_browse->name == category))
00226       cat = config->last_browse;
00227    else
00228       cat = ast_category_get(config, category);
00229 
00230    return (cat) ? cat->root : NULL;
00231 }

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

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

00422 {
00423    struct ast_variable *cur, *prev=NULL, *curn;
00424    int res = -1;
00425    cur = category->root;
00426    while (cur) {
00427       if (cur->name == variable) {
00428          if (prev) {
00429             prev->next = cur->next;
00430             if (cur == category->last)
00431                category->last = prev;
00432          } else {
00433             category->root = cur->next;
00434             if (cur == category->last)
00435                category->last = NULL;
00436          }
00437          cur->next = NULL;
00438          ast_variables_destroy(cur);
00439          return 0;
00440       }
00441       prev = cur;
00442       cur = cur->next;
00443    }
00444 
00445    prev = NULL;
00446    cur = category->root;
00447    while (cur) {
00448       curn = cur->next;
00449       if (!strcasecmp(cur->name, variable) && (ast_strlen_zero(match) || !strcasecmp(cur->value, match))) {
00450          if (prev) {
00451             prev->next = cur->next;
00452             if (cur == category->last)
00453                category->last = prev;
00454          } else {
00455             category->root = cur->next;
00456             if (cur == category->last)
00457                category->last = NULL;
00458          }
00459          cur->next = NULL;
00460          ast_variables_destroy(cur);
00461          res = 0;
00462       } else
00463          prev = cur;
00464 
00465       cur = curn;
00466    }
00467    return res;
00468 }

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

Definition at line 182 of file config.c.

References ast_calloc, and ast_variable::name.

Referenced by apply_outgoing(), ast_channeltype_list(), ast_httpd_helper_thread(), ast_variable_update(), astman_get_variables(), build_peer(), build_user(), check_access(), check_user_full(), config_mysql(), config_odbc(), config_pgsql(), handle_updates(), handle_uri(), iax_parse_ies(), parkandannounce_exec(), process_text_line(), realtime_directory(), realtime_multi_mysql(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_mysql(), realtime_odbc(), realtime_pgsql(), variable_clone(), and vm_change_password().

00183 {
00184    struct ast_variable *variable;
00185    int name_len = strlen(name) + 1; 
00186 
00187    if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + sizeof(*variable)))) {
00188       variable->name = variable->stuff;
00189       variable->value = variable->stuff + name_len;      
00190       strcpy(variable->name,name);
00191       strcpy(variable->value,value);
00192    }
00193 
00194    return variable;
00195 }

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
Returns the variable value on success, or NULL if unable to find it.

Definition at line 243 of file config.c.

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

Referenced by advanced_options(), aji_load_config(), ast_config_option(), ast_rtp_reload(), ast_udptl_reload(), attempt_reconnect(), cdr_pgsql_read_config(), directory_exec(), do_directory(), do_reload(), festival_exec(), function_ilink(), function_macro(), function_remote(), get_wait_interval(), gtalk_load_config(), handle_save_dialplan(), iax_template_parse(), ind_load_module(), init_acf_query(), init_logger_chain(), init_manager(), load_config(), load_config_meetme(), load_module(), load_modules(), load_rpt_vars(), my_load_module(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), privacy_exec(), process_my_load_module(), read_agent_config(), realtime_directory(), reload_config(), reload_followme(), reload_queues(), retrieve_astcfgint(), rpt(), rpt_exec(), rpt_master(), rpt_tele_thread(), set_config(), setup_zap(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), telem_lookup(), vm_change_password(), and vm_forwardoptions().

00244 {
00245    struct ast_variable *v;
00246 
00247    if (category) {
00248       for (v = ast_variable_browse(config, category); v; v = v->next) {
00249          if (!strcasecmp(variable, v->name))
00250             return v->value;
00251       }
00252    } else {
00253       struct ast_category *cat;
00254 
00255       for (cat = config->root; cat; cat = cat->next)
00256          for (v = cat->root; v; v = v->next)
00257             if (!strcasecmp(variable, v->name))
00258                return v->value;
00259    }
00260 
00261    return NULL;
00262 }

int ast_variable_update ( struct ast_category category,
const char *  variable,
const char *  value,
const char *  match,
unsigned int  object 
)

Definition at line 470 of file config.c.

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

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

00472 {
00473    struct ast_variable *cur, *prev=NULL, *newer;
00474 
00475    if (!(newer = ast_variable_new(variable, value)))
00476       return -1;
00477    
00478    newer->object = object;
00479 
00480    for (cur = category->root; cur; prev = cur, cur = cur->next) {
00481       if (strcasecmp(cur->name, variable) ||
00482          (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
00483          continue;
00484 
00485       newer->next = cur->next;
00486       newer->object = cur->object || object;
00487       if (prev)
00488          prev->next = newer;
00489       else
00490          category->root = newer;
00491       if (category->last == cur)
00492          category->last = newer;
00493 
00494       cur->next = NULL;
00495       ast_variables_destroy(cur);
00496 
00497       return 0;
00498    }
00499 
00500    if (prev)
00501       prev->next = newer;
00502    else
00503       category->root = newer;
00504 
00505    return 0;
00506 }

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

References free, and ast_variable::next.

Referenced by ast_category_delete(), ast_category_destroy(), ast_config_destroy(), ast_httpd_helper_thread(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_variable_delete(), ast_variable_update(), build_peer(), build_user(), destroy_user(), find_conf_realtime(), find_user_realtime(), handle_uri(), iax2_destroy(), load_realtime_queue(), realtime_alias(), realtime_canmatch(), realtime_exec(), realtime_exists(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_user(), sip_alloc(), sip_destroy_peer(), sip_destroy_user(), and socket_process().

00211 {
00212    struct ast_variable *vn;
00213 
00214    while(v) {
00215       vn = v;
00216       v = v->next;
00217       free(vn);
00218    }
00219 }

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

Definition at line 304 of file config.c.

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

Referenced by ast_category_get(), and process_text_line().

00305 {
00306    struct ast_category *cat;
00307 
00308    /* try exact match first, then case-insensitive match */
00309    for (cat = config->root; cat; cat = cat->next) {
00310       if (cat->name == category_name && (ignored || !cat->ignored))
00311          return cat;
00312    }
00313 
00314    for (cat = config->root; cat; cat = cat->next) {
00315       if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
00316          return cat;
00317    }
00318 
00319    return NULL;
00320 }

static void CB_ADD ( char **  comment_buffer,
int *  comment_buffer_size,
char *  str 
) [static]

Definition at line 93 of file config.c.

References ast_realloc, and CB_INCR.

Referenced by config_text_file_load().

00094 {
00095    int rem = *comment_buffer_size - strlen(*comment_buffer) - 1;
00096    int siz = strlen(str);
00097    if (rem < siz+1) {
00098       *comment_buffer = ast_realloc(*comment_buffer, *comment_buffer_size + CB_INCR + siz + 1);
00099       if (!(*comment_buffer))
00100          return;
00101       *comment_buffer_size += CB_INCR+siz+1;
00102    }
00103    strcat(*comment_buffer,str);
00104 }

static void CB_ADD_LEN ( char **  comment_buffer,
int *  comment_buffer_size,
char *  str,
int  len 
) [static]

Definition at line 106 of file config.c.

References ast_realloc, and CB_INCR.

Referenced by config_text_file_load().

00107 {
00108    int cbl = strlen(*comment_buffer) + 1;
00109    int rem = *comment_buffer_size - cbl;
00110    if (rem < len+1) {
00111       *comment_buffer = ast_realloc(*comment_buffer, *comment_buffer_size + CB_INCR + len + 1);
00112       if (!(*comment_buffer))
00113          return;
00114       *comment_buffer_size += CB_INCR+len+1;
00115    }
00116    strncat(*comment_buffer,str,len);
00117    (*comment_buffer)[cbl+len-1] = 0;
00118 }

static void CB_INIT ( char **  comment_buffer,
int *  comment_buffer_size,
char **  lline_buffer,
int *  lline_buffer_size 
) [static]

Definition at line 74 of file config.c.

References ast_malloc, and CB_INCR.

Referenced by config_text_file_load().

00075 {
00076    if (!(*comment_buffer)) {
00077       *comment_buffer = ast_malloc(CB_INCR);
00078       if (!(*comment_buffer))
00079          return;
00080       (*comment_buffer)[0] = 0;
00081       *comment_buffer_size = CB_INCR;
00082       *lline_buffer = ast_malloc(CB_INCR);
00083       if (!(*lline_buffer))
00084          return;
00085       (*lline_buffer)[0] = 0;
00086       *lline_buffer_size = CB_INCR;
00087    } else {
00088       (*comment_buffer)[0] = 0;
00089       (*lline_buffer)[0] = 0;
00090    }
00091 }

static void CB_RESET ( char **  comment_buffer,
char **  lline_buffer 
) [static]

Definition at line 133 of file config.c.

Referenced by process_text_line().

00134 { 
00135    (*comment_buffer)[0] = 0; 
00136    (*lline_buffer)[0] = 0;
00137 }

static void clear_config_maps ( void   )  [static]

Definition at line 1040 of file config.c.

References ast_mutex_lock(), ast_mutex_unlock(), config_maps, free, map, and ast_config_map::next.

Referenced by read_config_maps().

01041 {
01042    struct ast_config_map *map;
01043 
01044    ast_mutex_lock(&config_lock);
01045 
01046    while (config_maps) {
01047       map = config_maps;
01048       config_maps = config_maps->next;
01049       free(map);
01050    }
01051       
01052    ast_mutex_unlock(&config_lock);
01053 }

static int config_command ( int  fd,
int  argc,
char **  argv 
) [static]

Definition at line 1373 of file config.c.

References ast_cli(), ast_mutex_lock(), config_engine_list, config_maps, map, ast_config_engine::name, and ast_config_engine::next.

01374 {
01375    struct ast_config_engine *eng;
01376    struct ast_config_map *map;
01377    
01378    ast_mutex_lock(&config_lock);
01379 
01380    ast_cli(fd, "\n\n");
01381    for (eng = config_engine_list; eng; eng = eng->next) {
01382       ast_cli(fd, "\nConfig Engine: %s\n", eng->name);
01383       for (map = config_maps; map; map = map->next)
01384          if (!strcasecmp(map->driver, eng->name)) {
01385             ast_cli(fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
01386                map->table ? map->table : map->name);
01387          }
01388    }
01389    ast_cli(fd,"\n\n");
01390    
01391    ast_mutex_unlock(&config_lock);
01392 
01393    return 0;
01394 }

static struct ast_config* config_text_file_load ( const char *  database,
const char *  table,
const char *  filename,
struct ast_config cfg,
int  withcomments 
) [static]

Definition at line 762 of file config.c.

References ast_config_AST_CONFIG_DIR, ast_config_get_current_category(), ast_log(), ast_strlen_zero(), ast_verbose(), CB_ADD(), CB_ADD_LEN(), CB_INIT(), COMMENT_META, COMMENT_TAG, f, lineno, LLB_ADD(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, option_debug, option_verbose, process_text_line(), and VERBOSE_PREFIX_2.

00763 {
00764    char fn[256];
00765    char buf[8192];
00766    char *new_buf, *comment_p, *process_buf;
00767    FILE *f;
00768    int lineno=0;
00769    int comment = 0, nest[MAX_NESTED_COMMENTS];
00770    struct ast_category *cat = NULL;
00771    int count = 0;
00772    struct stat statbuf;
00773    /*! Growable string buffer */
00774    char *comment_buffer=0;   /*!< this will be a comment collector.*/
00775    int   comment_buffer_size=0;  /*!< the amount of storage so far alloc'd for the comment_buffer */
00776 
00777    char *lline_buffer=0;    /*!< A buffer for stuff behind the ; */
00778    int  lline_buffer_size=0;
00779 
00780    
00781    cat = ast_config_get_current_category(cfg);
00782 
00783    if (filename[0] == '/') {
00784       ast_copy_string(fn, filename, sizeof(fn));
00785    } else {
00786       snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, filename);
00787    }
00788 
00789    if (withcomments) {
00790       CB_INIT(&comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size);
00791       if (!lline_buffer || !comment_buffer) {
00792          ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
00793          return NULL;
00794       }
00795    }
00796 #ifdef AST_INCLUDE_GLOB
00797    {
00798       int glob_ret;
00799       glob_t globbuf;
00800       globbuf.gl_offs = 0; /* initialize it to silence gcc */
00801 #ifdef SOLARIS
00802       glob_ret = glob(fn, GLOB_NOCHECK, NULL, &globbuf);
00803 #else
00804       glob_ret = glob(fn, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf);
00805 #endif
00806       if (glob_ret == GLOB_NOSPACE)
00807          ast_log(LOG_WARNING,
00808             "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
00809       else if (glob_ret  == GLOB_ABORTED)
00810          ast_log(LOG_WARNING,
00811             "Glob Expansion of pattern '%s' failed: Read error\n", fn);
00812       else  {
00813          /* loop over expanded files */
00814          int i;
00815          for (i=0; i<globbuf.gl_pathc; i++) {
00816             ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
00817 #endif
00818    do {
00819       if (stat(fn, &statbuf))
00820          continue;
00821 
00822       if (!S_ISREG(statbuf.st_mode)) {
00823          ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
00824          continue;
00825       }
00826       if (option_verbose > 1) {
00827          ast_verbose(VERBOSE_PREFIX_2 "Parsing '%s': ", fn);
00828          fflush(stdout);
00829       }
00830       if (!(f = fopen(fn, "r"))) {
00831          if (option_debug)
00832             ast_log(LOG_DEBUG, "No file to parse: %s\n", fn);
00833          if (option_verbose > 1)
00834             ast_verbose( "Not found (%s)\n", strerror(errno));
00835          continue;
00836       }
00837       count++;
00838       if (option_debug)
00839          ast_log(LOG_DEBUG, "Parsing %s\n", fn);
00840       if (option_verbose > 1)
00841          ast_verbose("Found\n");
00842       while(!feof(f)) {
00843          lineno++;
00844          if (fgets(buf, sizeof(buf), f)) {
00845             if ( withcomments ) {
00846                CB_ADD(&comment_buffer, &comment_buffer_size, lline_buffer);       /* add the current lline buffer to the comment buffer */
00847                lline_buffer[0] = 0;        /* erase the lline buffer */
00848             }
00849             
00850             new_buf = buf;
00851             if (comment) 
00852                process_buf = NULL;
00853             else
00854                process_buf = buf;
00855             
00856             while ((comment_p = strchr(new_buf, COMMENT_META))) {
00857                if ((comment_p > new_buf) && (*(comment_p-1) == '\\')) {
00858                   /* Yuck, gotta memmove */
00859                   memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
00860                   new_buf = comment_p;
00861                } else if(comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
00862                   /* Meta-Comment start detected ";--" */
00863                   if (comment < MAX_NESTED_COMMENTS) {
00864                      *comment_p = '\0';
00865                      new_buf = comment_p + 3;
00866                      comment++;
00867                      nest[comment-1] = lineno;
00868                   } else {
00869                      ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
00870                   }
00871                } else if ((comment_p >= new_buf + 2) &&
00872                      (*(comment_p - 1) == COMMENT_TAG) &&
00873                      (*(comment_p - 2) == COMMENT_TAG)) {
00874                   /* Meta-Comment end detected */
00875                   comment--;
00876                   new_buf = comment_p + 1;
00877                   if (!comment) {
00878                      /* Back to non-comment now */
00879                      if (process_buf) {
00880                         /* Actually have to move what's left over the top, then continue */
00881                         char *oldptr;
00882                         oldptr = process_buf + strlen(process_buf);
00883                         if ( withcomments ) {
00884                            CB_ADD(&comment_buffer, &comment_buffer_size, ";");
00885                            CB_ADD_LEN(&comment_buffer, &comment_buffer_size, oldptr+1, new_buf-oldptr-1);
00886                         }
00887                         
00888                         memmove(oldptr, new_buf, strlen(new_buf) + 1);
00889                         new_buf = oldptr;
00890                      } else
00891                         process_buf = new_buf;
00892                   }
00893                } else {
00894                   if (!comment) {
00895                      /* If ; is found, and we are not nested in a comment, 
00896                         we immediately stop all comment processing */
00897                      if ( withcomments ) {
00898                         LLB_ADD(&lline_buffer, &lline_buffer_size, comment_p);
00899                      }
00900                      *comment_p = '\0'; 
00901                      new_buf = comment_p;
00902                   } else
00903                      new_buf = comment_p + 1;
00904                }
00905             }
00906             if( withcomments && comment && !process_buf )
00907             {
00908                CB_ADD(&comment_buffer, &comment_buffer_size, buf);  /* the whole line is a comment, store it */
00909             }
00910             
00911             if (process_buf) {
00912                char *buf = ast_strip(process_buf);
00913                if (!ast_strlen_zero(buf)) {
00914                   if (process_text_line(cfg, &cat, buf, lineno, fn, withcomments, &comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size)) {
00915                      cfg = NULL;
00916                      break;
00917                   }
00918                }
00919             }
00920          }
00921       }
00922       fclose(f);     
00923    } while(0);
00924    if (comment) {
00925       ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment]);
00926    }
00927 #ifdef AST_INCLUDE_GLOB
00928                if (!cfg)
00929                   break;
00930             }
00931             globfree(&globbuf);
00932          }
00933       }
00934 #endif
00935 
00936    if (cfg && cfg->include_level == 1 && withcomments && comment_buffer) {
00937       free(comment_buffer);
00938       free(lline_buffer);
00939       comment_buffer = NULL;
00940       lline_buffer = NULL;
00941       comment_buffer_size = 0;
00942       lline_buffer_size = 0;
00943    }
00944    
00945    if (count == 0)
00946       return NULL;
00947 
00948    return cfg;
00949 }

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

Definition at line 951 of file config.c.

References ast_config_AST_CONFIG_DIR, ast_log(), ast_verbose(), ast_comment::cmt, f, LOG_DEBUG, ast_category::name, ast_category::next, option_debug, option_verbose, ast_category::precomments, ast_config::root, ast_category::root, ast_category::sameline, t, var, and VERBOSE_PREFIX_2.

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

00952 {
00953    FILE *f;
00954    char fn[256];
00955    char date[256]="";
00956    time_t t;
00957    struct ast_variable *var;
00958    struct ast_category *cat;
00959    struct ast_comment *cmt;
00960    int blanklines = 0;
00961 
00962    if (configfile[0] == '/') {
00963       ast_copy_string(fn, configfile, sizeof(fn));
00964    } else {
00965       snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
00966    }
00967    time(&t);
00968    ast_copy_string(date, ctime(&t), sizeof(date));
00969 #ifdef __CYGWIN__ 
00970    if ((f = fopen(fn, "w+"))) {
00971 #else
00972    if ((f = fopen(fn, "w"))) {
00973 #endif       
00974       if (option_verbose > 1)
00975          ast_verbose(VERBOSE_PREFIX_2 "Saving '%s': ", fn);
00976       fprintf(f, ";!\n");
00977       fprintf(f, ";! Automatically generated configuration file\n");
00978       if (strcmp(configfile, fn))
00979          fprintf(f, ";! Filename: %s (%s)\n", configfile, fn);
00980       else
00981          fprintf(f, ";! Filename: %s\n", configfile);
00982       fprintf(f, ";! Generator: %s\n", generator);
00983       fprintf(f, ";! Creation Date: %s", date);
00984       fprintf(f, ";!\n");
00985       cat = cfg->root;
00986       while(cat) {
00987          /* Dump section with any appropriate comment */
00988          for (cmt = cat->precomments; cmt; cmt=cmt->next)
00989          {
00990             if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
00991                fprintf(f,"%s", cmt->cmt);
00992          }
00993          if (!cat->precomments)
00994             fprintf(f,"\n");
00995          fprintf(f, "[%s]", cat->name);
00996          for(cmt = cat->sameline; cmt; cmt=cmt->next)
00997          {
00998             fprintf(f,"%s", cmt->cmt);
00999          }
01000          if (!cat->sameline)
01001             fprintf(f,"\n");
01002          var = cat->root;
01003          while(var) {
01004             for (cmt = var->precomments; cmt; cmt=cmt->next)
01005             {
01006                if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
01007                   fprintf(f,"%s", cmt->cmt);
01008             }
01009             if (var->sameline) 
01010                fprintf(f, "%s %s %s  %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
01011             else  
01012                fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
01013             if (var->blanklines) {
01014                blanklines = var->blanklines;
01015                while (blanklines--)
01016                   fprintf(f, "\n");
01017             }
01018                
01019             var = var->next;
01020          }
01021 #if 0
01022          /* Put an empty line */
01023          fprintf(f, "\n");
01024 #endif
01025          cat = cat->next;
01026       }
01027       if ((option_verbose > 1) && !option_debug)
01028          ast_verbose("Saved\n");
01029    } else {
01030       if (option_debug)
01031          ast_log(LOG_DEBUG, "Unable to open for writing: %s\n", fn);
01032       if (option_verbose > 1)
01033          ast_verbose(VERBOSE_PREFIX_2 "Unable to write (%s)", strerror(errno));
01034       return -1;
01035    }
01036    fclose(f);
01037    return 0;
01038 }

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

Find realtime engine for realtime family.

Definition at line 1200 of file config.c.

References ast_mutex_lock(), config_maps, and map.

Referenced by ast_check_realtime(), ast_config_internal_load(), ast_load_realtime(), ast_load_realtime_multientry(), ast_speech_new(), ast_speech_register(), and ast_update_realtime().

01201 {
01202    struct ast_config_engine *eng, *ret = NULL;
01203    struct ast_config_map *map;
01204 
01205    ast_mutex_lock(&config_lock);
01206 
01207    for (map = config_maps; map; map = map->next) {
01208       if (!strcasecmp(family, map->name)) {
01209          if (database)
01210             ast_copy_string(database, map->database, dbsiz);
01211          if (table)
01212             ast_copy_string(table, map->table ? map->table : family, tabsiz);
01213          break;
01214       }
01215    }
01216 
01217    /* Check if the required driver (engine) exist */
01218    if (map) {
01219       for (eng = config_engine_list; !ret && eng; eng = eng->next) {
01220          if (!strcasecmp(eng->name, map->driver))
01221             ret = eng;
01222       }
01223    }
01224 
01225    ast_mutex_unlock(&config_lock);
01226    
01227    /* if we found a mapping, but the engine is not available, then issue a warning */
01228    if (map && !ret)
01229       ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
01230 
01231    return ret;
01232 }

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

Definition at line 404 of file config.c.

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

Referenced by process_text_line().

00405 {
00406    struct ast_variable *var;
00407 
00408    for (var = base->root; var; var = var->next)
00409       ast_variable_append(new, variable_clone(var));
00410 }

static void LLB_ADD ( char **  lline_buffer,
int *  lline_buffer_size,
char *  str 
) [static]

Definition at line 120 of file config.c.

References ast_realloc, and CB_INCR.

Referenced by config_text_file_load().

00121 {
00122    int rem = *lline_buffer_size - strlen(*lline_buffer) - 1;
00123    int siz = strlen(str);
00124    if (rem < siz+1) {
00125       *lline_buffer = ast_realloc(*lline_buffer, *lline_buffer_size + CB_INCR + siz + 1);
00126       if (!(*lline_buffer)) 
00127          return;
00128       *lline_buffer_size += CB_INCR + siz + 1;
00129    }
00130    strcat(*lline_buffer,str);
00131 }

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

Definition at line 278 of file config.c.

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

Referenced by process_text_line().

00279 {
00280    struct ast_variable *var = old->root;
00281    old->root = NULL;
00282 #if 1
00283    /* we can just move the entire list in a single op */
00284    ast_variable_append(new, var);
00285 #else
00286    while (var) {
00287       struct ast_variable *next = var->next;
00288       var->next = NULL;
00289       ast_variable_append(new, var);
00290       var = next;
00291    }
00292 #endif
00293 }

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

Definition at line 349 of file config.c.

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

Referenced by ast_category_browse().

00350 {
00351    for (; cat && cat->ignored; cat = cat->next);
00352 
00353    return cat;
00354 }

static int process_text_line ( struct ast_config cfg,
struct ast_category **  cat,
char *  buf,
int  lineno,
const char *  configfile,
int  withcomments,
char **  comment_buffer,
int *  comment_buffer_size,
char **  lline_buffer,
int *  lline_buffer_size 
) [static]

Definition at line 582 of file config.c.

References ALLOC_COMMENT(), ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_destroy(), ast_config_internal_load(), ast_log(), ast_opt_exec_includes, ast_safe_system(), ast_strlen_zero(), ast_variable_append(), ast_variable_new(), ast_variable::blanklines, category_get(), CB_RESET(), inherit_category(), ast_variable::lineno, LOG_WARNING, move_variables(), ast_variable::object, ast_variable::precomments, ast_category::precomments, ast_variable::sameline, ast_category::sameline, and strsep().

Referenced by config_text_file_load().

00584 {
00585    char *c;
00586    char *cur = buf;
00587    struct ast_variable *v;
00588    char cmd[512], exec_file[512];
00589    int object, do_exec, do_include;
00590 
00591    /* Actually parse the entry */
00592    if (cur[0] == '[') {
00593       struct ast_category *newcat = NULL;
00594       char *catname;
00595 
00596       /* A category header */
00597       c = strchr(cur, ']');
00598       if (!c) {
00599          ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
00600          return -1;
00601       }
00602       *c++ = '\0';
00603       cur++;
00604       if (*c++ != '(')
00605          c = NULL;
00606       catname = cur;
00607       if (!(*cat = newcat = ast_category_new(catname))) {
00608          return -1;
00609       }
00610       /* add comments */
00611       if (withcomments && *comment_buffer && (*comment_buffer)[0] ) {
00612          newcat->precomments = ALLOC_COMMENT(*comment_buffer);
00613       }
00614       if (withcomments && *lline_buffer && (*lline_buffer)[0] ) {
00615          newcat->sameline = ALLOC_COMMENT(*lline_buffer);
00616       }
00617       if( withcomments )
00618          CB_RESET(comment_buffer, lline_buffer);
00619       
00620       /* If there are options or categories to inherit from, process them now */
00621       if (c) {
00622          if (!(cur = strchr(c, ')'))) {
00623             ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
00624             return -1;
00625          }
00626          *cur = '\0';
00627          while ((cur = strsep(&c, ","))) {
00628             if (!strcasecmp(cur, "!")) {
00629                (*cat)->ignored = 1;
00630             } else if (!strcasecmp(cur, "+")) {
00631                *cat = category_get(cfg, catname, 1);
00632                if (!(*cat)) {
00633                   ast_config_destroy(cfg);
00634                   if (newcat)
00635                      ast_category_destroy(newcat);
00636                   ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
00637                   return -1;
00638                }
00639                if (newcat) {
00640                   move_variables(newcat, *cat);
00641                   ast_category_destroy(newcat);
00642                   newcat = NULL;
00643                }
00644             } else {
00645                struct ast_category *base;
00646             
00647                base = category_get(cfg, cur, 1);
00648                if (!base) {
00649                   ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
00650                   return -1;
00651                }
00652                inherit_category(*cat, base);
00653             }
00654          }
00655       }
00656       if (newcat)
00657          ast_category_append(cfg, *cat);
00658    } else if (cur[0] == '#') {
00659       /* A directive */
00660       cur++;
00661       c = cur;
00662       while(*c && (*c > 32)) c++;
00663       if (*c) {
00664          *c = '\0';
00665          /* Find real argument */
00666          c = ast_skip_blanks(c + 1);
00667          if (!(*c))
00668             c = NULL;
00669       } else 
00670          c = NULL;
00671       do_include = !strcasecmp(cur, "include");
00672       if(!do_include)
00673          do_exec = !strcasecmp(cur, "exec");
00674       else
00675          do_exec = 0;
00676       if (do_exec && !ast_opt_exec_includes) {
00677          ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
00678          do_exec = 0;
00679       }
00680       if (do_include || do_exec) {
00681          if (c) {
00682             /* Strip off leading and trailing "'s and <>'s */
00683             while((*c == '<') || (*c == '>') || (*c == '\"')) c++;
00684             /* Get rid of leading mess */
00685             cur = c;
00686             while (!ast_strlen_zero(cur)) {
00687                c = cur + strlen(cur) - 1;
00688                if ((*c == '>') || (*c == '<') || (*c == '\"'))
00689                   *c = '\0';
00690                else
00691                   break;
00692             }
00693             /* #exec </path/to/executable>
00694                We create a tmp file, then we #include it, then we delete it. */
00695             if (do_exec) { 
00696                snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d.%ld", (int)time(NULL), (long)pthread_self());
00697                snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file);
00698                ast_safe_system(cmd);
00699                cur = exec_file;
00700             } else
00701                exec_file[0] = '\0';
00702             /* A #include */
00703             do_include = ast_config_internal_load(cur, cfg, withcomments) ? 1 : 0;
00704             if(!ast_strlen_zero(exec_file))
00705                unlink(exec_file);
00706             if(!do_include)
00707                return 0;
00708 
00709          } else {
00710             ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n", 
00711                   do_exec ? "exec" : "include",
00712                   do_exec ? "/path/to/executable" : "filename",
00713                   lineno,
00714                   configfile);
00715          }
00716       }
00717       else 
00718          ast_log(LOG_WARNING, "Unknown directive '%s' at line %d of %s\n", cur, lineno, configfile);
00719    } else {
00720       /* Just a line (variable = value) */
00721       if (!(*cat)) {
00722          ast_log(LOG_WARNING,
00723             "parse error: No category context for line %d of %s\n", lineno, configfile);
00724          return -1;
00725       }
00726       c = strchr(cur, '=');
00727       if (c) {
00728          *c = 0;
00729          c++;
00730          /* Ignore > in => */
00731          if (*c== '>') {
00732             object = 1;
00733             c++;
00734          } else
00735             object = 0;
00736          if ((v = ast_variable_new(ast_strip(cur), ast_strip(c)))) {
00737             v->lineno = lineno;
00738             v->object = object;
00739             /* Put and reset comments */
00740             v->blanklines = 0;
00741             ast_variable_append(*cat, v);
00742             /* add comments */
00743             if (withcomments && *comment_buffer && (*comment_buffer)[0] ) {
00744                v->precomments = ALLOC_COMMENT(*comment_buffer);
00745             }
00746             if (withcomments && *lline_buffer && (*lline_buffer)[0] ) {
00747                v->sameline = ALLOC_COMMENT(*lline_buffer);
00748             }
00749             if( withcomments )
00750                CB_RESET(comment_buffer, lline_buffer);
00751             
00752          } else {
00753             return -1;
00754          }
00755       } else {
00756          ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
00757       }
00758    }
00759    return 0;
00760 }

int read_config_maps ( void   ) 

Definition at line 1090 of file config.c.

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

Referenced by main().

01091 {
01092    struct ast_config *config, *configtmp;
01093    struct ast_variable *v;
01094    char *driver, *table, *database, *stringp, *tmp;
01095 
01096    clear_config_maps();
01097 
01098    configtmp = ast_config_new();
01099    configtmp->max_include_level = 1;
01100    config = ast_config_internal_load(extconfig_conf, configtmp, 0);
01101    if (!config) {
01102       ast_config_destroy(configtmp);
01103       return 0;
01104    }
01105 
01106    for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
01107       stringp = v->value;
01108       driver = strsep(&stringp, ",");
01109 
01110       if ((tmp = strchr(stringp, '\"')))
01111          stringp = tmp;
01112 
01113       /* check if the database text starts with a double quote */
01114       if (*stringp == '"') {
01115          stringp++;
01116          database = strsep(&stringp, "\"");
01117          strsep(&stringp, ",");
01118       } else {
01119          /* apparently this text has no quotes */
01120          database = strsep(&stringp, ",");
01121       }
01122 
01123       table = strsep(&stringp, ",");
01124 
01125       if (!strcmp(v->name, extconfig_conf)) {
01126          ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
01127          continue;
01128       }
01129 
01130       if (!strcmp(v->name, "asterisk.conf")) {
01131          ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
01132          continue;
01133       }
01134 
01135       if (!strcmp(v->name, "logger.conf")) {
01136          ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
01137          continue;
01138       }
01139 
01140       if (!driver || !database)
01141          continue;
01142       if (!strcasecmp(v->name, "sipfriends")) {
01143          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");
01144          append_mapping("sipusers", driver, database, table ? table : "sipfriends");
01145          append_mapping("sippeers", driver, database, table ? table : "sipfriends");
01146       } else if (!strcasecmp(v->name, "iaxfriends")) {
01147          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");
01148          append_mapping("iaxusers", driver, database, table ? table : "iaxfriends");
01149          append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends");
01150       } else 
01151          append_mapping(v->name, driver, database, table);
01152    }
01153       
01154    ast_config_destroy(config);
01155    return 0;
01156 }

int register_config_cli ( void   ) 

Definition at line 1411 of file config.c.

References ast_cli_register_multiple(), and cli_config.

Referenced by main().

01412 {
01413    ast_cli_register_multiple(cli_config, sizeof(cli_config) / sizeof(struct ast_cli_entry));
01414    return 0;
01415 }

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

Definition at line 264 of file config.c.

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

Referenced by inherit_category().

00265 {
00266    struct ast_variable *new = ast_variable_new(old->name, old->value);
00267 
00268    if (new) {
00269       new->lineno = old->lineno;
00270       new->object = old->object;
00271       new->blanklines = old->blanklines;
00272       /* TODO: clone comments? */
00273    }
00274 
00275    return new;
00276 }


Variable Documentation

struct ast_cli_entry cli_config[] [static]

Initial value:

 {
   { { "core", "show", "config", "mappings", NULL },
   config_command, "Display config mappings (file names to config engines)",
   show_config_help, NULL, &cli_show_config_mappings_deprecated },
}

Definition at line 1405 of file config.c.

Referenced by register_config_cli().

struct ast_cli_entry cli_show_config_mappings_deprecated [static]

Initial value:

 {
   { "show", "config", "mappings", NULL },
   config_command, NULL,
   NULL }

Definition at line 1400 of file config.c.

struct ast_config_engine* config_engine_list [static]

Definition at line 158 of file config.c.

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

struct ast_config_map * config_maps [static]

Referenced by append_mapping(), clear_config_maps(), config_command(), and find_engine().

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

Definition at line 63 of file config.c.

Referenced by ast_config_internal_load(), and read_config_maps().

char show_config_help[] [static]

Initial value:

   "Usage: core show config mappings\n"
   "  Shows the filenames to config engines.\n"

Definition at line 1396 of file config.c.

struct ast_config_engine text_file_engine [static]

Initial value:

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

Definition at line 1234 of file config.c.

Referenced by ast_config_internal_load().


Generated on Mon Apr 30 07:41:45 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1