Fri Aug 24 02:24:58 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)
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 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 1061 of file config.c.

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

Referenced by read_config_maps().

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

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 364 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(), odbc_load_module(), osp_load(), pbx_load_config(), pbx_load_users(), read_agent_config(), realtime_directory(), realtime_peer(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_queues(), rpt_master(), set_config(), setup_zap(), sla_load_config(), update_realtime_members(), and vm_change_password().

00365 {  
00366    struct ast_category *cat = NULL;
00367 
00368    if (prev && config->last_browse && (config->last_browse->name == prev))
00369       cat = config->last_browse->next;
00370    else if (!prev && config->root)
00371       cat = config->root;
00372    else if (prev) {
00373       for (cat = config->root; cat; cat = cat->next) {
00374          if (cat->name == prev) {
00375             cat = cat->next;
00376             break;
00377          }
00378       }
00379       if (!cat) {
00380          for (cat = config->root; cat; cat = cat->next) {
00381             if (!strcasecmp(cat->name, prev)) {
00382                cat = cat->next;
00383                break;
00384             }
00385          }
00386       }
00387    }
00388    
00389    if (cat)
00390       cat = next_available_category(cat);
00391 
00392    config->last_browse = cat;
00393    return (cat) ? cat->name : NULL;
00394 }

int ast_category_delete ( struct ast_config cfg,
char *  category 
)

Definition at line 516 of file config.c.

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

Referenced by handle_updates().

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

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

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

Referenced by realtime_switch_common().

00397 {
00398    struct ast_variable *v;
00399 
00400    v = cat->root;
00401    cat->root = NULL;
00402    cat->last = NULL;
00403 
00404    return v;
00405 }

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_category_root(), 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 407 of file config.c.

References ast_category::name.

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

00408 {
00409    ast_copy_string(cat->name, name, sizeof(cat->name));
00410 }

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

returns the root ast_variable of a config

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

Definition at line 356 of file config.c.

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

Referenced by realtime_peer().

00357 {
00358    struct ast_category *category = ast_category_get(config, cat);
00359    if (category)
00360       return category->root;
00361    return NULL;
00362 }

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

References find_engine().

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

01335 {
01336    struct ast_config_engine *eng;
01337 
01338    eng = find_engine(family, NULL, 0, NULL, 0);
01339    if (eng)
01340       return 1;
01341    return 0;
01342 
01343 }

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 562 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(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_users(), play_message(), privacy_exec(), read_agent_config(), read_config_maps(), realtime_directory(), realtime_multi_mysql(), realtime_peer(), 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().

00563 {
00564    struct ast_category *cat, *catn;
00565 
00566    if (!cfg)
00567       return;
00568 
00569    cat = cfg->root;
00570    while(cat) {
00571       ast_variables_destroy(cat->root);
00572       catn = cat;
00573       cat = cat->next;
00574       free(catn);
00575    }
00576    free(cfg);
00577 }

int ast_config_engine_deregister ( struct ast_config_engine del  ) 

Deegister config engine.

Definition at line 1183 of file config.c.

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

Referenced by unload_module().

01184 {
01185    struct ast_config_engine *ptr, *last=NULL;
01186 
01187    ast_mutex_lock(&config_lock);
01188 
01189    for (ptr = config_engine_list; ptr; ptr=ptr->next) {
01190       if (ptr == del) {
01191          if (last)
01192             last->next = ptr->next;
01193          else
01194             config_engine_list = ptr->next;
01195          break;
01196       }
01197       last = ptr;
01198    }
01199 
01200    ast_mutex_unlock(&config_lock);
01201 
01202    return 0;
01203 }

int ast_config_engine_register ( struct ast_config_engine new  ) 

Register config engine.

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

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

struct ast_category* ast_config_get_current_category ( const struct ast_config cfg  ) 

Definition at line 579 of file config.c.

References ast_config::current.

Referenced by config_odbc(), and config_text_file_load().

00580 {
00581    return cfg->current;
00582 }

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

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

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

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 1284 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(), node_lookup(), 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(), rpt_master(), set_config(), setup_zap(), sla_load_config(), smdi_load(), tds_load_module(), and vm_forwardoptions().

01285 {
01286    struct ast_config *cfg;
01287    struct ast_config *result;
01288 
01289    cfg = ast_config_new();
01290    if (!cfg)
01291       return NULL;
01292 
01293    result = ast_config_internal_load(filename, cfg, 0);
01294    if (!result)
01295       ast_config_destroy(cfg);
01296 
01297    return result;
01298 }

struct ast_config* ast_config_load_with_comments ( const char *  filename  ) 

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

01301 {
01302    struct ast_config *cfg;
01303    struct ast_config *result;
01304 
01305    cfg = ast_config_new();
01306    if (!cfg)
01307       return NULL;
01308 
01309    result = ast_config_internal_load(filename, cfg, 1);
01310    if (!result)
01311       ast_config_destroy(cfg);
01312 
01313    return result;
01314 }

struct ast_config* ast_config_new ( void   ) 

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

00421 {
00422    struct ast_config *config;
00423 
00424    if ((config = ast_calloc(1, sizeof(*config))))
00425       config->max_include_level = MAX_INCLUDE_LEVEL;
00426    return config;
00427 }

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

References ast_config::current.

00585 {
00586    /* cast below is just to silence compiler warning about dropping "const" */
00587    cfg->current = (struct ast_category *) cat;
00588 }

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

01317 {
01318    struct ast_config_engine *eng;
01319    char db[256]="";
01320    char table[256]="";
01321    struct ast_variable *res=NULL;
01322    va_list ap;
01323 
01324    va_start(ap, family);
01325    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01326    if (eng && eng->realtime_func) 
01327       res = eng->realtime_func(db, table, ap);
01328    va_end(ap);
01329 
01330    return res;
01331 }

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

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

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

01346 {
01347    struct ast_config_engine *eng;
01348    char db[256]="";
01349    char table[256]="";
01350    struct ast_config *res=NULL;
01351    va_list ap;
01352 
01353    va_start(ap, family);
01354    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01355    if (eng && eng->realtime_multi_func) 
01356       res = eng->realtime_multi_func(db, table, ap);
01357    va_end(ap);
01358 
01359    return res;
01360 }

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

01363 {
01364    struct ast_config_engine *eng;
01365    int res = -1;
01366    char db[256]="";
01367    char table[256]="";
01368    va_list ap;
01369 
01370    va_start(ap, lookup);
01371    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01372    if (eng && eng->update_func) 
01373       res = eng->update_func(db, table, keyfield, lookup, ap);
01374    va_end(ap);
01375 
01376    return res;
01377 }

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(), check_tx_freq(), collect_function_digits(), conf_exec(), database_first_connect(), do_directory(), do_say(), do_scheduler(), 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(), node_lookup(), 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 429 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().

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

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(), 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(), cdr_pgsql_read_config(), directory_exec(), do_directory(), do_reload(), do_scheduler(), festival_exec(), function_macro(), 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(), node_lookup(), 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(), realtime_peer(), reload_config(), reload_followme(), reload_queues(), retreive_memory(), retrieve_astcfgint(), rpt(), rpt_master(), rpt_tele_thread(), set_config(), setup_zap(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), telem_lookup(), update_realtime_members(), 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 478 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().

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

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

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

01047 {
01048    struct ast_config_map *map;
01049 
01050    ast_mutex_lock(&config_lock);
01051 
01052    while (config_maps) {
01053       map = config_maps;
01054       config_maps = config_maps->next;
01055       free(map);
01056    }
01057       
01058    ast_mutex_unlock(&config_lock);
01059 }

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

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

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

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

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

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

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

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

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

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

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

Definition at line 412 of file config.c.

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

Referenced by process_text_line().

00413 {
00414    struct ast_variable *var;
00415 
00416    for (var = base->root; var; var = var->next)
00417       ast_variable_append(new, variable_clone(var));
00418 }

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

References ALLOC_COMMENT(), ast_category_append(), ast_category_destroy(), ast_category_new(), 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().

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

int read_config_maps ( void   ) 

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

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

int register_config_cli ( void   ) 

Definition at line 1417 of file config.c.

References ast_cli_register_multiple(), and cli_config.

Referenced by main().

01418 {
01419    ast_cli_register_multiple(cli_config, sizeof(cli_config) / sizeof(struct ast_cli_entry));
01420    return 0;
01421 }

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 1411 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 1406 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 1402 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 1240 of file config.c.

Referenced by ast_config_internal_load().


Generated on Fri Aug 24 02:24:59 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1