Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Macros | Enumerations | Functions | Variables
main/config.c File Reference

Configuration File Parser. More...

#include "asterisk.h"
#include "asterisk/paths.h"
#include "asterisk/network.h"
#include <string.h>
#include <libgen.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <math.h>
#include <regex.h>
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/netsock2.h"
#include "asterisk/module.h"
Include dependency graph for main/config.c:

Go to the source code of this file.

Data Structures

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

Macros

#define AST_MODULE   "extconfig"
 
#define CB_SIZE   250 /* initial size of comment buffers */
 
#define COMMENT_END   "--;"
 
#define COMMENT_META   ';'
 
#define COMMENT_START   ";--"
 
#define COMMENT_TAG   '-'
 
#define MAX_INCLUDE_LEVEL   10
 
#define MAX_NESTED_COMMENTS   128
 
#define MIN_VARIABLE_FNAME_SPACE   40
 
#define realtime_arguments_to_fields(ap, result)   realtime_arguments_to_fields2(ap, 0, result)
 
#define UTF8_BOM   "\xEF\xBB\xBF"
 

Enumerations

enum  config_cache_attribute_enum { ATTRIBUTE_INCLUDE = 0 , ATTRIBUTE_EXEC = 1 }
 

Functions

static void __init_appendbuf (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_variable_ast_variable_new (const char *name, const char *value, const char *filename, const char *file, const char *func, int lineno)
 
static struct ast_commentALLOC_COMMENT (struct ast_str *buffer)
 
void ast_category_append (struct ast_config *config, struct ast_category *category)
 Appends a category to a config. More...
 
char * ast_category_browse (struct ast_config *config, const char *prev_name)
 Browse categories. More...
 
struct ast_categoryast_category_browse_filtered (struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
 Browse categories with filters. More...
 
struct ast_categoryast_category_delete (struct ast_config *config, struct ast_category *category)
 Delete a category. More...
 
void ast_category_destroy (struct ast_category *cat)
 
struct ast_variableast_category_detach_variables (struct ast_category *cat)
 
int ast_category_empty (struct ast_category *category)
 Removes and destroys all variables in a category. More...
 
int ast_category_exist (const struct ast_config *config, const char *category_name, const char *filter)
 Check for category duplicates. More...
 
struct ast_variableast_category_first (struct ast_category *cat)
 given a pointer to a category, return the root variable. More...
 
struct ast_categoryast_category_get (const struct ast_config *config, const char *category_name, const char *filter)
 Retrieve a category if it exists. More...
 
const char * ast_category_get_name (const struct ast_category *category)
 Return the name of the category. More...
 
struct ast_strast_category_get_templates (const struct ast_category *category)
 Return the template names this category inherits from. More...
 
int ast_category_inherit (struct ast_category *new, const struct ast_category *base)
 Applies base (template) to category. More...
 
int ast_category_insert (struct ast_config *config, struct ast_category *cat, const char *match)
 Inserts new category. More...
 
int ast_category_is_template (const struct ast_category *category)
 Check if category is a template. More...
 
struct ast_categoryast_category_new (const char *name, const char *in_file, int lineno)
 Create a category. More...
 
struct ast_categoryast_category_new_template (const char *name, const char *in_file, int lineno)
 Create a category making it a template. More...
 
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 More...
 
int ast_check_realtime (const char *family)
 Check if realtime engine is configured for family. More...
 
static void ast_comment_destroy (struct ast_comment **comment)
 
struct ast_configast_config_copy (const struct ast_config *old)
 Copies the contents of one ast_config into another. More...
 
void ast_config_destroy (struct ast_config *cfg)
 Destroys a config. More...
 
int ast_config_engine_deregister (struct ast_config_engine *del)
 Deregister config engine. More...
 
int ast_config_engine_register (struct ast_config_engine *new)
 Register config engine. More...
 
struct ast_categoryast_config_get_current_category (const struct ast_config *cfg)
 Retrieve the current category name being built. More...
 
int ast_config_hook_register (const char *name, const char *filename, const char *module, enum config_hook_flags flags, config_hook_cb hook_cb)
 Register a config hook for a particular file and module. More...
 
void ast_config_hook_unregister (const char *name)
 Unregister a config hook. More...
 
struct ast_configast_config_internal_load (const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
 
struct ast_configast_config_load2 (const char *filename, const char *who_asked, struct ast_flags flags)
 Load a config file. More...
 
struct ast_configast_config_new (void)
 Create a new base configuration structure. More...
 
const char * ast_config_option (struct ast_config *cfg, const char *cat, const char *var)
 Retrieve a configuration variable within the configuration set. More...
 
void ast_config_set_current_category (struct ast_config *cfg, const struct ast_category *cat)
 Set the category within the configuration as being current. More...
 
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. More...
 
int ast_config_text_file_save (const char *configfile, const struct ast_config *cfg, const char *generator)
 Save a config text file preserving the pre 13.2 behavior. More...
 
int ast_config_text_file_save2 (const char *configfile, const struct ast_config *cfg, const char *generator, uint32_t flags)
 Save a config text file. More...
 
int ast_destroy_realtime (const char *family, const char *keyfield, const char *lookup,...)
 Destroy realtime configuration. More...
 
int ast_destroy_realtime_fields (const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
 Destroy realtime configuration. More...
 
static void ast_destroy_template_list (struct ast_category *cat)
 
struct ast_config_includeast_include_find (struct ast_config *conf, const char *included_file)
 
struct ast_config_includeast_include_new (struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size)
 
void ast_include_rename (struct ast_config *conf, const char *from_file, const char *to_file)
 
static void ast_includes_destroy (struct ast_config_include *incls)
 
struct ast_variableast_load_realtime (const char *family,...)
 
struct ast_variableast_load_realtime_all (const char *family,...)
 
struct ast_variableast_load_realtime_all_fields (const char *family, const struct ast_variable *fields)
 
struct ast_variableast_load_realtime_fields (const char *family, const struct ast_variable *fields)
 Retrieve realtime configuration. More...
 
struct ast_configast_load_realtime_multientry (const char *family,...)
 Retrieve realtime configuration. More...
 
struct ast_configast_load_realtime_multientry_fields (const char *family, const struct ast_variable *fields)
 Retrieve realtime configuration. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
int ast_parse_arg (const char *arg, enum ast_parse_flags flags, void *p_result,...)
 Helper function to parse arguments See documentation in config.h. More...
 
static int ast_realtime_append_mapping (const char *name, const char *driver, const char *database, const char *table, int priority)
 
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. More...
 
int ast_realtime_enabled (void)
 Check if there's any realtime engines loaded. More...
 
char * ast_realtime_encode_chunk (struct ast_str **dest, ssize_t maxlen, const char *chunk)
 Encodes a chunk of data for realtime. More...
 
int ast_realtime_is_mapping_defined (const char *family)
 Determine if a mapping exists for a given family. More...
 
int ast_realtime_require_field (const char *family,...)
 Inform realtime what fields that may be stored. More...
 
int ast_store_realtime (const char *family,...)
 Create realtime configuration. More...
 
int ast_store_realtime_fields (const char *family, const struct ast_variable *fields)
 Create realtime configuration. More...
 
int ast_unload_realtime (const char *family)
 Release any resources cached for a realtime family. More...
 
int ast_update2_realtime (const char *family,...)
 Update realtime configuration. More...
 
int ast_update2_realtime_fields (const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
 Update realtime configuration. More...
 
int ast_update_realtime (const char *family, const char *keyfield, const char *lookup,...)
 Update realtime configuration. More...
 
int ast_update_realtime_fields (const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
 Update realtime configuration. More...
 
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)
 
int ast_variable_delete (struct ast_category *category, const char *variable, const char *match, const char *line)
 
static void ast_variable_destroy (struct ast_variable *doomed)
 
const char * ast_variable_find (const struct ast_category *category, const char *variable)
 Gets a variable value from a specific category structure by name. More...
 
const char * ast_variable_find_in_list (const struct ast_variable *list, const char *variable)
 Gets the value of a variable from a variable list by name. More...
 
const char * ast_variable_find_last_in_list (const struct ast_variable *list, const char *variable)
 Gets the value of the LAST occurrence of a variable from a variable list. More...
 
const struct ast_variableast_variable_find_variable_in_list (const struct ast_variable *list, const char *variable_name)
 Gets a variable from a variable list by name. More...
 
void ast_variable_insert (struct ast_category *category, struct ast_variable *variable, const char *line)
 
struct ast_variableast_variable_list_append_hint (struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *newvar)
 Appends a variable list to the end of another list. More...
 
struct ast_variableast_variable_list_from_quoted_string (const char *input, const char *item_separator, const char *name_value_separator, const char *quote_str)
 Parse a string into an ast_variable list. The reverse of ast_variable_list_join. More...
 
struct ast_variableast_variable_list_from_string (const char *input, const char *item_separator, const char *name_value_separator)
 Parse a string into an ast_variable list. The reverse of ast_variable_list_join. More...
 
struct ast_strast_variable_list_join (const struct ast_variable *head, const char *item_separator, const char *name_value_separator, const char *quote_char, struct ast_str **str)
 Join an ast_variable list with specified separators and quoted values. More...
 
int ast_variable_list_replace (struct ast_variable **head, struct ast_variable *replacement)
 Replace a variable in the given list with a new value. More...
 
int ast_variable_list_replace_variable (struct ast_variable **head, struct ast_variable *old, struct ast_variable *new)
 Replace a variable in the given list with a new variable. More...
 
struct ast_variableast_variable_list_sort (struct ast_variable *start)
 Performs an in-place sort on the variable list by ascending name. More...
 
int ast_variable_lists_match (const struct ast_variable *left, const struct ast_variable *right, int exact_match)
 Tests 2 variable lists to see if they match. More...
 
static void ast_variable_move (struct ast_variable *dst_var, struct ast_variable *src_var)
 
const char * ast_variable_retrieve (struct ast_config *config, const char *category, const char *variable)
 
const char * ast_variable_retrieve_filtered (struct ast_config *config, const char *category, const char *variable, const char *filter)
 Gets a variable by context and variable names. More...
 
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. More...
 
void ast_variables_destroy (struct ast_variable *var)
 Free variable list. More...
 
struct ast_variableast_variables_dup (struct ast_variable *var)
 Duplicate variable list. More...
 
int ast_variables_match (const struct ast_variable *left, const struct ast_variable *right)
 Tests 2 variable values to see if they match. More...
 
struct ast_variableast_variables_reverse (struct ast_variable *var)
 Reverse a variable list. More...
 
static struct ast_categorycategory_get_sep (const struct ast_config *config, const char *category_name, const char *filter, char sep, char pointer_match_possible)
 
static void CB_ADD (struct ast_str **cb, const char *str)
 
static void CB_ADD_LEN (struct ast_str **cb, const char *str, int len)
 
static void CB_RESET (struct ast_str *cb, struct ast_str *llb)
 
static int cfmstat_cmp (struct cache_file_mtime *cfmtime, struct stat *statbuf)
 
static void cfmstat_save (struct cache_file_mtime *cfmtime, struct stat *statbuf)
 
static struct cache_file_mtimecfmtime_new (const char *filename, const char *who_asked)
 
static void clear_config_maps (void)
 
static void config_cache_attribute (const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked)
 
static void config_cache_destroy_entry (struct cache_file_mtime *cfmtime)
 
static void config_cache_flush_includes (struct cache_file_mtime *cfmtime)
 
static void config_cache_remove (const char *filename, const char *who_asked)
 
static void config_hook_exec (const char *filename, const char *module, const struct ast_config *cfg)
 
static void config_shutdown (void)
 
static struct ast_configconfig_text_file_load (const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
 
static int count_linefeeds (char *str)
 
static int count_linefeeds_in_comments (struct ast_comment *x)
 
static int does_category_match (struct ast_category *cat, const char *category_name, const char *match, char sep)
 Returns true if ALL of the regex expressions and category name match. Both can be NULL (I.E. no predicate) which results in a true return;. More...
 
static struct ast_config_enginefind_engine (const char *family, int priority, char *database, int dbsiz, char *table, int tabsiz)
 Find realtime engine for realtime family. More...
 
static void gen_header (FILE *f1, const char *configfile, const char *fn, const char *generator)
 
static char * handle_cli_config_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_config_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_core_show_config_mappings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int handle_include_exec (const char *command, const char *output_file)
 
static int hash_string (const void *obj, const int flags)
 
static int hashtab_compare_strings (void *a, void *b, int flags)
 
static int hook_cmp (void *obj, void *arg, int flags)
 
static void hook_destroy (void *obj)
 
static int hook_hash (const void *obj, const int flags)
 
static void inclfile_destroy (void *obj)
 
static int init_appendbuf (void *data)
 
static void insert_leading_blank_lines (FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
 
static int is_writable (const char *fn)
 
static int load_module (void)
 
static void make_fn (char *fn, size_t fn_size, const char *file, const char *configfile)
 
static void move_variables (struct ast_category *old, struct ast_category *new)
 
static struct ast_categorynew_category (const char *name, const char *in_file, int lineno, int template)
 
static struct ast_categorynext_available_category (struct ast_category *cat, const char *name, const char *filter)
 
static int process_text_line (struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked)
 parse one line in the configuration. More...
 
static int realtime_arguments_to_fields2 (va_list ap, int skip, struct ast_variable **result)
 
int register_config_cli (void)
 Exposed initialization method for core process. More...
 
static int reload_module (void)
 
static struct inclfileset_fn (char *fn, size_t fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
 
static int unload_module (void)
 
static struct ast_variablevariable_clone (const struct ast_variable *old)
 
static struct ast_variablevariable_list_switch (struct ast_variable *l1, struct ast_variable *l2)
 

Variables

static struct ast_module_info __mod_info = { .name = "extconfig" , .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = 0, }
 
static struct ast_threadstorage appendbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_appendbuf , .custom_init = init_appendbuf , }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ao2_containercfg_hooks
 
static struct cfmtime_head cfmtime_head = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static struct ast_cli_entry cli_config []
 
static struct ast_config_engineconfig_engine_list
 
static ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct ast_config_mapconfig_maps = NULL
 
static char * extconfig_conf = "extconfig.conf"
 
static struct ast_config_engine text_file_engine
 

Detailed Description

Configuration File Parser.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Includes the Asterisk Realtime API - ARA See https://docs.asterisk.org

Definition in file main/config.c.

Macro Definition Documentation

◆ AST_MODULE

#define AST_MODULE   "extconfig"

Definition at line 36 of file main/config.c.

◆ CB_SIZE

#define CB_SIZE   250 /* initial size of comment buffers */

Definition at line 128 of file main/config.c.

◆ COMMENT_END

#define COMMENT_END   "--;"

Definition at line 65 of file main/config.c.

◆ COMMENT_META

#define COMMENT_META   ';'

Definition at line 66 of file main/config.c.

◆ COMMENT_START

#define COMMENT_START   ";--"

Definition at line 64 of file main/config.c.

◆ COMMENT_TAG

#define COMMENT_TAG   '-'

Definition at line 67 of file main/config.c.

◆ MAX_INCLUDE_LEVEL

#define MAX_INCLUDE_LEVEL   10

Definition at line 218 of file main/config.c.

◆ MAX_NESTED_COMMENTS

#define MAX_NESTED_COMMENTS   128

Definition at line 63 of file main/config.c.

◆ MIN_VARIABLE_FNAME_SPACE

#define MIN_VARIABLE_FNAME_SPACE   40

Define the minimum filename space to reserve for each ast_variable in case the filename is renamed later by ast_include_rename().

Definition at line 74 of file main/config.c.

◆ realtime_arguments_to_fields

#define realtime_arguments_to_fields (   ap,
  result 
)    realtime_arguments_to_fields2(ap, 0, result)

Definition at line 3352 of file main/config.c.

◆ UTF8_BOM

#define UTF8_BOM   "\xEF\xBB\xBF"

Enumeration Type Documentation

◆ config_cache_attribute_enum

Enumerator
ATTRIBUTE_INCLUDE 
ATTRIBUTE_EXEC 

Definition at line 1684 of file main/config.c.

1684 {
1686 ATTRIBUTE_EXEC = 1,
1687};
@ ATTRIBUTE_EXEC
Definition: main/config.c:1686
@ ATTRIBUTE_INCLUDE
Definition: main/config.c:1685

Function Documentation

◆ __init_appendbuf()

static void __init_appendbuf ( void  )
static

Definition at line 125 of file main/config.c.

131{

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4367 of file main/config.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4367 of file main/config.c.

◆ _ast_variable_new()

struct ast_variable * _ast_variable_new ( const char *  name,
const char *  value,
const char *  filename,
const char *  file,
const char *  func,
int  lineno 
)

Definition at line 289 of file main/config.c.

290{
291 struct ast_variable *variable;
292 int name_len = strlen(name) + 1;
293 int val_len = strlen(value) + 1;
294 int fn_len = strlen(filename) + 1;
295
296 /* Ensure a minimum length in case the filename is changed later. */
297 if (fn_len < MIN_VARIABLE_FNAME_SPACE) {
299 }
300
301 variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable),
302 file, lineno, func);
303 if (variable) {
304 char *dst = variable->stuff; /* writable space starts here */
305
306 /* Put file first so ast_include_rename() can calculate space available. */
307 variable->file = strcpy(dst, filename);
308 dst += fn_len;
309 variable->name = strcpy(dst, name);
310 dst += name_len;
311 variable->value = strcpy(dst, value);
312 }
313 return variable;
314}
void * __ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func) attribute_malloc
Definition: astmm.c:1603
static const char name[]
Definition: format_mp3.c:68
#define MIN_VARIABLE_FNAME_SPACE
Definition: main/config.c:74
Structure for variables, used for configurations and for channel variables.
char stuff[0]
Contents of file, name, and value in that order stuffed here.
int value
Definition: syslog.c:37

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

◆ ALLOC_COMMENT()

static struct ast_comment * ALLOC_COMMENT ( struct ast_str buffer)
static

Definition at line 154 of file main/config.c.

155{
156 struct ast_comment *x = NULL;
157 if (!buffer || !ast_str_strlen(buffer)) {
158 return NULL;
159 }
160 if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
161 strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
162 }
163 return x;
164}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define NULL
Definition: resample.c:96
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
Structure to keep comments for rewriting configuration files.
Definition: main/config.c:85
char cmt[0]
Definition: main/config.c:88

References ast_calloc, ast_str_buffer(), ast_str_strlen(), ast_comment::cmt, and NULL.

Referenced by config_text_file_load(), and process_text_line().

◆ ast_category_append()

void ast_category_append ( struct ast_config config,
struct ast_category category 
)

Appends a category to a config.

Parameters
configwhich config to use
categorycategory to insert

Definition at line 1165 of file main/config.c.

1166{
1167 if (config->last) {
1168 config->last->next = category;
1169 category->prev = config->last;
1170 } else {
1171 config->root = category;
1172 category->prev = NULL;
1173 }
1174 category->next = NULL;
1175 category->include_level = config->include_level;
1176
1177 config->last = category;
1178 config->current = category;
1179}
static const char config[]
Definition: chan_ooh323.c:111
struct ast_category * next
Definition: main/config.c:247
struct ast_category * prev
Definition: main/config.c:245

References config, ast_category::include_level, ast_category::next, NULL, and ast_category::prev.

Referenced by append_row_to_cfg(), ast_config_copy(), AST_TEST_DEFINE(), build_cfg(), config_curl(), config_ldap(), config_mysql(), config_odbc(), config_pgsql(), handle_updates(), process_text_line(), realtime_directory(), realtime_multi_curl(), realtime_multi_ldap(), realtime_multi_mysql(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_sorcery_multi(), realtime_sorcery_store(), realtime_sorcery_update(), static_realtime_cb(), and write_password_to_file().

◆ ast_category_browse()

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

Browse categories.

Parameters
configWhich config structure you wish to "browse"
prev_nameA pointer to a previous category name.

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 name on success
NULLon failure/no-more-categories
Note
ast_category_browse maintains internal state. Therefore is not thread safe, cannot be called recursively, and it is not safe to add or remove categories while browsing. ast_category_browse_filtered does not have these restrictions.

Definition at line 1387 of file main/config.c.

1388{
1389 struct ast_category *cat;
1390
1391 if (!prev_name) {
1392 /* First time browse. */
1393 cat = config->root;
1394 } else if (config->last_browse && (config->last_browse->name == prev_name)) {
1395 /* Simple last browse found. */
1396 cat = config->last_browse->next;
1397 } else {
1398 /*
1399 * Config changed since last browse.
1400 *
1401 * First try cheap last browse search. (Rebrowsing a different
1402 * previous category?)
1403 */
1404 for (cat = config->root; cat; cat = cat->next) {
1405 if (cat->name == prev_name) {
1406 /* Found it. */
1407 cat = cat->next;
1408 break;
1409 }
1410 }
1411 if (!cat) {
1412 /*
1413 * Have to do it the hard way. (Last category was deleted and
1414 * re-added?)
1415 */
1416 for (cat = config->root; cat; cat = cat->next) {
1417 if (!strcasecmp(cat->name, prev_name)) {
1418 /* Found it. */
1419 cat = cat->next;
1420 break;
1421 }
1422 }
1423 }
1424 }
1425
1426 if (cat)
1427 cat = next_available_category(cat, NULL, NULL);
1428
1429 config->last_browse = cat;
1430 return (cat) ? cat->name : NULL;
1431}
static struct ast_category * next_available_category(struct ast_category *cat, const char *name, const char *filter)
Definition: main/config.c:1246
char name[80]
Definition: main/config.c:227

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

Referenced by __init_manager(), __queues_show(), actual_load_config(), ast_cli_perms_init(), AST_TEST_DEFINE(), check_for_old_config(), conf_exec(), find_queue_by_name_rt(), find_realtime(), iax_provision_reload(), internal_process_ast_config(), load_common(), load_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_realtime_musiconhold(), load_realtime_queues(), load_realtime_rules(), load_tech_calendars(), load_users(), mbl_load_config(), named_acl_find_realtime(), parse_config(), pbx_load_config(), pbx_load_users(), realtime_directory(), realtime_sorcery(), realtime_sorcery_multi(), realtime_switch_common(), 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(), test_config_validity(), update_realtime_members(), and vm_change_password().

◆ ast_category_browse_filtered()

struct ast_category * ast_category_browse_filtered ( struct ast_config config,
const char *  category_name,
struct ast_category prev,
const char *  filter 
)

Browse categories with filters.

Parameters
configWhich config structure you wish to "browse"
category_nameAn optional category name. Pass NULL to not restrict by category name.
prevA pointer to the starting category structure. Pass NULL to start at the beginning.
filterAn optional comma-separated list of <name_regex>=<value_regex> pairs. Only categories with matching variables will be returned. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.
Return values
acategory on success
NULLon failure/no-more-categories

Definition at line 1433 of file main/config.c.

1435{
1436 struct ast_category *cat;
1437
1438 if (!prev) {
1439 prev = config->root;
1440 } else {
1441 prev = prev->next;
1442 }
1443
1444 cat = next_available_category(prev, category_name, filter);
1445
1446 return cat;
1447}
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:807

References config, filter(), ast_category::next, next_available_category(), and ast_category::prev.

Referenced by action_getconfig(), action_getconfigjson(), action_listcategories(), AST_TEST_DEFINE(), ast_variable_retrieve_filtered(), handle_updates(), object_type_loaded_observer(), sorcery_config_internal_load(), and sorcery_realtime_retrieve_multiple().

◆ ast_category_delete()

struct ast_category * ast_category_delete ( struct ast_config cfg,
struct ast_category cat 
)

Delete a category.

Parameters
cfgwhich config to use
catcategory to delete
Returns
the category after the deleted one which could be NULL.
Note
It is not safe to call ast_category_delete while browsing with ast_category_browse. It is safe with ast_category_browse_filtered.

Definition at line 1582 of file main/config.c.

1584{
1585 struct ast_category *prev;
1586
1587 if (!config || !category) {
1588 return NULL;
1589 }
1590
1591 if (category->prev) {
1592 category->prev->next = category->next;
1593 } else {
1594 config->root = category->next;
1595 }
1596
1597 if (category->next) {
1598 category->next->prev = category->prev;
1599 } else {
1600 config->last = category->prev;
1601 }
1602
1603 prev = category->prev;
1604
1605 if (config->last_browse == category) {
1606 config->last_browse = prev;
1607 }
1608
1609 ast_category_destroy(category);
1610
1611 return prev;
1612}
void ast_category_destroy(struct ast_category *cat)
Definition: main/config.c:1220

References ast_category_destroy(), config, ast_category::next, NULL, and ast_category::prev.

Referenced by AST_TEST_DEFINE(), handle_updates(), object_type_loaded_observer(), realtime_sorcery_destroy(), and realtime_sorcery_update().

◆ ast_category_destroy()

void ast_category_destroy ( struct ast_category cat)

Definition at line 1220 of file main/config.c.

1221{
1223 cat->root = NULL;
1224 cat->last = NULL;
1229 ast_free(cat->file);
1230 ast_free(cat);
1231}
#define ast_free(a)
Definition: astmm.h:180
static void ast_destroy_template_list(struct ast_category *cat)
Definition: main/config.c:1212
static void ast_comment_destroy(struct ast_comment **comment)
Definition: main/config.c:524
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: main/config.c:590
struct ast_comment * precomments
Definition: main/config.c:237
struct ast_variable * last
Definition: main/config.c:243
struct ast_comment * trailing
Definition: main/config.c:239
struct ast_variable * root
Definition: main/config.c:241
struct ast_comment * sameline
Definition: main/config.c:238
char * file
The file name from whence this declaration was read.
Definition: main/config.c:234

References ast_comment_destroy(), ast_destroy_template_list(), ast_free, ast_variables_destroy(), ast_category::file, free(), ast_category::last, NULL, ast_category::precomments, ast_category::root, ast_category::sameline, and ast_category::trailing.

Referenced by ast_category_delete(), ast_config_destroy(), handle_updates(), new_category(), process_text_line(), realtime_multi_odbc(), static_realtime_cb(), and write_password_to_file().

◆ ast_category_detach_variables()

struct ast_variable * ast_category_detach_variables ( struct ast_category cat)

Definition at line 1449 of file main/config.c.

1450{
1451 struct ast_variable *v;
1452
1453 v = cat->root;
1454 cat->root = NULL;
1455 cat->last = NULL;
1456
1457 return v;
1458}

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

Referenced by realtime_switch_common(), and sorcery_realtime_retrieve_multiple().

◆ ast_category_empty()

int ast_category_empty ( struct ast_category category)

Removes and destroys all variables in a category.

Parameters
categorycategory to empty
Return values
0if succeeded
-1if category is NULL

Definition at line 1614 of file main/config.c.

1615{
1616 if (!category) {
1617 return -1;
1618 }
1619
1620 ast_variables_destroy(category->root);
1621 category->root = NULL;
1622 category->last = NULL;
1623
1624 return 0;
1625}

References ast_variables_destroy(), ast_category::last, NULL, and ast_category::root.

Referenced by AST_TEST_DEFINE(), and handle_updates().

◆ ast_category_exist()

int ast_category_exist ( const struct ast_config config,
const char *  category_name,
const char *  filter 
)

Check for category duplicates.

Parameters
configwhich config to use
category_namename of the category you're looking for
filteran optional comma-separated list of <name_regex>=<value_regex> pairs. Only categories with matching variables will be returned. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.

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

Returns
non-zero if found

Definition at line 1159 of file main/config.c.

1161{
1162 return !!ast_category_get(config, category_name, filter);
1163}
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name, const char *filter)
Retrieve a category if it exists.
Definition: main/config.c:1120

References ast_category_get(), config, and filter().

Referenced by realtime_sorcery_store().

◆ ast_category_first()

struct ast_variable * ast_category_first ( struct ast_category cat)

◆ ast_category_get()

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

Retrieve a category if it exists.

Parameters
configwhich config to use
category_namename of the category you're looking for
filterIf a config contains more than 1 category with the same name, you can specify a filter to narrow the search. The filter is a comma-separated list of <name_regex>=<value_regex> pairs. Only a category with matching variables will be returned. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.

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 1120 of file main/config.c.

1122{
1123 return category_get_sep(config, category_name, filter, ',', 1);
1124}
static struct ast_category * category_get_sep(const struct ast_config *config, const char *category_name, const char *filter, char sep, char pointer_match_possible)
Definition: main/config.c:1098

References category_get_sep(), config, and filter().

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

◆ ast_category_get_name()

const char * ast_category_get_name ( const struct ast_category category)

Return the name of the category.

Parameters
categorycategory structure
Return values
pointerto category name if found
NULLif not.

Definition at line 1126 of file main/config.c.

1127{
1128 return category->name;
1129}

References ast_category::name.

Referenced by action_getconfig(), action_getconfigjson(), action_listcategories(), AST_TEST_DEFINE(), handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), object_type_loaded_observer(), sorcery_config_internal_load(), and sorcery_is_explicit_name_met().

◆ ast_category_get_templates()

struct ast_str * ast_category_get_templates ( const struct ast_category category)

Return the template names this category inherits from.

Parameters
categorycategory structure
Returns
an ast_str (which must be freed after use) with a comma separated list of templates names or NULL if there were no templates.

Definition at line 1136 of file main/config.c.

1137{
1138 struct ast_category_template_instance *template;
1139 struct ast_str *str;
1140 int first = 1;
1141
1142 if (AST_LIST_EMPTY(&category->template_instances)) {
1143 return NULL;
1144 }
1145
1146 str = ast_str_create(128);
1147 if (!str) {
1148 return NULL;
1149 }
1150
1151 AST_LIST_TRAVERSE(&category->template_instances, template, next) {
1152 ast_str_append(&str, 0, "%s%s", first ? "" : ",", template->name);
1153 first = 0;
1154 }
1155
1156 return str;
1157}
const char * str
Definition: app_jack.c:147
struct sla_ringing_trunk * first
Definition: app_sla.c:332
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
struct ast_category_template_instance * next
Definition: main/config.c:223
struct ast_category::template_instance_list template_instances
Support for dynamic strings.
Definition: strings.h:623

References AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_str_append(), ast_str_create, first, ast_category::next, NULL, str, and ast_category::template_instances.

Referenced by action_getconfig(), and action_getconfigjson().

◆ ast_category_inherit()

int ast_category_inherit ( struct ast_category existing,
const struct ast_category base 
)

Applies base (template) to category.

Parameters
existingexisting category
basebase category

This function is used to apply a base (template) to an existing category

Return values
0if succeeded
-1if the memory allocation failed

Definition at line 1465 of file main/config.c.

1466{
1467 struct ast_variable *var;
1469
1470 x = ast_calloc(1, sizeof(*x));
1471 if (!x) {
1472 return -1;
1473 }
1474 strcpy(x->name, base->name);
1475 x->inst = base;
1477 for (var = base->root; var; var = var->next) {
1478 struct ast_variable *cloned = variable_clone(var);
1479 if (!cloned) {
1480 return -1;
1481 }
1482 cloned->inherited = 1;
1483 ast_variable_append(new, cloned);
1484 }
1485 return 0;
1486}
#define var
Definition: ast_expr2f.c:605
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: main/config.c:487
static struct ast_variable * variable_clone(const struct ast_variable *old)
Definition: main/config.c:953
const struct ast_category * inst
Definition: main/config.c:222

References ast_calloc, AST_LIST_INSERT_TAIL, ast_variable_append(), ast_variable::inherited, ast_category_template_instance::inst, ast_category_template_instance::name, ast_category::name, ast_category::next, ast_category::root, var, and variable_clone().

Referenced by handle_updates(), and process_text_line().

◆ ast_category_insert()

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

Return values
0if succeeded
-1if the specified match category wasn't found

Definition at line 1181 of file main/config.c.

1182{
1183 struct ast_category *cur_category;
1184
1185 if (!config || !config->root || !cat || !match) {
1186 return -1;
1187 }
1188
1189 if (!strcasecmp(config->root->name, match)) {
1190 cat->next = config->root;
1191 cat->prev = NULL;
1192 config->root->prev = cat;
1193 config->root = cat;
1194 return 0;
1195 }
1196
1197 for (cur_category = config->root->next; cur_category; cur_category = cur_category->next) {
1198 if (!strcasecmp(cur_category->name, match)) {
1199 cat->prev = cur_category->prev;
1200 cat->prev->next = cat;
1201
1202 cat->next = cur_category;
1203 cur_category->prev = cat;
1204
1205 return 0;
1206 }
1207 }
1208
1209 return -1;
1210}
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362

References config, match(), ast_category::name, ast_category::next, NULL, and ast_category::prev.

Referenced by AST_TEST_DEFINE(), and handle_updates().

◆ ast_category_is_template()

int ast_category_is_template ( const struct ast_category category)

Check if category is a template.

Parameters
categorycategory structure
Return values
1if a template.
0if not.

Definition at line 1131 of file main/config.c.

1132{
1133 return category->ignored;
1134}

References ast_category::ignored.

Referenced by action_getconfig(), and action_getconfigjson().

◆ ast_category_new()

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

Create a category.

Parameters
namename of new category
in_filefilename which contained the new config
linenoline number

Definition at line 1088 of file main/config.c.

1089{
1090 return new_category(name, in_file, lineno, 0);
1091}
static struct ast_category * new_category(const char *name, const char *in_file, int lineno, int template)
Definition: main/config.c:1069

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

Referenced by ast_config_copy(), AST_TEST_DEFINE(), build_cfg(), handle_updates(), process_text_line(), realtime_sorcery_multi(), realtime_sorcery_store(), realtime_sorcery_update(), and write_password_to_file().

◆ ast_category_new_template()

struct ast_category * ast_category_new_template ( const char *  name,
const char *  in_file,
int  lineno 
)

Create a category making it a template.

Parameters
namename of new template
in_filefilename which contained the new config
linenoline number

Definition at line 1093 of file main/config.c.

1094{
1095 return new_category(name, in_file, lineno, 1);
1096}

References ast_category::lineno, name, and new_category().

Referenced by AST_TEST_DEFINE(), and handle_updates().

◆ ast_category_rename()

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

Definition at line 1460 of file main/config.c.

1461{
1462 ast_copy_string(cat->name, name, sizeof(cat->name));
1463}
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

References ast_copy_string(), ast_category::name, and name.

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

◆ ast_category_root()

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

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 1260 of file main/config.c.

1261{
1262 struct ast_category *category = ast_category_get(config, cat, NULL);
1263
1264 if (category)
1265 return category->root;
1266 return NULL;
1267}

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

Referenced by config_function_read(), realtime_sorcery(), and realtime_sorcery_multi().

◆ ast_check_realtime()

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 3545 of file main/config.c.

3546{
3547 struct ast_config_engine *eng;
3548 if (!ast_realtime_enabled()) {
3549 return 0; /* There are no engines at all so fail early */
3550 }
3551
3552 eng = find_engine(family, 1, NULL, 0, NULL, 0);
3553 if (eng)
3554 return 1;
3555 return 0;
3556}
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
Definition: main/config.c:3559
static struct ast_config_engine * find_engine(const char *family, int priority, char *database, int dbsiz, char *table, int tabsiz)
Find realtime engine for realtime family.
Definition: main/config.c:3224
Configuration engine structure, used to define realtime drivers.

References ast_realtime_enabled(), find_engine(), and NULL.

Referenced by __queues_show(), ast_named_acl_find(), ast_queue_log(), close_mailbox(), copy_plain_file(), handle_voicemail_show_users(), leave_voicemail(), load_module(), load_moh_classes(), load_realtime_queues(), load_realtime_rules(), local_ast_moh_start(), logger_queue_rt_start(), manager_queues_status(), manager_queues_summary(), msg_create_from_file(), rename_file(), set_member_paused(), set_member_value(), and vm_delete().

◆ ast_comment_destroy()

static void ast_comment_destroy ( struct ast_comment **  comment)
static

Definition at line 524 of file main/config.c.

525{
526 struct ast_comment *n, *p;
527
528 for (p = *comment; p; p = n) {
529 n = p->next;
530 ast_free(p);
531 }
532
533 *comment = NULL;
534}
#define comment
Definition: ael_lex.c:965
struct ast_comment * next
Definition: main/config.c:86

References ast_free, comment, ast_comment::next, and NULL.

Referenced by ast_category_destroy(), and ast_variable_destroy().

◆ ast_config_copy()

struct ast_config * ast_config_copy ( const struct ast_config orig)

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 3261 of file main/config.c.

3262{
3263 struct ast_config *new_config = ast_config_new();
3264 struct ast_category *cat_iter;
3265
3266 if (!new_config) {
3267 return NULL;
3268 }
3269
3270 for (cat_iter = old->root; cat_iter; cat_iter = cat_iter->next) {
3271 struct ast_category *new_cat =
3272 ast_category_new(cat_iter->name, cat_iter->file, cat_iter->lineno);
3273 if (!new_cat) {
3274 goto fail;
3275 }
3276 ast_category_append(new_config, new_cat);
3277 if (cat_iter->root) {
3278 new_cat->root = ast_variables_dup(cat_iter->root);
3279 if (!new_cat->root) {
3280 goto fail;
3281 }
3282 new_cat->last = cat_iter->last;
3283 }
3284 }
3285
3286 return new_config;
3287
3288fail:
3289 ast_config_destroy(new_config);
3290 return NULL;
3291}
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: main/config.c:1627
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: main/config.c:1488
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
Definition: main/config.c:1088
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
Definition: main/config.c:1165
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:544
struct ast_category * root
Definition: main/config.c:252

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, NULL, ast_category::root, and ast_config::root.

Referenced by AST_TEST_DEFINE(), and config_hook_exec().

◆ ast_config_destroy()

void ast_config_destroy ( struct ast_config cfg)

Destroys a config.

Parameters
cfgpointer to config data structure

Free memory associated with a given config

Definition at line 1627 of file main/config.c.

1628{
1629 struct ast_category *cat, *catn;
1630
1631 if (!cfg)
1632 return;
1633
1635
1636 cat = cfg->root;
1637 while (cat) {
1638 catn = cat;
1639 cat = cat->next;
1641 }
1642 ast_free(cfg);
1643}
static void ast_includes_destroy(struct ast_config_include *incls)
Definition: main/config.c:1233
struct ast_config_include * includes
Definition: main/config.c:259

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

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_sorcery_apply_config(), __init_manager(), __queues_show(), _dsp_init(), aco_process_config(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), ast_cli_perms_init(), ast_config_copy(), ast_config_load2(), ast_init_logger_for_socket_console(), ast_load_realtime_multientry_fields(), AST_TEST_DEFINE(), build_cfg(), check_for_old_config(), conf_exec(), config_function_read(), config_module(), deinitialize_sorcery(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_load_queue_rt_friendly(), find_realtime(), forward_message(), get_defaults(), handle_cli_dialplan_save(), hook_cb(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), load_asterisk_conf(), load_common(), load_config(), load_config_force(), load_config_meetme(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_realtime_musiconhold(), load_realtime_queues(), load_realtime_rules(), load_users(), loader_config_init(), make_email_file(), mbl_load_config(), message_range_and_existence_check(), my_load_module(), named_acl_find_realtime(), notify_new_message(), object_type_loaded_observer(), odbc_load_module(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), process_config(), read_password_from_file(), read_pjproject_startup_options(), realtime_directory(), realtime_multi_mysql(), realtime_multi_pgsql(), realtime_sorcery_multi(), realtime_sqlite3_multi(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), rtp_reload(), run_startup_commands(), set_config(), set_member_value(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), smdi_load(), sorcery_config_internal_load(), sorcery_realtime_retrieve_multiple(), tds_load_module(), unload_module(), update_realtime_members(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), vm_msg_snapshot_create(), write_password_to_file(), and xmldoc_load_documentation().

◆ ast_config_engine_deregister()

int ast_config_engine_deregister ( struct ast_config_engine del)

Deregister config engine.

Return values
0Always

Definition at line 3188 of file main/config.c.

3189{
3190 struct ast_config_engine *ptr, *last=NULL;
3191
3193
3194 for (ptr = config_engine_list; ptr; ptr=ptr->next) {
3195 if (ptr == del) {
3196 if (last)
3197 last->next = ptr->next;
3198 else
3199 config_engine_list = ptr->next;
3200 break;
3201 }
3202 last = ptr;
3203 }
3204
3205 return 0;
3206}
ast_mutex_t lock
Definition: app_sla.c:331
struct sla_ringing_trunk * last
Definition: app_sla.c:332
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:589
static ast_mutex_t config_lock
Definition: main/config.c:215
static struct ast_config_engine * config_engine_list
Definition: main/config.c:216
struct ast_config_engine * next
struct sla_ringing_trunk * next
Definition: app_sla.c:308

References config_engine_list, config_lock, last, lock, sla_ringing_trunk::next, ast_config_engine::next, NULL, and SCOPED_MUTEX.

Referenced by unload_module().

◆ ast_config_engine_register()

int ast_config_engine_register ( struct ast_config_engine newconfig)

Register config engine.

Return values
1Always

Definition at line 3172 of file main/config.c.

3173{
3174 struct ast_config_engine *ptr;
3175
3177
3178 if (!config_engine_list) {
3179 config_engine_list = new;
3180 } else {
3181 for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
3182 ptr->next = new;
3183 }
3184
3185 return 1;
3186}

References config_engine_list, config_lock, lock, ast_config_engine::next, and SCOPED_MUTEX.

Referenced by load_module().

◆ ast_config_get_current_category()

struct ast_category * ast_config_get_current_category ( const struct ast_config cfg)

Retrieve the current category name being built.

API for backend configuration engines while building a configuration set.

Definition at line 1645 of file main/config.c.

1646{
1647 return cfg->current;
1648}
struct ast_category * current
Definition: main/config.c:255

References ast_config::current.

Referenced by config_text_file_load().

◆ ast_config_hook_register()

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 4317 of file main/config.c.

4322{
4323 struct cfg_hook *hook;
4324 if (!cfg_hooks) {
4327 if (!cfg_hooks) {
4328 return -1;
4329 }
4330 }
4331
4332 if (!(hook = ao2_alloc(sizeof(*hook), hook_destroy))) {
4333 return -1;
4334 }
4335
4336 hook->hook_cb = hook_cb;
4337 hook->filename = ast_strdup(filename);
4338 hook->name = ast_strdup(name);
4339 hook->module = ast_strdup(module);
4340
4341 ao2_link(cfg_hooks, hook);
4342 ao2_ref(hook, -1);
4343 return 0;
4344}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
static int hook_hash(const void *obj, const int flags)
Definition: main/config.c:4282
static struct ao2_container * cfg_hooks
Definition: main/config.c:78
static void hook_destroy(void *obj)
Definition: main/config.c:4266
static int hook_cmp(void *obj, void *arg, int flags)
Definition: main/config.c:4274
config_hook_cb hook_cb
Definition: main/config.c:4263
const char * filename
Definition: main/config.c:4261
const char * module
Definition: main/config.c:4262
const char * name
Definition: main/config.c:4260
static int hook_cb(struct ast_config *cfg)
Definition: test_config.c:875

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_link, ao2_ref, ast_strdup, cfg_hooks, cfg_hook::filename, cfg_hook::hook_cb, hook_cb(), hook_cmp(), hook_destroy(), hook_hash(), cfg_hook::module, name, cfg_hook::name, and NULL.

Referenced by AST_TEST_DEFINE().

◆ ast_config_hook_unregister()

void ast_config_hook_unregister ( const char *  name)

Unregister a config hook.

Parameters
nameThe name of the hook to unregister

Definition at line 4289 of file main/config.c.

4290{
4291 struct cfg_hook tmp;
4292
4293 tmp.name = ast_strdupa(name);
4294
4296}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_UNLINK
Definition: astobj2.h:1039
static int tmp()
Definition: bt_open.c:389

References ao2_find, ast_strdupa, cfg_hooks, name, OBJ_NODATA, OBJ_POINTER, OBJ_UNLINK, and tmp().

Referenced by AST_TEST_DEFINE().

◆ ast_config_internal_load()

struct ast_config * ast_config_internal_load ( const char *  filename,
struct ast_config cfg,
struct ast_flags  flags,
const char *  suggested_include_file,
const char *  who_asked 
)

Definition at line 3294 of file main/config.c.

3295{
3296 char db[256];
3297 char table[256];
3298 struct ast_config_engine *loader = &text_file_engine;
3299 struct ast_config *result;
3300
3301 /* The config file itself bumps include_level by 1 */
3302 if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
3303 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
3304 return NULL;
3305 }
3306
3307 cfg->include_level++;
3308
3310 struct ast_config_engine *eng;
3311
3312 eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
3313
3314
3315 if (eng && eng->load_func) {
3316 loader = eng;
3317 } else {
3318 eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
3319 if (eng && eng->load_func)
3320 loader = eng;
3321 }
3322 }
3323
3324 result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
3325
3327 result->include_level--;
3328 config_hook_exec(filename, who_asked, result);
3329 } else if (result != CONFIG_STATUS_FILEINVALID) {
3330 cfg->include_level--;
3331 }
3332
3333 return result;
3334}
#define ast_log
Definition: astobj2.c:42
static char * table
Definition: cdr_odbc.c:55
static sqlite3 * db
static PGresult * result
Definition: cel_pgsql.c:84
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
@ CONFIG_FLAG_NOREALTIME
#define LOG_WARNING
static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg)
Definition: main/config.c:4298
static struct ast_config_engine text_file_engine
Definition: main/config.c:3256
config_load_func * load_func
int include_level
Definition: main/config.c:257
int max_include_level
Definition: main/config.c:258
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_log, ast_test_flag, config_engine_list, 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, NULL, result, table, and text_file_engine.

Referenced by ast_config_load2(), config_curl(), config_ldap(), config_mysql(), config_odbc(), config_pgsql(), process_text_line(), reload_module(), and static_realtime_cb().

◆ ast_config_load2()

struct ast_config * ast_config_load2 ( const char *  filename,
const char *  who_asked,
struct ast_flags  flags 
)

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 3336 of file main/config.c.

3337{
3338 struct ast_config *cfg;
3339 struct ast_config *result;
3340
3341 cfg = ast_config_new();
3342 if (!cfg)
3343 return NULL;
3344
3345 result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
3347 ast_config_destroy(cfg);
3348
3349 return result;
3350}
struct ast_config * ast_config_internal_load(const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
Definition: main/config.c:3294

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

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_sorcery_apply_config(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), ast_cli_perms_init(), ast_init_logger_for_socket_console(), AST_TEST_DEFINE(), do_reload(), iax_provision_reload(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), load_asterisk_conf(), load_config(), load_indications(), loader_config_init(), object_type_loaded_observer(), private_enum_init(), read_pjproject_startup_options(), rtp_reload(), run_startup_commands(), set_config(), sorcery_config_internal_load(), and xmldoc_load_documentation().

◆ ast_config_new()

struct ast_config * ast_config_new ( void  )

◆ ast_config_option()

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 774 of file main/config.c.

775{
776 const char *tmp;
777 tmp = ast_variable_retrieve(cfg, cat, var);
778 if (!tmp) {
779 tmp = ast_variable_retrieve(cfg, "general", var);
780 }
781 return tmp;
782}
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:784

References ast_variable_retrieve(), tmp(), and var.

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

◆ ast_config_set_current_category()

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 1650 of file main/config.c.

1651{
1652 /* cast below is just to silence compiler warning about dropping "const" */
1653 cfg->current = (struct ast_category *) cat;
1654}

References ast_config::current.

Referenced by process_text_line().

◆ ast_config_sort_categories()

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
comparatorvariable Which 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 1269 of file main/config.c.

1271{
1272 /*
1273 * The contents of this function are adapted from
1274 * an example of linked list merge sorting
1275 * copyright 2001 Simon Tatham.
1276 *
1277 * Permission is hereby granted, free of charge, to any person
1278 * obtaining a copy of this software and associated documentation
1279 * files (the "Software"), to deal in the Software without
1280 * restriction, including without limitation the rights to use,
1281 * copy, modify, merge, publish, distribute, sublicense, and/or
1282 * sell copies of the Software, and to permit persons to whom the
1283 * Software is furnished to do so, subject to the following
1284 * conditions:
1285 *
1286 * The above copyright notice and this permission notice shall be
1287 * included in all copies or substantial portions of the Software.
1288 *
1289 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1290 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1291 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1292 * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
1293 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
1294 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1295 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1296 * SOFTWARE.
1297 */
1298
1299 int insize = 1;
1300 struct ast_category *p, *q, *e, *tail;
1301 int nmerges, psize, qsize, i;
1302
1303 /* If the descending flag was sent, we'll apply inversion to the comparison function's return. */
1304 if (descending) {
1305 descending = -1;
1306 } else {
1307 descending = 1;
1308 }
1309
1310 if (!config->root) {
1311 return;
1312 }
1313
1314 while (1) {
1315 p = config->root;
1316 config->root = NULL;
1317 tail = NULL;
1318
1319 nmerges = 0; /* count number of merges we do in this pass */
1320
1321 while (p) {
1322 nmerges++; /* there exists a merge to be done */
1323
1324 /* step `insize' places along from p */
1325 q = p;
1326 psize = 0;
1327 for (i = 0; i < insize; i++) {
1328 psize++;
1329 q = q->next;
1330 if (!q) {
1331 break;
1332 }
1333 }
1334
1335 /* if q hasn't fallen off end, we have two lists to merge */
1336 qsize = insize;
1337
1338 /* now we have two lists; merge them */
1339 while (psize > 0 || (qsize > 0 && q)) {
1340 /* decide whether next element of merge comes from p or q */
1341 if (psize == 0) {
1342 /* p is empty; e must come from q. */
1343 e = q;
1344 q = q->next;
1345 qsize--;
1346 } else if (qsize == 0 || !q) {
1347 /* q is empty; e must come from p. */
1348 e = p; p = p->next; psize--;
1349 } else if ((comparator(p,q) * descending) <= 0) {
1350 /* First element of p is lower (or same) e must come from p. */
1351 e = p;
1352 p = p->next;
1353 psize--;
1354 } else {
1355 /* First element of q is lower; e must come from q. */
1356 e = q;
1357 q = q->next;
1358 qsize--;
1359 }
1360
1361 /* add the next element to the merged list */
1362 if (tail) {
1363 tail->next = e;
1364 } else {
1365 config->root = e;
1366 }
1367 tail = e;
1368 }
1369
1370 /* now p has stepped `insize' places along, and q has too */
1371 p = q;
1372 }
1373
1374 tail->next = NULL;
1375
1376 /* If we have done only one merge, we're finished. */
1377 if (nmerges <= 1) { /* allow for nmerges==0, the empty list case */
1378 return;
1379 }
1380
1381 /* Otherwise repeat, merging lists twice the size */
1382 insize *= 2;
1383 }
1384
1385}

References config, ast_category::next, and NULL.

Referenced by named_acl_find_realtime(), and realtime_switch_common().

◆ ast_config_text_file_save()

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

Save a config text file preserving the pre 13.2 behavior.

Parameters
filenameFilename
cfgast_config
generatorgenerator
Return values
0on success.
-1on failure.

Definition at line 2716 of file main/config.c.

2717{
2719}
@ CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT
int ast_config_text_file_save2(const char *configfile, const struct ast_config *cfg, const char *generator, uint32_t flags)
Save a config text file.
Definition: main/config.c:2740

References ast_config_text_file_save2(), and CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT.

Referenced by add_message_id(), AST_TEST_DEFINE(), vm_change_password(), vm_forwardoptions(), and write_password_to_file().

◆ ast_config_text_file_save2()

int ast_config_text_file_save2 ( const char *  filename,
const struct ast_config cfg,
const char *  generator,
uint32_t  flags 
)

Save a config text file.

Since
13.2.0
Parameters
filenameFilename
cfgast_config
generatorgenerator
flagsList of config_save_flags
Return values
0on success.
-1on failure.

Definition at line 2740 of file main/config.c.

2741{
2742 FILE *f;
2743 char fn[PATH_MAX];
2744 struct ast_variable *var;
2745 struct ast_category *cat;
2746 struct ast_comment *cmt;
2747 struct ast_config_include *incl;
2748 int blanklines = 0;
2749 struct ao2_container *fileset;
2750 struct inclfile *fi;
2751
2754 if (!fileset) {
2755 /* Container creation failed. */
2756 return -1;
2757 }
2758
2759 /* Check all the files for write access before attempting to modify any of them */
2760 for (incl = cfg->includes; incl; incl = incl->next) {
2761 /* reset all the output flags in case this isn't our first time saving this data */
2762 incl->output = 0;
2763
2764 if (!incl->exec) {
2765 /* now make sure we have write access to the include file or its parent directory */
2766 make_fn(fn, sizeof(fn), incl->included_file, configfile);
2767 /* If the file itself doesn't exist, make sure we have write access to the directory */
2768 if (!is_writable(fn)) {
2769 return -1;
2770 }
2771 }
2772 }
2773
2774 /* now make sure we have write access to the main config file or its parent directory */
2775 make_fn(fn, sizeof(fn), 0, configfile);
2776 if (!is_writable(fn)) {
2777 return -1;
2778 }
2779
2780 /* Now that we know we have write access to all files, it's safe to start truncating them */
2781
2782 /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
2783 are all truncated to zero bytes and have that nice header*/
2784 for (incl = cfg->includes; incl; incl = incl->next) {
2785 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*/
2786 /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
2787 fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
2788 f = fopen(fn, "w");
2789 if (f) {
2790 gen_header(f, configfile, fn, generator);
2791 fclose(f); /* this should zero out the file */
2792 } else {
2793 ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
2794 }
2795 if (fi) {
2796 ao2_ref(fi, -1);
2797 }
2798 }
2799 }
2800
2801 /* just set fn to absolute ver of configfile */
2802 fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
2803 if (
2804#ifdef __CYGWIN__
2805 (f = fopen(fn, "w+"))
2806#else
2807 (f = fopen(fn, "w"))
2808#endif
2809 ) {
2810 ast_verb(2, "Saving '%s'\n", fn);
2811 gen_header(f, configfile, fn, generator);
2812 cat = cfg->root;
2813 fclose(f);
2814 if (fi) {
2815 ao2_ref(fi, -1);
2816 }
2817
2818 /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
2819 /* since each var, cat, and associated comments can come from any file, we have to be
2820 mobile, and open each file, print, and close it on an entry-by-entry basis */
2821
2822 while (cat) {
2823 fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
2824 f = fopen(fn, "a");
2825 if (!f) {
2826 ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
2827 if (fi) {
2828 ao2_ref(fi, -1);
2829 }
2830 ao2_ref(fileset, -1);
2831 return -1;
2832 }
2833
2834 /* dump any includes that happen before this category header */
2835 for (incl=cfg->includes; incl; incl = incl->next) {
2836 if (strcmp(incl->include_location_file, cat->file) == 0){
2837 if (cat->lineno > incl->include_location_lineno && !incl->output) {
2838 if (incl->exec)
2839 fprintf(f,"#exec \"%s\"\n", incl->exec_file);
2840 else
2841 fprintf(f,"#include \"%s\"\n", incl->included_file);
2842 incl->output = 1;
2843 }
2844 }
2845 }
2846
2848 /* Dump section with any appropriate comment */
2849 for (cmt = cat->precomments; cmt; cmt=cmt->next) {
2850 char *cmtp = cmt->cmt;
2851 while (cmtp && *cmtp == ';' && *(cmtp+1) == '!') {
2852 char *cmtp2 = strchr(cmtp+1, '\n');
2853 if (cmtp2)
2854 cmtp = cmtp2+1;
2855 else cmtp = 0;
2856 }
2857 if (cmtp)
2858 fprintf(f,"%s", cmtp);
2859 }
2860 fprintf(f, "[%s]", cat->name);
2861 if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
2862 fprintf(f, "(");
2863 if (cat->ignored) {
2864 fprintf(f, "!");
2865 }
2866 if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
2867 fprintf(f, ",");
2868 }
2869 if (!AST_LIST_EMPTY(&cat->template_instances)) {
2872 fprintf(f,"%s",x->name);
2873 if (x != AST_LIST_LAST(&cat->template_instances))
2874 fprintf(f,",");
2875 }
2876 }
2877 fprintf(f, ")");
2878 }
2879 for(cmt = cat->sameline; cmt; cmt=cmt->next)
2880 {
2881 fprintf(f,"%s", cmt->cmt);
2882 }
2883 if (!cat->sameline)
2884 fprintf(f,"\n");
2885 for (cmt = cat->trailing; cmt; cmt=cmt->next) {
2886 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
2887 fprintf(f,"%s", cmt->cmt);
2888 }
2889 fclose(f);
2890 if (fi) {
2891 ao2_ref(fi, -1);
2892 }
2893
2894 var = cat->root;
2895 while (var) {
2897 int found = 0;
2898
2900 struct ast_variable *v;
2901 for (v = x->inst->root; v; v = v->next) {
2902
2904 if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
2905 found = 1;
2906 break;
2907 }
2908 } else {
2909 if (var->inherited) {
2910 found = 1;
2911 break;
2912 } else {
2913 if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
2914 found = 1;
2915 break;
2916 }
2917 }
2918 }
2919 }
2920 if (found) {
2921 break;
2922 }
2923 }
2924 if (found) {
2925 var = var->next;
2926 continue;
2927 }
2928 fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
2929 f = fopen(fn, "a");
2930 if (!f) {
2931 ast_debug(1, "Unable to open for writing: %s\n", fn);
2932 ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
2933 if (fi) {
2934 ao2_ref(fi, -1);
2935 }
2936 ao2_ref(fileset, -1);
2937 return -1;
2938 }
2939
2940 /* dump any includes that happen before this category header */
2941 for (incl=cfg->includes; incl; incl = incl->next) {
2942 if (strcmp(incl->include_location_file, var->file) == 0){
2943 if (var->lineno > incl->include_location_lineno && !incl->output) {
2944 if (incl->exec)
2945 fprintf(f,"#exec \"%s\"\n", incl->exec_file);
2946 else
2947 fprintf(f,"#include \"%s\"\n", incl->included_file);
2948 incl->output = 1;
2949 }
2950 }
2951 }
2952
2953 insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
2954 for (cmt = var->precomments; cmt; cmt=cmt->next) {
2955 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
2956 fprintf(f,"%s", cmt->cmt);
2957 }
2958
2959 { /* Block for 'escaped' scope */
2960 int escaped_len = 2 * strlen(var->value) + 1;
2961 char escaped[escaped_len];
2962
2963 ast_escape_semicolons(var->value, escaped, escaped_len);
2964
2965 if (var->sameline) {
2966 fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="),
2967 escaped, var->sameline->cmt);
2968 } else {
2969 fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="),
2970 escaped);
2971 }
2972 }
2973
2974 for (cmt = var->trailing; cmt; cmt=cmt->next) {
2975 if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
2976 fprintf(f,"%s", cmt->cmt);
2977 }
2978 if (var->blanklines) {
2979 blanklines = var->blanklines;
2980 while (blanklines--)
2981 fprintf(f, "\n");
2982 }
2983
2984 fclose(f);
2985 if (fi) {
2986 ao2_ref(fi, -1);
2987 }
2988
2989 var = var->next;
2990 }
2991 cat = cat->next;
2992 }
2993 ast_verb(2, "Saving '%s': saved\n", fn);
2994 } else {
2995 ast_debug(1, "Unable to open for writing: %s\n", fn);
2996 ast_verb(2, "Unable to write '%s' (%s)\n", fn, strerror(errno));
2997 if (fi) {
2998 ao2_ref(fi, -1);
2999 }
3000 ao2_ref(fileset, -1);
3001 return -1;
3002 }
3003
3004 /* Now, for files with trailing #include/#exec statements,
3005 we have to make sure every entry is output */
3006 for (incl=cfg->includes; incl; incl = incl->next) {
3007 if (!incl->output) {
3008 /* open the respective file */
3009 fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
3010 f = fopen(fn, "a");
3011 if (!f) {
3012 ast_debug(1, "Unable to open for writing: %s\n", fn);
3013 ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
3014 if (fi) {
3015 ao2_ref(fi, -1);
3016 }
3017 ao2_ref(fileset, -1);
3018 return -1;
3019 }
3020
3021 /* output the respective include */
3022 if (incl->exec)
3023 fprintf(f,"#exec \"%s\"\n", incl->exec_file);
3024 else
3025 fprintf(f,"#include \"%s\"\n", incl->included_file);
3026 fclose(f);
3027 incl->output = 1;
3028 if (fi) {
3029 ao2_ref(fi, -1);
3030 }
3031 }
3032 }
3033 ao2_ref(fileset, -1); /* this should destroy the hash container */
3034
3035 /* pass new configuration to any config hooks */
3036 config_hook_exec(configfile, generator, cfg);
3037
3038 return 0;
3039}
#define PATH_MAX
Definition: asterisk.h:40
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define ast_verb(level,...)
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
Definition: main/config.c:2680
static int hashtab_compare_strings(void *a, void *b, int flags)
Definition: main/config.c:194
static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
Definition: main/config.c:2584
static int hash_string(const void *obj, const int flags)
Definition: main/config.c:174
static struct inclfile * set_fn(char *fn, size_t fn_size, const char *file, const char *configfile, struct ao2_container *fileset)
Definition: main/config.c:2625
static int is_writable(const char *fn)
Definition: main/config.c:2721
static void make_fn(char *fn, size_t fn_size, const char *file, const char *configfile)
Definition: main/config.c:2610
int errno
Generic container type.
char * include_location_file
file name in which the include occurs
Definition: main/config.c:267
char * exec_file
if it's an exec, you'll have both the /var/tmp to read, and the original script
Definition: main/config.c:274
char * included_file
file name included
Definition: main/config.c:279
struct ast_config_include * next
Definition: main/config.c:283
struct ast_variable * next
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
Definition: utils.c:811

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_debug, ast_escape_semicolons(), AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_log, ast_verb, ast_comment::cmt, config_hook_exec(), CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT, errno, ast_config_include::exec, ast_config_include::exec_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, is_writable(), ast_category::lineno, LOG_ERROR, make_fn(), ast_variable::name, ast_category_template_instance::name, ast_category::name, ast_variable::next, ast_comment::next, ast_category::next, ast_config_include::next, NULL, ast_config_include::output, PATH_MAX, ast_category::precomments, ast_category::root, ast_config::root, ast_category::sameline, set_fn(), ast_category::template_instances, ast_category::trailing, ast_variable::value, and var.

Referenced by action_updateconfig(), and ast_config_text_file_save().

◆ ast_destroy_realtime()

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 3791 of file main/config.c.

3792{
3793 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3794 int res = 0;
3795 va_list ap;
3796
3797 va_start(ap, lookup);
3798 if (realtime_arguments_to_fields(ap, &fields)) {
3799 res = -1;
3800 }
3801 va_end(ap);
3802
3803 if (res) {
3804 return -1;
3805 }
3806
3807 return ast_destroy_realtime_fields(family, keyfield, lookup, fields);
3808}
int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Destroy realtime configuration.
Definition: main/config.c:3771
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3352
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ast_destroy_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

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

◆ ast_destroy_realtime_fields()

int ast_destroy_realtime_fields ( const char *  family,
const char *  keyfield,
const char *  lookup,
const struct ast_variable fields 
)

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.
fieldsfields themselves

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.

Definition at line 3771 of file main/config.c.

3772{
3773 struct ast_config_engine *eng;
3774 int res = -1, i;
3775 char db[256];
3776 char table[256];
3777
3778 for (i = 1; ; i++) {
3779 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3780 if (eng->destroy_func && ((res = eng->destroy_func(db, table, keyfield, lookup, fields)) >= 0)) {
3781 break;
3782 }
3783 } else {
3784 break;
3785 }
3786 }
3787
3788 return res;
3789}
realtime_destroy * destroy_func

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

Referenced by ast_destroy_realtime(), and sorcery_realtime_delete().

◆ ast_destroy_template_list()

static void ast_destroy_template_list ( struct ast_category cat)
static

Definition at line 1212 of file main/config.c.

1213{
1215
1216 while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
1217 ast_free(x);
1218}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833

References ast_free, AST_LIST_REMOVE_HEAD, ast_category::next, and ast_category::template_instances.

Referenced by ast_category_destroy().

◆ ast_include_find()

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

Definition at line 476 of file main/config.c.

477{
478 struct ast_config_include *x;
479 for (x=conf->includes;x;x=x->next) {
480 if (strcmp(x->included_file,included_file) == 0)
481 return x;
482 }
483 return 0;
484}
All configuration options for http media cache.

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

Referenced by ast_include_new().

◆ ast_include_new()

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 
)

Definition at line 336 of file main/config.c.

337{
338 /* a file should be included ONCE. Otherwise, if one of the instances is changed,
339 * then all be changed. -- how do we know to include it? -- Handling modified
340 * instances is possible, I'd have
341 * to create a new master for each instance. */
342 struct ast_config_include *inc;
343 struct stat statbuf;
344
345 inc = ast_include_find(conf, included_file);
346 if (inc) {
347 do {
348 inc->inclusion_count++;
349 snprintf(real_included_file_name, real_included_file_name_size, "%s~~%d", included_file, inc->inclusion_count);
350 } while (stat(real_included_file_name, &statbuf) == 0);
351 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);
352 } else
353 *real_included_file_name = 0;
354
355 inc = ast_calloc(1,sizeof(struct ast_config_include));
356 if (!inc) {
357 return NULL;
358 }
359 inc->include_location_file = ast_strdup(from_file);
360 inc->include_location_lineno = from_lineno;
361 if (!ast_strlen_zero(real_included_file_name))
362 inc->included_file = ast_strdup(real_included_file_name);
363 else
364 inc->included_file = ast_strdup(included_file);
365
366 inc->exec = is_exec;
367 if (is_exec)
368 inc->exec_file = ast_strdup(exec_file);
369
370 if (!inc->include_location_file
371 || !inc->included_file
372 || (is_exec && !inc->exec_file)) {
374 return NULL;
375 }
376
377 /* attach this new struct to the conf struct */
378 inc->next = conf->includes;
379 conf->includes = inc;
380
381 return inc;
382}
struct ast_config_include * ast_include_find(struct ast_config *conf, const char *included_file)
Definition: main/config.c:476
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_calloc, ast_include_find(), ast_includes_destroy(), ast_log, ast_strdup, ast_strlen_zero(), ast_config_include::exec, ast_config_include::exec_file, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config_include::inclusion_count, LOG_WARNING, ast_config_include::next, and NULL.

Referenced by AST_TEST_DEFINE(), and process_text_line().

◆ ast_include_rename()

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

Definition at line 384 of file main/config.c.

385{
386 struct ast_config_include *incl;
387 struct ast_category *cat;
388 char *str;
389
390 int from_len = strlen(from_file);
391 int to_len = strlen(to_file);
392
393 if (strcmp(from_file, to_file) == 0) /* no use wasting time if the name is the same */
394 return;
395
396 /* the manager code allows you to read in one config file, then
397 * write it back out under a different name. But, the new arrangement
398 * ties output lines to the file name. So, before you try to write
399 * the config file to disk, better riffle thru the data and make sure
400 * the file names are changed.
401 */
402 /* file names are on categories, includes (of course), and on variables. So,
403 * traverse all this and swap names */
404
405 for (incl = conf->includes; incl; incl=incl->next) {
406 if (strcmp(incl->include_location_file,from_file) == 0) {
407 if (from_len >= to_len)
408 strcpy(incl->include_location_file, to_file);
409 else {
410 /* Keep the old filename if the allocation fails. */
411 str = ast_strdup(to_file);
412 if (str) {
415 }
416 }
417 }
418 }
419 for (cat = conf->root; cat; cat = cat->next) {
420 struct ast_variable **prev;
421 struct ast_variable *v;
422 struct ast_variable *new_var;
423
424 if (strcmp(cat->file,from_file) == 0) {
425 if (from_len >= to_len)
426 strcpy(cat->file, to_file);
427 else {
428 /* Keep the old filename if the allocation fails. */
429 str = ast_strdup(to_file);
430 if (str) {
431 ast_free(cat->file);
432 cat->file = str;
433 }
434 }
435 }
436 for (prev = &cat->root, v = cat->root; v; prev = &v->next, v = v->next) {
437 if (strcmp(v->file, from_file)) {
438 continue;
439 }
440
441 /*
442 * Calculate actual space available. The file string is
443 * intentionally stuffed before the name string just so we can
444 * do this.
445 */
446 if (to_len < v->name - v->file) {
447 /* The new name will fit in the available space. */
448 str = (char *) v->file;/* Stupid compiler complains about discarding qualifiers even though I used a cast. */
449 strcpy(str, to_file);/* SAFE */
450 continue;
451 }
452
453 /* Keep the old filename if the allocation fails. */
454 new_var = ast_variable_new(v->name, v->value, to_file);
455 if (!new_var) {
456 continue;
457 }
458
459 /* Move items from the old list node to the replacement node. */
460 ast_variable_move(new_var, v);
461
462 /* Replace the old node in the list with the new node. */
463 new_var->next = v->next;
464 if (cat->last == v) {
465 cat->last = new_var;
466 }
467 *prev = new_var;
468
470
471 v = new_var;
472 }
473 }
474}
#define ast_variable_new(name, value, filename)
static void ast_variable_destroy(struct ast_variable *doomed)
Definition: main/config.c:536
static void ast_variable_move(struct ast_variable *dst_var, struct ast_variable *src_var)
Definition: main/config.c:323

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_category::last, name, ast_variable::name, ast_variable::next, ast_category::next, ast_config_include::next, ast_category::root, str, and ast_variable::value.

Referenced by action_updateconfig().

◆ ast_includes_destroy()

static void ast_includes_destroy ( struct ast_config_include incls)
static

Definition at line 1233 of file main/config.c.

1234{
1235 struct ast_config_include *incl,*inclnext;
1236
1237 for (incl=incls; incl; incl = inclnext) {
1238 inclnext = incl->next;
1240 ast_free(incl->exec_file);
1241 ast_free(incl->included_file);
1242 ast_free(incl);
1243 }
1244}

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

Referenced by ast_config_destroy(), and ast_include_new().

◆ ast_load_realtime()

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

Definition at line 3521 of file main/config.c.

3522{
3523 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3524 int field_res = 0;
3525 va_list ap;
3526
3527 va_start(ap, family);
3528 if (realtime_arguments_to_fields(ap, &fields)) {
3529 field_res = -1;
3530 }
3531 va_end(ap);
3532
3533 if (field_res) {
3534 return NULL;
3535 }
3536
3537 if (!fields) {
3538 return NULL;
3539 }
3540
3541 return ast_load_realtime_fields(family, fields);
3542}
struct ast_variable * ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3486

References ast_load_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by conf_run(), copy_plain_file(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_user_realtime(), leave_queue(), load_realtime_musiconhold(), queue_function_queuegetchannel(), queue_function_queuewaitingcount(), realtime_peer(), realtime_switch_common(), realtime_user(), and rt_extend_conf().

◆ ast_load_realtime_all()

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

Definition at line 3469 of file main/config.c.

3470{
3471 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3472 struct ast_variable *res = NULL;
3473 va_list ap;
3474
3475 va_start(ap, family);
3476 realtime_arguments_to_fields(ap, &fields);
3477 va_end(ap);
3478
3479 if (fields) {
3480 res = ast_load_realtime_all_fields(family, fields);
3481 }
3482
3483 return res;
3484}
struct ast_variable * ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
Definition: main/config.c:3448

References ast_load_realtime_all_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

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

◆ ast_load_realtime_all_fields()

struct ast_variable * ast_load_realtime_all_fields ( const char *  family,
const struct ast_variable fields 
)

Definition at line 3448 of file main/config.c.

3449{
3450 struct ast_config_engine *eng;
3451 char db[256];
3452 char table[256];
3453 struct ast_variable *res=NULL;
3454 int i;
3455
3456 for (i = 1; ; i++) {
3457 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3458 if (eng->realtime_func && (res = eng->realtime_func(db, table, fields))) {
3459 return res;
3460 }
3461 } else {
3462 return NULL;
3463 }
3464 }
3465
3466 return res;
3467}
realtime_var_get * realtime_func

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

Referenced by ast_load_realtime_all(), and ast_load_realtime_fields().

◆ ast_load_realtime_fields()

struct ast_variable * ast_load_realtime_fields ( const char *  family,
const struct ast_variable fields 
)

Retrieve realtime configuration.

Parameters
familywhich family/config to lookup
fieldswhich fields 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 3486 of file main/config.c.

3487{
3488 struct ast_variable *res;
3489 struct ast_variable *cur;
3490 struct ast_variable **prev;
3491
3492 res = ast_load_realtime_all_fields(family, fields);
3493
3494 /* Filter the list. */
3495 prev = &res;
3496 cur = res;
3497 while (cur) {
3498 if (ast_strlen_zero(cur->value)) {
3499 /* Eliminate empty entries */
3500 struct ast_variable *next;
3501
3502 next = cur->next;
3503 *prev = next;
3505 cur = next;
3506 } else {
3507 /* Make blank entries empty and keep them. */
3508 if (cur->value[0] == ' ' && cur->value[1] == '\0') {
3509 char *vptr = (char *) cur->value;
3510
3511 vptr[0] = '\0';
3512 }
3513
3514 prev = &cur->next;
3515 cur = cur->next;
3516 }
3517 }
3518 return res;
3519}

References ast_load_realtime_all_fields(), ast_strlen_zero(), ast_variable_destroy(), ast_variable::next, ast_category::next, ast_category::prev, and ast_variable::value.

Referenced by ast_load_realtime(), and sorcery_realtime_retrieve_fields().

◆ ast_load_realtime_multientry()

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

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 3637 of file main/config.c.

3638{
3639 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3640 va_list ap;
3641
3642 va_start(ap, family);
3643 realtime_arguments_to_fields(ap, &fields);
3644 va_end(ap);
3645
3646 if (!fields) {
3647 return NULL;
3648 }
3649
3650 return ast_load_realtime_multientry_fields(family, fields);
3651}
struct ast_config * ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3611

References ast_load_realtime_multientry_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by __queues_show(), conf_exec(), find_load_queue_rt_friendly(), find_realtime(), load_module(), load_realtime_musiconhold(), load_realtime_queues(), load_realtime_rules(), named_acl_find_realtime(), realtime_directory(), realtime_switch_common(), set_member_value(), show_users_realtime(), and update_realtime_members().

◆ ast_load_realtime_multientry_fields()

struct ast_config * ast_load_realtime_multientry_fields ( const char *  family,
const struct ast_variable fields 
)

Retrieve realtime configuration.

Parameters
familywhich family/config to lookup
fieldslist of fields

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

Definition at line 3611 of file main/config.c.

3612{
3613 struct ast_config_engine *eng;
3614 char db[256];
3615 char table[256];
3616 struct ast_config *res = NULL;
3617 int i;
3618
3619 for (i = 1; ; i++) {
3620 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3621 if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, fields))) {
3622 /* If we were returned an empty cfg, destroy it and return NULL */
3623 if (!res->root) {
3624 ast_config_destroy(res);
3625 res = NULL;
3626 }
3627 break;
3628 }
3629 } else {
3630 break;
3631 }
3632 }
3633
3634 return res;
3635}
realtime_multi_get * realtime_multi_func

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

Referenced by ast_load_realtime_multientry(), and sorcery_realtime_retrieve_multiple().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 4367 of file main/config.c.

◆ ast_parse_arg()

int ast_parse_arg ( const char *  arg,
enum ast_parse_flags  flags,
void *  p_result,
  ... 
)

Helper function to parse arguments See documentation in config.h.

The argument parsing routine.

Definition at line 3842 of file main/config.c.

3844{
3845 va_list ap;
3846 int error = 0;
3847
3848 va_start(ap, p_result);
3849 switch (flags & PARSE_TYPE) {
3850 case PARSE_INT32:
3851 {
3852 long int x = 0;
3853 int32_t *result = p_result;
3854 int32_t def = result ? *result : 0, high = INT32_MAX, low = INT32_MIN;
3855 char *endptr = NULL;
3856
3857 /* optional arguments: default value and/or (low, high) */
3858 if (flags & PARSE_DEFAULT) {
3859 def = va_arg(ap, int32_t);
3860 }
3861 if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
3862 low = va_arg(ap, int32_t);
3863 high = va_arg(ap, int32_t);
3864 }
3865 if (ast_strlen_zero(arg)) {
3866 error = 1;
3867 goto int32_done;
3868 }
3869 errno = 0;
3870 x = strtol(arg, &endptr, 0);
3871 if (*endptr || errno || x < INT32_MIN || x > INT32_MAX) {
3872 /* Parse error, or type out of int32_t bounds */
3873 error = 1;
3874 goto int32_done;
3875 }
3876 error = (x < low) || (x > high);
3877 if (flags & PARSE_RANGE_DEFAULTS) {
3878 if (x < low) {
3879 def = low;
3880 } else if (x > high) {
3881 def = high;
3882 }
3883 }
3884 if (flags & PARSE_OUT_RANGE) {
3885 error = !error;
3886 }
3887int32_done:
3888 if (result) {
3889 *result = error ? def : x;
3890 }
3891
3892 ast_debug(3, "extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
3893 arg, low, high, result ? *result : x, error);
3894 break;
3895 }
3896
3897 case PARSE_UINT32:
3898 {
3899 unsigned long int x = 0;
3900 uint32_t *result = p_result;
3901 uint32_t def = result ? *result : 0, low = 0, high = UINT32_MAX;
3902 char *endptr = NULL;
3903
3904 /* optional argument: first default value, then range */
3905 if (flags & PARSE_DEFAULT) {
3906 def = va_arg(ap, uint32_t);
3907 }
3908 if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
3909 /* range requested, update bounds */
3910 low = va_arg(ap, uint32_t);
3911 high = va_arg(ap, uint32_t);
3912 }
3913
3914 if (ast_strlen_zero(arg)) {
3915 error = 1;
3916 goto uint32_done;
3917 }
3918 /* strtoul will happily and silently negate negative numbers */
3919 arg = ast_skip_blanks(arg);
3920 if (*arg == '-') {
3921 error = 1;
3922 goto uint32_done;
3923 }
3924 errno = 0;
3925 x = strtoul(arg, &endptr, 0);
3926 if (*endptr || errno || x > UINT32_MAX) {
3927 error = 1;
3928 goto uint32_done;
3929 }
3930 error = (x < low) || (x > high);
3931 if (flags & PARSE_RANGE_DEFAULTS) {
3932 if (x < low) {
3933 def = low;
3934 } else if (x > high) {
3935 def = high;
3936 }
3937 }
3938 if (flags & PARSE_OUT_RANGE) {
3939 error = !error;
3940 }
3941uint32_done:
3942 if (result) {
3943 *result = error ? def : x;
3944 }
3945 ast_debug(3, "extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
3946 arg, low, high, result ? *result : x, error);
3947 break;
3948 }
3949
3950 case PARSE_TIMELEN:
3951 {
3952 int x = 0;
3953 int *result = p_result;
3954 int def = result ? *result : 0;
3955 int high = INT_MAX;
3956 int low = INT_MIN;
3957 enum ast_timelen defunit;
3958
3959 defunit = va_arg(ap, enum ast_timelen);
3960 /* optional arguments: default value and/or (low, high) */
3961 if (flags & PARSE_DEFAULT) {
3962 def = va_arg(ap, int);
3963 }
3964 if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
3965 low = va_arg(ap, int);
3966 high = va_arg(ap, int);
3967 }
3968 if (ast_strlen_zero(arg)) {
3969 error = 1;
3970 goto timelen_done;
3971 }
3972 error = ast_app_parse_timelen(arg, &x, defunit);
3973 if (error || x < INT_MIN || x > INT_MAX) {
3974 /* Parse error, or type out of int bounds */
3975 error = 1;
3976 goto timelen_done;
3977 }
3978 error = (x < low) || (x > high);
3979 if (flags & PARSE_RANGE_DEFAULTS) {
3980 if (x < low) {
3981 def = low;
3982 } else if (x > high) {
3983 def = high;
3984 }
3985 }
3986 if (flags & PARSE_OUT_RANGE) {
3987 error = !error;
3988 }
3989timelen_done:
3990 if (result) {
3991 *result = error ? def : x;
3992 }
3993
3994 ast_debug(3, "extract timelen from [%s] in [%d, %d] gives [%d](%d)\n",
3995 arg, low, high, result ? *result : x, error);
3996 break;
3997 }
3998
3999 case PARSE_DOUBLE:
4000 {
4001 double *result = p_result;
4002 double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
4003 char *endptr = NULL;
4004
4005 /* optional argument: first default value, then range */
4006 if (flags & PARSE_DEFAULT) {
4007 def = va_arg(ap, double);
4008 }
4009 if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
4010 /* range requested, update bounds */
4011 low = va_arg(ap, double);
4012 high = va_arg(ap, double);
4013 }
4014 if (ast_strlen_zero(arg)) {
4015 error = 1;
4016 goto double_done;
4017 }
4018 errno = 0;
4019 x = strtod(arg, &endptr);
4020 if (*endptr || errno == ERANGE) {
4021 error = 1;
4022 goto double_done;
4023 }
4024 error = (x < low) || (x > high);
4025 if (flags & PARSE_OUT_RANGE) {
4026 error = !error;
4027 }
4028double_done:
4029 if (result) {
4030 *result = error ? def : x;
4031 }
4032 ast_debug(3, "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
4033 arg, low, high, result ? *result : x, error);
4034 break;
4035 }
4036 case PARSE_ADDR:
4037 {
4038 struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result;
4039
4040 if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) {
4041 error = 1;
4042 }
4043
4044 ast_debug(3, "extract addr from %s gives %s(%d)\n",
4045 arg, ast_sockaddr_stringify(addr), error);
4046
4047 break;
4048 }
4049 case PARSE_INADDR: /* TODO Remove this (use PARSE_ADDR instead). */
4050 {
4051 char *port, *buf;
4052 struct sockaddr_in _sa_buf; /* buffer for the result */
4053 struct sockaddr_in *sa = p_result ?
4054 (struct sockaddr_in *)p_result : &_sa_buf;
4055 /* default is either the supplied value or the result itself */
4056 struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
4057 va_arg(ap, struct sockaddr_in *) : sa;
4058 struct ast_sockaddr addr = { {0,} };
4059
4060 memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
4061 /* duplicate the string to strip away the :port */
4062 port = ast_strdupa(arg);
4063 buf = strsep(&port, ":");
4064 sa->sin_family = AF_INET; /* assign family */
4065 /*
4066 * honor the ports flag setting, assign default value
4067 * in case of errors or field unset.
4068 */
4069 flags &= PARSE_PORT_MASK; /* the only flags left to process */
4070 if (port) {
4071 if (flags == PARSE_PORT_FORBID) {
4072 error = 1; /* port was forbidden */
4073 sa->sin_port = def->sin_port;
4074 } else if (flags == PARSE_PORT_IGNORE)
4075 sa->sin_port = def->sin_port;
4076 else /* accept or require */
4077 sa->sin_port = htons(strtol(port, NULL, 0));
4078 } else {
4079 sa->sin_port = def->sin_port;
4080 if (flags == PARSE_PORT_REQUIRE)
4081 error = 1;
4082 }
4083 /* Now deal with host part, even if we have errors before. */
4084 if (ast_sockaddr_resolve_first_af(&addr, buf, PARSE_PORT_FORBID, AF_INET)) {
4085 error = 1;
4086 sa->sin_addr = def->sin_addr;
4087 } else {
4088 struct sockaddr_in tmp;
4089 ast_sockaddr_to_sin(&addr, &tmp);
4090 sa->sin_addr = tmp.sin_addr;
4091 }
4092 ast_debug(3,
4093 "extract inaddr from [%s] gives [%s:%d](%d)\n",
4094 arg, ast_inet_ntoa(sa->sin_addr),
4095 ntohs(sa->sin_port), error);
4096 break;
4097 }
4098 }
4099 va_end(ap);
4100 return error;
4101}
#define INT32_MAX
Definition: ast_expr2f.c:79
#define INT32_MIN
Definition: ast_expr2f.c:70
#define UINT32_MAX
Definition: ast_expr2f.c:88
int int32_t
Definition: db.h:60
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
Definition: main/app.c:3273
char * strsep(char **str, const char *delims)
@ PARSE_RANGE_DEFAULTS
@ PARSE_PORT_REQUIRE
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Return the first entry from ast_sockaddr_resolve filtered by address family.
Definition: netsock2.c:337
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:765
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:928
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
Socket address structure.
Definition: netsock2.h:97
int error(const char *format,...)
Definition: utils/frame.c:999

References ast_app_parse_timelen(), ast_debug, ast_inet_ntoa(), ast_skip_blanks(), ast_sockaddr_parse(), ast_sockaddr_resolve_first_af(), ast_sockaddr_stringify(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), buf, errno, error(), INT32_MAX, INT32_MIN, NULL, 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_TIMELEN, PARSE_TYPE, PARSE_UINT32, result, strsep(), tmp(), and UINT32_MAX.

Referenced by __ast_http_load(), __init_manager(), app_exec(), AST_TEST_DEFINE(), ast_tls_read_conf(), build_peer(), build_user(), configure_local_rtp(), double_handler_fn(), general_set(), iax2_call(), iax2_request(), int_handler_fn(), load_asterisk_conf(), load_config(), new_realtime_sqlite3_db(), realtime_peer(), reload_config(), rtp_reload(), sample_rate_handler(), set_config(), setup_rtp_connection(), setup_rtp_remote(), setup_udptl_connection(), sockaddr_handler_fn(), timelen_handler_fn(), uint_handler_fn(), and xfer_set().

◆ ast_realtime_append_mapping()

static int ast_realtime_append_mapping ( const char *  name,
const char *  driver,
const char *  database,
const char *  table,
int  priority 
)
static

Definition at line 3055 of file main/config.c.

3057{
3058 struct ast_config_map *map;
3059 char *dst;
3060 int length;
3061
3062 length = sizeof(*map);
3063 length += strlen(name) + 1;
3064 length += strlen(driver) + 1;
3065 length += strlen(database) + 1;
3066 if (table)
3067 length += strlen(table) + 1;
3068
3069 if (!(map = ast_calloc(1, length)))
3070 return -1;
3071
3072 dst = map->stuff; /* writable space starts here */
3073 map->name = strcpy(dst, name);
3074 dst += strlen(dst) + 1;
3075 map->driver = strcpy(dst, driver);
3076 dst += strlen(dst) + 1;
3077 map->database = strcpy(dst, database);
3078 if (table) {
3079 dst += strlen(dst) + 1;
3080 map->table = strcpy(dst, table);
3081 }
3082 map->priority = priority;
3083 map->next = config_maps;
3084 config_maps = map;
3085
3086 ast_verb(5, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
3087
3088 return 0;
3089}
static int priority
static struct ast_config_map * config_maps
const char * driver
Definition: main/config.c:206
struct ast_config_map * next
Definition: main/config.c:201
const char * table
Definition: main/config.c:210
const char * database
Definition: main/config.c:208
const char * name
Definition: main/config.c:204

References ast_calloc, ast_verb, config_maps, ast_config_map::database, ast_config_map::driver, name, ast_config_map::name, ast_config_map::next, priority, ast_config_map::priority, ast_config_map::stuff, table, and ast_config_map::table.

Referenced by load_module(), and reload_module().

◆ ast_realtime_decode_chunk()

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
Warning
This function modifies the original buffer

Definition at line 3810 of file main/config.c.

3811{
3812 char *orig = chunk;
3813 for (; *chunk; chunk++) {
3814 if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
3815 sscanf(chunk + 1, "%02hhX", (unsigned char *)chunk);
3816 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
3817 }
3818 }
3819 return orig;
3820}

Referenced by realtime_multi_pgsql(), and realtime_pgsql().

◆ ast_realtime_enabled()

int ast_realtime_enabled ( void  )

Check if there's any realtime engines loaded.

Definition at line 3559 of file main/config.c.

3560{
3561 return config_maps ? 1 : 0;
3562}

References config_maps.

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

◆ ast_realtime_encode_chunk()

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 3822 of file main/config.c.

3823{
3824 if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
3825 ast_str_set(dest, maxlen, "%s", chunk);
3826 } else {
3827 ast_str_reset(*dest);
3828 for (; *chunk; chunk++) {
3829 if (strchr(";^", *chunk)) {
3830 ast_str_append(dest, maxlen, "^%02hhX", *chunk);
3831 } else {
3832 ast_str_append(dest, maxlen, "%c", *chunk);
3833 }
3834 }
3835 }
3836 return ast_str_buffer(*dest);
3837}
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113

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

◆ ast_realtime_is_mapping_defined()

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 3208 of file main/config.c.

3209{
3210 struct ast_config_map *map;
3212
3213 for (map = config_maps; map; map = map->next) {
3214 if (!strcasecmp(family, map->name)) {
3215 return 1;
3216 }
3217 }
3218 ast_debug(5, "Failed to find a realtime mapping for %s\n", family);
3219
3220 return 0;
3221}

References ast_debug, config_lock, config_maps, lock, ast_config_map::name, ast_config_map::next, and SCOPED_MUTEX.

Referenced by ast_named_acl_find(), and sorcery_realtime_open().

◆ ast_realtime_require_field()

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.

TODO The return value of this function is routinely ignored. Ignoring the return value means that it's mostly pointless to be calling this. You'll see some warning messages potentially, but that's it.

XXX This function is super useful for detecting configuration problems early, but unfortunately, the latest in configuration management, sorcery, doesn't work well with this. Users of sorcery are familiar with the fields they will need to write but don't know if realtime is being used. Sorcery knows what storage mechanism is being used but has no high-level knowledge of what sort of data is going to be written.

Definition at line 3564 of file main/config.c.

3565{
3566 struct ast_config_engine *eng;
3567 char db[256];
3568 char table[256];
3569 va_list ap, aq;
3570 int res = -1, i;
3571
3572 va_start(ap, family);
3573 for (i = 1; ; i++) {
3574 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3575 va_copy(aq, ap);
3576 /* If the require succeeds, it returns 0. */
3577 if (eng->require_func && !(res = eng->require_func(db, table, aq))) {
3578 va_end(aq);
3579 break;
3580 }
3581 va_end(aq);
3582 } else {
3583 break;
3584 }
3585 }
3586 va_end(ap);
3587
3588 return res;
3589}
realtime_require * require_func

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

◆ ast_store_realtime()

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 3755 of file main/config.c.

3756{
3757 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3758 va_list ap;
3759
3760 va_start(ap, family);
3761 realtime_arguments_to_fields(ap, &fields);
3762 va_end(ap);
3763
3764 if (!fields) {
3765 return -1;
3766 }
3767
3768 return ast_store_realtime_fields(family, fields);
3769}
int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
Create realtime configuration.
Definition: main/config.c:3734

References ast_store_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

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

◆ ast_store_realtime_fields()

int ast_store_realtime_fields ( const char *  family,
const struct ast_variable fields 
)

Create realtime configuration.

Parameters
familywhich family/config to be created
fieldsfields themselves

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.

Definition at line 3734 of file main/config.c.

3735{
3736 struct ast_config_engine *eng;
3737 int res = -1, i;
3738 char db[256];
3739 char table[256];
3740
3741 for (i = 1; ; i++) {
3742 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3743 /* If the store succeeds, it returns >= 0*/
3744 if (eng->store_func && ((res = eng->store_func(db, table, fields)) >= 0)) {
3745 break;
3746 }
3747 } else {
3748 break;
3749 }
3750 }
3751
3752 return res;
3753}
realtime_store * store_func

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

Referenced by ast_store_realtime(), and sorcery_realtime_create().

◆ ast_unload_realtime()

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 3591 of file main/config.c.

3592{
3593 struct ast_config_engine *eng;
3594 char db[256];
3595 char table[256];
3596 int res = -1, i;
3597
3598 for (i = 1; ; i++) {
3599 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3600 if (eng->unload_func) {
3601 /* Do this for ALL engines */
3602 res = eng->unload_func(db, table);
3603 }
3604 } else {
3605 break;
3606 }
3607 }
3608 return res;
3609}
realtime_unload * unload_func

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

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

◆ ast_update2_realtime()

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 3710 of file main/config.c.

3711{
3712 RAII_VAR(struct ast_variable *, lookup_fields, NULL, ast_variables_destroy);
3713 RAII_VAR(struct ast_variable *, update_fields, NULL, ast_variables_destroy);
3714 va_list ap;
3715
3716 va_start(ap, family);
3717 /* XXX: If we wanted to pass no lookup fields (select all), we'd be
3718 * out of luck. realtime_arguments_to_fields expects at least one key
3719 * value pair. */
3720 realtime_arguments_to_fields(ap, &lookup_fields);
3721 va_end(ap);
3722
3723 va_start(ap, family);
3724 realtime_arguments_to_fields2(ap, 1, &update_fields);
3725 va_end(ap);
3726
3727 if (!lookup_fields || !update_fields) {
3728 return -1;
3729 }
3730
3731 return ast_update2_realtime_fields(family, lookup_fields, update_fields);
3732}
static int realtime_arguments_to_fields2(va_list ap, int skip, struct ast_variable **result)
Definition: main/config.c:3367
int ast_update2_realtime_fields(const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
Update realtime configuration.
Definition: main/config.c:3690

References ast_update2_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, realtime_arguments_to_fields, and realtime_arguments_to_fields2().

Referenced by change_password_realtime(), and cli_realtime_update2().

◆ ast_update2_realtime_fields()

int ast_update2_realtime_fields ( const char *  family,
const struct ast_variable lookup_fields,
const struct ast_variable update_fields 
)

Update realtime configuration.

Parameters
familywhich family/config to be updated
lookup_fieldsfields used to look up entries
update_fieldsfields to update

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.

Definition at line 3690 of file main/config.c.

3691{
3692 struct ast_config_engine *eng;
3693 int res = -1, i;
3694 char db[256];
3695 char table[256];
3696
3697 for (i = 1; ; i++) {
3698 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3699 if (eng->update2_func && !(res = eng->update2_func(db, table, lookup_fields, update_fields))) {
3700 break;
3701 }
3702 } else {
3703 break;
3704 }
3705 }
3706
3707 return res;
3708}
realtime_update2 * update2_func

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

Referenced by ast_update2_realtime().

◆ ast_update_realtime()

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 3674 of file main/config.c.

3675{
3676 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3677 va_list ap;
3678
3679 va_start(ap, lookup);
3680 realtime_arguments_to_fields(ap, &fields);
3681 va_end(ap);
3682
3683 if (!fields) {
3684 return -1;
3685 }
3686
3687 return ast_update_realtime_fields(family, keyfield, lookup, fields);
3688}
int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Update realtime configuration.
Definition: main/config.c:3653

References ast_update_realtime_fields(), ast_variables_destroy(), NULL, RAII_VAR, and realtime_arguments_to_fields.

Referenced by cli_realtime_update(), conf_run(), function_realtime_write(), leave_voicemail(), realtime_update_peer(), rename_file(), rt_extend_conf(), set_queue_member_pause(), and update_realtime_member_field().

◆ ast_update_realtime_fields()

int ast_update_realtime_fields ( const char *  family,
const char *  keyfield,
const char *  lookup,
const struct ast_variable fields 
)

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.
fieldsfields to update

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

Returns
Number of rows affected, or -1 on error.

Definition at line 3653 of file main/config.c.

3654{
3655 struct ast_config_engine *eng;
3656 int res = -1, i;
3657 char db[256];
3658 char table[256];
3659
3660 for (i = 1; ; i++) {
3661 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3662 /* If the update succeeds, it returns >= 0. */
3663 if (eng->update_func && ((res = eng->update_func(db, table, keyfield, lookup, fields)) >= 0)) {
3664 break;
3665 }
3666 } else {
3667 break;
3668 }
3669 }
3670
3671 return res;
3672}
realtime_update * update_func

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

Referenced by ast_update_realtime(), and sorcery_realtime_update().

◆ ast_variable_append()

void ast_variable_append ( struct ast_category category,
struct ast_variable variable 
)

◆ ast_variable_browse()

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

Definition at line 601 of file main/config.c.

602{
603 struct ast_category *cat;
604
605 if (config->last_browse && (config->last_browse->name == category)) {
606 cat = config->last_browse;
607 } else {
608 cat = ast_category_get(config, category, NULL);
609 }
610
611 return (cat) ? cat->root : NULL;
612}

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

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_sorcery_apply_config(), __init_manager(), _dsp_init(), aco_process_category_options(), actual_load_config(), adsi_load(), ast_cli_perms_init(), AST_TEST_DEFINE(), ast_variable_retrieve(), build_calendar(), build_device(), caldav_load_calendar(), conf_exec(), config_module(), do_reload(), do_say(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), get_defaults(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), load_aliases(), load_asterisk_conf(), load_common(), load_config(), load_general_config(), load_module(), load_moh_classes(), load_odbc_config(), load_users(), load_zonemessages(), loader_config_init(), mbl_load_adapter(), mbl_load_config(), mbl_load_device(), new_realtime_sqlite3_db(), odbc_load_module(), parse_config(), parse_tone_zone(), pbx_load_config(), process_my_load_module(), read_pjproject_startup_options(), realtime_directory(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_single_queue(), rtp_reload(), run_startup_commands(), search_directory_sub(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_build_station(), sla_build_trunk(), smdi_load(), tds_load_module(), test_config_validity(), and xmldoc_load_documentation().

◆ ast_variable_delete()

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

Definition at line 1497 of file main/config.c.

1498{
1499 struct ast_variable *cur, *prev=NULL, *curn;
1500 int res = -1;
1501 int num_item = 0;
1502 int req_item;
1503
1504 req_item = -1;
1505 if (!ast_strlen_zero(line)) {
1506 /* Requesting to delete by item number. */
1507 if (sscanf(line, "%30d", &req_item) != 1
1508 || req_item < 0) {
1509 /* Invalid item number to delete. */
1510 return -1;
1511 }
1512 }
1513
1514 prev = NULL;
1515 cur = category->root;
1516 while (cur) {
1517 curn = cur->next;
1518 /* Delete by item number or by variable name with optional value. */
1519 if ((0 <= req_item && num_item == req_item)
1520 || (req_item < 0 && !strcasecmp(cur->name, variable)
1521 && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
1522 if (prev) {
1523 prev->next = cur->next;
1524 if (cur == category->last)
1525 category->last = prev;
1526 } else {
1527 category->root = cur->next;
1528 if (cur == category->last)
1529 category->last = NULL;
1530 }
1532 res = 0;
1533 } else
1534 prev = cur;
1535
1536 cur = curn;
1537 ++num_item;
1538 }
1539 return res;
1540}

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

Referenced by handle_updates().

◆ ast_variable_destroy()

static void ast_variable_destroy ( struct ast_variable doomed)
static

◆ ast_variable_find()

const char * ast_variable_find ( const struct ast_category category,
const char *  variable 
)

Gets a variable value from a specific category structure by name.

Parameters
categorycategory structure under which the variable lies
variablewhich variable you wish to get the data for

Goes through a given category and searches for the given variable

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

Definition at line 833 of file main/config.c.

834{
835 return ast_variable_find_in_list(category->root, variable);
836}
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
Definition: main/config.c:928

References ast_variable_find_in_list(), and ast_category::root.

Referenced by AST_TEST_DEFINE(), ast_variable_retrieve_filtered(), and extension_length_comparator().

◆ ast_variable_find_in_list()

const char * ast_variable_find_in_list ( const struct ast_variable list,
const char *  variable 
)

Gets the value of a variable from a variable list by name.

Parameters
listvariable list to search
variablewhich variable you wish to get the data for

Goes through a given variable list and searches for the given variable

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

Definition at line 928 of file main/config.c.

929{
930 const struct ast_variable *v;
931
932 for (v = list; v; v = v->next) {
933 if (!strcasecmp(variable, v->name)) {
934 return v->value;
935 }
936 }
937 return NULL;
938}

References ast_variable::name, ast_variable::next, NULL, and ast_variable::value.

Referenced by ast_ari_callback(), ast_geoloc_eprofile_to_uri(), ast_geoloc_gml_validate_varlist(), ast_sorcery_changeset_create(), AST_TEST_DEFINE(), ast_variable_find(), geoloc_civicaddr_list_to_xml(), geoloc_eprofile_to_intermediate(), geoloc_gml_list_to_xml(), handle_export_primitives(), load_realtime_musiconhold(), retrieve_cert_from_url(), and validate_location_info().

◆ ast_variable_find_last_in_list()

const char * ast_variable_find_last_in_list ( const struct ast_variable list,
const char *  variable 
)

Gets the value of the LAST occurrence of a variable from a variable list.

Parameters
listThe ast_variable list to search
variableThe name of the ast_variable you wish to fetch data for

Iterates over a given ast_variable list to search for the last occurrence of an ast_variable entry with a name attribute matching the given name (variable). This is useful if the list has duplicate entries (such as in cases where entries are created by a template)

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

Definition at line 940 of file main/config.c.

941{
942 const struct ast_variable *v;
943 const char *found = NULL;
944
945 for (v = list; v; v = v->next) {
946 if (!strcasecmp(variable, v->name)) {
947 found = v->value;
948 }
949 }
950 return found;
951}

References ast_variable::name, ast_variable::next, NULL, and ast_variable::value.

Referenced by AST_TEST_DEFINE(), handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), is_variable_true(), and wizard_apply_handler().

◆ ast_variable_find_variable_in_list()

const struct ast_variable * ast_variable_find_variable_in_list ( const struct ast_variable list,
const char *  variable_name 
)

Gets a variable from a variable list by name.

Since
13.9.0
Parameters
listvariable list to search
variable_namename you wish to get the data for

Goes through a given variable list and searches for the given variable

Return values
Thevariable (not the value) on success
NULLif unable to find it.

Definition at line 838 of file main/config.c.

839{
840 const struct ast_variable *v;
841
842 for (v = list; v; v = v->next) {
843 if (!strcasecmp(variable_name, v->name)) {
844 return v;
845 }
846 }
847 return NULL;
848}

References ast_variable::name, ast_variable::next, and NULL.

Referenced by ast_variable_lists_match(), and realtime_sorcery_store().

◆ ast_variable_insert()

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

Definition at line 500 of file main/config.c.

501{
502 struct ast_variable *cur = category->root;
503 int lineno;
504 int insertline;
505
506 if (!variable || sscanf(line, "%30d", &insertline) != 1) {
507 return;
508 }
509 if (!insertline) {
510 variable->next = category->root;
511 category->root = variable;
512 } else {
513 for (lineno = 1; lineno < insertline; lineno++) {
514 cur = cur->next;
515 if (!cur->next) {
516 break;
517 }
518 }
519 variable->next = cur->next;
520 cur->next = variable;
521 }
522}

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

Referenced by AST_TEST_DEFINE(), and handle_updates().

◆ ast_variable_list_append_hint()

struct ast_variable * ast_variable_list_append_hint ( struct ast_variable **  head,
struct ast_variable search_hint,
struct ast_variable new_var 
)

Appends a variable list to the end of another list.

Parameters
headA pointer to an ast_variable * of the existing variable list head. May NOT be NULL but the content may be to initialize a new list. If so, upon return, this parameter will be updated with a pointer to the new list head.
search_hintThe place in the current list to start searching for the end of the list. Might help performance on longer lists. If NULL, it defaults to head.
new_varThe head of the new variable list to be appended
Returns
The tail of the resulting list.
Note
If the existing *head is NULL, it will be updated to new_var. This allows you to call ast_variable_list_append in a loop or callback without initializing the list first.

Definition at line 647 of file main/config.c.

648{
649 struct ast_variable *curr;
650 struct ast_variable *sh = search_hint;
651 ast_assert(head != NULL);
652
653 if (!*head) {
654 *head = newvar;
655 } else {
656 if (sh == NULL) {
657 sh = *head;
658 }
659 for (curr = sh; curr->next; curr = curr->next);
660 curr->next = newvar;
661 }
662
663 for (curr = newvar; curr->next; curr = curr->next);
664
665 return curr;
666}
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, ast_variable::next, and NULL.

Referenced by ast_json_to_ast_variables(), ast_sorcery_objectset_create2(), and AST_TEST_DEFINE().

◆ ast_variable_list_from_quoted_string()

struct ast_variable * ast_variable_list_from_quoted_string ( const char *  input,
const char *  item_separator,
const char *  name_value_separator,
const char *  quote_str 
)

Parse a string into an ast_variable list. The reverse of ast_variable_list_join.

Parameters
inputThe name-value pair string to parse.
item_separatorThe string used to separate the list items. Only the first character in the string will be used. If NULL, "," will be used.
name_value_separatorThe string used to separate each item's name and value. Only the first character in the string will be used. If NULL, "=" will be used.
quote_strThe string used to quote values. Only the first character in the string will be used. If NULL, '"' will be used.
Return values
Apointer to a list of ast_variables.
NULLif there was an error or no variables could be parsed.

Definition at line 727 of file main/config.c.

729{
730 char item_sep;
731 char nv_sep;
732 char quote;
733 struct ast_variable *new_list = NULL;
734 struct ast_variable *new_var = NULL;
735 char *item_string;
736 char *item;
737 char *item_name;
738 char *item_value;
739
740 if (ast_strlen_zero(input)) {
741 return NULL;
742 }
743
744 item_sep = ast_strlen_zero(item_separator) ? ',' : item_separator[0];
745 nv_sep = ast_strlen_zero(name_value_separator) ? '=' : name_value_separator[0];
746 quote = ast_strlen_zero(quote_str) ? '"' : quote_str[0];
747 item_string = ast_strip(ast_strdupa(input));
748
749 while ((item = ast_strsep_quoted(&item_string, item_sep, quote, AST_STRSEP_ALL))) {
750 item_name = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL);
751 if (!item_name) {
752 ast_variables_destroy(new_list);
753 return NULL;
754 }
755
756 item_value = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL);
757
758 new_var = ast_variable_new(item_name, item_value ?: "", "");
759 if (!new_var) {
760 ast_variables_destroy(new_list);
761 return NULL;
762 }
763 ast_variable_list_append(&new_list, new_var);
764 }
765 return new_list;
766}
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1570
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
#define ast_variable_list_append(head, new_var)
char * ast_strsep_quoted(char **s, const char sep, const char quote, uint32_t flags)
Like ast_strsep() except you can specify a specific quote character.
Definition: utils.c:1899
@ AST_STRSEP_ALL
Definition: strings.h:258
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
static struct aco_type item
Definition: test_config.c:1463

References ast_strdupa, ast_strip(), ast_strlen_zero(), AST_STRSEP_ALL, ast_strsep_quoted(), ast_variable_list_append, ast_variable_new, ast_variables_destroy(), input(), item, NULL, and quote().

Referenced by AST_TEST_DEFINE(), and ast_variable_list_from_string().

◆ ast_variable_list_from_string()

struct ast_variable * ast_variable_list_from_string ( const char *  input,
const char *  item_separator,
const char *  name_value_separator 
)

Parse a string into an ast_variable list. The reverse of ast_variable_list_join.

Parameters
inputThe name-value pair string to parse.
item_separatorThe string used to separate the list items. Only the first character in the string will be used. If NULL, "," will be used.
name_value_separatorThe string used to separate each item's name and value. Only the first character in the string will be used. If NULL, "=" will be used.
Return values
Apointer to a list of ast_variables.
NULLif there was an error or no variables could be parsed.

Definition at line 768 of file main/config.c.

770{
771 return ast_variable_list_from_quoted_string(input, item_separator, name_value_separator, NULL);
772}
struct ast_variable * ast_variable_list_from_quoted_string(const char *input, const char *item_separator, const char *name_value_separator, const char *quote_str)
Parse a string into an ast_variable list. The reverse of ast_variable_list_join.
Definition: main/config.c:727

References ast_variable_list_from_quoted_string(), input(), and NULL.

◆ ast_variable_list_join()

struct ast_str * ast_variable_list_join ( const struct ast_variable head,
const char *  item_separator,
const char *  name_value_separator,
const char *  quote_char,
struct ast_str **  str 
)

Join an ast_variable list with specified separators and quoted values.

Parameters
headA pointer to an ast_variable list head.
item_separatorThe string to use to separate the list items. If NULL, "," will be used.
name_value_separatorThe string to use to separate each item's name and value. If NULL, "=" will be used.
strA pointer to a pre-allocated ast_str in which to put the results. If NULL, one will be allocated and returned.
quote_charThe quote char to use for the values. May be NULL or empty for no quoting.
Return values
Apointer to the result ast_str. This may NOT be the same as the pointer passed in if the original ast_str wasn't large enough to hold the result. Regardless, the pointer MUST be freed after use.
NULLif there was an error.

Definition at line 701 of file main/config.c.

703{
704 struct ast_variable *var = (struct ast_variable *)head;
705 struct ast_str *local_str = NULL;
706
707 if (str == NULL || *str == NULL) {
709 if (!local_str) {
710 return NULL;
711 }
712 } else {
713 local_str = *str;
714 }
715
716 for (; var; var = var->next) {
717 ast_str_append(&local_str, 0, "%s%s%s%s%s%s", var->name, name_value_separator, S_OR(quote_char, ""),
718 var->value, S_OR(quote_char, ""), var->next ? item_separator : "");
719 }
720
721 if (str != NULL) {
722 *str = local_str;
723 }
724 return local_str;
725}
#define AST_MAX_USER_FIELD
Definition: channel.h:176
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80

References AST_MAX_USER_FIELD, ast_str_append(), ast_str_create, NULL, S_OR, str, and var.

Referenced by add_eprofile_to_channel(), AST_TEST_DEFINE(), geoloc_config_list_locations(), geoloc_config_show_profiles(), validate_location_info(), var_list_from_confidence(), var_list_from_loc_info(), and var_list_from_node().

◆ ast_variable_list_replace()

int ast_variable_list_replace ( struct ast_variable **  head,
struct ast_variable replacement 
)

Replace a variable in the given list with a new value.

Since
13.30.0
Parameters
headA pointer to an ast_variable * of the existing variable list head. May NOT be NULL but the content may be to initialize a new list. If so, upon return, this parameter will be updated with a pointer to the new list head.
replacementThe variable that replaces another variable in the list with the same name.
Return values
0if a variable was replaced in the list
-1if no replacement occured
Note
The variable name comparison is performed case-sensitively
If a variable is replaced, its memory is freed.

Definition at line 668 of file main/config.c.

669{
670 struct ast_variable *v, **prev = head;
671
672 for (v = *head; v; prev = &v->next, v = v->next) {
673 if (!strcmp(v->name, replacement->name)) {
674 replacement->next = v->next;
675 *prev = replacement;
676 ast_free(v);
677 return 0;
678 }
679 }
680
681 return -1;
682}

References ast_free, ast_variable::name, and ast_variable::next.

Referenced by ast_geoloc_eprofile_refresh_location(), build_user(), check_access(), mkintf(), process_dahdi(), and set_var_handler().

◆ ast_variable_list_replace_variable()

int ast_variable_list_replace_variable ( struct ast_variable **  head,
struct ast_variable oldvar,
struct ast_variable newvar 
)

Replace a variable in the given list with a new variable.

Parameters
headA pointer to the current variable list head. Since the variable to be replaced, this pointer may be updated with the new head.
oldvarA pointer to the existing variable to be replaced.
newvarA pointer to the new variable that will replace the old one.
Return values
0if a variable was replaced in the list
-1if no replacement occured
Note
The search for the old variable is done simply on the pointer.
If a variable is replaced, its memory is freed.

Definition at line 684 of file main/config.c.

686{
687 struct ast_variable *v, **prev = head;
688
689 for (v = *head; v; prev = &v->next, v = v->next) {
690 if (v == old) {
691 new->next = v->next;
692 *prev = new;
693 ast_free(v);
694 return 0;
695 }
696 }
697
698 return -1;
699}

References ast_free, and ast_variable::next.

Referenced by AST_TEST_DEFINE().

◆ ast_variable_list_sort()

struct ast_variable * ast_variable_list_sort ( struct ast_variable head)

Performs an in-place sort on the variable list by ascending name.

Parameters
headThe variable list head
Returns
The new list head

Definition at line 621 of file main/config.c.

622{
623 struct ast_variable *p, *q;
624 struct ast_variable top;
625 int changed = 1;
626 memset(&top, 0, sizeof(top));
627 top.next = start;
628 if (start != NULL && start->next != NULL) {
629 while (changed) {
630 changed = 0;
631 q = &top;
632 p = top.next;
633 while (p->next != NULL) {
634 if (p->next != NULL && strcmp(p->name, p->next->name) > 0) {
635 q->next = variable_list_switch(p, p->next);
636 changed = 1;
637 }
638 q = p;
639 if (p->next != NULL)
640 p = p->next;
641 }
642 }
643 }
644 return top.next;
645}
static struct ast_variable * variable_list_switch(struct ast_variable *l1, struct ast_variable *l2)
Definition: main/config.c:614

References ast_variable::name, ast_variable::next, NULL, and variable_list_switch().

Referenced by aeap_cli_show(), ast_sip_cli_print_sorcery_objectset(), and config_object_cli_show().

◆ ast_variable_lists_match()

int ast_variable_lists_match ( const struct ast_variable left,
const struct ast_variable right,
int  exact_match 
)

Tests 2 variable lists to see if they match.

Since
13.9.0
Parameters
leftVariable list to test
rightVariable list with an optional realtime-style operator in the names
exact_matchIf true, all variables in left must match all variables in right and vice versa. This does exact value matches only. Operators aren't supported. Except for order, the left and right lists must be equal.

If false, every variable in the right list must match some variable in the left list using the operators supplied. Variables in the left list that aren't in the right list are ignored for matching purposes.

Return values
1matches
0doesn't match

Iterates over the variable lists calling ast_variables_match. If any match fails or a variable in the right list isn't in the left list, 0 is returned.

Definition at line 870 of file main/config.c.

871{
872 const struct ast_variable *field;
873 int right_count = 0;
874 int left_count = 0;
875
876 if (left == right) {
877 return 1;
878 }
879
880 if (!(left && right)) {
881 return 0;
882 }
883
884 for (field = right; field; field = field->next) {
885 char *space = strrchr(field->name, ' ');
886 const struct ast_variable *old;
887 char * name = (char *)field->name;
888
889 if (space) {
890 name = ast_strdup(field->name);
891 if (!name) {
892 return 0;
893 }
894 name[space - field->name] = '\0';
895 }
896
898 if (name != field->name) {
899 ast_free(name);
900 }
901
902 if (exact_match) {
903 if (!old || strcmp(old->value, field->value)) {
904 return 0;
905 }
906 } else {
907 if (!ast_variables_match(old, field)) {
908 return 0;
909 }
910 }
911
912 right_count++;
913 }
914
915 if (exact_match) {
916 for (field = left; field; field = field->next) {
917 left_count++;
918 }
919
920 if (right_count != left_count) {
921 return 0;
922 }
923 }
924
925 return 1;
926}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
int ast_variables_match(const struct ast_variable *left, const struct ast_variable *right)
Tests 2 variable values to see if they match.
Definition: main/config.c:850
const struct ast_variable * ast_variable_find_variable_in_list(const struct ast_variable *list, const char *variable_name)
Gets a variable from a variable list by name.
Definition: main/config.c:838

References ast_free, ast_strdup, ast_variable_find_variable_in_list(), ast_variables_match(), if(), name, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by AST_TEST_DEFINE(), object_type_loaded_observer(), realtime_sorcery(), realtime_sorcery_multi(), sorcery_astdb_retrieve_fields_common(), sorcery_config_fields_cmp(), sorcery_memory_cache_fields_cmp(), and sorcery_memory_fields_cmp().

◆ ast_variable_move()

static void ast_variable_move ( struct ast_variable dst_var,
struct ast_variable src_var 
)
static

Definition at line 323 of file main/config.c.

324{
325 dst_var->lineno = src_var->lineno;
326 dst_var->object = src_var->object;
327 dst_var->blanklines = src_var->blanklines;
328 dst_var->precomments = src_var->precomments;
329 src_var->precomments = NULL;
330 dst_var->sameline = src_var->sameline;
331 src_var->sameline = NULL;
332 dst_var->trailing = src_var->trailing;
333 src_var->trailing = NULL;
334}

References ast_variable::blanklines, ast_variable::lineno, NULL, ast_variable::object, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.

Referenced by ast_include_rename(), and ast_variable_update().

◆ ast_variable_retrieve()

const char * ast_variable_retrieve ( struct ast_config config,
const char *  category,
const char *  variable 
)

Definition at line 784 of file main/config.c.

785{
786 struct ast_variable *v;
787 const char *match = NULL;
788
789 /* We can't return as soon as we find a match, because if a config section overrides
790 * something specified in a template, then the actual effective value is the last
791 * one encountered, not the first one.
792 * (This is like using the -1 index for the AST_CONFIG function.)
793 * Also see ast_variable_find_last_in_list
794 */
795
796 if (category) {
797 for (v = ast_variable_browse(config, category); v; v = v->next) {
798 if (!strcasecmp(variable, v->name)) {
799 match = v->value;
800 }
801 }
802 } else {
803 struct ast_category *cat;
804
805 for (cat = config->root; cat; cat = cat->next) {
806 for (v = cat->root; v; v = v->next) {
807 if (!strcasecmp(variable, v->name)) {
808 match = v->value;
809 }
810 }
811 }
812 }
813
814 return match;
815}
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Definition: main/config.c:601

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

Referenced by __init_manager(), __queues_show(), actual_load_config(), advanced_options(), ast_config_option(), ast_init_logger_for_socket_console(), AST_TEST_DEFINE(), check_for_old_config(), conf_exec(), config_module(), directory_exec(), festival_exec(), find_realtime(), forward_message(), get_defaults(), iax_template_parse(), init_acf_query(), init_logger_chain(), initialize_cc_devstate_map_helper(), initialize_cc_max_requests(), internal_aco_type_find(), load_config(), load_config_meetme(), load_indications(), load_module(), load_mysql_config(), load_realtime_musiconhold(), load_realtime_queues(), load_realtime_rules(), load_tech_calendars(), load_users(), loader_config_init(), make_email_file(), mbl_load_adapter(), mbl_load_device(), message_range_and_existence_check(), named_acl_find_realtime(), notify_new_message(), odbc_load_module(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), process_my_load_module(), queue_rules_set_global_params(), queue_set_global_params(), read_password_from_file(), realtime_directory(), realtime_switch_common(), reload(), reload_config(), reload_followme(), reload_single_queue(), rt_handle_member_record(), rtp_reload(), search_directory(), search_directory_sub(), set_config(), set_member_value(), 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().

◆ ast_variable_retrieve_filtered()

const char * ast_variable_retrieve_filtered ( struct ast_config config,
const char *  category,
const char *  variable,
const char *  filter 
)

Gets a variable by context and variable names.

Parameters
configwhich (opened) config to use
categorycategory under which the variable lies
variablewhich variable you wish to get the data for
filteran optional comma-separated list of <name_regex>=<value_regex> pairs. Only categories with matching variables will be searched. The special name 'TEMPLATES' can be used with the special values 'include' or 'restrict' to include templates in the result or restrict the result to only templates.
Return values
Thevariable value on success
NULLif unable to find it.

Definition at line 817 of file main/config.c.

819{
820 struct ast_category *cat = NULL;
821 const char *value;
822
823 while ((cat = ast_category_browse_filtered(config, category, cat, filter))) {
824 value = ast_variable_find(cat, variable);
825 if (value) {
826 return value;
827 }
828 }
829
830 return NULL;
831}
const char * ast_variable_find(const struct ast_category *category, const char *variable)
Gets a variable value from a specific category structure by name.
Definition: main/config.c:833
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
Definition: main/config.c:1433

References ast_category_browse_filtered(), ast_variable_find(), config, filter(), NULL, and value.

◆ ast_variable_update()

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 1542 of file main/config.c.

1544{
1545 struct ast_variable *cur, *prev=NULL, *newer=NULL, *matchvar = NULL;
1546
1547 for (cur = category->root; cur; prev = cur, cur = cur->next) {
1548 if (strcasecmp(cur->name, variable) ||
1549 (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
1550 continue;
1551 matchvar = cur;
1552 }
1553
1554 for (cur = category->root; cur; prev = cur, cur = cur->next) {
1555 if (cur != matchvar) {
1556 continue;
1557 }
1558 if (!(newer = ast_variable_new(variable, value, cur->file)))
1559 return -1;
1560
1561 ast_variable_move(newer, cur);
1562 newer->object = newer->object || object;
1563
1564 /* Replace the old node in the list with the new node. */
1565 newer->next = cur->next;
1566 if (prev)
1567 prev->next = newer;
1568 else
1569 category->root = newer;
1570 if (category->last == cur)
1571 category->last = newer;
1572
1574
1575 return 0;
1576 }
1577
1578 /* Could not find variable to update */
1579 return -1;
1580}

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

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

◆ ast_variables_destroy()

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

591{
592 struct ast_variable *vn;
593
594 while (var) {
595 vn = var;
596 var = var->next;
598 }
599}

References ast_variable_destroy(), free(), ast_variable::next, and var.

Referenced by __init_manager(), aco_set_defaults(), action_messagesend(), action_originate(), add_message_id(), aeap_cli_show(), announce_to_dial(), app_notify(), ast_aeap_client_configs_get(), ast_ari_asterisk_update_object(), ast_ari_callback(), ast_ari_channels_create(), ast_ari_channels_originate(), ast_ari_channels_originate_with_id(), ast_ari_endpoints_refer(), ast_ari_endpoints_refer_to_endpoint(), ast_ari_endpoints_send_message(), ast_ari_endpoints_send_message_to_endpoint(), ast_ari_invoke(), ast_category_destroy(), ast_category_empty(), ast_destroy_realtime(), ast_geoloc_eprofile_refresh_location(), ast_geoloc_eprofile_to_uri(), ast_http_get_cookies(), ast_http_manid_from_vars(), ast_json_to_ast_variables(), ast_load_realtime(), ast_load_realtime_all(), ast_load_realtime_multientry(), ast_sip_cli_print_sorcery_objectset(), ast_sip_sorcery_object_to_ami(), ast_sorcery_changeset_create(), ast_sorcery_copy(), ast_sorcery_diff(), ast_sorcery_object_set_extended(), ast_sorcery_objectset_apply(), ast_sorcery_objectset_json_create(), ast_store_realtime(), ast_stream_free(), ast_stream_get_metadata_list(), AST_TEST_DEFINE(), ast_update2_realtime(), ast_update_realtime(), ast_var_channel_types(), ast_var_channel_types_table(), ast_variable_list_from_quoted_string(), ast_variables_dup(), auth_http_callback(), calendar_destructor(), can_reuse_registration(), check_expiration_thread(), cli_contact_get_container(), cli_realtime_load(), conf_run(), config_object_cli_show(), copy_plain_file(), create_mwi_subscriptions(), curl_header_data_free(), destroy_dahdi_pvt(), destroy_fast_originate_helper(), dup_vars(), endpoint_destructor(), external_media_audiosocket_tcp(), external_media_rtp_udp(), fields_handler(), find_conf_realtime(), find_load_queue_rt_friendly(), find_realtime(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), generic_http_callback(), geoloc_eprofile_destructor(), geoloc_eprofile_resolve_varlist(), geoloc_eprofile_to_intermediate(), geoloc_location_destructor(), geoloc_profile_destructor(), get_multiple_fields_as_var_list(), get_object_variables(), handle_aor(), handle_auth(), handle_endpoint(), handle_export_primitives(), handle_identify(), handle_phoneprov(), handle_pjproject_show_log_mappings(), handle_registrations(), handle_showchan(), handle_uri(), http_request_headers_get(), httpd_process_request(), httpstatus_callback(), ldap_loadentry(), leave_queue(), load_realtime_musiconhold(), local_ast_moh_start(), manager_free_user(), manager_send_response(), mkintf(), notify_ami_channel_data_destroy(), notify_ami_data_destroy(), notify_ami_uri_data_destroy(), object_type_loaded_observer(), originate_exec(), pjsip_aor_function_read(), pjsip_contact_function_read(), pjsip_endpoint_function_read(), process_dahdi(), publication_resource_destroy(), pvt_destructor(), queue_function_queuegetchannel(), queue_function_queuewaitingcount(), realtime_arguments_to_fields(), realtime_arguments_to_fields2(), realtime_canmatch(), realtime_common(), realtime_exec(), realtime_exists(), realtime_ldap_base(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_user(), realtimefield_read(), return_sorcery_object(), row_to_varlist(), rt_extend_conf(), session_destructor(), sip_aor_to_ami(), socket_process_helper(), sorcery_astdb_filter_objectset(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_destructor(), sorcery_config_fields_cmp(), sorcery_function_read(), sorcery_is_criteria_met(), sorcery_memory_cache_fields_cmp(), sorcery_memory_cached_object_destructor(), sorcery_memory_fields_cmp(), sorcery_object_destructor(), sorcery_realtime_create(), sorcery_realtime_filter_objectset(), sorcery_realtime_retrieve_fields(), sorcery_realtime_retrieve_id(), sorcery_realtime_retrieve_multiple(), sorcery_realtime_retrieve_prefix(), sorcery_realtime_retrieve_regex(), sorcery_realtime_update(), speech_aeap_engine_create(), table_configs_free(), test_sorcery_object_destroy(), test_sorcery_transform(), transport_apply(), update_ldap(), user_destructor(), var_list_from_confidence(), var_list_from_loc_info(), and var_list_from_node().

◆ ast_variables_dup()

struct ast_variable * ast_variables_dup ( struct ast_variable var)

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 544 of file main/config.c.

545{
546 struct ast_variable *cloned;
547 struct ast_variable *tmp;
548
549 if (!(cloned = ast_variable_new(var->name, var->value, var->file))) {
550 return NULL;
551 }
552
553 tmp = cloned;
554
555 while ((var = var->next)) {
556 if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) {
557 ast_variables_destroy(cloned);
558 return NULL;
559 }
560 tmp = tmp->next;
561 }
562
563 return cloned;
564}

References ast_variable_new, ast_variables_destroy(), NULL, tmp(), and var.

Referenced by action_originate(), ast_ari_callback(), ast_config_copy(), authenticate(), handle_registrations(), jim_handler(), jim_vl(), realtime_sorcery(), realtime_sorcery_multi(), realtime_sorcery_store(), realtime_sorcery_update(), set_var_to_vl(), and sorcery_extended_fields_handler().

◆ ast_variables_match()

int ast_variables_match ( const struct ast_variable left,
const struct ast_variable right 
)

Tests 2 variable values to see if they match.

Since
13.9.0
Parameters
leftVariable to test
rightVariable to match against with an optional realtime-style operator in the name
Return values
1matches
0doesn't match

The values of the variables are passed to ast_strings_match. If right->name is suffixed with a space and an operator, that operator is also passed to ast_strings_match.

Examples:

left->name = "id" (ignored) left->value = "abc" right->name = "id regex" (id is ignored) right->value = "a[bdef]c"

will result in ast_strings_match("abc", "regex", "a[bdef]c") which will return 1.

left->name = "id" (ignored) left->value = "abc" right->name = "id" (ignored) right->value = "abc"

will result in ast_strings_match("abc", NULL, "abc") which will return 1.

See the documentation for ast_strings_match for the valid operators.

Definition at line 850 of file main/config.c.

851{
852 char *op;
853
854 if (left == right) {
855 return 1;
856 }
857
858 if (!(left && right)) {
859 return 0;
860 }
861
862 op = strrchr(right->name, ' ');
863 if (op) {
864 op++;
865 }
866
867 return ast_strings_match(left->value, op ? ast_strdupa(op) : NULL, right->value);
868}
int ast_strings_match(const char *left, const char *op, const char *right)
Compares 2 strings using realtime-style operators.
Definition: strings.c:247

References ast_strdupa, ast_strings_match(), ast_variable::name, NULL, and ast_variable::value.

Referenced by ast_variable_lists_match().

◆ ast_variables_reverse()

struct ast_variable * ast_variables_reverse ( struct ast_variable var)

Reverse a variable list.

Parameters
varthe linked list of variables to reverse
Returns
The head of the reversed variable list
Note
The variable list var is not preserved in this function and should not be used after reversing it.

Definition at line 566 of file main/config.c.

567{
568 struct ast_variable *var1, *var2;
569
570 var1 = var;
571
572 if (!var1 || !var1->next) {
573 return var1;
574 }
575
576 var2 = var1->next;
577 var1->next = NULL;
578
579 while (var2) {
580 struct ast_variable *next = var2->next;
581
582 var2->next = var1;
583 var1 = var2;
584 var2 = next;
585 }
586
587 return var1;
588}

References ast_variable::next, NULL, and var.

Referenced by astman_get_variables_order().

◆ category_get_sep()

static struct ast_category * category_get_sep ( const struct ast_config config,
const char *  category_name,
const char *  filter,
char  sep,
char  pointer_match_possible 
)
static

Definition at line 1098 of file main/config.c.

1100{
1101 struct ast_category *cat;
1102
1103 if (pointer_match_possible) {
1104 for (cat = config->root; cat; cat = cat->next) {
1105 if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) {
1106 return cat;
1107 }
1108 }
1109 }
1110
1111 for (cat = config->root; cat; cat = cat->next) {
1112 if (does_category_match(cat, category_name, filter, sep)) {
1113 return cat;
1114 }
1115 }
1116
1117 return NULL;
1118}
static int does_category_match(struct ast_category *cat, const char *category_name, const char *match, char sep)
Returns true if ALL of the regex expressions and category name match. Both can be NULL (I....
Definition: main/config.c:979

References config, does_category_match(), filter(), ast_category::name, ast_category::next, and NULL.

Referenced by ast_category_get(), and process_text_line().

◆ CB_ADD()

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

Definition at line 130 of file main/config.c.

131{
132 ast_str_append(cb, 0, "%s", str);
133}

References ast_str_append(), and str.

Referenced by config_text_file_load().

◆ CB_ADD_LEN()

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

Definition at line 135 of file main/config.c.

136{
137 char *s = ast_alloca(len + 1);
138
139 memcpy(s, str, len);
140 s[len] = '\0';
141 ast_str_append(cb, 0, "%s", s);
142}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References ast_alloca, ast_str_append(), len(), and str.

Referenced by config_text_file_load().

◆ CB_RESET()

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

Definition at line 144 of file main/config.c.

145{
146 if (cb) {
147 ast_str_reset(cb);
148 }
149 if (llb) {
150 ast_str_reset(llb);
151 }
152}

References ast_str_reset().

Referenced by config_text_file_load(), and process_text_line().

◆ cfmstat_cmp()

static int cfmstat_cmp ( struct cache_file_mtime cfmtime,
struct stat *  statbuf 
)
static

Definition at line 1720 of file main/config.c.

1721{
1722 struct cache_file_mtime cfm_buf;
1723
1724 cfmstat_save(&cfm_buf, statbuf);
1725
1726 return cfmtime->stat_size != cfm_buf.stat_size
1727 || cfmtime->stat_mtime != cfm_buf.stat_mtime
1728 || cfmtime->stat_mtime_nsec != cfm_buf.stat_mtime_nsec;
1729}
static void cfmstat_save(struct cache_file_mtime *cfmtime, struct stat *statbuf)
Definition: main/config.c:1696
unsigned long stat_size
Definition: main/config.c:103
unsigned long stat_mtime_nsec
Definition: main/config.c:105

References cfmstat_save(), cache_file_mtime::stat_mtime, cache_file_mtime::stat_mtime_nsec, and cache_file_mtime::stat_size.

Referenced by config_text_file_load().

◆ cfmstat_save()

static void cfmstat_save ( struct cache_file_mtime cfmtime,
struct stat *  statbuf 
)
static

Definition at line 1696 of file main/config.c.

1697{
1698 cfmtime->stat_size = statbuf->st_size;
1699#if defined(HAVE_STRUCT_STAT_ST_MTIM)
1700 cfmtime->stat_mtime_nsec = statbuf->st_mtim.tv_nsec;
1701#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
1702 cfmtime->stat_mtime_nsec = statbuf->st_mtimensec;
1703#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
1704 cfmtime->stat_mtime_nsec = statbuf->st_mtimespec.tv_nsec;
1705#else
1706 cfmtime->stat_mtime_nsec = 0;
1707#endif
1708 cfmtime->stat_mtime = statbuf->st_mtime;
1709}

References cache_file_mtime::stat_mtime, cache_file_mtime::stat_mtime_nsec, and cache_file_mtime::stat_size.

Referenced by cfmstat_cmp(), and config_text_file_load().

◆ cfmtime_new()

static struct cache_file_mtime * cfmtime_new ( const char *  filename,
const char *  who_asked 
)
static

Definition at line 1666 of file main/config.c.

1667{
1668 struct cache_file_mtime *cfmtime;
1669 char *dst;
1670
1671 cfmtime = ast_calloc(1,
1672 sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
1673 if (!cfmtime) {
1674 return NULL;
1675 }
1676 dst = cfmtime->filename; /* writable space starts here */
1677 strcpy(dst, filename); /* Safe */
1678 dst += strlen(dst) + 1;
1679 cfmtime->who_asked = strcpy(dst, who_asked); /* Safe */
1680
1681 return cfmtime;
1682}
const char * who_asked
Definition: main/config.c:110

References ast_calloc, cache_file_mtime::filename, NULL, and cache_file_mtime::who_asked.

Referenced by config_cache_attribute(), and config_text_file_load().

◆ clear_config_maps()

static void clear_config_maps ( void  )
static

Definition at line 3041 of file main/config.c.

3042{
3043 struct ast_config_map *map;
3044
3045 while (config_maps) {
3046 map = config_maps;
3048 ast_free(map);
3049 }
3050}

References ast_free, config_maps, and ast_config_map::next.

Referenced by config_shutdown(), and reload_module().

◆ config_cache_attribute()

static void config_cache_attribute ( const char *  configfile,
enum config_cache_attribute_enum  attrtype,
const char *  filename,
const char *  who_asked 
)
static

Definition at line 1786 of file main/config.c.

1787{
1788 struct cache_file_mtime *cfmtime;
1789 struct cache_file_include *cfinclude;
1790
1791 /* Find our cached entry for this configuration file */
1793 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
1794 if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
1795 break;
1796 }
1797 if (!cfmtime) {
1798 cfmtime = cfmtime_new(configfile, who_asked);
1799 if (!cfmtime) {
1801 return;
1802 }
1803 /* Note that the file mtime is initialized to 0, i.e. 1970 */
1804 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
1805 }
1806
1807 switch (attrtype) {
1808 case ATTRIBUTE_INCLUDE:
1809 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
1810 if (!strcmp(cfinclude->include, filename)) {
1812 return;
1813 }
1814 }
1815 cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
1816 if (!cfinclude) {
1818 return;
1819 }
1820 strcpy(cfinclude->include, filename); /* Safe */
1821 AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
1822 break;
1823 case ATTRIBUTE_EXEC:
1824 cfmtime->has_exec = 1;
1825 break;
1826 }
1828}
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield)
Inserts a list entry into a alphabetically sorted list.
Definition: linkedlists.h:751
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
static struct cache_file_mtime * cfmtime_new(const char *filename, const char *who_asked)
Definition: main/config.c:1666
Hold the mtime for config files, so if we don't need to reread our config, don't.
Definition: main/config.c:92
struct cache_file_include::@335 list
struct cache_file_mtime::includes includes
unsigned int has_exec
Definition: main/config.c:101

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

Referenced by process_text_line().

◆ config_cache_destroy_entry()

static void config_cache_destroy_entry ( struct cache_file_mtime cfmtime)
static

Definition at line 1756 of file main/config.c.

1757{
1759 ast_free(cfmtime);
1760}
static void config_cache_flush_includes(struct cache_file_mtime *cfmtime)
Definition: main/config.c:1739

References ast_free, and config_cache_flush_includes().

Referenced by config_cache_remove(), and config_shutdown().

◆ config_cache_flush_includes()

static void config_cache_flush_includes ( struct cache_file_mtime cfmtime)
static

Definition at line 1739 of file main/config.c.

1740{
1741 struct cache_file_include *cfinclude;
1742
1743 while ((cfinclude = AST_LIST_REMOVE_HEAD(&cfmtime->includes, list))) {
1744 ast_free(cfinclude);
1745 }
1746}

References ast_free, AST_LIST_REMOVE_HEAD, and cache_file_mtime::includes.

Referenced by config_cache_destroy_entry(), and config_text_file_load().

◆ config_cache_remove()

static void config_cache_remove ( const char *  filename,
const char *  who_asked 
)
static

Definition at line 1769 of file main/config.c.

1770{
1771 struct cache_file_mtime *cfmtime;
1772
1775 if (!strcmp(cfmtime->filename, filename)
1776 && !strcmp(cfmtime->who_asked, who_asked)) {
1779 break;
1780 }
1781 }
1784}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
static void config_cache_destroy_entry(struct cache_file_mtime *cfmtime)
Definition: main/config.c:1756
struct cache_file_mtime::@336 list

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, config_cache_destroy_entry(), cache_file_mtime::filename, and cache_file_mtime::who_asked.

Referenced by config_text_file_load().

◆ config_hook_exec()

static void config_hook_exec ( const char *  filename,
const char *  module,
const struct ast_config cfg 
)
static

Definition at line 4298 of file main/config.c.

4299{
4300 struct ao2_iterator it;
4301 struct cfg_hook *hook;
4302 if (!(cfg_hooks)) {
4303 return;
4304 }
4306 while ((hook = ao2_iterator_next(&it))) {
4307 if (!strcasecmp(hook->filename, filename) &&
4308 !strcasecmp(hook->module, module)) {
4309 struct ast_config *copy = ast_config_copy(cfg);
4310 hook->hook_cb(copy);
4311 }
4312 ao2_ref(hook, -1);
4313 }
4315}
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ast_config * ast_config_copy(const struct ast_config *old)
Copies the contents of one ast_config into another.
Definition: main/config.c:3261
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_config_copy(), cfg_hooks, copy(), cfg_hook::filename, cfg_hook::hook_cb, and cfg_hook::module.

Referenced by ast_config_internal_load(), and ast_config_text_file_save2().

◆ config_shutdown()

static void config_shutdown ( void  )
static

Definition at line 4233 of file main/config.c.

4234{
4235 struct cache_file_mtime *cfmtime;
4236
4238 while ((cfmtime = AST_LIST_REMOVE_HEAD(&cfmtime_head, list))) {
4240 }
4242
4244
4246
4248 cfg_hooks = NULL;
4249}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct ast_cli_entry cli_config[]
Definition: main/config.c:4227
static void clear_config_maps(void)
Definition: main/config.c:3041
#define ARRAY_LEN(a)
Definition: utils.h:666

References ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, cfg_hooks, clear_config_maps(), cli_config, config_cache_destroy_entry(), and NULL.

Referenced by register_config_cli().

◆ config_text_file_load()

static struct ast_config * config_text_file_load ( const char *  database,
const char *  table,
const char *  filename,
struct ast_config cfg,
struct ast_flags  flags,
const char *  suggested_include_file,
const char *  who_asked 
)
static

Growable string buffer

< this will be a comment collector.

< A buffer for stuff behind the ;

Definition at line 2227 of file main/config.c.

2228{
2229 char fn[256];
2230#if defined(LOW_MEMORY)
2231 char buf[512];
2232#else
2233 char buf[8192];
2234#endif
2235 char *new_buf, *comment_p, *process_buf;
2236 FILE *f;
2237 int lineno=0;
2238 int comment = 0, nest[MAX_NESTED_COMMENTS];
2239 struct ast_category *cat = NULL;
2240 int count = 0;
2241 struct stat statbuf;
2242 struct cache_file_mtime *cfmtime = NULL;
2243 struct cache_file_include *cfinclude;
2244 struct ast_variable *last_var = NULL;
2245 struct ast_category *last_cat = NULL;
2246 /*! Growable string buffer */
2247 struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/
2248 struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */
2249 int glob_ret;
2250 glob_t globbuf;
2251
2252 if (cfg) {
2254 }
2255
2256 if (filename[0] == '/') {
2257 ast_copy_string(fn, filename, sizeof(fn));
2258 } else {
2259 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
2260 }
2261
2264 if (comment_buffer) {
2266 }
2267 if (!lline_buffer) {
2269 ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
2270 return NULL;
2271 }
2272 }
2273
2274 globbuf.gl_offs = 0; /* initialize it to silence gcc */
2275 glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf);
2276 if (glob_ret == GLOB_NOSPACE) {
2278 "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
2279 } else if (glob_ret == GLOB_ABORTED) {
2281 "Glob Expansion of pattern '%s' failed: Read error\n", fn);
2282 } else {
2283 /* loop over expanded files */
2284 int i;
2285
2286 if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
2287 /*
2288 * We just want a file changed answer and since we cannot
2289 * tell if a file was deleted with wildcard matching we will
2290 * assume that something has always changed. Also without
2291 * a lot of refactoring we couldn't check more than one file
2292 * for changes in the glob loop anyway.
2293 */
2294 globfree(&globbuf);
2297 return NULL;
2298 }
2299 for (i=0; i<globbuf.gl_pathc; i++) {
2300 ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
2301
2302 /*
2303 * The following is not a loop, but just a convenient way to define a block
2304 * (using do { } while(0) ), and be able to exit from it with 'continue'
2305 * or 'break' in case of errors. Nice trick.
2306 */
2307 do {
2308 if (stat(fn, &statbuf)) {
2309 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
2310 config_cache_remove(fn, who_asked);
2311 }
2312 continue;
2313 }
2314
2315 if (!S_ISREG(statbuf.st_mode)) {
2316 ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
2317 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
2318 config_cache_remove(fn, who_asked);
2319 }
2320 continue;
2321 }
2322
2323 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
2324 /* Find our cached entry for this configuration file */
2326 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
2327 if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) {
2328 break;
2329 }
2330 }
2331 if (!cfmtime) {
2332 cfmtime = cfmtime_new(fn, who_asked);
2333 if (!cfmtime) {
2335 continue;
2336 }
2337 /* Note that the file mtime is initialized to 0, i.e. 1970 */
2338 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
2339 }
2340 }
2341
2342 if (cfmtime
2343 && !cfmtime->has_exec
2344 && !cfmstat_cmp(cfmtime, &statbuf)
2346 int unchanged = 1;
2347
2348 /* File is unchanged, what about the (cached) includes (if any)? */
2349 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
2350 if (!config_text_file_load(NULL, NULL, cfinclude->include,
2351 NULL, flags, "", who_asked)) {
2352 /* One change is enough to short-circuit and reload the whole shebang */
2353 unchanged = 0;
2354 break;
2355 }
2356 }
2357
2358 if (unchanged) {
2360 globfree(&globbuf);
2364 }
2365 }
2366
2367 /* If cfg is NULL, then we just want a file changed answer. */
2368 if (cfg == NULL) {
2369 if (cfmtime) {
2371 }
2372 continue;
2373 }
2374
2375 if (cfmtime) {
2376 /* Forget about what we thought we knew about this file's includes. */
2377 cfmtime->has_exec = 0;
2379
2380 cfmstat_save(cfmtime, &statbuf);
2382 }
2383
2384 if (!(f = fopen(fn, "r"))) {
2385 ast_debug(1, "No file to parse: %s\n", fn);
2386 ast_verb(2, "Parsing '%s': Not found (%s)\n", fn, strerror(errno));
2387 continue;
2388 }
2389 count++;
2390 /* If we get to this point, then we're loading regardless */
2392 ast_debug(1, "Parsing %s\n", fn);
2393 while (!feof(f)) {
2394 lineno++;
2395 if (fgets(buf, sizeof(buf), f)) {
2396 /* Skip lines that are too long */
2397 if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 2] != '\n') {
2398 ast_log(LOG_WARNING, "Line %d too long, skipping. It begins with: %.32s...\n", lineno, buf);
2399 while (fgets(buf, sizeof(buf), f)) {
2400 if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 2] == '\n') {
2401 break;
2402 }
2403 }
2404 continue;
2405 }
2406
2407 /* If there is a UTF-8 BOM, skip over it */
2408 if (lineno == 1) {
2409#define UTF8_BOM "\xEF\xBB\xBF"
2410 size_t line_bytes = strlen(buf);
2411 size_t bom_bytes = sizeof(UTF8_BOM) - 1;
2412 if (line_bytes >= bom_bytes
2413 && !memcmp(buf, UTF8_BOM, bom_bytes)) {
2414 memmove(buf, &buf[bom_bytes], line_bytes - bom_bytes + 1);
2415 }
2416#undef UTF8_BOM
2417 }
2418
2420 && lline_buffer
2422 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
2423 ast_str_reset(lline_buffer); /* erase the lline buffer */
2424 }
2425
2426 new_buf = buf;
2427 if (comment) {
2428 process_buf = NULL;
2429 } else {
2430 process_buf = buf;
2431 }
2432
2436 && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) {
2437 /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */
2438 CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */
2439 continue; /* go get a new line, then */
2440 }
2441
2442 while ((comment_p = strchr(new_buf, COMMENT_META))) {
2443 if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) {
2444 /* Escaped semicolons aren't comments. */
2445 new_buf = comment_p;
2446 /* write over the \ and bring the null terminator with us */
2447 memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
2448 } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
2449 /* Meta-Comment start detected ";--" */
2451 *comment_p = '\0';
2452 new_buf = comment_p + 3;
2453 comment++;
2454 nest[comment-1] = lineno;
2455 } else {
2456 ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
2457 }
2458 } else if ((comment_p >= new_buf + 2) &&
2459 (*(comment_p - 1) == COMMENT_TAG) &&
2460 (*(comment_p - 2) == COMMENT_TAG)) {
2461 /* Meta-Comment end detected "--;" */
2462 comment--;
2463 new_buf = comment_p + 1;
2464 if (!comment) {
2465 /* Back to non-comment now */
2466 if (process_buf) {
2467 /* Actually have to move what's left over the top, then continue */
2468 char *oldptr;
2469
2470 oldptr = process_buf + strlen(process_buf);
2472 CB_ADD(&comment_buffer, ";");
2473 CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
2474 }
2475
2476 memmove(oldptr, new_buf, strlen(new_buf) + 1);
2477 new_buf = oldptr;
2478 } else {
2479 process_buf = new_buf;
2480 }
2481 }
2482 } else {
2483 if (!comment) {
2484 /* If ; is found, and we are not nested in a comment,
2485 we immediately stop all comment processing */
2487 CB_ADD(&lline_buffer, comment_p);
2488 }
2489 *comment_p = '\0';
2490 new_buf = comment_p;
2491 } else {
2492 new_buf = comment_p + 1;
2493 }
2494 }
2495 }
2496 if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) {
2497 CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */
2498 }
2499
2500 if (process_buf) {
2501 char *buffer = ast_strip(process_buf);
2502
2503 if (!ast_strlen_zero(buffer)) {
2504 if (process_text_line(cfg, &cat, buffer, lineno, fn,
2506 suggested_include_file, &last_cat, &last_var,
2507 who_asked)) {
2509 break;
2510 }
2511 }
2512 }
2513 }
2514 }
2515 /* end of file-- anything in a comment buffer? */
2516 if (last_cat) {
2519 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
2520 ast_str_reset(lline_buffer); /* erase the lline buffer */
2521 }
2523 }
2524 } else if (last_var) {
2527 CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
2528 ast_str_reset(lline_buffer); /* erase the lline buffer */
2529 }
2531 }
2532 } else {
2534 ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer));
2535 }
2536 }
2539 }
2540
2541 fclose(f);
2542 } while (0);
2543 if (comment) {
2544 ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
2545 }
2546 if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
2547 break;
2548 }
2549 }
2550 globfree(&globbuf);
2551 }
2552
2555
2556 if (count == 0) {
2557 return NULL;
2558 }
2559
2560 return cfg;
2561}
#define GLOB_ABORTED
Definition: ael_lex.c:828
static char * lline_buffer
Definition: extconf.c:708
static char * comment_buffer
Definition: extconf.c:705
#define MY_GLOB_FLAGS
@ CONFIG_FLAG_NOCACHE
@ CONFIG_FLAG_WITHCOMMENTS
@ CONFIG_FLAG_FILEUNCHANGED
#define MAX_NESTED_COMMENTS
Definition: main/config.c:63
#define UTF8_BOM
static int cfmstat_cmp(struct cache_file_mtime *cfmtime, struct stat *statbuf)
Definition: main/config.c:1720
static void config_cache_remove(const char *filename, const char *who_asked)
Definition: main/config.c:1769
#define CB_SIZE
Definition: main/config.c:128
#define COMMENT_TAG
Definition: main/config.c:67
static struct ast_config * config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, struct ast_flags flags, const char *suggested_include_file, const char *who_asked)
Definition: main/config.c:2227
struct ast_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
Definition: main/config.c:1645
static void CB_RESET(struct ast_str *cb, struct ast_str *llb)
Definition: main/config.c:144
#define COMMENT_META
Definition: main/config.c:66
static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, struct ast_flags flags, struct ast_str *comment_buffer, struct ast_str *lline_buffer, const char *suggested_include_file, struct ast_category **last_cat, struct ast_variable **last_var, const char *who_asked)
parse one line in the configuration.
Definition: main/config.c:1930
static void CB_ADD_LEN(struct ast_str **cb, const char *str, int len)
Definition: main/config.c:135
static struct ast_comment * ALLOC_COMMENT(struct ast_str *buffer)
Definition: main/config.c:154
static void CB_ADD(struct ast_str **cb, const char *str)
Definition: main/config.c:130
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
#define ast_clear_flag(p, flag)
Definition: utils.h:77

References ALLOC_COMMENT(), ast_clear_flag, ast_config_AST_CONFIG_DIR, ast_config_get_current_category(), ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_SORTALPHA, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_str_buffer(), ast_str_create, ast_str_reset(), ast_str_strlen(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_verb, buf, CB_ADD(), CB_ADD_LEN(), CB_RESET(), CB_SIZE, cfmstat_cmp(), cfmstat_save(), cfmtime_new(), comment, comment_buffer, COMMENT_META, COMMENT_TAG, config_cache_flush_includes(), config_cache_remove(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, config_text_file_load(), errno, cache_file_mtime::filename, GLOB_ABORTED, cache_file_mtime::has_exec, cache_file_include::include, cache_file_mtime::includes, ast_category::lineno, lline_buffer, LOG_ERROR, LOG_WARNING, MAX_NESTED_COMMENTS, MY_GLOB_FLAGS, NULL, process_text_line(), ast_variable::trailing, ast_category::trailing, UTF8_BOM, and cache_file_mtime::who_asked.

Referenced by config_text_file_load().

◆ count_linefeeds()

static int count_linefeeds ( char *  str)
static

Definition at line 2657 of file main/config.c.

2658{
2659 int count = 0;
2660
2661 while (*str) {
2662 if (*str =='\n')
2663 count++;
2664 str++;
2665 }
2666 return count;
2667}

References str.

Referenced by count_linefeeds_in_comments().

◆ count_linefeeds_in_comments()

static int count_linefeeds_in_comments ( struct ast_comment x)
static

Definition at line 2669 of file main/config.c.

2670{
2671 int count = 0;
2672
2673 while (x) {
2674 count += count_linefeeds(x->cmt);
2675 x = x->next;
2676 }
2677 return count;
2678}
static int count_linefeeds(char *str)
Definition: main/config.c:2657

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

Referenced by insert_leading_blank_lines().

◆ does_category_match()

static int does_category_match ( struct ast_category cat,
const char *  category_name,
const char *  match,
char  sep 
)
static

Returns true if ALL of the regex expressions and category name match. Both can be NULL (I.E. no predicate) which results in a true return;.

Definition at line 979 of file main/config.c.

981{
982 char *dupmatch;
983 char *nvp = NULL;
984 int match_found = 0, match_expressions = 0;
985 int template_ok = 0;
986
987 /* Only match on category name if it's not a NULL or empty string */
988 if (!ast_strlen_zero(category_name) && strcasecmp(cat->name, category_name)) {
989 return 0;
990 }
991
992 /* If match is NULL or empty, automatically match if not a template */
993 if (ast_strlen_zero(match)) {
994 return !cat->ignored;
995 }
996
997 dupmatch = ast_strdupa(match);
998
999 while ((nvp = ast_strsep(&dupmatch, sep, AST_STRSEP_STRIP))) {
1000 struct ast_variable *v;
1001 char *match_name;
1002 char *match_value = NULL;
1003 char *regerr;
1004 int rc;
1005 regex_t r_name, r_value;
1006
1007 match_expressions++;
1008
1009 match_name = ast_strsep(&nvp, '=', AST_STRSEP_STRIP);
1010 match_value = ast_strsep(&nvp, '=', AST_STRSEP_STRIP);
1011
1012 /* an empty match value is OK. A NULL match value (no =) is NOT. */
1013 if (match_value == NULL) {
1014 break;
1015 }
1016
1017 if (!strcmp("TEMPLATES", match_name)) {
1018 if (!strcasecmp("include", match_value)) {
1019 if (cat->ignored) {
1020 template_ok = 1;
1021 }
1022 match_found++;
1023 } else if (!strcasecmp("restrict", match_value)) {
1024 if (cat->ignored) {
1025 match_found++;
1026 template_ok = 1;
1027 } else {
1028 break;
1029 }
1030 }
1031 continue;
1032 }
1033
1034 if ((rc = regcomp(&r_name, match_name, REG_EXTENDED | REG_NOSUB))) {
1035 regerr = ast_alloca(128);
1036 regerror(rc, &r_name, regerr, 128);
1037 ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n",
1038 match_name, regerr);
1039 regfree(&r_name);
1040 return 0;
1041 }
1042 if ((rc = regcomp(&r_value, match_value, REG_EXTENDED | REG_NOSUB))) {
1043 regerr = ast_alloca(128);
1044 regerror(rc, &r_value, regerr, 128);
1045 ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n",
1046 match_value, regerr);
1047 regfree(&r_name);
1048 regfree(&r_value);
1049 return 0;
1050 }
1051
1052 for (v = cat->root; v; v = v->next) {
1053 if (!regexec(&r_name, v->name, 0, NULL, 0)
1054 && !regexec(&r_value, v->value, 0, NULL, 0)) {
1055 match_found++;
1056 break;
1057 }
1058 }
1059 regfree(&r_name);
1060 regfree(&r_value);
1061 }
1062 if (match_found == match_expressions && (!cat->ignored || template_ok)) {
1063 return 1;
1064 }
1065 return 0;
1066}
@ AST_STRSEP_STRIP
Definition: strings.h:255
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835

References ast_alloca, ast_log, ast_strdupa, ast_strlen_zero(), ast_strsep(), AST_STRSEP_STRIP, ast_category::ignored, LOG_ERROR, match(), ast_variable::name, ast_category::name, ast_variable::next, NULL, ast_category::root, and ast_variable::value.

Referenced by category_get_sep(), and next_available_category().

◆ find_engine()

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

Find realtime engine for realtime family.

Definition at line 3224 of file main/config.c.

3225{
3226 struct ast_config_engine *eng, *ret = NULL;
3227 struct ast_config_map *map;
3228
3230
3231 for (map = config_maps; map; map = map->next) {
3232 if (!strcasecmp(family, map->name) && (priority == map->priority)) {
3233 if (database)
3234 ast_copy_string(database, map->database, dbsiz);
3235 if (table)
3236 ast_copy_string(table, map->table ? map->table : family, tabsiz);
3237 break;
3238 }
3239 }
3240
3241 /* Check if the required driver (engine) exist */
3242 if (map) {
3243 for (eng = config_engine_list; !ret && eng; eng = eng->next) {
3244 if (!strcasecmp(eng->name, map->driver))
3245 ret = eng;
3246 }
3247 }
3248
3249 /* if we found a mapping, but the engine is not available, then issue a warning */
3250 if (map && !ret)
3251 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
3252
3253 return ret;
3254}

References ast_copy_string(), ast_log, config_engine_list, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, lock, LOG_WARNING, ast_config_map::name, ast_config_engine::next, ast_config_map::next, NULL, priority, ast_config_map::priority, SCOPED_MUTEX, table, and ast_config_map::table.

Referenced by ast_check_realtime(), ast_config_internal_load(), ast_destroy_realtime_fields(), ast_load_realtime_all_fields(), ast_load_realtime_multientry_fields(), ast_realtime_require_field(), ast_store_realtime_fields(), ast_unload_realtime(), ast_update2_realtime_fields(), and ast_update_realtime_fields().

◆ gen_header()

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

Definition at line 2584 of file main/config.c.

2585{
2586 char date[256]="";
2587 time_t t;
2588
2589 time(&t);
2590 ast_copy_string(date, ctime(&t), sizeof(date));
2591
2592 fprintf(f1, ";!\n");
2593 fprintf(f1, ";! Automatically generated configuration file\n");
2594 if (strcmp(configfile, fn))
2595 fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
2596 else
2597 fprintf(f1, ";! Filename: %s\n", configfile);
2598 fprintf(f1, ";! Generator: %s\n", generator);
2599 fprintf(f1, ";! Creation Date: %s", date);
2600 fprintf(f1, ";!\n");
2601}

References ast_copy_string().

Referenced by ast_config_text_file_save2().

◆ handle_cli_config_list()

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

Definition at line 4203 of file main/config.c.

4204{
4205 struct cache_file_mtime *cfmtime;
4206
4207 switch (cmd) {
4208 case CLI_INIT:
4209 e->command = "config list";
4210 e->usage =
4211 "Usage: config list\n"
4212 " Show all modules that have loaded a configuration file\n";
4213 return NULL;
4214 case CLI_GENERATE:
4215 return NULL;
4216 }
4217
4219 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4220 ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
4221 }
4223
4224 return CLI_SUCCESS;
4225}
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, cache_file_mtime::filename, NULL, S_OR, ast_cli_entry::usage, and cache_file_mtime::who_asked.

◆ handle_cli_config_reload()

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

Definition at line 4140 of file main/config.c.

4141{
4142 struct cache_file_mtime *cfmtime;
4143 char *prev = "";
4144 int wordlen;
4145
4146 switch (cmd) {
4147 case CLI_INIT:
4148 e->command = "config reload";
4149 e->usage =
4150 "Usage: config reload <filename.conf>\n"
4151 " Reloads all modules that reference <filename.conf>\n";
4152 return NULL;
4153 case CLI_GENERATE:
4154 if (a->pos > 2) {
4155 return NULL;
4156 }
4157
4158 wordlen = strlen(a->word);
4159
4161 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4162 /* Core configs cannot be reloaded */
4163 if (ast_strlen_zero(cfmtime->who_asked)) {
4164 continue;
4165 }
4166
4167 /* Skip duplicates - this only works because the list is sorted by filename */
4168 if (!strcmp(cfmtime->filename, prev)) {
4169 continue;
4170 }
4171
4172 if (!strncmp(cfmtime->filename, a->word, wordlen)) {
4174 break;
4175 }
4176 }
4177
4178 /* Otherwise save that we've seen this filename */
4179 prev = cfmtime->filename;
4180 }
4182
4183 return NULL;
4184 }
4185
4186 if (a->argc != 3) {
4187 return CLI_SHOWUSAGE;
4188 }
4189
4191 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4192 if (!strcmp(cfmtime->filename, a->argv[2])) {
4193 char *buf = ast_alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
4194 sprintf(buf, "module reload %s", cfmtime->who_asked);
4195 ast_cli_command(a->fd, buf);
4196 }
4197 }
4199
4200 return CLI_SUCCESS;
4201}
#define CLI_SHOWUSAGE
Definition: cli.h:45
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2768
ast_cli_command
calling arguments for new-style handlers.
Definition: cli.h:151

References a, ast_alloca, ast_cli_completion_add(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strlen_zero(), buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, cache_file_mtime::filename, NULL, ast_category::prev, ast_cli_entry::usage, and cache_file_mtime::who_asked.

◆ handle_cli_core_show_config_mappings()

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

Definition at line 4103 of file main/config.c.

4104{
4105 struct ast_config_engine *eng;
4106 struct ast_config_map *map;
4107
4108 switch (cmd) {
4109 case CLI_INIT:
4110 e->command = "core show config mappings";
4111 e->usage =
4112 "Usage: core show config mappings\n"
4113 " Shows the filenames to config engines.\n";
4114 return NULL;
4115 case CLI_GENERATE:
4116 return NULL;
4117 }
4118
4119 {
4121
4122 if (!config_engine_list) {
4123 ast_cli(a->fd, "No config mappings found.\n");
4124 } else {
4125 for (eng = config_engine_list; eng; eng = eng->next) {
4126 ast_cli(a->fd, "Config Engine: %s\n", eng->name);
4127 for (map = config_maps; map; map = map->next) {
4128 if (!strcasecmp(map->driver, eng->name)) {
4129 ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
4130 map->table ? map->table : map->name);
4131 }
4132 }
4133 }
4134 }
4135 }
4136
4137 return CLI_SUCCESS;
4138}

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, config_engine_list, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, lock, ast_config_engine::name, ast_config_map::name, ast_config_engine::next, ast_config_map::next, NULL, SCOPED_MUTEX, ast_config_map::table, and ast_cli_entry::usage.

◆ handle_include_exec()

static int handle_include_exec ( const char *  command,
const char *  output_file 
)
static

Definition at line 1844 of file main/config.c.

1845{
1846 char buf[1024];
1847 FILE *fp;
1848 int status;
1849 struct stat output_file_info;
1850
1851 /* stderr to stdout, stdout to file */
1852 if (snprintf(buf, sizeof(buf), "%s 2>&1 > %s", command, output_file) >= sizeof(buf)) {
1853 ast_log(LOG_ERROR, "Failed to construct command string to execute %s.\n", command);
1854 return -1;
1855 }
1856
1858
1859 errno = 0;
1860
1861 fp = popen(buf, "r");
1862 if (!fp) {
1863 ast_log(LOG_ERROR, "#exec <%s>: Failed to execute: %s\n",
1864 command,
1865 strerror(errno));
1867 return 0;
1868 }
1869
1870 while (fgets(buf, sizeof(buf), fp)) {
1871 /* Ensure we have a \n at the end */
1872 if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 2] != '\n') {
1873 ast_log(LOG_ERROR, "#exec <%s>: %s... <truncated>\n",
1874 command,
1875 buf);
1876
1877 /* Consume the rest of the line */
1878 while (fgets(buf, sizeof(buf), fp)) {
1879 if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 2] == '\n') {
1880 break;
1881 }
1882 }
1883
1884 continue;
1885 }
1886
1887 /* `buf` has the newline, so we don't need to print it ourselves */
1888 ast_log(LOG_ERROR, "#exec <%s>: %s",
1889 command,
1890 buf);
1891 }
1892
1893 status = pclose(fp);
1894 if (status == -1) {
1895 ast_log(LOG_ERROR, "#exec <%s>: Failed to retrieve exit status: %s\n",
1896 command,
1897 strerror(errno));
1898 } else {
1900 if (status) {
1901 ast_log(LOG_ERROR, "#exec <%s>: Exited with return value %d\n",
1902 command,
1903 status);
1904 }
1905 }
1906
1908
1909 /* Check that the output file contains something */
1910 if (stat(output_file, &output_file_info) == -1) {
1911 ast_log(LOG_ERROR, "#exec <%s>: Unable to stat() temporary file `%s': %s\n",
1912 command,
1913 output_file,
1914 strerror(errno));
1915 } else if (output_file_info.st_size == 0) {
1916 ast_log(LOG_WARNING, "#exec <%s>: The program generated no usable output.\n",
1917 command);
1918 }
1919
1920 return 0;
1921}
jack_status_t status
Definition: app_jack.c:146
void ast_replace_sigchld(void)
Replace the SIGCHLD handler.
Definition: extconf.c:801
void ast_unreplace_sigchld(void)
Restore the SIGCHLD handler.
Definition: extconf.c:815
#define WEXITSTATUS(status)
#define WIFEXITED(status)

References ast_log, ast_replace_sigchld(), ast_unreplace_sigchld(), buf, errno, LOG_ERROR, LOG_WARNING, status, WEXITSTATUS, and WIFEXITED.

Referenced by process_text_line().

◆ hash_string()

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

Definition at line 174 of file main/config.c.

175{
176 char *str = ((struct inclfile *) obj)->fname;
177 int total;
178
179 for (total = 0; *str; str++) {
180 unsigned int tmp = total;
181 total <<= 1; /* multiply by 2 */
182 total += tmp; /* multiply by 3 */
183 total <<= 2; /* multiply by 12 */
184 total += tmp; /* multiply by 13 */
185
186 total += ((unsigned int) (*str));
187 }
188 if (total < 0) {
189 total = -total;
190 }
191 return total;
192}
static int total
Definition: res_adsi.c:970

References str, tmp(), and total.

Referenced by ast_config_text_file_save2().

◆ hashtab_compare_strings()

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

Definition at line 194 of file main/config.c.

195{
196 const struct inclfile *ae = a, *be = b;
197 return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0;
198}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
char * be
Definition: eagi_proxy.c:73
char * fname
Definition: main/config.c:170
static struct test_val b

References a, b, be, CMP_MATCH, CMP_STOP, and inclfile::fname.

Referenced by ast_config_text_file_save2().

◆ hook_cmp()

static int hook_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 4274 of file main/config.c.

4275{
4276 struct cfg_hook *hook1 = obj;
4277 struct cfg_hook *hook2 = arg;
4278
4279 return !(strcasecmp(hook1->name, hook2->name)) ? CMP_MATCH | CMP_STOP : 0;
4280}

References CMP_MATCH, CMP_STOP, and cfg_hook::name.

Referenced by ast_config_hook_register().

◆ hook_destroy()

static void hook_destroy ( void *  obj)
static

Definition at line 4266 of file main/config.c.

4267{
4268 struct cfg_hook *hook = obj;
4269 ast_free((void *) hook->name);
4270 ast_free((void *) hook->filename);
4271 ast_free((void *) hook->module);
4272}

References ast_free, cfg_hook::filename, cfg_hook::module, and cfg_hook::name.

Referenced by ast_config_hook_register().

◆ hook_hash()

static int hook_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 4282 of file main/config.c.

4283{
4284 const struct cfg_hook *hook = obj;
4285
4286 return ast_str_hash(hook->name);
4287}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

References ast_str_hash(), and cfg_hook::name.

Referenced by ast_config_hook_register().

◆ inclfile_destroy()

static void inclfile_destroy ( void *  obj)
static

Definition at line 2603 of file main/config.c.

2604{
2605 const struct inclfile *o = obj;
2606
2607 ast_free(o->fname);
2608}

References ast_free, and inclfile::fname.

Referenced by set_fn().

◆ init_appendbuf()

static int init_appendbuf ( void *  data)
static

Definition at line 118 of file main/config.c.

119{
120 struct ast_str **str = data;
121 *str = ast_str_create(16);
122 return *str ? 0 : -1;
123}

References ast_str_create, and str.

◆ insert_leading_blank_lines()

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

Definition at line 2680 of file main/config.c.

2681{
2682 int precomment_lines;
2683 int i;
2684
2685 if (!fi) {
2686 /* No file scratch pad object so insert no blank lines. */
2687 return;
2688 }
2689
2690 precomment_lines = count_linefeeds_in_comments(precomments);
2691
2692 /* I don't have to worry about those ;! comments, they are
2693 stored in the precomments, but not printed back out.
2694 I did have to make sure that comments following
2695 the ;! header comments were not also deleted in the process */
2696 if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */
2697 return;
2698 } else if (lineno == 0) {
2699 /* Line replacements also mess things up */
2700 return;
2701 } else if (lineno - precomment_lines - fi->lineno < 5) {
2702 /* Only insert less than 5 blank lines; if anything more occurs,
2703 * it's probably due to context deletion. */
2704 for (i = fi->lineno; i < lineno - precomment_lines; i++) {
2705 fprintf(fp, "\n");
2706 }
2707 } else {
2708 /* Deletion occurred - insert a single blank line, for separation of
2709 * contexts. */
2710 fprintf(fp, "\n");
2711 }
2712
2713 fi->lineno = lineno + 1; /* Advance the file lineno */
2714}
static int count_linefeeds_in_comments(struct ast_comment *x)
Definition: main/config.c:2669
int lineno
Definition: main/config.c:171

References count_linefeeds_in_comments(), inclfile::lineno, ast_category::lineno, and ast_category::precomments.

Referenced by ast_config_text_file_save2().

◆ is_writable()

static int is_writable ( const char *  fn)
static

Definition at line 2721 of file main/config.c.

2722{
2723 if (access(fn, F_OK)) {
2724 char *dn = dirname(ast_strdupa(fn));
2725
2726 if (access(dn, R_OK | W_OK)) {
2727 ast_log(LOG_ERROR, "Unable to write to directory %s (%s)\n", dn, strerror(errno));
2728 return 0;
2729 }
2730 } else {
2731 if (access(fn, R_OK | W_OK)) {
2732 ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
2733 return 0;
2734 }
2735 }
2736
2737 return 1;
2738}

References ast_log, ast_strdupa, errno, and LOG_ERROR.

Referenced by ast_config_text_file_save2().

◆ load_module()

static int load_module ( void  )
static

Definition at line 4351 of file main/config.c.

4352{
4353 if (ast_opt_console) {
4354 ast_verb(0, "[ Initializing Custom Configuration Options ]\n");
4355 }
4356
4358}
static int reload_module(void)
Definition: main/config.c:3091
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define ast_opt_console
Definition: options.h:111

References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_opt_console, ast_verb, and reload_module().

◆ make_fn()

static void make_fn ( char *  fn,
size_t  fn_size,
const char *  file,
const char *  configfile 
)
static

Definition at line 2610 of file main/config.c.

2611{
2612 if (ast_strlen_zero(file)) {
2613 if (configfile[0] == '/') {
2614 ast_copy_string(fn, configfile, fn_size);
2615 } else {
2616 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
2617 }
2618 } else if (file[0] == '/') {
2619 ast_copy_string(fn, file, fn_size);
2620 } else {
2621 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
2622 }
2623}

References ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_strlen_zero(), and make_ari_stubs::file.

Referenced by ast_config_text_file_save2(), and set_fn().

◆ move_variables()

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

Definition at line 967 of file main/config.c.

968{
969 struct ast_variable *var = old->root;
970
971 old->root = NULL;
972 /* we can just move the entire list in a single op */
974}

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

Referenced by process_text_line().

◆ new_category()

static struct ast_category * new_category ( const char *  name,
const char *  in_file,
int  lineno,
int  template 
)
static

Definition at line 1069 of file main/config.c.

1070{
1071 struct ast_category *category;
1072
1073 category = ast_calloc(1, sizeof(*category));
1074 if (!category) {
1075 return NULL;
1076 }
1077 category->file = ast_strdup(in_file);
1078 if (!category->file) {
1079 ast_category_destroy(category);
1080 return NULL;
1081 }
1082 ast_copy_string(category->name, name, sizeof(category->name));
1083 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
1084 category->ignored = template;
1085 return category;
1086}

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

Referenced by ast_category_new(), and ast_category_new_template().

◆ next_available_category()

static struct ast_category * next_available_category ( struct ast_category cat,
const char *  name,
const char *  filter 
)
static

Definition at line 1246 of file main/config.c.

1248{
1249 for (; cat && !does_category_match(cat, name, filter, ','); cat = cat->next);
1250
1251 return cat;
1252}

References does_category_match(), filter(), name, and ast_category::next.

Referenced by ast_category_browse(), and ast_category_browse_filtered().

◆ process_text_line()

static int process_text_line ( struct ast_config cfg,
struct ast_category **  cat,
char *  buf,
int  lineno,
const char *  configfile,
struct ast_flags  flags,
struct ast_str comment_buffer,
struct ast_str lline_buffer,
const char *  suggested_include_file,
struct ast_category **  last_cat,
struct ast_variable **  last_var,
const char *  who_asked 
)
static

parse one line in the configuration.

* We can have a category header [foo](...)
* a directive               #include / #exec
* or a regular line         name = value
* 

Definition at line 1930 of file main/config.c.

1936{
1937 char *c;
1938 char *cur = buf;
1939 struct ast_variable *v;
1940 char exec_file[512];
1941
1942 /* Actually parse the entry */
1943 if (cur[0] == '[') { /* A category header */
1944 /* format is one of the following:
1945 * [foo] define a new category named 'foo'
1946 * [foo](!) define a new template category named 'foo'
1947 * [foo](+) append to category 'foo', error if foo does not exist.
1948 * [foo](a) define a new category and inherit from category or template a.
1949 * You can put a comma-separated list of categories and templates
1950 * and '!' and '+' between parentheses, with obvious meaning.
1951 */
1952 struct ast_category *newcat;
1953 char *catname;
1954
1955 c = strchr(cur, ']');
1956 if (!c) {
1957 ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
1958 return -1;
1959 }
1960 *c++ = '\0';
1961 cur++;
1962 if (*c++ != '(')
1963 c = NULL;
1964 catname = cur;
1965 *cat = newcat = ast_category_new(catname,
1966 S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile),
1967 lineno);
1968 if (!newcat) {
1969 return -1;
1970 }
1971 (*cat)->lineno = lineno;
1972
1973 /* add comments */
1980
1981 /* If there are options or categories to inherit from, process them now */
1982 if (c) {
1983 if (!(cur = strchr(c, ')'))) {
1984 ast_category_destroy(newcat);
1985 ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
1986 return -1;
1987 }
1988 *cur = '\0';
1989 while ((cur = strsep(&c, ","))) {
1990 if (!strcasecmp(cur, "!")) {
1991 (*cat)->ignored = 1;
1992 } else if (cur[0] == '+') {
1993 char *filter = NULL;
1994
1995 if (cur[1] != ',') {
1996 filter = &cur[1];
1997 }
1998 *cat = category_get_sep(cfg, catname, filter, '&', 0);
1999 if (!(*cat)) {
2000 if (newcat) {
2001 ast_category_destroy(newcat);
2002 }
2003 ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
2004 return -1;
2005 }
2006 if (newcat) {
2008 (*cat)->ignored |= newcat->ignored;
2009 move_variables(newcat, *cat);
2010 ast_category_destroy(newcat);
2011 newcat = NULL;
2012 }
2013 } else {
2014 struct ast_category *base;
2015
2016 base = category_get_sep(cfg, cur, "TEMPLATES=include", ',', 0);
2017 if (!base) {
2018 if (newcat) {
2019 ast_category_destroy(newcat);
2020 }
2021 ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
2022 return -1;
2023 }
2024 if (ast_category_inherit(*cat, base)) {
2025 if (newcat) {
2026 ast_category_destroy(newcat);
2027 }
2028 ast_log(LOG_ERROR, "Inheritance requested, but allocation failed\n");
2029 return -1;
2030 }
2031 }
2032 }
2033 }
2034
2035 /*
2036 * We need to set *last_cat to newcat here regardless. If the
2037 * category is being appended to we have no place for trailing
2038 * comments on the appended category. The appended category
2039 * may be in another file or it already has trailing comments
2040 * that we would then leak.
2041 */
2042 *last_var = NULL;
2043 *last_cat = newcat;
2044 if (newcat) {
2045 ast_category_append(cfg, newcat);
2046 }
2047 } else if (cur[0] == '#') { /* A directive - #include or #exec */
2048 char *cur2;
2049 char real_inclusion_name[256];
2050 int do_include = 0; /* otherwise, it is exec */
2051 int try_include = 0;
2052
2053 cur++;
2054 c = cur;
2055 while (*c && (*c > 32)) {
2056 c++;
2057 }
2058
2059 if (*c) {
2060 *c = '\0';
2061 /* Find real argument */
2062 c = ast_strip(c + 1);
2063 if (!(*c)) {
2064 c = NULL;
2065 }
2066 } else {
2067 c = NULL;
2068 }
2069 if (!strcasecmp(cur, "include")) {
2070 do_include = 1;
2071 } else if (!strcasecmp(cur, "tryinclude")) {
2072 do_include = 1;
2073 try_include = 1;
2074 } else if (!strcasecmp(cur, "exec")) {
2075 if (!ast_opt_exec_includes) {
2076 ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
2077 return 0; /* XXX is this correct ? or we should return -1 ? */
2078 }
2079 } else {
2080 ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
2081 return 0; /* XXX is this correct ? or we should return -1 ? */
2082 }
2083
2084 if (c == NULL) {
2085 ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
2086 do_include ? "include / tryinclude" : "exec",
2087 do_include ? "filename" : "/path/to/executable",
2088 lineno,
2089 configfile);
2090 return 0; /* XXX is this correct ? or we should return -1 ? */
2091 }
2092
2093 cur = c;
2094 /* Strip off leading and trailing "'s and <>'s */
2095 /* Dequote */
2096 if ((*c == '"') || (*c == '<')) {
2097 char quote_char = *c;
2098 if (quote_char == '<') {
2099 quote_char = '>';
2100 }
2101
2102 if (*(c + strlen(c) - 1) == quote_char) {
2103 cur++;
2104 *(c + strlen(c) - 1) = '\0';
2105 }
2106 }
2107 cur2 = cur;
2108
2109 /* #exec </path/to/executable>
2110 We create a tmp file, then we #include it, then we delete it. */
2111 if (!do_include) {
2112 struct timeval now = ast_tvnow();
2113
2114 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
2115 config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked);
2116 snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self());
2117 if (handle_include_exec(cur, exec_file)) {
2118 return -1;
2119 }
2120 cur = exec_file;
2121 } else {
2122 if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
2123 config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked);
2124 exec_file[0] = '\0';
2125 }
2126 /* A #include */
2127 /* record this inclusion */
2128 ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
2129
2130 do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0;
2131 if (!ast_strlen_zero(exec_file))
2132 unlink(exec_file);
2133 if (!do_include && !try_include) {
2134 ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur);
2135 return -1;
2136 }
2137 /* XXX otherwise what ? the default return is 0 anyways */
2138
2139 } else {
2140 /* Just a line (variable = value) */
2141 int object = 0;
2142 int is_escaped;
2143
2144 if (!(*cat)) {
2146 "parse error: No category context for line %d of %s\n", lineno, configfile);
2147 return -1;
2148 }
2149
2150 is_escaped = cur[0] == '\\';
2151 if (is_escaped) {
2152 /* First character is escaped. */
2153 ++cur;
2154 if (cur[0] < 33) {
2155 ast_log(LOG_ERROR, "Invalid escape in line %d of %s\n", lineno, configfile);
2156 return -1;
2157 }
2158 }
2159 c = strchr(cur + is_escaped, '=');
2160
2161 if (c && c > cur + is_escaped && (*(c - 1) == '+')) {
2162 struct ast_variable *var, *replace = NULL;
2163 struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str));
2164
2165 if (!str || !*str) {
2166 return -1;
2167 }
2168
2169 *(c - 1) = '\0';
2170 c++;
2171 cur = ast_strip(cur);
2172
2173 /* Must iterate through category until we find last variable of same name (since there could be multiple) */
2174 for (var = ast_category_first(*cat); var; var = var->next) {
2175 if (!strcmp(var->name, cur)) {
2176 replace = var;
2177 }
2178 }
2179
2180 if (!replace) {
2181 /* Nothing to replace; just set a variable normally. */
2182 goto set_new_variable;
2183 }
2184
2185 ast_str_set(str, 0, "%s", replace->value);
2186 ast_str_append(str, 0, "%s", c);
2188 ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object);
2189 } else if (c) {
2190 *c = 0;
2191 c++;
2192 /* Ignore > in => */
2193 if (*c== '>') {
2194 object = 1;
2195 c++;
2196 }
2197 cur = ast_strip(cur);
2198set_new_variable:
2199 if (ast_strlen_zero(cur)) {
2200 ast_log(LOG_WARNING, "No variable name in line %d of %s\n", lineno, configfile);
2201 } else if ((v = ast_variable_new(cur, ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) {
2202 v->lineno = lineno;
2203 v->object = object;
2204 *last_cat = NULL;
2205 *last_var = v;
2206 /* Put and reset comments */
2207 v->blanklines = 0;
2208 ast_variable_append(*cat, v);
2209 /* add comments */
2216
2217 } else {
2218 return -1;
2219 }
2220 } else {
2221 ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
2222 }
2223 }
2224 return 0;
2225}
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:888
static void config_cache_attribute(const char *configfile, enum config_cache_attribute_enum attrtype, const char *filename, const char *who_asked)
Definition: main/config.c:1786
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)
Definition: main/config.c:336
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.
Definition: main/config.c:1542
void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat)
Set the category within the configuration as being current.
Definition: main/config.c:1650
static void move_variables(struct ast_category *old, struct ast_category *new)
Definition: main/config.c:967
static struct ast_threadstorage appendbuf
Definition: main/config.c:125
static int handle_include_exec(const char *command, const char *output_file)
Definition: main/config.c:1844
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1255
int ast_category_inherit(struct ast_category *new, const struct ast_category *base)
Applies base (template) to category.
Definition: main/config.c:1465
def try_include(line)
#define ast_opt_exec_includes
Definition: options.h:108
void ast_str_trim_blanks(struct ast_str *buf)
Trims trailing whitespace characters from an ast_str string.
Definition: strings.h:719
static struct test_val c
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ALLOC_COMMENT(), appendbuf, ast_category_append(), ast_category_destroy(), ast_category_first(), ast_category_inherit(), ast_category_new(), ast_config_internal_load(), ast_config_set_current_category(), ast_include_new(), ast_log, ast_opt_exec_includes, ast_skip_blanks(), ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_trim_blanks(), ast_strip(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_tvnow(), ast_variable_append(), ast_variable_new, ast_variable_update(), ATTRIBUTE_EXEC, ATTRIBUTE_INCLUDE, ast_variable::blanklines, buf, c, category_get_sep(), CB_RESET(), comment_buffer, config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, filter(), handle_include_exec(), ast_category::ignored, ast_config::include_level, ast_variable::lineno, ast_category::lineno, lline_buffer, LOG_ERROR, LOG_WARNING, move_variables(), NULL, ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), astconfigparser::try_include(), and var.

Referenced by config_text_file_load().

◆ realtime_arguments_to_fields2()

static int realtime_arguments_to_fields2 ( va_list  ap,
int  skip,
struct ast_variable **  result 
)
static

Definition at line 3367 of file main/config.c.

3368{
3369 struct ast_variable *first, *fields = NULL;
3370 const char *newparam;
3371 const char *newval;
3372
3373 /*
3374 * Previously we would do:
3375 *
3376 * va_start(ap, last);
3377 * x = realtime_arguments_to_fields(ap);
3378 * y = realtime_arguments_to_fields(ap);
3379 * va_end(ap);
3380 *
3381 * While this works on generic amd64 machines (2014), it doesn't on the
3382 * raspberry PI. The va_arg() manpage says:
3383 *
3384 * If ap is passed to a function that uses va_arg(ap,type) then
3385 * the value of ap is undefined after the return of that function.
3386 *
3387 * On the raspberry, ap seems to get reset after the call: the contents
3388 * of y would be equal to the contents of x.
3389 *
3390 * So, instead we allow the caller to skip past earlier argument sets
3391 * using the skip parameter:
3392 *
3393 * va_start(ap, last);
3394 * if (realtime_arguments_to_fields(ap, &x)) {
3395 * // FAILURE CONDITIONS
3396 * }
3397 * va_end(ap);
3398 * va_start(ap, last);
3399 * if (realtime_arguments_to_fields2(ap, 1, &y)) {
3400 * // FAILURE CONDITIONS
3401 * }
3402 * va_end(ap);
3403 */
3404 while (skip--) {
3405 /* There must be at least one argument. */
3406 newparam = va_arg(ap, const char *);
3407 newval = va_arg(ap, const char *);
3408 while ((newparam = va_arg(ap, const char *))) {
3409 newval = va_arg(ap, const char *);
3410 }
3411 }
3412
3413 /* Load up the first vars. */
3414 newparam = va_arg(ap, const char *);
3415 if (!newparam) {
3416 *result = NULL;
3417 return 0;
3418 }
3419 newval = va_arg(ap, const char *);
3420
3421 if (!(first = ast_variable_new(newparam, newval, ""))) {
3422 *result = NULL;
3423 return -1;
3424 }
3425
3426 while ((newparam = va_arg(ap, const char *))) {
3427 struct ast_variable *field;
3428
3429 newval = va_arg(ap, const char *);
3430 if (!(field = ast_variable_new(newparam, newval, ""))) {
3431 ast_variables_destroy(fields);
3433 *result = NULL;
3434 return -1;
3435 }
3436
3437 field->next = fields;
3438 fields = field;
3439 }
3440
3441 first->next = fields;
3442 fields = first;
3443
3444 *result = fields;
3445 return 0;
3446}

References ast_variable_new, ast_variables_destroy(), first, sla_ringing_trunk::next, ast_variable::next, NULL, and result.

Referenced by ast_update2_realtime().

◆ register_config_cli()

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 4251 of file main/config.c.

4252{
4254 /* This is separate from the module load so cleanup can happen very late. */
4256 return 0;
4257}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static void config_shutdown(void)
Definition: main/config.c:4233

References ARRAY_LEN, ast_cli_register_multiple, ast_register_cleanup(), cli_config, and config_shutdown().

Referenced by asterisk_daemon().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 3091 of file main/config.c.

3092{
3093 struct ast_config *config, *configtmp;
3094 struct ast_variable *v;
3095 char *driver, *table, *database, *textpri, *stringp, *tmp;
3097 int pri;
3099
3101
3102 configtmp = ast_config_new();
3103 if (!configtmp) {
3104 ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
3105 return -1;
3106 }
3107 config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
3109 return -1;
3110 } else if (!config) {
3111 ast_config_destroy(configtmp);
3112 return 0;
3113 }
3114
3115 for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
3116 char buf[512];
3117 ast_copy_string(buf, v->value, sizeof(buf));
3118 stringp = buf;
3119 driver = strsep(&stringp, ",");
3120 if (!stringp) {
3121 ast_log(LOG_WARNING, "extconfig.conf: value '%s' ignored due to wrong format\n", v->value);
3122 continue;
3123 }
3124 if ((tmp = strchr(stringp, '\"')))
3125 stringp = tmp;
3126
3127 /* check if the database text starts with a double quote */
3128 if (*stringp == '"') {
3129 stringp++;
3130 database = strsep(&stringp, "\"");
3131 strsep(&stringp, ",");
3132 } else {
3133 /* apparently this text has no quotes */
3134 database = strsep(&stringp, ",");
3135 }
3136
3137 table = strsep(&stringp, ",");
3138 textpri = strsep(&stringp, ",");
3139 if (!textpri || !(pri = atoi(textpri))) {
3140 pri = 1;
3141 }
3142
3143 if (!strcmp(v->name, extconfig_conf)) {
3144 ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
3145 continue;
3146 }
3147
3148 if (!strcmp(v->name, "asterisk.conf")) {
3149 ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
3150 continue;
3151 }
3152
3153 if (!strcmp(v->name, "logger.conf")) {
3154 ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
3155 continue;
3156 }
3157
3158 if (!driver || !database)
3159 continue;
3160 if (!strcasecmp(v->name, "iaxfriends")) {
3161 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");
3162 ast_realtime_append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
3163 ast_realtime_append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
3164 } else
3165 ast_realtime_append_mapping(v->name, driver, database, table, pri);
3166 }
3167
3169 return 0;
3170}
static char * extconfig_conf
Definition: main/config.c:76
static int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
Definition: main/config.c:3055
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200

References ast_config_destroy(), ast_config_internal_load(), ast_config_new(), ast_copy_string(), ast_log, ast_realtime_append_mapping(), ast_variable_browse(), buf, clear_config_maps(), config, CONFIG_FLAG_NOREALTIME, config_lock, CONFIG_STATUS_FILEINVALID, extconfig_conf, lock, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, SCOPED_MUTEX, strsep(), table, tmp(), and ast_variable::value.

Referenced by load_module().

◆ set_fn()

static struct inclfile * set_fn ( char *  fn,
size_t  fn_size,
const char *  file,
const char *  configfile,
struct ao2_container fileset 
)
static

Definition at line 2625 of file main/config.c.

2626{
2627 struct inclfile lookup;
2628 struct inclfile *fi;
2629
2630 make_fn(fn, fn_size, file, configfile);
2631 lookup.fname = fn;
2632 fi = ao2_find(fileset, &lookup, OBJ_POINTER);
2633 if (fi) {
2634 /* Found existing include file scratch pad. */
2635 return fi;
2636 }
2637
2638 /* set up a file scratch pad */
2639 fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
2640 if (!fi) {
2641 /* Scratch pad creation failed. */
2642 return NULL;
2643 }
2644 fi->fname = ast_strdup(fn);
2645 if (!fi->fname) {
2646 /* Scratch pad creation failed. */
2647 ao2_ref(fi, -1);
2648 return NULL;
2649 }
2650 fi->lineno = 1;
2651
2652 ao2_link(fileset, fi);
2653
2654 return fi;
2655}
static void inclfile_destroy(void *obj)
Definition: main/config.c:2603

References ao2_alloc, ao2_find, ao2_link, ao2_ref, ast_strdup, make_ari_stubs::file, inclfile::fname, inclfile_destroy(), inclfile::lineno, make_fn(), NULL, and OBJ_POINTER.

Referenced by ast_config_text_file_save2().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 4346 of file main/config.c.

4347{
4348 return 0;
4349}

◆ variable_clone()

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

Definition at line 953 of file main/config.c.

954{
955 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
956
957 if (new) {
958 new->lineno = old->lineno;
959 new->object = old->object;
960 new->blanklines = old->blanklines;
961 /* TODO: clone comments? */
962 }
963
964 return new;
965}

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

Referenced by ast_category_inherit().

◆ variable_list_switch()

static struct ast_variable * variable_list_switch ( struct ast_variable l1,
struct ast_variable l2 
)
inlinestatic

Definition at line 614 of file main/config.c.

615{
616 l1->next = l2->next;
617 l2->next = l1;
618 return l2;
619}

References ast_variable::next.

Referenced by ast_variable_list_sort().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = "extconfig" , .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = 0, }
static

Definition at line 4367 of file main/config.c.

◆ appendbuf

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

Definition at line 125 of file main/config.c.

Referenced by process_text_line().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 4367 of file main/config.c.

◆ cfg_hooks

struct ao2_container* cfg_hooks
static

◆ cfmtime_head

struct cfmtime_head cfmtime_head = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ cli_config

struct ast_cli_entry cli_config[]
static
Initial value:
= {
{ .handler = handle_cli_core_show_config_mappings , .summary = "Display config mappings (file names to config engines)" ,},
{ .handler = handle_cli_config_reload , .summary = "Force a reload on modules using a particular configuration file" ,},
{ .handler = handle_cli_config_list , .summary = "Show all files that have loaded a configuration file" ,},
}
static char * handle_cli_config_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:4140
static char * handle_cli_core_show_config_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:4103
static char * handle_cli_config_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:4203

Definition at line 4227 of file main/config.c.

Referenced by config_shutdown(), and register_config_cli().

◆ config_engine_list

struct ast_config_engine* config_engine_list
static

◆ config_lock

ast_mutex_t config_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

◆ config_maps

struct ast_config_map * config_maps = NULL
static

◆ extconfig_conf

char* extconfig_conf = "extconfig.conf"
static

Definition at line 76 of file main/config.c.

Referenced by reload_module().

◆ text_file_engine

struct ast_config_engine text_file_engine
static
Initial value:
= {
.name = "text",
.load_func = config_text_file_load,
}

Definition at line 3256 of file main/config.c.

Referenced by ast_config_internal_load().