Sat Apr 26 2014 22:02:45

Asterisk developer's documentation


config.h File Reference

Configuration File Parser. More...

Include dependency graph for config.h:

Go to the source code of this file.

Data Structures

struct  ast_config_engine
 Configuration engine structure, used to define realtime drivers. More...
struct  ast_variable
 Structure for variables, used for configurations and for channel variables. More...

Defines

#define ast_config_load(filename, flags)   ast_config_load2(filename, AST_MODULE, flags)
 Load a config file.
#define CONFIG_STATUS_FILEINVALID   (void *)-2
#define CONFIG_STATUS_FILEMISSING   (void *)0
#define CONFIG_STATUS_FILEUNCHANGED   (void *)-1
#define CV_BOOL(__x, __dst)   CV_F(__x, (__dst) = ast_true(__val) )
 helper macros to assign the value to a BOOL, UINT, static string and dynamic string
#define CV_DSTR(__x, __dst)   CV_F(__x, ast_free(__dst); __dst = ast_strdup(__val))
#define CV_END   } while (0)
 close a variable parsing block
#define CV_F(__pattern, __body)   if (!strcasecmp((__var), __pattern)) { __body; break; }
 call a generic function if the name matches.
#define CV_START(__in_var, __in_val)
 the macro to open a block for variable parsing
#define CV_STR(__x, __dst)   CV_F(__x, ast_copy_string(__dst, __val, sizeof(__dst)))
#define CV_STRFIELD(__x, __obj, __field)   CV_F(__x, ast_string_field_set(__obj, __field, __val))
#define CV_UINT(__x, __dst)   CV_F(__x, (__dst) = strtoul(__val, NULL, 0) )

Typedefs

typedef int(* config_hook_cb )(struct ast_config *cfg)
typedef struct ast_configconfig_load_func (const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
typedef int realtime_destroy (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
typedef struct ast_configrealtime_multi_get (const char *database, const char *table, va_list ap)
typedef int realtime_require (const char *database, const char *table, va_list ap)
 Function pointer called to ensure database schema is properly configured for realtime use.
typedef int realtime_store (const char *database, const char *table, va_list ap)
typedef int realtime_unload (const char *database, const char *table)
 Function pointer called to clear the database cache and free resources used for such.
typedef int realtime_update (const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)
typedef int realtime_update2 (const char *database, const char *table, va_list ap)
typedef struct ast_variablerealtime_var_get (const char *database, const char *table, va_list ap)

Enumerations

enum  { CONFIG_FLAG_WITHCOMMENTS = (1 << 0), CONFIG_FLAG_FILEUNCHANGED = (1 << 1), CONFIG_FLAG_NOCACHE = (1 << 2), CONFIG_FLAG_NOREALTIME = (1 << 3) }
enum  ast_parse_flags {
  PARSE_TYPE = 0x000f, PARSE_INT32 = 0x0001, PARSE_UINT32 = 0x0002, PARSE_DOUBLE = 0x0003,
  PARSE_ADDR = 0x000e, PARSE_INADDR = 0x000f, PARSE_DEFAULT = 0x0010, PARSE_IN_RANGE = 0x0020,
  PARSE_OUT_RANGE = 0x0040, PARSE_RANGE_DEFAULTS = 0x0080, PARSE_PORT_MASK = 0x0300, PARSE_PORT_IGNORE = 0x0100,
  PARSE_PORT_REQUIRE = 0x0200, PARSE_PORT_FORBID = 0x0300
}
 Support code to parse config file arguments. More...
enum  config_hook_flags { butt }
 Flags that affect the behaviour of config hooks. More...
enum  require_type {
  RQ_INTEGER1, RQ_UINTEGER1, RQ_INTEGER2, RQ_UINTEGER2,
  RQ_INTEGER3, RQ_UINTEGER3, RQ_INTEGER4, RQ_UINTEGER4,
  RQ_INTEGER8, RQ_UINTEGER8, RQ_CHAR, RQ_FLOAT,
  RQ_DATE, RQ_DATETIME
}
 Types used in ast_realtime_require_field. More...

Functions

void ast_category_append (struct ast_config *config, struct ast_category *cat)
char * ast_category_browse (struct ast_config *config, const char *prev)
 Goes through categories.
int ast_category_delete (struct ast_config *cfg, const char *category)
void ast_category_destroy (struct ast_category *cat)
struct ast_variableast_category_detach_variables (struct ast_category *cat)
int ast_category_empty (struct ast_config *cfg, const char *category)
 Removes and destroys all variables within a category.
int ast_category_exist (const struct ast_config *config, const char *category_name)
 Check for category duplicates.
struct ast_variableast_category_first (struct ast_category *cat)
 given a pointer to a category, return the root variable.
struct ast_categoryast_category_get (const struct ast_config *config, const char *category_name)
 Retrieve a category if it exists.
void ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match)
 Inserts new category.
struct ast_categoryast_category_new (const char *name, const char *in_file, int lineno)
 Create a category structure.
void ast_category_rename (struct ast_category *cat, const char *name)
struct ast_variableast_category_root (struct ast_config *config, char *cat)
 returns the root ast_variable of a config
int ast_check_realtime (const char *family)
 Check if realtime engine is configured for family.
struct ast_configast_config_copy (const struct ast_config *orig)
 Copies the contents of one ast_config into another.
void ast_config_destroy (struct ast_config *config)
 Destroys a config.
int ast_config_engine_deregister (struct ast_config_engine *del)
 Deregister config engine.
int ast_config_engine_register (struct ast_config_engine *newconfig)
 Register config engine.
struct ast_categoryast_config_get_current_category (const struct ast_config *cfg)
 Retrieve the current category name being built.
int ast_config_hook_register (const char *name, const char *filename, const char *module, enum config_hook_flags flags, config_hook_cb hook)
 Register a config hook for a particular file and module.
void ast_config_hook_unregister (const char *name)
 Unregister a config hook.
struct ast_configast_config_internal_load (const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
struct ast_configast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags)
 Load a config file.
struct ast_configast_config_new (void)
 Create a new base configuration structure.
const char * ast_config_option (struct ast_config *cfg, const char *cat, const char *var)
 Retrieve a configuration variable within the configuration set.
void ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat)
 Set the category within the configuration as being current.
void ast_config_sort_categories (struct ast_config *config, int descending, int(*comparator)(struct ast_category *p, struct ast_category *q))
 Sorts categories in a config in the order of a numerical value contained within them.
int ast_config_text_file_save (const char *filename, const struct ast_config *cfg, const char *generator)
int ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
 Destroy realtime configuration.
struct ast_config_includeast_include_find (struct ast_config *conf, const char *included_file)
struct ast_config_includeast_include_new (struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
void ast_include_rename (struct ast_config *conf, const char *from_file, const char *to_file)
struct ast_variableast_load_realtime (const char *family,...) attribute_sentinel
 Retrieve realtime configuration.
struct ast_variableast_load_realtime_all (const char *family,...) attribute_sentinel
struct ast_configast_load_realtime_multientry (const char *family,...) attribute_sentinel
 Retrieve realtime configuration.
int ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *result,...)
 The argument parsing routine.
char * ast_realtime_decode_chunk (char *chunk)
 Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values.
int ast_realtime_enabled (void)
 Check if there's any realtime engines loaded.
char * ast_realtime_encode_chunk (struct ast_str **dest, ssize_t maxlen, const char *chunk)
 Encodes a chunk of data for realtime.
int ast_realtime_is_mapping_defined (const char *family)
 Determine if a mapping exists for a given family.
int ast_realtime_require_field (const char *family,...) attribute_sentinel
 Inform realtime what fields that may be stored.
int ast_rq_is_int (require_type type)
 Check if require type is an integer type.
int ast_store_realtime (const char *family,...) attribute_sentinel
 Create realtime configuration.
int ast_unload_realtime (const char *family)
 Release any resources cached for a realtime family.
int ast_update2_realtime (const char *family,...) attribute_sentinel
 Update realtime configuration.
int ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
 Update realtime configuration.
void ast_variable_append (struct ast_category *category, struct ast_variable *variable)
struct ast_variableast_variable_browse (const struct ast_config *config, const char *category)
 Goes through variables.
int ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line)
void ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line)
struct ast_variableast_variable_new (const char *name, const char *value, const char *filename)
const char * ast_variable_retrieve (const struct ast_config *config, const char *category, const char *variable)
 Gets a variable.
int ast_variable_update (struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
 Update variable value within a config.
void ast_variables_destroy (struct ast_variable *var)
 Free variable list.
struct ast_variableast_variables_dup (struct ast_variable *var)
 Duplicate variable list.
int config_text_file_save (const char *filename, const struct ast_config *cfg, const char *generator)
int read_config_maps (void)
 Exposed re-initialization method for core process.
int register_config_cli (void)
 Exposed initialization method for core process.

Detailed Description

Configuration File Parser.

Definition in file config.h.


Define Documentation

#define ast_config_load (   filename,
  flags 
)    ast_config_load2(filename, AST_MODULE, flags)

Load a config file.

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

Create a config structure from a given configuration file.

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

Definition at line 170 of file config.h.

Referenced by aco_process_config(), adsi_load(), advanced_options(), aji_load_config(), ast_plc_reload(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), festival_exec(), find_conf(), forward_message(), gtalk_load_config(), handle_cli_dialplan_save(), jingle_load_config(), load_config(), load_config_meetme(), load_format_config(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), make_email_file(), message_range_and_existence_check(), notify_new_message(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), read_agent_config(), read_password_from_file(), realtime_directory(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), set_config(), setup_dahdi_int(), sla_load_config(), smdi_load(), tds_load_module(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), and vm_msg_snapshot_create().

#define CV_BOOL (   __x,
  __dst 
)    CV_F(__x, (__dst) = ast_true(__val) )

helper macros to assign the value to a BOOL, UINT, static string and dynamic string

Definition at line 809 of file config.h.

Referenced by store_config_core().

#define CV_DSTR (   __x,
  __dst 
)    CV_F(__x, ast_free(__dst); __dst = ast_strdup(__val))

Definition at line 812 of file config.h.

#define CV_END   } while (0)

close a variable parsing block

Definition at line 800 of file config.h.

Referenced by store_config_core(), and store_config_tone_zone().

#define CV_F (   __pattern,
  __body 
)    if (!strcasecmp((__var), __pattern)) { __body; break; }

call a generic function if the name matches.

Definition at line 803 of file config.h.

Referenced by store_config_core(), and store_config_tone_zone().

#define CV_START (   __in_var,
  __in_val 
)
Value:
do {              \
      const char *__var = __in_var; \
      const char *__val = __in_val;

the macro to open a block for variable parsing

Definition at line 794 of file config.h.

Referenced by store_config_core(), and store_config_tone_zone().

#define CV_STR (   __x,
  __dst 
)    CV_F(__x, ast_copy_string(__dst, __val, sizeof(__dst)))

Definition at line 811 of file config.h.

Referenced by store_config_core(), and store_config_tone_zone().

#define CV_STRFIELD (   __x,
  __obj,
  __field 
)    CV_F(__x, ast_string_field_set(__obj, __field, __val))

Definition at line 813 of file config.h.

Referenced by store_config_core().

#define CV_UINT (   __x,
  __dst 
)    CV_F(__x, (__dst) = strtoul(__val, NULL, 0) )

Definition at line 810 of file config.h.

Referenced by store_config_core().


Typedef Documentation

typedef int(* config_hook_cb)(struct ast_config *cfg)

Definition at line 641 of file config.h.

typedef struct ast_config* config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)

Definition at line 100 of file config.h.

typedef int realtime_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)

Definition at line 106 of file config.h.

typedef struct ast_config* realtime_multi_get(const char *database, const char *table, va_list ap)

Definition at line 102 of file config.h.

typedef int realtime_require(const char *database, const char *table, va_list ap)

Function pointer called to ensure database schema is properly configured for realtime use.

Since:
1.6.1

Definition at line 112 of file config.h.

typedef int realtime_store(const char *database, const char *table, va_list ap)

Definition at line 105 of file config.h.

typedef int realtime_unload(const char *database, const char *table)

Function pointer called to clear the database cache and free resources used for such.

Since:
1.6.1

Definition at line 118 of file config.h.

typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap)

Definition at line 103 of file config.h.

typedef int realtime_update2(const char *database, const char *table, va_list ap)

Definition at line 104 of file config.h.

typedef struct ast_variable* realtime_var_get(const char *database, const char *table, va_list ap)

Definition at line 101 of file config.h.


Enumeration Type Documentation

anonymous enum

Options for ast_config_load()

Enumerator:
CONFIG_FLAG_WITHCOMMENTS 

Load the configuration, including comments

CONFIG_FLAG_FILEUNCHANGED 

On a reload, give us a -1 if the file hasn't changed.

CONFIG_FLAG_NOCACHE 

Don't attempt to cache mtime on this config file.

CONFIG_FLAG_NOREALTIME 

Don't attempt to load from realtime (typically called from a realtime driver dependency)

Definition at line 39 of file config.h.

     {
   /*! Load the configuration, including comments */
   CONFIG_FLAG_WITHCOMMENTS  = (1 << 0),
   /*! On a reload, give us a -1 if the file hasn't changed. */
   CONFIG_FLAG_FILEUNCHANGED = (1 << 1),
   /*! Don't attempt to cache mtime on this config file. */
   CONFIG_FLAG_NOCACHE       = (1 << 2),
   /*! Don't attempt to load from realtime (typically called from a realtime driver dependency) */
   CONFIG_FLAG_NOREALTIME    = (1 << 3),
};

Support code to parse config file arguments.

The function ast_parse_arg() provides a generic interface to parse strings (e.g. numbers, network addresses and so on) in a flexible way, e.g. by doing proper error and bound checks, provide default values, and so on. The function (described later) takes a string as an argument, a set of flags to specify the result format and checks to perform, a pointer to the result, and optionally some additional arguments.

Returns:
It returns 0 on success, != 0 otherwise.
Enumerator:
PARSE_TYPE 
PARSE_INT32 
PARSE_UINT32 
PARSE_DOUBLE 
PARSE_ADDR 
PARSE_INADDR 
PARSE_DEFAULT 
PARSE_IN_RANGE 
PARSE_OUT_RANGE 
PARSE_RANGE_DEFAULTS 
PARSE_PORT_MASK 
PARSE_PORT_IGNORE 
PARSE_PORT_REQUIRE 
PARSE_PORT_FORBID 

Definition at line 686 of file config.h.

                     {
   /* low 4 bits of flags are used for the operand type */
   PARSE_TYPE  =  0x000f,
   /* numeric types, with optional default value and bound checks.
    * Additional arguments are passed by value.
    */
   PARSE_INT32 =  0x0001,
   PARSE_UINT32   =  0x0002,
   PARSE_DOUBLE   =  0x0003,
#if 0 /* not supported yet */
   PARSE_INT16 =  0x0004,
   PARSE_UINT16   =  0x0005,
#endif

   /* Returns a struct ast_sockaddr, with optional default value
    * (passed by reference) and port handling (accept, ignore,
    * require, forbid). The format is 'ipaddress[:port]'. IPv6 address
    * literals need square brackets around them if a port is specified.
    */
   PARSE_ADDR  =  0x000e,

   /* Returns a struct sockaddr_in, with optional default value
    * (passed by reference) and port handling (accept, ignore,
    * require, forbid). The format is 'host.name[:port]'
    */
   PARSE_INADDR   =  0x000f,

   /* Other data types can be added as needed */

   /* If PARSE_DEFAULT is set, next argument is a default value
    * which is returned in case of error. The argument is passed
    * by value in case of numeric types, by reference in other cases.
    */
   PARSE_DEFAULT  =  0x0010,  /* assign default on error */

   /* Request a range check, applicable to numbers. Two additional
    * arguments are passed by value, specifying the low-high end of
    * the range (inclusive). An error is returned if the value
    * is outside or inside the range, respectively.
    */
   PARSE_IN_RANGE =       0x0020, /* accept values inside a range */
   PARSE_OUT_RANGE =      0x0040, /* accept values outside a range */
   PARSE_RANGE_DEFAULTS = 0x0080, /* default to range min/max on range error */

   /* Port handling, for ast_sockaddr. accept/ignore/require/forbid
    * port number after the hostname or address.
    */
   PARSE_PORT_MASK = 0x0300, /* 0x000: accept port if present */
   PARSE_PORT_IGNORE =  0x0100, /* 0x100: ignore port if present */
   PARSE_PORT_REQUIRE = 0x0200, /* 0x200: require port number */
   PARSE_PORT_FORBID =  0x0300, /* 0x100: forbid port number */
};

Flags that affect the behaviour of config hooks.

Enumerator:
butt 

Definition at line 631 of file config.h.

                       {
   butt,
};

Types used in ast_realtime_require_field.

Enumerator:
RQ_INTEGER1 
RQ_UINTEGER1 
RQ_INTEGER2 
RQ_UINTEGER2 
RQ_INTEGER3 
RQ_UINTEGER3 
RQ_INTEGER4 
RQ_UINTEGER4 
RQ_INTEGER8 
RQ_UINTEGER8 
RQ_CHAR 
RQ_FLOAT 
RQ_DATE 
RQ_DATETIME 

Definition at line 57 of file config.h.


Function Documentation

char* ast_category_browse ( struct ast_config config,
const char *  prev 
)

Goes through categories.

Parameters:
configWhich config structure you wish to "browse"
prevA pointer to a previous category.

This function is kind of non-intuitive in it's use. To begin, one passes NULL as the second argument. It will return a pointer to the string of the first category in the file. From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards.

Return values:
acategory on success
NULLon failure/no-more-categories

Definition at line 899 of file config.c.

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

Referenced by __init_manager(), __queues_show(), action_getconfig(), action_getconfigjson(), action_listcategories(), actual_load_config(), aji_load_config(), ast_cli_perms_init(), complete_sip_notify(), conf_exec(), config_load(), find_queue_by_name_rt(), find_realtime(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), gtalk_load_config(), iax_provision_reload(), internal_process_ast_config(), jingle_load_config(), load_config(), load_format_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_tech_calendars(), misdn_cfg_init(), named_acl_find_realtime(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), process_config(), queues_data_provider_get(), read_agent_config(), realtime_directory(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), search_directory(), search_directory_sub(), set_config(), set_member_value(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), update_realtime_members(), and vm_change_password().

{
   struct ast_category *cat;

   if (!prev) {
      /* First time browse. */
      cat = config->root;
   } else if (config->last_browse && (config->last_browse->name == prev)) {
      /* Simple last browse found. */
      cat = config->last_browse->next;
   } else {
      /*
       * Config changed since last browse.
       *
       * First try cheap last browse search. (Rebrowsing a different
       * previous category?)
       */
      for (cat = config->root; cat; cat = cat->next) {
         if (cat->name == prev) {
            /* Found it. */
            cat = cat->next;
            break;
         }
      }
      if (!cat) {
         /*
          * Have to do it the hard way. (Last category was deleted and
          * re-added?)
          */
         for (cat = config->root; cat; cat = cat->next) {
            if (!strcasecmp(cat->name, prev)) {
               /* Found it. */
               cat = cat->next;
               break;
            }
         }
      }
   }

   if (cat)
      cat = next_available_category(cat);

   config->last_browse = cat;
   return (cat) ? cat->name : NULL;
}
int ast_category_delete ( struct ast_config cfg,
const char *  category 
)

Definition at line 1065 of file config.c.

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

Referenced by handle_updates().

{
   struct ast_category *prev=NULL, *cat;

   cat = cfg->root;
   while (cat) {
      if (cat->name == category) {
         if (prev) {
            prev->next = cat->next;
            if (cat == cfg->last)
               cfg->last = prev;
         } else {
            cfg->root = cat->next;
            if (cat == cfg->last)
               cfg->last = NULL;
         }
         ast_category_destroy(cat);
         return 0;
      }
      prev = cat;
      cat = cat->next;
   }

   prev = NULL;
   cat = cfg->root;
   while (cat) {
      if (!strcasecmp(cat->name, category)) {
         if (prev) {
            prev->next = cat->next;
            if (cat == cfg->last)
               cfg->last = prev;
         } else {
            cfg->root = cat->next;
            if (cat == cfg->last)
               cfg->last = NULL;
         }
         ast_category_destroy(cat);
         return 0;
      }
      prev = cat;
      cat = cat->next;
   }
   return -1;
}
struct ast_variable* ast_category_detach_variables ( struct ast_category cat) [read]

Definition at line 945 of file config.c.

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

Referenced by realtime_switch_common().

{
   struct ast_variable *v;

   v = cat->root;
   cat->root = NULL;
   cat->last = NULL;

   return v;
}
int ast_category_empty ( struct ast_config cfg,
const char *  category 
)

Removes and destroys all variables within a category.

Return values:
0if the category was found and emptied
-1if the category was not found

Definition at line 1110 of file config.c.

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

Referenced by handle_updates().

{
   struct ast_category *cat;

   for (cat = cfg->root; cat; cat = cat->next) {
      if (!strcasecmp(cat->name, category))
         continue;
      ast_variables_destroy(cat->root);
      cat->root = NULL;
      cat->last = NULL;
      return 0;
   }

   return -1;
}
int ast_category_exist ( const struct ast_config config,
const char *  category_name 
)

Check for category duplicates.

Parameters:
configwhich config to use
category_namename of the category you're looking for

This will search through the categories within a given config file for a match.

Returns:
non-zero if found

Definition at line 689 of file config.c.

References ast_category_get().

{
   return !!ast_category_get(config, category_name);
}
struct ast_variable* ast_category_first ( struct ast_category cat) [read]

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

This is equivalent to ast_variable_browse(), but more efficient if we already have the struct ast_category * (e.g. from ast_category_get())

return the first var of a category

Definition at line 767 of file config.c.

References ast_category::root.

Referenced by acl_order_comparator(), and process_text_line().

{
   return (cat) ? cat->root : NULL;
}
struct ast_category* ast_category_get ( const struct ast_config config,
const char *  category_name 
) [read]

Retrieve a category if it exists.

Parameters:
configwhich config to use
category_namename of the category you're looking for

This will search through the categories within a given config file for a match.

Return values:
pointerto category if found
NULLif not.

Definition at line 684 of file config.c.

References category_get().

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

{
   return category_get(config, category_name, 0);
}
void ast_category_insert ( struct ast_config config,
struct ast_category cat,
const char *  match 
)

Inserts new category.

Parameters:
configwhich config to use
catnewly created category to insert
matchwhich category to insert above

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

Definition at line 705 of file config.c.

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

Referenced by handle_updates().

{
   struct ast_category *cur_category;

   if (!cat || !match)
      return;
   if (!strcasecmp(config->root->name, match)) {
      cat->next = config->root;
      config->root = cat;
      return;
   }
   for (cur_category = config->root; cur_category; cur_category = cur_category->next) {
      if (!strcasecmp(cur_category->next->name, match)) {
         cat->next = cur_category->next;
         cur_category->next = cat;
         break;
      }
   }
}
struct ast_category* ast_category_new ( const char *  name,
const char *  in_file,
int  lineno 
) [read]

Create a category structure.

Definition at line 648 of file config.c.

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

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

{
   struct ast_category *category;

   category = ast_calloc(1, sizeof(*category));
   if (!category) {
      return NULL;
   }
   category->file = ast_strdup(in_file);
   if (!category->file) {
      ast_category_destroy(category);
      return NULL;
   }
   ast_copy_string(category->name, name, sizeof(category->name));
   category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
   return category;
}
void ast_category_rename ( struct ast_category cat,
const char *  name 
)
struct ast_variable* ast_category_root ( struct ast_config config,
char *  cat 
) [read]

returns the root ast_variable of a config

Parameters:
configpointer to an ast_config data structure
catname of the category for which you want the root
Returns:
the category specified

Definition at line 772 of file config.c.

References ast_category_get(), and ast_category::root.

Referenced by get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), and register_realtime_peers_with_callbackextens().

{
   struct ast_category *category = ast_category_get(config, cat);

   if (category)
      return category->root;
   return NULL;
}
int ast_check_realtime ( const char *  family)

Check if realtime engine is configured for family.

Parameters:
familywhich family/config to be checked
Returns:
1 if family is configured in realtime and engine exists

Definition at line 2687 of file config.c.

References ast_realtime_enabled(), and find_engine().

Referenced by __queues_show(), _sip_show_peer(), _sip_show_peers(), ast_named_acl_find(), ast_queue_log(), close_mailbox(), copy_plain_file(), destroy_association(), find_realtime_gw(), handle_response_peerpoke(), handle_voicemail_show_users(), leave_voicemail(), load_module(), load_moh_classes(), local_ast_moh_start(), logger_queue_rt_start(), msg_create_from_file(), realtime_peer(), realtime_update_peer(), register_realtime_peers_with_callbackextens(), rename_file(), set_member_value(), sip_poke_noanswer(), sip_show_settings(), and vm_delete().

{
   struct ast_config_engine *eng;
   if (!ast_realtime_enabled()) {
      return 0;   /* There are no engines at all so fail early */
   }

   eng = find_engine(family, 1, NULL, 0, NULL, 0);
   if (eng)
      return 1;
   return 0;
}
struct ast_config* ast_config_copy ( const struct ast_config orig) [read]

Copies the contents of one ast_config into another.

Note:
This creates a config on the heap. The caller of this must be prepared to free the memory returned.
Parameters:
origthe config to copy
Returns:
The new config on success, NULL on failure.

Definition at line 2524 of file config.c.

References ast_category_append(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_variables_dup(), ast_category::file, ast_category::last, ast_category::lineno, ast_category::name, ast_category::next, ast_category::root, and ast_config::root.

Referenced by config_hook_exec().

{
   struct ast_config *new_config = ast_config_new();
   struct ast_category *cat_iter;

   if (!new_config) {
      return NULL;
   }

   for (cat_iter = old->root; cat_iter; cat_iter = cat_iter->next) {
      struct ast_category *new_cat =
         ast_category_new(cat_iter->name, cat_iter->file, cat_iter->lineno);
      if (!new_cat) {
         goto fail;
      }
      ast_category_append(new_config, new_cat);
      if (cat_iter->root) {
         new_cat->root = ast_variables_dup(cat_iter->root);
         if (!new_cat->root) {
            goto fail;
         }
         new_cat->last = cat_iter->last;
      }
   }

   return new_config;

fail:
   ast_config_destroy(new_config);
   return NULL;
}
void ast_config_destroy ( struct ast_config config)

Destroys a config.

Parameters:
configpointer to config data structure

Free memory associated with a given config

Definition at line 1126 of file config.c.

References ast_category_destroy(), ast_free, ast_includes_destroy(), ast_config::includes, ast_category::next, and ast_config::root.

Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), __queues_show(), _dsp_init(), aco_process_config(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), aji_load_config(), ast_cli_perms_init(), ast_config_copy(), ast_config_load2(), ast_load_realtime_multientry(), ast_plc_reload(), ast_readconfig(), ast_xmldoc_load_documentation(), conf_exec(), config_function_read(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_load_queue_rt_friendly(), find_realtime(), forward_message(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), gtalk_load_config(), handle_cli_dialplan_save(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), jingle_load_config(), load_config(), load_config_meetme(), load_format_config(), load_indications(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), make_email_file(), message_range_and_existence_check(), misdn_cfg_init(), named_acl_find_realtime(), notify_new_message(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queues_data_provider_get(), read_agent_config(), read_config_maps(), read_password_from_file(), realtime_directory(), realtime_multi_handler(), realtime_multi_pgsql(), realtime_sqlite3_multi(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), rtp_reload(), run_startup_commands(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), smdi_load(), tds_load_module(), unload_module(), update_realtime_members(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), vm_msg_snapshot_create(), and write_password_to_file().

{
   struct ast_category *cat, *catn;

   if (!cfg)
      return;

   ast_includes_destroy(cfg->includes);

   cat = cfg->root;
   while (cat) {
      catn = cat;
      cat = cat->next;
      ast_category_destroy(catn);
   }
   ast_free(cfg);
}

Deregister config engine.

Return values:
0Always

Definition at line 2445 of file config.c.

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

Referenced by unload_module().

{
   struct ast_config_engine *ptr, *last=NULL;

   ast_mutex_lock(&config_lock);

   for (ptr = config_engine_list; ptr; ptr=ptr->next) {
      if (ptr == del) {
         if (last)
            last->next = ptr->next;
         else
            config_engine_list = ptr->next;
         break;
      }
      last = ptr;
   }

   ast_mutex_unlock(&config_lock);

   return 0;
}
int ast_config_engine_register ( struct ast_config_engine newconfig)

Register config engine.

Return values:
1Always

Definition at line 2426 of file config.c.

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

Referenced by load_module().

{
   struct ast_config_engine *ptr;

   ast_mutex_lock(&config_lock);

   if (!config_engine_list) {
      config_engine_list = new;
   } else {
      for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
      ptr->next = new;
   }

   ast_mutex_unlock(&config_lock);
   ast_log(LOG_NOTICE,"Registered Config Engine %s\n", new->name);

   return 1;
}
struct ast_category* ast_config_get_current_category ( const struct ast_config cfg) [read]

Retrieve the current category name being built.

API for backend configuration engines while building a configuration set.

Definition at line 1144 of file config.c.

References ast_config::current.

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

{
   return cfg->current;
}
int ast_config_hook_register ( const char *  name,
const char *  filename,
const char *  module,
enum config_hook_flags  flags,
config_hook_cb  hook 
)

Register a config hook for a particular file and module.

Parameters:
nameThe name of the hook you are registering.
filenameThe file whose config you wish to hook into.
moduleThe module that is reloading the config. This can be useful if multiple modules may possibly reload the same file, but you are only interested when a specific module reloads the file
flagsFlags that affect the way hooks work.
hookThe callback to be called when config is loaded. return 0 Success return -1 Unsuccess, also known as UTTER AND COMPLETE FAILURE

Definition at line 3328 of file config.c.

References ao2_alloc, ao2_container_alloc, ao2_link, ast_strdup, cfg_hook::filename, cfg_hook::hook_cb, hook_cmp(), hook_destroy(), hook_hash(), cfg_hook::module, and cfg_hook::name.

{
   struct cfg_hook *hook;
   if (!cfg_hooks && !(cfg_hooks = ao2_container_alloc(17, hook_hash, hook_cmp))) {
      return -1;
   }

   if (!(hook = ao2_alloc(sizeof(*hook), hook_destroy))) {
      return -1;
   }

   hook->hook_cb = hook_cb;
   hook->filename = ast_strdup(filename);
   hook->name = ast_strdup(name);
   hook->module = ast_strdup(module);

   ao2_link(cfg_hooks, hook);
   return 0;
}
void ast_config_hook_unregister ( const char *  name)

Unregister a config hook.

Parameters:
nameThe name of the hook to unregister

Definition at line 3300 of file config.c.

References ao2_find, cfg_hook::name, OBJ_NODATA, OBJ_POINTER, and OBJ_UNLINK.

{
   struct cfg_hook tmp;

   tmp.name = ast_strdupa(name);

   ao2_find(cfg_hooks, &tmp, OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA);
}
struct ast_config* ast_config_internal_load ( const char *  configfile,
struct ast_config cfg,
struct ast_flags  flags,
const char *  suggested_incl_file,
const char *  who_asked 
) [read]

Definition at line 2557 of file config.c.

References ast_log(), ast_test_flag, CONFIG_FLAG_NOREALTIME, config_hook_exec(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, db, find_engine(), ast_config::include_level, ast_config_engine::load_func, LOG_WARNING, ast_config::max_include_level, table, and text_file_engine.

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

{
   char db[256];
   char table[256];
   struct ast_config_engine *loader = &text_file_engine;
   struct ast_config *result;

   /* The config file itself bumps include_level by 1 */
   if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
      ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
      return NULL;
   }

   cfg->include_level++;

   if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) {
      struct ast_config_engine *eng;

      eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));


      if (eng && eng->load_func) {
         loader = eng;
      } else {
         eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
         if (eng && eng->load_func)
            loader = eng;
      }
   }

   result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);

   if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED) {
      result->include_level--;
      config_hook_exec(filename, who_asked, result);
   } else if (result != CONFIG_STATUS_FILEINVALID) {
      cfg->include_level--;
   }

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

Load a config file.

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

Create a config structure from a given configuration file.

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

Definition at line 2599 of file config.c.

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

Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_cli_perms_init(), ast_readconfig(), ast_xmldoc_load_documentation(), do_reload(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), load_config(), load_indications(), load_modules(), misdn_cfg_init(), private_enum_init(), rtp_reload(), run_startup_commands(), and set_config().

{
   struct ast_config *cfg;
   struct ast_config *result;

   cfg = ast_config_new();
   if (!cfg)
      return NULL;

   result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
   if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID)
      ast_config_destroy(cfg);

   return result;
}
const char* ast_config_option ( struct ast_config cfg,
const char *  cat,
const char *  var 
)

Retrieve a configuration variable within the configuration set.

Retrieves the named variable var within category cat of configuration set cfg. If not found, attempts to retrieve the named variable var from within category general.

Returns:
Value of var, or NULL if not found.

Definition at line 589 of file config.c.

References ast_variable_retrieve().

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

{
   const char *tmp;
   tmp = ast_variable_retrieve(cfg, cat, var);
   if (!tmp) {
      tmp = ast_variable_retrieve(cfg, "general", var);
   }
   return tmp;
}
void ast_config_set_current_category ( struct ast_config cfg,
const struct ast_category cat 
)

Set the category within the configuration as being current.

API for backend configuration engines while building a configuration set.

Definition at line 1149 of file config.c.

References ast_config::current.

{
   /* cast below is just to silence compiler warning about dropping "const" */
   cfg->current = (struct ast_category *) cat;
}
void ast_config_sort_categories ( struct ast_config config,
int  descending,
int(*)(struct ast_category *p, struct ast_category *q)  comparator 
)

Sorts categories in a config in the order of a numerical value contained within them.

Parameters:
configThe config structure you wish to sort
variableWhich numerical value you wish to sort by
descendingIf true, we sort highest to lowest instead of lowest to highest

This function will assume a value of 0 for any non-numerical strings and NULL fields.

Definition at line 781 of file config.c.

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

Referenced by named_acl_find_realtime().

{
   /*
    * The contents of this function are adapted from
    * an example of linked list merge sorting
    * copyright 2001 Simon Tatham.
    *
    * Permission is hereby granted, free of charge, to any person
    * obtaining a copy of this software and associated documentation
    * files (the "Software"), to deal in the Software without
    * restriction, including without limitation the rights to use,
    * copy, modify, merge, publish, distribute, sublicense, and/or
    * sell copies of the Software, and to permit persons to whom the
    * Software is furnished to do so, subject to the following
    * conditions:
    *
    * The above copyright notice and this permission notice shall be
    * included in all copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    * NONINFRINGEMENT.  IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
    * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
    * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    * SOFTWARE.
    */

   int insize = 1;
   struct ast_category *p, *q, *e, *tail;
   int nmerges, psize, qsize, i;

   /* If the descending flag was sent, we'll apply inversion to the comparison function's return. */
   if (descending) {
      descending = -1;
   } else {
      descending = 1;
   }

   if (!config->root) {
      return;
   }

   while (1) {
      p = config->root;
      config->root = NULL;
      tail = NULL;

      nmerges = 0; /* count number of merges we do in this pass */

      while (p) {
         nmerges++; /* there exists a merge to be done */

         /* step `insize' places along from p */
         q = p;
         psize = 0;
         for (i = 0; i < insize; i++) {
            psize++;
            q = q->next;
            if (!q) {
               break;
            }
         }

         /* if q hasn't fallen off end, we have two lists to merge */
         qsize = insize;

         /* now we have two lists; merge them */
         while (psize > 0 || (qsize > 0 && q)) {
            /* decide whether next element of merge comes from p or q */
            if (psize == 0) {
               /* p is empty; e must come from q. */
               e = q;
               q = q->next;
               qsize--;
            } else if (qsize == 0 || !q) {
               /* q is empty; e must come from p. */
               e = p; p = p->next; psize--;
            } else if ((comparator(p,q) * descending) <= 0) {
               /* First element of p is lower (or same) e must come from p. */
               e = p;
               p = p->next;
               psize--;
            } else {
               /* First element of q is lower; e must come from q. */
               e = q;
               q = q->next;
               qsize--;
            }

            /* add the next element to the merged list */
            if (tail) {
               tail->next = e;
            } else {
               config->root = e;
            }
            tail = e;
         }

         /* now p has stepped `insize' places along, and q has too */
         p = q;
      }

      tail->next = NULL;

      /* If we have done only one merge, we're finished. */
      if (nmerges <= 1) { /* allow for nmerges==0, the empty list case */
         return;
      }

      /* Otherwise repeat, merging lists twice the size */
      insize *= 2;
   }

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

Definition at line 2040 of file config.c.

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

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

{
   FILE *f;
   char fn[PATH_MAX];
   struct ast_variable *var;
   struct ast_category *cat;
   struct ast_comment *cmt;
   struct ast_config_include *incl;
   int blanklines = 0;
   struct ao2_container *fileset;
   struct inclfile *fi;

   fileset = ao2_container_alloc(1023, hash_string, hashtab_compare_strings);
   if (!fileset) {
      /* Container creation failed. */
      return -1;
   }

   /* reset all the output flags, in case this isn't our first time saving this data */
   for (incl = cfg->includes; incl; incl = incl->next) {
      incl->output = 0;
   }

   /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
      are all truncated to zero bytes and have that nice header*/
   for (incl = cfg->includes; incl; incl = incl->next) {
      if (!incl->exec) { /* leave the execs alone -- we'll write out the #exec directives, but won't zero out the include files or exec files*/
         /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
         fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
         f = fopen(fn, "w");
         if (f) {
            gen_header(f, configfile, fn, generator);
            fclose(f); /* this should zero out the file */
         } else {
            ast_debug(1, "Unable to open for writing: %s\n", fn);
            ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
         }
         if (fi) {
            ao2_ref(fi, -1);
         }
      }
   }

   /* just set fn to absolute ver of configfile */
   fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
   if (
#ifdef __CYGWIN__
      (f = fopen(fn, "w+"))
#else
      (f = fopen(fn, "w"))
#endif
      ) {
      ast_verb(2, "Saving '%s'\n", fn);
      gen_header(f, configfile, fn, generator);
      cat = cfg->root;
      fclose(f);
      if (fi) {
         ao2_ref(fi, -1);
      }

      /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
      /* since each var, cat, and associated comments can come from any file, we have to be
         mobile, and open each file, print, and close it on an entry-by-entry basis */

      while (cat) {
         fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
         f = fopen(fn, "a");
         if (!f) {
            ast_debug(1, "Unable to open for writing: %s\n", fn);
            ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
            if (fi) {
               ao2_ref(fi, -1);
            }
            ao2_ref(fileset, -1);
            return -1;
         }

         /* dump any includes that happen before this category header */
         for (incl=cfg->includes; incl; incl = incl->next) {
            if (strcmp(incl->include_location_file, cat->file) == 0){
               if (cat->lineno > incl->include_location_lineno && !incl->output) {
                  if (incl->exec)
                     fprintf(f,"#exec \"%s\"\n", incl->exec_file);
                  else
                     fprintf(f,"#include \"%s\"\n", incl->included_file);
                  incl->output = 1;
               }
            }
         }

         insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno);
         /* Dump section with any appropriate comment */
         for (cmt = cat->precomments; cmt; cmt=cmt->next) {
            char *cmtp = cmt->cmt;
            while (cmtp && *cmtp == ';' && *(cmtp+1) == '!') {
               char *cmtp2 = strchr(cmtp+1, '\n');
               if (cmtp2)
                  cmtp = cmtp2+1;
               else cmtp = 0;
            }
            if (cmtp)
               fprintf(f,"%s", cmtp);
         }
         fprintf(f, "[%s]", cat->name);
         if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
            fprintf(f, "(");
            if (cat->ignored) {
               fprintf(f, "!");
            }
            if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
               fprintf(f, ",");
            }
            if (!AST_LIST_EMPTY(&cat->template_instances)) {
               struct ast_category_template_instance *x;
               AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
                  fprintf(f,"%s",x->name);
                  if (x != AST_LIST_LAST(&cat->template_instances))
                     fprintf(f,",");
               }
            }
            fprintf(f, ")");
         }
         for(cmt = cat->sameline; cmt; cmt=cmt->next)
         {
            fprintf(f,"%s", cmt->cmt);
         }
         if (!cat->sameline)
            fprintf(f,"\n");
         for (cmt = cat->trailing; cmt; cmt=cmt->next) {
            if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
               fprintf(f,"%s", cmt->cmt);
         }
         fclose(f);
         if (fi) {
            ao2_ref(fi, -1);
         }

         var = cat->root;
         while (var) {
            struct ast_category_template_instance *x;
            int found = 0;
            AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
               struct ast_variable *v;
               for (v = x->inst->root; v; v = v->next) {
                  if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
                     found = 1;
                     break;
                  }
               }
               if (found)
                  break;
            }
            if (found) {
               var = var->next;
               continue;
            }
            fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
            f = fopen(fn, "a");
            if (!f) {
               ast_debug(1, "Unable to open for writing: %s\n", fn);
               ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
               if (fi) {
                  ao2_ref(fi, -1);
               }
               ao2_ref(fileset, -1);
               return -1;
            }

            /* dump any includes that happen before this category header */
            for (incl=cfg->includes; incl; incl = incl->next) {
               if (strcmp(incl->include_location_file, var->file) == 0){
                  if (var->lineno > incl->include_location_lineno && !incl->output) {
                     if (incl->exec)
                        fprintf(f,"#exec \"%s\"\n", incl->exec_file);
                     else
                        fprintf(f,"#include \"%s\"\n", incl->included_file);
                     incl->output = 1;
                  }
               }
            }

            insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
            for (cmt = var->precomments; cmt; cmt=cmt->next) {
               if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
                  fprintf(f,"%s", cmt->cmt);
            }
            if (var->sameline)
               fprintf(f, "%s %s %s  %s", var->name, (var->object ? "=>" : "="), var->value, var->sameline->cmt);
            else
               fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="), var->value);
            for (cmt = var->trailing; cmt; cmt=cmt->next) {
               if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
                  fprintf(f,"%s", cmt->cmt);
            }
            if (var->blanklines) {
               blanklines = var->blanklines;
               while (blanklines--)
                  fprintf(f, "\n");
            }

            fclose(f);
            if (fi) {
               ao2_ref(fi, -1);
            }

            var = var->next;
         }
         cat = cat->next;
      }
      if (!option_debug) {
         ast_verb(2, "Saving '%s': saved\n", fn);
      }
   } else {
      ast_debug(1, "Unable to open for writing: %s\n", fn);
      ast_verb(2, "Unable to write '%s' (%s)\n", fn, strerror(errno));
      if (fi) {
         ao2_ref(fi, -1);
      }
      ao2_ref(fileset, -1);
      return -1;
   }

   /* Now, for files with trailing #include/#exec statements,
      we have to make sure every entry is output */
   for (incl=cfg->includes; incl; incl = incl->next) {
      if (!incl->output) {
         /* open the respective file */
         fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
         f = fopen(fn, "a");
         if (!f) {
            ast_debug(1, "Unable to open for writing: %s\n", fn);
            ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
            if (fi) {
               ao2_ref(fi, -1);
            }
            ao2_ref(fileset, -1);
            return -1;
         }

         /* output the respective include */
         if (incl->exec)
            fprintf(f,"#exec \"%s\"\n", incl->exec_file);
         else
            fprintf(f,"#include \"%s\"\n", incl->included_file);
         fclose(f);
         incl->output = 1;
         if (fi) {
            ao2_ref(fi, -1);
         }
      }
   }
   ao2_ref(fileset, -1); /* this should destroy the hash container */

   return 0;
}
int ast_destroy_realtime ( const char *  family,
const char *  keyfield,
const char *  lookup,
  ... 
)

Destroy realtime configuration.

Parameters:
familywhich family/config to be destroyed
keyfieldwhich field to use as the key
lookupwhich value to look for in the key field to match the entry.

This function is used to destroy an entry in realtime configuration space. Additional params are used as keys.

Returns:
Number of rows affected, or -1 on error.
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 2850 of file config.c.

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

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

{
   struct ast_config_engine *eng;
   int res = -1, i;
   char db[256];
   char table[256];
   va_list ap;

   va_start(ap, lookup);
   for (i = 1; ; i++) {
      if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
         if (eng->destroy_func && !(res = eng->destroy_func(db, table, keyfield, lookup, ap))) {
            break;
         }
      } else {
         break;
      }
   }
   va_end(ap);

   return res;
}
struct ast_config_include* ast_include_find ( struct ast_config conf,
const char *  included_file 
) [read]

Definition at line 471 of file config.c.

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

Referenced by ast_include_new().

{
   struct ast_config_include *x;
   for (x=conf->includes;x;x=x->next) {
      if (strcmp(x->included_file,included_file) == 0)
         return x;
   }
   return 0;
}
struct ast_config_include* ast_include_new ( struct ast_config conf,
const char *  from_file,
const char *  included_file,
int  is_exec,
const char *  exec_file,
int  from_lineno,
char *  real_included_file_name,
int  real_included_file_name_size 
) [read]

Definition at line 331 of file config.c.

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

Referenced by process_text_line().

{
   /* a file should be included ONCE. Otherwise, if one of the instances is changed,
    * then all be changed. -- how do we know to include it? -- Handling modified
    * instances is possible, I'd have
    * to create a new master for each instance. */
   struct ast_config_include *inc;
   struct stat statbuf;

   inc = ast_include_find(conf, included_file);
   if (inc) {
      do {
         inc->inclusion_count++;
         snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
      } while (stat(real_included_file_name, &statbuf) == 0);
      ast_log(LOG_WARNING,"'%s', line %d:  Same File included more than once! This data will be saved in %s if saved back to disk.\n", from_file, from_lineno, real_included_file_name);
   } else
      *real_included_file_name = 0;

   inc = ast_calloc(1,sizeof(struct ast_config_include));
   if (!inc) {
      return NULL;
   }
   inc->include_location_file = ast_strdup(from_file);
   inc->include_location_lineno = from_lineno;
   if (!ast_strlen_zero(real_included_file_name))
      inc->included_file = ast_strdup(real_included_file_name);
   else
      inc->included_file = ast_strdup(included_file);

   inc->exec = is_exec;
   if (is_exec)
      inc->exec_file = ast_strdup(exec_file);

   if (!inc->include_location_file
      || !inc->included_file
      || (is_exec && !inc->exec_file)) {
      ast_includes_destroy(inc);
      return NULL;
   }

   /* attach this new struct to the conf struct */
   inc->next = conf->includes;
   conf->includes = inc;

   return inc;
}
void ast_include_rename ( struct ast_config conf,
const char *  from_file,
const char *  to_file 
)

Definition at line 379 of file config.c.

References ast_free, ast_strdup, ast_variable_destroy(), ast_variable_move(), ast_variable_new(), ast_variable::file, ast_category::file, ast_config_include::include_location_file, ast_config::includes, ast_category::last, ast_variable::name, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, ast_config::root, str, and ast_variable::value.

Referenced by action_updateconfig().

{
   struct ast_config_include *incl;
   struct ast_category *cat;
   char *str;

   int from_len = strlen(from_file);
   int to_len = strlen(to_file);

   if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
      return;

   /* the manager code allows you to read in one config file, then
    * write it back out under a different name. But, the new arrangement
    * ties output lines to the file name. So, before you try to write
    * the config file to disk, better riffle thru the data and make sure
    * the file names are changed.
    */
   /* file names are on categories, includes (of course), and on variables. So,
    * traverse all this and swap names */

   for (incl = conf->includes; incl; incl=incl->next) {
      if (strcmp(incl->include_location_file,from_file) == 0) {
         if (from_len >= to_len)
            strcpy(incl->include_location_file, to_file);
         else {
            /* Keep the old filename if the allocation fails. */
            str = ast_strdup(to_file);
            if (str) {
               ast_free(incl->include_location_file);
               incl->include_location_file = str;
            }
         }
      }
   }
   for (cat = conf->root; cat; cat = cat->next) {
      struct ast_variable **prev;
      struct ast_variable *v;
      struct ast_variable *new_var;

      if (strcmp(cat->file,from_file) == 0) {
         if (from_len >= to_len)
            strcpy(cat->file, to_file);
         else {
            /* Keep the old filename if the allocation fails. */
            str = ast_strdup(to_file);
            if (str) {
               ast_free(cat->file);
               cat->file = str;
            }
         }
      }
      for (prev = &cat->root, v = cat->root; v; prev = &v->next, v = v->next) {
         if (strcmp(v->file, from_file)) {
            continue;
         }

         /*
          * Calculate actual space available.  The file string is
          * intentionally stuffed before the name string just so we can
          * do this.
          */
         if (to_len < v->name - v->file) {
            /* The new name will fit in the available space. */
            str = (char *) v->file;/* Stupid compiler complains about discarding qualifiers even though I used a cast. */
            strcpy(str, to_file);/* SAFE */
            continue;
         }

         /* Keep the old filename if the allocation fails. */
         new_var = ast_variable_new(v->name, v->value, to_file);
         if (!new_var) {
            continue;
         }

         /* Move items from the old list node to the replacement node. */
         ast_variable_move(new_var, v);

         /* Replace the old node in the list with the new node. */
         new_var->next = v->next;
         if (cat->last == v) {
            cat->last = new_var;
         }
         *prev = new_var;

         ast_variable_destroy(v);

         v = new_var;
      }
   }
}
struct ast_variable* ast_load_realtime ( const char *  family,
  ... 
) [read]

Retrieve realtime configuration.

Parameters:
familywhich family/config to lookup

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

Note:
Unlike the variables in ast_config, the resulting list of variables MUST be freed with ast_variables_destroy() as there is no container.
The difference between these two calls is that ast_load_realtime excludes fields whose values are NULL, while ast_load_realtime_all loads all columns.
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 2648 of file config.c.

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

Referenced by conf_run(), copy_plain_file(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_realtime_gw(), find_user_realtime(), leave_queue(), local_ast_moh_start(), queue_function_queuewaitingcount(), realtime_alias(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_switch_common(), realtime_user(), and rt_extend_conf().

{
   struct ast_variable *res;
   struct ast_variable *cur;
   struct ast_variable **prev;
   va_list ap;

   va_start(ap, family);
   res = ast_load_realtime_helper(family, ap);
   va_end(ap);

   /* Filter the list. */
   prev = &res;
   cur = res;
   while (cur) {
      if (ast_strlen_zero(cur->value)) {
         /* Eliminate empty entries */
         struct ast_variable *next;

         next = cur->next;
         *prev = next;
         ast_variable_destroy(cur);
         cur = next;
      } else {
         /* Make blank entries empty and keep them. */
         if (cur->value[0] == ' ' && cur->value[1] == '\0') {
            char *vptr = (char *) cur->value;

            vptr[0] = '\0';
         }

         prev = &cur->next;
         cur = cur->next;
      }
   }
   return res;
}
struct ast_variable* ast_load_realtime_all ( const char *  family,
  ... 
) [read]

Definition at line 2636 of file config.c.

References ast_load_realtime_helper().

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

{
   struct ast_variable *res;
   va_list ap;

   va_start(ap, family);
   res = ast_load_realtime_helper(family, ap);
   va_end(ap);

   return res;
}
struct ast_config* ast_load_realtime_multientry ( const char *  family,
  ... 
) [read]

Retrieve realtime configuration.

Parameters:
familywhich family/config to lookup

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

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

Definition at line 2750 of file config.c.

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

Referenced by __queues_show(), conf_exec(), find_load_queue_rt_friendly(), find_realtime(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), load_module(), named_acl_find_realtime(), queues_data_provider_get(), realtime_directory(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), set_member_value(), show_users_realtime(), and update_realtime_members().

{
   struct ast_config_engine *eng;
   char db[256];
   char table[256];
   struct ast_config *res = NULL;
   va_list ap;
   int i;

   va_start(ap, family);
   for (i = 1; ; i++) {
      if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
         if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, ap))) {
            /* If we were returned an empty cfg, destroy it and return NULL */
            if (!res->root) {
               ast_config_destroy(res);
               res = NULL;
            }
            break;
         }
      } else {
         break;
      }
   }
   va_end(ap);

   return res;
}
int ast_parse_arg ( const char *  arg,
enum ast_parse_flags  flags,
void *  p_result,
  ... 
)

The argument parsing routine.

Parameters:
argthe string to parse. It is not modified.
flagscombination of ast_parse_flags to specify the return type and additional checks.
resultpointer to the result. NULL is valid here, and can be used to perform only the validity checks.
...extra arguments are required according to flags.
Return values:
0in case of success, != 0 otherwise.
resultreturns the parsed value in case of success, the default value in case of error, or it is left unchanged in case of error and no default specified. Note that in certain cases (e.g. sockaddr_in, with multi-field return values) some of the fields in result may be changed even if an error occurs.

Examples of use: ast_parse_arg("223", PARSE_INT32|PARSE_IN_RANGE, &a, -1000, 1000); returns 0, a = 223 ast_parse_arg("22345", PARSE_INT32|PARSE_IN_RANGE|PARSE_DEFAULT, &a, 9999, 10, 100); returns 1, a = 9999 ast_parse_arg("22345ssf", PARSE_UINT32|PARSE_IN_RANGE, &b, 10, 100); returns 1, b unchanged ast_parse_arg("12", PARSE_UINT32|PARSE_IN_RANGE|PARSE_RANGE_DEFAULTS, &a, 1, 10); returns 1, a = 10 ast_parse_arg("www.foo.biz:44", PARSE_INADDR, &sa); returns 0, sa contains address and port ast_parse_arg("www.foo.biz", PARSE_INADDR|PARSE_PORT_REQUIRE, &sa); returns 1 because port is missing, sa contains address

Definition at line 2905 of file config.c.

References ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_skip_blanks(), ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_strlen_zero(), errno, hp, INT32_MAX, INT32_MIN, PARSE_ADDR, PARSE_DEFAULT, PARSE_DOUBLE, PARSE_IN_RANGE, PARSE_INADDR, PARSE_INT32, PARSE_OUT_RANGE, PARSE_PORT_FORBID, PARSE_PORT_IGNORE, PARSE_PORT_MASK, PARSE_PORT_REQUIRE, PARSE_RANGE_DEFAULTS, PARSE_TYPE, PARSE_UINT32, and UINT32_MAX.

Referenced by __ast_http_load(), __init_manager(), app_exec(), ast_tls_read_conf(), double_handler_fn(), gtalk_load_config(), int_handler_fn(), reload_config(), rtp_reload(), sockaddr_handler_fn(), and uint_handler_fn().

{
   va_list ap;
   int error = 0;

   va_start(ap, p_result);
   switch (flags & PARSE_TYPE) {
   case PARSE_INT32:
   {
      long int x = 0;
      int32_t *result = p_result;
      int32_t def = result ? *result : 0, high = INT32_MAX, low = INT32_MIN;
      char *endptr = NULL;

      /* optional arguments: default value and/or (low, high) */
      if (flags & PARSE_DEFAULT) {
         def = va_arg(ap, int32_t);
      }
      if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
         low = va_arg(ap, int32_t);
         high = va_arg(ap, int32_t);
      }
      if (ast_strlen_zero(arg)) {
         error = 1;
         goto int32_done;
      }
      errno = 0;
      x = strtol(arg, &endptr, 0);
      if (*endptr || errno || x < INT32_MIN || x > INT32_MAX) {
         /* Parse error, or type out of int32_t bounds */
         error = 1;
         goto int32_done;
      }
      error = (x < low) || (x > high);
      if (flags & PARSE_RANGE_DEFAULTS) {
         if (x < low) {
            def = low;
         } else if (x > high) {
            def = high;
         }
      }
      if (flags & PARSE_OUT_RANGE) {
         error = !error;
      }
int32_done:
      if (result) {
         *result  = error ? def : x;
      }

      ast_debug(3, "extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
            arg, low, high, result ? *result : x, error);
      break;
   }

   case PARSE_UINT32:
   {
      unsigned long int x = 0;
      uint32_t *result = p_result;
      uint32_t def = result ? *result : 0, low = 0, high = UINT32_MAX;
      char *endptr = NULL;

      /* optional argument: first default value, then range */
      if (flags & PARSE_DEFAULT) {
         def = va_arg(ap, uint32_t);
      }
      if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
         /* range requested, update bounds */
         low = va_arg(ap, uint32_t);
         high = va_arg(ap, uint32_t);
      }

      if (ast_strlen_zero(arg)) {
         error = 1;
         goto uint32_done;
      }
      /* strtoul will happilly and silently negate negative numbers */
      arg = ast_skip_blanks(arg);
      if (*arg == '-') {
         error = 1;
         goto uint32_done;
      }
      errno = 0;
      x = strtoul(arg, &endptr, 0);
      if (*endptr || errno || x > UINT32_MAX) {
         error = 1;
         goto uint32_done;
      }
      error = (x < low) || (x > high);
      if (flags & PARSE_RANGE_DEFAULTS) {
         if (x < low) {
            def = low;
         } else if (x > high) {
            def = high;
         }
      }
      if (flags & PARSE_OUT_RANGE) {
         error = !error;
      }
uint32_done:
      if (result) {
         *result  = error ? def : x;
      }
      ast_debug(3, "extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
            arg, low, high, result ? *result : x, error);
      break;
   }

   case PARSE_DOUBLE:
   {
      double *result = p_result;
      double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
      char *endptr = NULL;

      /* optional argument: first default value, then range */
      if (flags & PARSE_DEFAULT) {
         def = va_arg(ap, double);
      }
      if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
         /* range requested, update bounds */
         low = va_arg(ap, double);
         high = va_arg(ap, double);
      }
      if (ast_strlen_zero(arg)) {
         error = 1;
         goto double_done;
      }
      errno = 0;
      x = strtod(arg, &endptr);
      if (*endptr || errno == ERANGE) {
         error = 1;
         goto double_done;
      }
      error = (x < low) || (x > high);
      if (flags & PARSE_OUT_RANGE) {
         error = !error;
      }
double_done:
      if (result) {
         *result = error ? def : x;
      }
      ast_debug(3, "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
            arg, low, high, result ? *result : x, error);
      break;
   }
   case PARSE_ADDR:
       {
      struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result;

      if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) {
         error = 1;
      }

      ast_debug(3, "extract addr from %s gives %s(%d)\n",
           arg, ast_sockaddr_stringify(addr), error);

      break;
       }
   case PARSE_INADDR:   /* TODO Remove this (use PARSE_ADDR instead). */
       {
      char *port, *buf;
      struct sockaddr_in _sa_buf;   /* buffer for the result */
      struct sockaddr_in *sa = p_result ?
         (struct sockaddr_in *)p_result : &_sa_buf;
      /* default is either the supplied value or the result itself */
      struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
         va_arg(ap, struct sockaddr_in *) : sa;
      struct hostent *hp;
      struct ast_hostent ahp;

      memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
      /* duplicate the string to strip away the :port */
      port = ast_strdupa(arg);
      buf = strsep(&port, ":");
      sa->sin_family = AF_INET;  /* assign family */
      /*
       * honor the ports flag setting, assign default value
       * in case of errors or field unset.
       */
      flags &= PARSE_PORT_MASK; /* the only flags left to process */
      if (port) {
         if (flags == PARSE_PORT_FORBID) {
            error = 1;  /* port was forbidden */
            sa->sin_port = def->sin_port;
         } else if (flags == PARSE_PORT_IGNORE)
            sa->sin_port = def->sin_port;
         else /* accept or require */
            sa->sin_port = htons(strtol(port, NULL, 0));
      } else {
         sa->sin_port = def->sin_port;
         if (flags == PARSE_PORT_REQUIRE)
            error = 1;
      }
      /* Now deal with host part, even if we have errors before. */
      hp = ast_gethostbyname(buf, &ahp);
      if (hp)  /* resolved successfully */
         memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
      else {
         error = 1;
         sa->sin_addr = def->sin_addr;
      }
      ast_debug(3,
         "extract inaddr from [%s] gives [%s:%d](%d)\n",
         arg, ast_inet_ntoa(sa->sin_addr),
         ntohs(sa->sin_port), error);
      break;
       }
   }
   va_end(ap);
   return error;
}
char* ast_realtime_decode_chunk ( char *  chunk)

Remove standard encoding from realtime values, which ensures that a semicolon embedded within a single value is not treated upon retrieval as multiple values.

Parameters:
chunkData to be decoded
Returns:
The decoded data, in the original buffer
Since:
1.8 This function modifies the original buffer

Definition at line 2873 of file config.c.

Referenced by realtime_multi_pgsql(), and realtime_pgsql().

{
   char *orig = chunk;
   for (; *chunk; chunk++) {
      if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
         sscanf(chunk + 1, "%02hhX", chunk);
         memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
      }
   }
   return orig;
}
int ast_realtime_enabled ( void  )

Check if there's any realtime engines loaded.

Definition at line 2701 of file config.c.

References config_maps.

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

{
   return config_maps ? 1 : 0;
}
char* ast_realtime_encode_chunk ( struct ast_str **  dest,
ssize_t  maxlen,
const char *  chunk 
)

Encodes a chunk of data for realtime.

Parameters:
destDestination buffer
maxlenLength passed through to ast_str_* functions
chunkSource data to be encoded
Returns:
Buffer within dest
Since:
1.8

Definition at line 2885 of file config.c.

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

{
   if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
      ast_str_set(dest, maxlen, "%s", chunk);
   } else {
      ast_str_reset(*dest);
      for (; *chunk; chunk++) {
         if (strchr(";^", *chunk)) {
            ast_str_append(dest, maxlen, "^%02hhX", *chunk);
         } else {
            ast_str_append(dest, maxlen, "%c", *chunk);
         }
      }
   }
   return ast_str_buffer(*dest);
}
int ast_realtime_is_mapping_defined ( const char *  family)

Determine if a mapping exists for a given family.

Parameters:
familywhich family you are looking to see if a mapping exists for
Return values:
1if it is mapped
0if it is not

Definition at line 2467 of file config.c.

References ast_mutex_lock, ast_mutex_unlock, config_lock, config_maps, map, ast_config_map::name, and ast_config_map::next.

Referenced by ast_named_acl_find().

{
   struct ast_config_map *map;
   ast_mutex_lock(&config_lock);

   for (map = config_maps; map; map = map->next) {
      if (!strcasecmp(family, map->name)) {
         ast_mutex_unlock(&config_lock);
         return 1;
      }
   }

   ast_mutex_unlock(&config_lock);

   return 0;
}
int ast_realtime_require_field ( const char *  family,
  ... 
)

Inform realtime what fields that may be stored.

Since:
1.6.1
Parameters:
familywhich family/config is referenced

This will inform builtin configuration backends that particular fields may be updated during the use of that configuration section. This is mainly to be used during startup routines, to ensure that various fields exist in the backend. The backends may take various actions, such as creating new fields in the data store or warning the administrator that new fields may need to be created, in order to ensure proper function.

The arguments are specified in groups of 3: column name, column type, and column size. The column types are specified as integer constants, defined by the enum require_type. Note that the size is specified as the number of equivalent character fields that a field may take up, even if a field is otherwise specified as an integer type. This is due to the fact that some fields have historically been specified as character types, even if they contained integer values.

A family should always specify its fields to the minimum necessary requirements to fulfill all possible values (within reason; for example, a timeout value may reasonably be specified as an INTEGER2, with size 5. Even though values above 32767 seconds are possible, they are unlikely to be useful, and we should not complain about that size).

Return values:
0Required fields met specified standards
-1One or more fields was missing or insufficient
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 2706 of file config.c.

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

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

{
   struct ast_config_engine *eng;
   char db[256];
   char table[256];
   va_list ap;
   int res = -1, i;

   va_start(ap, family);
   for (i = 1; ; i++) {
      if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
         /* If the require succeeds, it returns 0. */
         if (eng->require_func && !(res = eng->require_func(db, table, ap))) {
            break;
         }
      } else {
         break;
      }
   }
   va_end(ap);

   return res;
}
int ast_rq_is_int ( require_type  type) [inline]

Check if require type is an integer type.

Definition at line 835 of file config.h.

Referenced by realtime_require_handler(), require_odbc(), and require_pgsql().

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

Create realtime configuration.

Parameters:
familywhich family/config to be created

This function is used to create a parameter in realtime configuration space.

Returns:
Number of rows affected, or -1 on error.
Note:
On the MySQL engine only, for reasons of backwards compatibility, the return value is the insert ID. This value is nonportable and may be changed in a future version to match the other engines.
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 2826 of file config.c.

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

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

{
   struct ast_config_engine *eng;
   int res = -1, i;
   char db[256];
   char table[256];
   va_list ap;

   va_start(ap, family);
   for (i = 1; ; i++) {
      if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
         /* If the store succeeds, it returns 0. */
         if (eng->store_func && !(res = eng->store_func(db, table, ap))) {
            break;
         }
      } else {
         break;
      }
   }
   va_end(ap);

   return res;
}
int ast_unload_realtime ( const char *  family)

Release any resources cached for a realtime family.

Since:
1.6.1
Parameters:
familywhich family/config to destroy

Various backends may cache attributes about a realtime data storage facility; on reload, a front end resource may request to purge that cache.

Return values:
0If any cache was purged
-1If no cache was found

Definition at line 2730 of file config.c.

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

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

{
   struct ast_config_engine *eng;
   char db[256];
   char table[256];
   int res = -1, i;

   for (i = 1; ; i++) {
      if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
         if (eng->unload_func) {
            /* Do this for ALL engines */
            res = eng->unload_func(db, table);
         }
      } else {
         break;
      }
   }
   return res;
}
int ast_update2_realtime ( const char *  family,
  ... 
)

Update realtime configuration.

Parameters:
familywhich family/config to be updated

This function is used to update a parameter in realtime configuration space. It includes the ability to lookup a row based upon multiple key criteria. As a result, this function includes two sentinel values, one to terminate lookup values and the other to terminate the listing of fields to update.

Returns:
Number of rows affected, or -1 on error.
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 2803 of file config.c.

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

Referenced by change_password_realtime(), and cli_realtime_update2().

{
   struct ast_config_engine *eng;
   int res = -1, i;
   char db[256];
   char table[256];
   va_list ap;

   va_start(ap, family);
   for (i = 1; ; i++) {
      if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
         if (eng->update2_func && !(res = eng->update2_func(db, table, ap))) {
            break;
         }
      } else {
         break;
      }
   }
   va_end(ap);

   return res;
}
int ast_update_realtime ( const char *  family,
const char *  keyfield,
const char *  lookup,
  ... 
)

Update realtime configuration.

Parameters:
familywhich family/config to be updated
keyfieldwhich field to use as the key
lookupwhich value to look for in the key field to match the entry.

This function is used to update a parameter in realtime configuration space.

Returns:
Number of rows affected, or -1 on error.
Note:
You should use the constant SENTINEL to terminate arguments, in order to preserve cross-platform compatibility.

Definition at line 2779 of file config.c.

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

Referenced by cli_realtime_update(), conf_run(), destroy_association(), function_realtime_write(), handle_response_peerpoke(), leave_voicemail(), realtime_update_peer(), rename_file(), rt_extend_conf(), sip_poke_noanswer(), and update_realtime_member_field().

{
   struct ast_config_engine *eng;
   int res = -1, i;
   char db[256];
   char table[256];
   va_list ap;

   va_start(ap, lookup);
   for (i = 1; ; i++) {
      if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
         /* If the update succeeds, it returns 0. */
         if (eng->update_func && !(res = eng->update_func(db, table, keyfield, lookup, ap))) {
            break;
         }
      } else {
         break;
      }
   }
   va_end(ap);

   return res;
}
struct ast_variable* ast_variable_browse ( const struct ast_config config,
const char *  category 
) [read]

Goes through variables.

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

Return values:
ast_variablelist on success
NULLon failure

Definition at line 572 of file config.c.

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

Referenced by __ast_http_load(), __ast_http_post_load(), __init_manager(), _dsp_init(), aco_process_category_options(), action_getconfig(), action_getconfigjson(), actual_load_config(), adsi_load(), aji_load_config(), ast_cli_perms_init(), ast_plc_reload(), ast_readconfig(), ast_variable_retrieve(), ast_xmldoc_load_documentation(), build_calendar(), build_device(), caldav_load_calendar(), conf_exec(), config_load(), config_module(), do_reload(), do_say(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), jingle_load_config(), load_config(), load_format_config(), load_general_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), misdn_cfg_init(), new_realtime_sqlite3_db(), odbc_load_module(), osp_create_provider(), parse_config(), parse_tone_zone(), pbx_load_config(), process_config(), read_agent_config(), read_config_maps(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_single_queue(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), and tds_load_module().

{
   struct ast_category *cat = NULL;

   if (!category) {
      return NULL;
   }

   if (config->last_browse && (config->last_browse->name == category)) {
      cat = config->last_browse;
   } else {
      cat = ast_category_get(config, category);
   }

   return (cat) ? cat->root : NULL;
}
int ast_variable_delete ( struct ast_category category,
const char *  variable,
const char *  match,
const char *  line 
)

Definition at line 986 of file config.c.

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

Referenced by handle_updates().

{
   struct ast_variable *cur, *prev=NULL, *curn;
   int res = -1;
   int num_item = 0;
   int req_item;

   req_item = -1;
   if (!ast_strlen_zero(line)) {
      /* Requesting to delete by item number. */
      if (sscanf(line, "%30d", &req_item) != 1
         || req_item < 0) {
         /* Invalid item number to delete. */
         return -1;
      }
   }

   prev = NULL;
   cur = category->root;
   while (cur) {
      curn = cur->next;
      /* Delete by item number or by variable name with optional value. */
      if ((0 <= req_item && num_item == req_item)
         || (req_item < 0 && !strcasecmp(cur->name, variable)
            && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
         if (prev) {
            prev->next = cur->next;
            if (cur == category->last)
               category->last = prev;
         } else {
            category->root = cur->next;
            if (cur == category->last)
               category->last = NULL;
         }
         ast_variable_destroy(cur);
         res = 0;
      } else
         prev = cur;

      cur = curn;
      ++num_item;
   }
   return res;
}
void ast_variable_insert ( struct ast_category category,
struct ast_variable variable,
const char *  line 
)

Definition at line 495 of file config.c.

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

Referenced by handle_updates().

{
   struct ast_variable *cur = category->root;
   int lineno;
   int insertline;

   if (!variable || sscanf(line, "%30d", &insertline) != 1) {
      return;
   }
   if (!insertline) {
      variable->next = category->root;
      category->root = variable;
   } else {
      for (lineno = 1; lineno < insertline; lineno++) {
         cur = cur->next;
         if (!cur->next) {
            break;
         }
      }
      variable->next = cur->next;
      cur->next = variable;
   }
}
struct ast_variable* ast_variable_new ( const char *  name,
const char *  value,
const char *  filename 
) [read]

Definition at line 277 of file config.c.

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

Referenced by __init_manager(), aco_set_defaults(), add_cfg_entry(), add_message_id(), add_rt_cfg_entry(), add_rt_multi_cfg_entry(), add_var(), append_row_to_cfg(), apply_outgoing(), ast_channeltype_list(), ast_http_get_post_vars(), ast_include_rename(), ast_variable_update(), ast_variables_dup(), build_calendar(), build_user(), check_access(), config_curl(), config_ldap(), config_odbc(), config_pgsql(), copy_vars(), create_vmaccount(), dup_vars(), handle_updates(), handle_uri(), httpd_helper_thread(), iax_parse_ies(), ldap_table_config_add_attribute(), man_do_variable_value(), manager_sipnotify(), mkintf(), parkandannounce_exec(), parse_cookies(), process_dahdi(), process_text_line(), realtime_curl(), realtime_directory(), realtime_ldap_entry_to_var(), realtime_ldap_result_to_vars(), realtime_multi_curl(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_odbc(), realtime_pgsql(), row_to_varlist(), sip_cli_notify(), static_realtime_cb(), variable_clone(), vm_change_password(), and write_password_to_file().

{
   struct ast_variable *variable;
   int name_len = strlen(name) + 1;
   int val_len = strlen(value) + 1;
   int fn_len = strlen(filename) + 1;

   /* Ensure a minimum length in case the filename is changed later. */
   if (fn_len < MIN_VARIABLE_FNAME_SPACE) {
      fn_len = MIN_VARIABLE_FNAME_SPACE;
   }

   if (
#ifdef MALLOC_DEBUG
      (variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable), file, lineno, func))
#else
      (variable = ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable)))
#endif
      ) {
      char *dst = variable->stuff;  /* writable space starts here */

      /* Put file first so ast_include_rename() can calculate space available. */
      variable->file = strcpy(dst, filename);
      dst += fn_len;
      variable->name = strcpy(dst, name);
      dst += name_len;
      variable->value = strcpy(dst, value);
   }
   return variable;
}
const char* ast_variable_retrieve ( const struct ast_config config,
const char *  category,
const char *  variable 
)

Gets a variable.

Parameters:
configwhich (opened) config to use
categorycategory under which the variable lies
variablewhich variable you wish to get the data for

Goes through a given config file in the given category and searches for the given variable

Return values:
Thevariable value on success
NULLif unable to find it.

Definition at line 600 of file config.c.

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

Referenced by __init_manager(), actual_load_config(), advanced_options(), aji_load_config(), ast_config_option(), build_extension(), conf_exec(), config_function_read(), config_module(), directory_exec(), do_reload(), festival_exec(), find_realtime(), forward_message(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), gtalk_load_config(), iax_template_parse(), init_acf_query(), init_logger_chain(), initialize_cc_devstate_map_helper(), initialize_cc_max_requests(), internal_aco_type_find(), jingle_load_config(), load_config(), load_config_meetme(), load_format_config(), load_indications(), load_module(), load_modules(), load_tech_calendars(), make_email_file(), message_range_and_existence_check(), named_acl_find_realtime(), notify_new_message(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), queue_set_global_params(), read_agent_config(), read_password_from_file(), realtime_directory(), reload_config(), reload_followme(), reload_single_queue(), rt_handle_member_record(), rtp_reload(), search_directory(), search_directory_sub(), set_config(), setup_dahdi_int(), sla_build_station(), sla_build_trunk(), sla_load_config(), tds_load_module(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), and vm_msg_snapshot_create().

{
   struct ast_variable *v;

   if (category) {
      for (v = ast_variable_browse(config, category); v; v = v->next) {
         if (!strcasecmp(variable, v->name)) {
            return v->value;
         }
      }
   } else {
      struct ast_category *cat;

      for (cat = config->root; cat; cat = cat->next) {
         for (v = cat->root; v; v = v->next) {
            if (!strcasecmp(variable, v->name)) {
               return v->value;
            }
         }
      }
   }

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

Update variable value within a config.

Parameters:
categoryCategory element within the config
variableName of the variable to change
valueNew value of the variable
matchIf set, previous value of the variable (if NULL or zero-length, no matching will be done)
objectBoolean of whether to make the new variable an object
Returns:
0 on success or -1 on failure.

Definition at line 1031 of file config.c.

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

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

{
   struct ast_variable *cur, *prev=NULL, *newer=NULL;

   for (cur = category->root; cur; prev = cur, cur = cur->next) {
      if (strcasecmp(cur->name, variable) ||
         (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
         continue;

      if (!(newer = ast_variable_new(variable, value, cur->file)))
         return -1;

      ast_variable_move(newer, cur);
      newer->object = newer->object || object;

      /* Replace the old node in the list with the new node. */
      newer->next = cur->next;
      if (prev)
         prev->next = newer;
      else
         category->root = newer;
      if (category->last == cur)
         category->last = newer;

      ast_variable_destroy(cur);

      return 0;
   }

   /* Could not find variable to update */
   return -1;
}
void ast_variables_destroy ( struct ast_variable var)

Free variable list.

Parameters:
varthe linked list of variables to free

This function frees a list of variables.

Definition at line 561 of file config.c.

References ast_variable_destroy(), and ast_variable::next.

Referenced by __init_manager(), __sip_destroy(), aco_set_defaults(), action_messagesend(), action_originate(), add_message_id(), ast_category_destroy(), ast_category_empty(), ast_http_get_cookies(), ast_http_manid_from_vars(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variables_dup(), auth_http_callback(), build_gateway(), build_peer(), build_user(), calendar_destructor(), check_peer_ok(), cli_realtime_load(), conf_run(), copy_plain_file(), destroy_dahdi_pvt(), destroy_endpoint(), destroy_fast_originate_helper(), dup_vars(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_realtime_gw(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), generic_http_callback(), get_insecure_variable_from_sipregs(), handle_uri(), http_post_callback(), httpd_helper_thread(), httpstatus_callback(), ldap_loadentry(), leave_queue(), local_ast_moh_start(), manager_free_user(), manager_sipnotify(), mkintf(), parkandannounce_exec(), process_dahdi(), pvt_destructor(), queue_function_queuewaitingcount(), realtime_alias(), realtime_canmatch(), realtime_common(), realtime_exec(), realtime_exists(), realtime_handler(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_user(), realtimefield_read(), row_to_varlist(), rt_extend_conf(), session_destructor(), sip_destroy_peer(), socket_process_helper(), table_configs_free(), and user_destructor().

{
   struct ast_variable *vn;

   while (v) {
      vn = v;
      v = v->next;
      ast_variable_destroy(vn);
   }
}
struct ast_variable* ast_variables_dup ( struct ast_variable var) [read]

Duplicate variable list.

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

Definition at line 539 of file config.c.

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

Referenced by action_originate(), ast_config_copy(), authenticate(), get_insecure_variable_from_sippeers(), and get_insecure_variable_from_sipregs().

{
   struct ast_variable *cloned;
   struct ast_variable *tmp;

   if (!(cloned = ast_variable_new(var->name, var->value, var->file))) {
      return NULL;
   }

   tmp = cloned;

   while ((var = var->next)) {
      if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) {
         ast_variables_destroy(cloned);
         return NULL;
      }
      tmp = tmp->next;
   }

   return cloned;
}
int config_text_file_save ( const char *  filename,
const struct ast_config cfg,
const char *  generator 
)

Definition at line 2035 of file config.c.

References ast_config_text_file_save().

{
   return ast_config_text_file_save(configfile, cfg, generator);
}
int read_config_maps ( void  )

Exposed re-initialization method for core process.

This method is intended for use only with the core re-initialization and is not designed to be called from any user applications.

Definition at line 2346 of file config.c.

References append_mapping(), ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log(), ast_variable_browse(), clear_config_maps(), config, CONFIG_FLAG_NOREALTIME, CONFIG_STATUS_FILEINVALID, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, table, and ast_variable::value.

Referenced by main().

{
   struct ast_config *config, *configtmp;
   struct ast_variable *v;
   char *driver, *table, *database, *textpri, *stringp, *tmp;
   struct ast_flags flags = { CONFIG_FLAG_NOREALTIME };
   int pri;

   clear_config_maps();

   configtmp = ast_config_new();
   if (!configtmp) {
      ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
      return -1;
   }
   config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
   if (config == CONFIG_STATUS_FILEINVALID) {
      return -1;
   } else if (!config) {
      ast_config_destroy(configtmp);
      return 0;
   }

   for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
      char buf[512];
      ast_copy_string(buf, v->value, sizeof(buf));
      stringp = buf;
      driver = strsep(&stringp, ",");

      if ((tmp = strchr(stringp, '\"')))
         stringp = tmp;

      /* check if the database text starts with a double quote */
      if (*stringp == '"') {
         stringp++;
         database = strsep(&stringp, "\"");
         strsep(&stringp, ",");
      } else {
         /* apparently this text has no quotes */
         database = strsep(&stringp, ",");
      }

      table = strsep(&stringp, ",");
      textpri = strsep(&stringp, ",");
      if (!textpri || !(pri = atoi(textpri))) {
         pri = 1;
      }

      if (!strcmp(v->name, extconfig_conf)) {
         ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
         continue;
      }

      if (!strcmp(v->name, "asterisk.conf")) {
         ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
         continue;
      }

      if (!strcmp(v->name, "logger.conf")) {
         ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
         continue;
      }

      if (!driver || !database)
         continue;
      if (!strcasecmp(v->name, "sipfriends")) {
         ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
         append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
      } else if (!strcasecmp(v->name, "iaxfriends")) {
         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");
         append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
         append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
      } else
         append_mapping(v->name, driver, database, table, pri);
   }

   ast_config_destroy(config);
   return 0;
}
int register_config_cli ( void  )

Exposed initialization method for core process.

This method is intended for use only with the core initialization and is not designed to be called from any user applications.

Definition at line 3263 of file config.c.

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

Referenced by main().