Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:28 2007

Asterisk developer's documentation :: Codename Pineapple


config.c File Reference


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.

#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
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, const 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_variableast_load_realtime_all (const char *family,...)
static struct ast_variableast_load_realtime_helper (const char *family, va_list ap)
ast_configast_load_realtime_multientry (const char *family,...)
 Retrieve realtime configuration.
 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, const char *variable, const 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)
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 *str)
static void CB_ADD_LEN (char *str, int len)
static void CB_INIT (void)
static void CB_RESET (void)
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 *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)
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 char * comment_buffer
static int comment_buffer_size
static struct ast_config_engineconfig_engine_list
static struct ast_config_mapconfig_maps
static char * extconfig_conf = "extconfig.conf"
static char * lline_buffer
static int lline_buffer_size
static char show_config_help []
static struct ast_config_engine text_file_engine


Define Documentation

#define AST_INCLUDE_GLOB   1
 

Definition at line 40 of file config.c.

#define CB_INCR   250
 

Definition at line 78 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 167 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 147 of file config.c.

References ast_calloc, and ast_comment::cmt.

Referenced by process_text_line().

00148 { 
00149    struct ast_comment *x = ast_calloc(1,sizeof(struct ast_comment)+strlen(buffer)+1);
00150    strcpy(x->cmt, buffer);
00151    return x;
00152 }

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

Definition at line 1067 of file config.c.

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

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

void ast_category_append struct ast_config config,
struct ast_category category
 

Definition at line 339 of file config.c.

References config, and ast_category::include_level.

Referenced by config_odbc(), config_pgsql(), handle_updates(), process_text_line(), and realtime_multi_odbc().

00340 {
00341    if (config->last)
00342       config->last->next = category;
00343    else
00344       config->root = category;
00345    category->include_level = config->include_level;
00346    config->last = category;
00347    config->current = category;
00348 }

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 363 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(), gtalk_load_config(), iax_provision_reload(), ind_load_module(), jingle_load_config(), load_config(), load_module(), load_moh_classes(), load_odbc_config(), pbx_load_users(), read_agent_config(), realtime_switch_common(), reload(), reload_config(), set_config(), and setup_zap().

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

int ast_category_delete struct ast_config cfg,
const char *  category
 

Definition at line 528 of file config.c.

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

Referenced by handle_updates().

00529 {
00530    struct ast_category *prev=NULL, *cat;
00531    cat = cfg->root;
00532    while (cat) {
00533       if (cat->name == category) {
00534          ast_variables_destroy(cat->root);
00535          if (prev) {
00536             prev->next = cat->next;
00537             if (cat == cfg->last)
00538                cfg->last = prev;
00539          } else {
00540             cfg->root = cat->next;
00541             if (cat == cfg->last)
00542                cfg->last = NULL;
00543          }
00544          free(cat);
00545          return 0;
00546       }
00547       prev = cat;
00548       cat = cat->next;
00549    }
00550 
00551    prev = NULL;
00552    cat = cfg->root;
00553    while (cat) {
00554       if (!strcasecmp(cat->name, category)) {
00555          ast_variables_destroy(cat->root);
00556          if (prev) {
00557             prev->next = cat->next;
00558             if (cat == cfg->last)
00559                cfg->last = prev;
00560          } else {
00561             cfg->root = cat->next;
00562             if (cat == cfg->last)
00563                cfg->last = NULL;
00564          }
00565          free(cat);
00566          return 0;
00567       }
00568       prev = cat;
00569       cat = cat->next;
00570    }
00571    return -1;
00572 }

void ast_category_destroy struct ast_category cat  ) 
 

Definition at line 350 of file config.c.

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

Referenced by process_text_line(), and realtime_multi_odbc().

00351 {
00352    ast_variables_destroy(cat->root);
00353    free(cat);
00354 }

struct ast_variable* ast_category_detach_variables struct ast_category cat  ) 
 

Definition at line 395 of file config.c.

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

Referenced by realtime_switch_common().

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

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

References ast_category_get(), and config.

00335 {
00336    return !!ast_category_get(config, category_name);
00337 }

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

References category_get(), and config.

Referenced by ast_category_exist(), ast_variable_browse(), handle_updates(), and realtime_switch_common().

00330 {
00331    return category_get(config, category_name, 0);
00332 }

struct ast_category* ast_category_new const char *  name  ) 
 

Definition at line 302 of file config.c.

References ast_calloc.

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

00303 {
00304    struct ast_category *category;
00305 
00306    if ((category = ast_calloc(1, sizeof(*category))))
00307       ast_copy_string(category->name, name, sizeof(category->name));
00308    return category;
00309 }

void ast_category_rename struct ast_category cat,
const char *  name
 

Definition at line 406 of file config.c.

References ast_category::name.

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

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

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

References find_engine().

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

01377 {
01378    struct ast_config_engine *eng;
01379 
01380    eng = find_engine(family, NULL, 0, NULL, 0);
01381    if (eng)
01382       return 1;
01383    return 0;
01384 
01385 }

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

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

Referenced by action_getconfig(), action_updateconfig(), ast_config_load(), ast_config_load_with_comments(), ast_enum_init(), ast_rtp_reload(), ast_udptl_reload(), do_reload(), handle_save_dialplan(), iax_provision_reload(), ind_load_module(), load_config(), load_module(), parse_config(), process_text_line(), read_agent_config(), read_config_maps(), realtime_switch_common(), reload_config(), set_config(), and setup_zap().

00575 {
00576    struct ast_category *cat, *catn;
00577 
00578    if (!cfg)
00579       return;
00580 
00581    cat = cfg->root;
00582    while (cat) {
00583       ast_variables_destroy(cat->root);
00584       catn = cat;
00585       cat = cat->next;
00586       free(catn);
00587    }
00588    free(cfg);
00589 }

int ast_config_engine_deregister struct ast_config_engine del  ) 
 

Deegister config engine.

Definition at line 1189 of file config.c.

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

Referenced by unload_module().

01190 {
01191    struct ast_config_engine *ptr, *last=NULL;
01192 
01193    ast_mutex_lock(&config_lock);
01194 
01195    for (ptr = config_engine_list; ptr; ptr=ptr->next) {
01196       if (ptr == del) {
01197          if (last)
01198             last->next = ptr->next;
01199          else
01200             config_engine_list = ptr->next;
01201          break;
01202       }
01203       last = ptr;
01204    }
01205 
01206    ast_mutex_unlock(&config_lock);
01207 
01208    return 0;
01209 }

int ast_config_engine_register struct ast_config_engine new  ) 
 

Register config engine.

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

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

struct ast_category* ast_config_get_current_category const struct ast_config cfg  ) 
 

Definition at line 591 of file config.c.

References ast_config::current.

Referenced by config_odbc(), and config_text_file_load().

00592 {
00593    return cfg->current;
00594 }

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

Definition at line 1251 of file config.c.

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

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

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

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

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

Referenced by __ast_http_load(), adsi_load(), aji_load_config(), ast_enum_init(), ast_readconfig(), ast_rtp_reload(), ast_udptl_reload(), authenticate(), do_reload(), gtalk_load_config(), handle_save_dialplan(), iax_provision_reload(), ind_load_module(), init_logger_chain(), init_manager(), jingle_load_config(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), parse_config(), pbx_load_config(), pbx_load_users(), read_agent_config(), reload(), reload_config(), set_config(), setup_zap(), and smdi_load().

01289 {
01290    struct ast_config *cfg;
01291    struct ast_config *result;
01292 
01293    cfg = ast_config_new();
01294    if (!cfg)
01295       return NULL;
01296 
01297    result = ast_config_internal_load(filename, cfg, 0);
01298    if (!result)
01299       ast_config_destroy(cfg);
01300 
01301    return result;
01302 }

struct ast_config* ast_config_load_with_comments const char *  filename  ) 
 

Definition at line 1304 of file config.c.

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

Referenced by action_getconfig(), and action_updateconfig().

01305 {
01306    struct ast_config *cfg;
01307    struct ast_config *result;
01308 
01309    cfg = ast_config_new();
01310    if (!cfg)
01311       return NULL;
01312 
01313    result = ast_config_internal_load(filename, cfg, 1);
01314    if (!result)
01315       ast_config_destroy(cfg);
01316 
01317    return result;
01318 }

struct ast_config* ast_config_new void   ) 
 

Definition at line 419 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_odbc(), and realtime_multi_pgsql().

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

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

Definition at line 240 of file config.c.

References ast_variable_retrieve().

Referenced by pbx_load_users().

00241 {
00242    const char *tmp;
00243    tmp = ast_variable_retrieve(cfg, cat, var);
00244    if (!tmp)
00245       tmp = ast_variable_retrieve(cfg, "general", var);
00246    return tmp;
00247 }

void ast_config_set_current_category struct ast_config cfg,
const struct ast_category cat
 

Definition at line 596 of file config.c.

References ast_config::current.

00597 {
00598    /* cast below is just to silence compiler warning about dropping "const" */
00599    cfg->current = (struct ast_category *) cat;
00600 }

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

References ast_load_realtime_helper(), free, and ast_variable::next.

Referenced by realtime_alias(), realtime_peer(), realtime_switch_common(), and realtime_user().

01347 {
01348    struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL;
01349    va_list ap;
01350 
01351    va_start(ap, family);
01352    res = ast_load_realtime_helper(family, ap);
01353    va_end(ap);
01354 
01355    /* Eliminate blank entries */
01356    for (cur = res; cur; cur = cur->next) {
01357       if (freeme) {
01358          free(freeme);
01359          freeme = NULL;
01360       }
01361 
01362       if (ast_strlen_zero(cur->value)) {
01363          if (prev)
01364             prev->next = cur->next;
01365          else
01366             res = cur->next;
01367          freeme = cur;
01368       } else {
01369          prev = cur;
01370       }
01371    }
01372    return res;
01373 }

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

Definition at line 1334 of file config.c.

References ast_load_realtime_helper().

Referenced by cli_realtime_load().

01335 {
01336    struct ast_variable *res;
01337    va_list ap;
01338 
01339    va_start(ap, family);
01340    res = ast_load_realtime_helper(family, ap);
01341    va_end(ap);
01342 
01343    return res;
01344 }

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

Definition at line 1320 of file config.c.

References find_engine(), and ast_config_engine::realtime_func.

Referenced by ast_load_realtime(), and ast_load_realtime_all().

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

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

References find_engine(), and ast_config_engine::realtime_multi_func.

Referenced by realtime_switch_common().

01388 {
01389    struct ast_config_engine *eng;
01390    char db[256]="";
01391    char table[256]="";
01392    struct ast_config *res=NULL;
01393    va_list ap;
01394 
01395    va_start(ap, family);
01396    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01397    if (eng && eng->realtime_multi_func) 
01398       res = eng->realtime_multi_func(db, table, ap);
01399    va_end(ap);
01400 
01401    return res;
01402 }

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

References find_engine(), and ast_config_engine::update_func.

Referenced by cli_realtime_update(), destroy_association(), and realtime_update_peer().

01405 {
01406    struct ast_config_engine *eng;
01407    int res = -1;
01408    char db[256]="";
01409    char table[256]="";
01410    va_list ap;
01411 
01412    va_start(ap, lookup);
01413    eng = find_engine(family, db, sizeof(db), table, sizeof(table));
01414    if (eng && eng->update_func) 
01415       res = eng->update_func(db, table, keyfield, lookup, ap);
01416    va_end(ap);
01417 
01418    return res;
01419 }

void ast_variable_append struct ast_category category,
struct ast_variable variable
 

Definition at line 204 of file config.c.

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

Referenced by config_odbc(), config_pgsql(), handle_updates(), inherit_category(), move_variables(), process_text_line(), realtime_multi_odbc(), and realtime_multi_pgsql().

00205 {
00206    if (!variable)
00207       return;
00208    if (category->last)
00209       category->last->next = variable;
00210    else
00211       category->root = variable;
00212    category->last = variable;
00213    while (category->last->next)
00214       category->last = category->last->next;
00215 }

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 228 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(), gtalk_load_config(), handle_save_dialplan(), iax_template_parse(), ind_load_module(), init_logger_chain(), init_manager(), jingle_load_config(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), pbx_load_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), set_config(), setup_zap(), sip_notify(), smdi_load(), and store_config().

00229 {
00230    struct ast_category *cat = NULL;
00231 
00232    if (category && config->last_browse && (config->last_browse->name == category))
00233       cat = config->last_browse;
00234    else
00235       cat = ast_category_get(config, category);
00236 
00237    return (cat) ? cat->root : NULL;
00238 }

int ast_variable_delete struct ast_category category,
const char *  variable,
const char *  match
 

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

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

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

Definition at line 189 of file config.c.

References ast_calloc, and ast_variable::name.

Referenced by add_var(), apply_outgoing(), ast_channeltype_list(), ast_variable_update(), astman_get_variables(), build_user(), check_access(), check_user_full(), config_odbc(), config_pgsql(), copy_vars(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), process_text_line(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_odbc(), realtime_pgsql(), and variable_clone().

00190 {
00191    struct ast_variable *variable;
00192    int name_len = strlen(name) + 1; 
00193 
00194    if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + sizeof(*variable)))) {
00195       variable->name = variable->stuff;
00196       variable->value = variable->stuff + name_len;      
00197       strcpy(variable->name,name);
00198       strcpy(variable->value,value);
00199    }
00200 
00201    return variable;
00202 }

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

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

Referenced by aji_load_config(), ast_config_option(), ast_rtp_reload(), ast_udptl_reload(), do_reload(), gtalk_load_config(), handle_save_dialplan(), iax_template_parse(), ind_load_module(), init_logger_chain(), jingle_load_config(), parse_config(), pbx_load_config(), pbx_load_users(), read_agent_config(), reload_config(), set_config(), and setup_zap().

00251 {
00252    struct ast_variable *v;
00253 
00254    if (category) {
00255       for (v = ast_variable_browse(config, category); v; v = v->next) {
00256          if (!strcasecmp(variable, v->name))
00257             return v->value;
00258       }
00259    } else {
00260       struct ast_category *cat;
00261 
00262       for (cat = config->root; cat; cat = cat->next)
00263          for (v = cat->root; v; v = v->next)
00264             if (!strcasecmp(variable, v->name))
00265                return v->value;
00266    }
00267 
00268    return NULL;
00269 }

int ast_variable_update struct ast_category category,
const char *  variable,
const char *  value,
const char *  match
 

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

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

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

References free, and ast_variable::next.

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

00218 {
00219    struct ast_variable *vn;
00220 
00221    while (v) {
00222       vn = v;
00223       v = v->next;
00224       free(vn);
00225    }
00226 }

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

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

00312 {
00313    struct ast_category *cat;
00314 
00315    /* try exact match first, then case-insensitive match */
00316    for (cat = config->root; cat; cat = cat->next) {
00317       if (cat->name == category_name && (ignored || !cat->ignored))
00318          return cat;
00319    }
00320 
00321    for (cat = config->root; cat; cat = cat->next) {
00322       if (!strcasecmp(cat->name, category_name) && (ignored || !cat->ignored))
00323          return cat;
00324    }
00325 
00326    return NULL;
00327 }

static void CB_ADD char *  str  )  [static]
 

Definition at line 99 of file config.c.

References ast_realloc, and CB_INCR.

Referenced by config_text_file_load().

00100 {
00101    int rem = comment_buffer_size - strlen(comment_buffer) - 1;
00102    int siz = strlen(str);
00103    if (rem < siz+1) {
00104       comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + siz + 1);
00105       if (!comment_buffer)
00106          return;
00107       comment_buffer_size += CB_INCR+siz+1;
00108    }
00109    strcat(comment_buffer,str);
00110 }

static void CB_ADD_LEN char *  str,
int  len
[static]
 

Definition at line 112 of file config.c.

References ast_realloc, and CB_INCR.

Referenced by config_text_file_load().

00113 {
00114    int cbl = strlen(comment_buffer) + 1;
00115    int rem = comment_buffer_size - cbl;
00116    if (rem < len+1) {
00117       comment_buffer = ast_realloc(comment_buffer, comment_buffer_size + CB_INCR + len + 1);
00118       if (!comment_buffer)
00119          return;
00120       comment_buffer_size += CB_INCR+len+1;
00121    }
00122    strncat(comment_buffer,str,len);
00123    comment_buffer[cbl+len-1] = 0;
00124 }

static void CB_INIT void   )  [static]
 

Definition at line 80 of file config.c.

References ast_malloc, and CB_INCR.

Referenced by config_text_file_load().

00081 {
00082    if (!comment_buffer) {
00083       comment_buffer = ast_malloc(CB_INCR);
00084       if (!comment_buffer)
00085          return;
00086       comment_buffer[0] = 0;
00087       comment_buffer_size = CB_INCR;
00088       lline_buffer = ast_malloc(CB_INCR);
00089       if (!lline_buffer)
00090          return;
00091       lline_buffer[0] = 0;
00092       lline_buffer_size = CB_INCR;
00093    } else {
00094       comment_buffer[0] = 0;
00095       lline_buffer[0] = 0;
00096    }
00097 }

static void CB_RESET void   )  [static]
 

Definition at line 139 of file config.c.

Referenced by process_text_line().

00140 { 
00141    comment_buffer[0] = 0; 
00142    lline_buffer[0] = 0;
00143 }

static void clear_config_maps void   )  [static]
 

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

01053 {
01054    struct ast_config_map *map;
01055 
01056    ast_mutex_lock(&config_lock);
01057 
01058    while (config_maps) {
01059       map = config_maps;
01060       config_maps = config_maps->next;
01061       free(map);
01062    }
01063       
01064    ast_mutex_unlock(&config_lock);
01065 }

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

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

01422 {
01423    struct ast_config_engine *eng;
01424    struct ast_config_map *map;
01425    
01426    ast_mutex_lock(&config_lock);
01427 
01428    ast_cli(fd, "\n\n");
01429    for (eng = config_engine_list; eng; eng = eng->next) {
01430       ast_cli(fd, "\nConfig Engine: %s\n", eng->name);
01431       for (map = config_maps; map; map = map->next)
01432          if (!strcasecmp(map->driver, eng->name)) {
01433             ast_cli(fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
01434                map->table ? map->table : map->name);
01435          }
01436    }
01437    ast_cli(fd,"\n\n");
01438    
01439    ast_mutex_unlock(&config_lock);
01440 
01441    return 0;
01442 }

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 781 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, lineno, LLB_ADD(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, option_debug, option_verbose, process_text_line(), and VERBOSE_PREFIX_2.

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

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

Definition at line 963 of file config.c.

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

Referenced by action_updateconfig().

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

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

References ast_mutex_lock(), config_maps, and map.

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

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

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

Definition at line 411 of file config.c.

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

Referenced by process_text_line().

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

static void LLB_ADD char *  str  )  [static]
 

Definition at line 126 of file config.c.

References ast_realloc, and CB_INCR.

Referenced by config_text_file_load().

00127 {
00128    int rem = lline_buffer_size - strlen(lline_buffer) - 1;
00129    int siz = strlen(str);
00130    if (rem < siz+1) {
00131       lline_buffer = ast_realloc(lline_buffer, lline_buffer_size + CB_INCR + siz + 1);
00132       if (!lline_buffer) 
00133          return;
00134       lline_buffer_size += CB_INCR + siz + 1;
00135    }
00136    strcat(lline_buffer,str);
00137 }

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

Definition at line 285 of file config.c.

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

Referenced by process_text_line().

00286 {
00287    struct ast_variable *var = old->root;
00288    old->root = NULL;
00289 #if 1
00290    /* we can just move the entire list in a single op */
00291    ast_variable_append(new, var);
00292 #else
00293    while (var) {
00294       struct ast_variable *next = var->next;
00295       var->next = NULL;
00296       ast_variable_append(new, var);
00297       var = next;
00298    }
00299 #endif
00300 }

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

Definition at line 356 of file config.c.

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

Referenced by ast_category_browse().

00357 {
00358    for (; cat && cat->ignored; cat = cat->next);
00359 
00360    return cat;
00361 }

static int process_text_line struct ast_config cfg,
struct ast_category **  cat,
char *  buf,
int  lineno,
const char *  configfile,
int  withcomments
[static]
 

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

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

int read_config_maps void   ) 
 

Definition at line 1102 of file config.c.

References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_variable_browse(), clear_config_maps(), config, ast_config::max_include_level, ast_variable::next, strsep(), and ast_variable::value.

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

int register_config_cli void   ) 
 

Definition at line 1454 of file config.c.

References ast_cli_register_multiple(), and cli_config.

01455 {
01456    ast_cli_register_multiple(cli_config, sizeof(cli_config) / sizeof(struct ast_cli_entry));
01457    return 0;
01458 }

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

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

00272 {
00273    struct ast_variable *new = ast_variable_new(old->name, old->value);
00274 
00275    if (new) {
00276       new->lineno = old->lineno;
00277       new->object = old->object;
00278       new->blanklines = old->blanklines;
00279       /* TODO: clone comments? */
00280    }
00281 
00282    return new;
00283 }


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 },
}

Definition at line 1448 of file config.c.

Referenced by register_config_cli().

char* comment_buffer [static]
 

Growable string buffer this will be a comment collector.

Definition at line 66 of file config.c.

int comment_buffer_size [static]
 

the amount of storage so far alloc'd for the comment_buffer

Definition at line 67 of file config.c.

struct ast_config_engine* config_engine_list [static]
 

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

char* lline_buffer [static]
 

A buffer for stuff behind the ;

Definition at line 69 of file config.c.

int lline_buffer_size [static]
 

Definition at line 70 of file config.c.

char show_config_help[] [static]
 

Initial value:

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

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

Referenced by ast_config_internal_load().


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen