Asterisk - The Open Source Telephony Project GIT-master-2de1a68
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 <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 127 of file main/config.c.

◆ COMMENT_END

#define COMMENT_END   "--;"

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

◆ COMMENT_META

#define COMMENT_META   ';'

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

◆ COMMENT_START

#define COMMENT_START   ";--"

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

◆ COMMENT_TAG

#define COMMENT_TAG   '-'

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

◆ MAX_INCLUDE_LEVEL

#define MAX_INCLUDE_LEVEL   10

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

◆ MAX_NESTED_COMMENTS

#define MAX_NESTED_COMMENTS   128

Definition at line 62 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 73 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 3337 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 1669 of file main/config.c.

1669 {
1671 ATTRIBUTE_EXEC = 1,
1672};
@ ATTRIBUTE_EXEC
Definition: main/config.c:1671
@ ATTRIBUTE_INCLUDE
Definition: main/config.c:1670

Function Documentation

◆ __init_appendbuf()

static void __init_appendbuf ( void  )
static

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

130{

◆ __reg_module()

static void __reg_module ( void  )
static

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

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4352 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 288 of file main/config.c.

289{
290 struct ast_variable *variable;
291 int name_len = strlen(name) + 1;
292 int val_len = strlen(value) + 1;
293 int fn_len = strlen(filename) + 1;
294
295 /* Ensure a minimum length in case the filename is changed later. */
296 if (fn_len < MIN_VARIABLE_FNAME_SPACE) {
298 }
299
300 variable = __ast_calloc(1, fn_len + name_len + val_len + sizeof(*variable),
301 file, lineno, func);
302 if (variable) {
303 char *dst = variable->stuff; /* writable space starts here */
304
305 /* Put file first so ast_include_rename() can calculate space available. */
306 variable->file = strcpy(dst, filename);
307 dst += fn_len;
308 variable->name = strcpy(dst, name);
309 dst += name_len;
310 variable->value = strcpy(dst, value);
311 }
312 return variable;
313}
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:73
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 153 of file main/config.c.

154{
155 struct ast_comment *x = NULL;
156 if (!buffer || !ast_str_strlen(buffer)) {
157 return NULL;
158 }
159 if ((x = ast_calloc(1, sizeof(*x) + ast_str_strlen(buffer) + 1))) {
160 strcpy(x->cmt, ast_str_buffer(buffer)); /* SAFE */
161 }
162 return x;
163}
#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:84
char cmt[0]
Definition: main/config.c:87

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

1157{
1158 if (config->last) {
1159 config->last->next = category;
1160 category->prev = config->last;
1161 } else {
1162 config->root = category;
1163 category->prev = NULL;
1164 }
1165 category->next = NULL;
1166 category->include_level = config->include_level;
1167
1168 config->last = category;
1169 config->current = category;
1170}
static const char config[]
Definition: chan_ooh323.c:111
struct ast_category * next
Definition: main/config.c:246
struct ast_category * prev
Definition: main/config.c:244

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

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

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

1426{
1427 struct ast_category *cat;
1428
1429 if (!prev) {
1430 prev = config->root;
1431 } else {
1432 prev = prev->next;
1433 }
1434
1435 cat = next_available_category(prev, category_name, filter);
1436
1437 return cat;
1438}
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 1567 of file main/config.c.

1569{
1570 struct ast_category *prev;
1571
1572 if (!config || !category) {
1573 return NULL;
1574 }
1575
1576 if (category->prev) {
1577 category->prev->next = category->next;
1578 } else {
1579 config->root = category->next;
1580 }
1581
1582 if (category->next) {
1583 category->next->prev = category->prev;
1584 } else {
1585 config->last = category->prev;
1586 }
1587
1588 prev = category->prev;
1589
1590 if (config->last_browse == category) {
1591 config->last_browse = prev;
1592 }
1593
1594 ast_category_destroy(category);
1595
1596 return prev;
1597}
void ast_category_destroy(struct ast_category *cat)
Definition: main/config.c:1211

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

1212{
1214 cat->root = NULL;
1215 cat->last = NULL;
1220 ast_free(cat->file);
1221 ast_free(cat);
1222}
#define ast_free(a)
Definition: astmm.h:180
static void ast_destroy_template_list(struct ast_category *cat)
Definition: main/config.c:1203
static void ast_comment_destroy(struct ast_comment **comment)
Definition: main/config.c:523
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: main/config.c:589
struct ast_comment * precomments
Definition: main/config.c:236
struct ast_variable * last
Definition: main/config.c:242
struct ast_comment * trailing
Definition: main/config.c:238
struct ast_variable * root
Definition: main/config.c:240
struct ast_comment * sameline
Definition: main/config.c:237
char * file
The file name from whence this declaration was read.
Definition: main/config.c:233

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

1441{
1442 struct ast_variable *v;
1443
1444 v = cat->root;
1445 cat->root = NULL;
1446 cat->last = NULL;
1447
1448 return v;
1449}

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

1600{
1601 if (!category) {
1602 return -1;
1603 }
1604
1605 ast_variables_destroy(category->root);
1606 category->root = NULL;
1607 category->last = NULL;
1608
1609 return 0;
1610}

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

1152{
1153 return !!ast_category_get(config, category_name, filter);
1154}
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:1111

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

1113{
1114 return category_get_sep(config, category_name, filter, ',', 1);
1115}
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:1089

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

1118{
1119 return category->name;
1120}

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

1128{
1129 struct ast_category_template_instance *template;
1130 struct ast_str *str;
1131 int first = 1;
1132
1133 if (AST_LIST_EMPTY(&category->template_instances)) {
1134 return NULL;
1135 }
1136
1137 str = ast_str_create(128);
1138 if (!str) {
1139 return NULL;
1140 }
1141
1142 AST_LIST_TRAVERSE(&category->template_instances, template, next) {
1143 ast_str_append(&str, 0, "%s%s", first ? "" : ",", template->name);
1144 first = 0;
1145 }
1146
1147 return str;
1148}
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:222
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 1456 of file main/config.c.

1457{
1458 struct ast_variable *var;
1460
1461 x = ast_calloc(1, sizeof(*x));
1462 if (!x) {
1463 return -1;
1464 }
1465 strcpy(x->name, base->name);
1466 x->inst = base;
1468 for (var = base->root; var; var = var->next) {
1469 struct ast_variable *cloned = variable_clone(var);
1470 if (!cloned) {
1471 return -1;
1472 }
1473 cloned->inherited = 1;
1474 ast_variable_append(new, cloned);
1475 }
1476 return 0;
1477}
#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:486
static struct ast_variable * variable_clone(const struct ast_variable *old)
Definition: main/config.c:944
const struct ast_category * inst
Definition: main/config.c:221

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

1173{
1174 struct ast_category *cur_category;
1175
1176 if (!config || !config->root || !cat || !match) {
1177 return -1;
1178 }
1179
1180 if (!strcasecmp(config->root->name, match)) {
1181 cat->next = config->root;
1182 cat->prev = NULL;
1183 config->root->prev = cat;
1184 config->root = cat;
1185 return 0;
1186 }
1187
1188 for (cur_category = config->root->next; cur_category; cur_category = cur_category->next) {
1189 if (!strcasecmp(cur_category->name, match)) {
1190 cat->prev = cur_category->prev;
1191 cat->prev->next = cat;
1192
1193 cat->next = cur_category;
1194 cur_category->prev = cat;
1195
1196 return 0;
1197 }
1198 }
1199
1200 return -1;
1201}
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:2365

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

1123{
1124 return category->ignored;
1125}

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

1080{
1081 return new_category(name, in_file, lineno, 0);
1082}
static struct ast_category * new_category(const char *name, const char *in_file, int lineno, int template)
Definition: main/config.c:1060

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

1085{
1086 return new_category(name, in_file, lineno, 1);
1087}

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

1452{
1453 ast_copy_string(cat->name, name, sizeof(cat->name));
1454}
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 1251 of file main/config.c.

1252{
1253 struct ast_category *category = ast_category_get(config, cat, NULL);
1254
1255 if (category)
1256 return category->root;
1257 return NULL;
1258}

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

3531{
3532 struct ast_config_engine *eng;
3533 if (!ast_realtime_enabled()) {
3534 return 0; /* There are no engines at all so fail early */
3535 }
3536
3537 eng = find_engine(family, 1, NULL, 0, NULL, 0);
3538 if (eng)
3539 return 1;
3540 return 0;
3541}
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
Definition: main/config.c:3544
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:3209
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 523 of file main/config.c.

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

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

3247{
3248 struct ast_config *new_config = ast_config_new();
3249 struct ast_category *cat_iter;
3250
3251 if (!new_config) {
3252 return NULL;
3253 }
3254
3255 for (cat_iter = old->root; cat_iter; cat_iter = cat_iter->next) {
3256 struct ast_category *new_cat =
3257 ast_category_new(cat_iter->name, cat_iter->file, cat_iter->lineno);
3258 if (!new_cat) {
3259 goto fail;
3260 }
3261 ast_category_append(new_config, new_cat);
3262 if (cat_iter->root) {
3263 new_cat->root = ast_variables_dup(cat_iter->root);
3264 if (!new_cat->root) {
3265 goto fail;
3266 }
3267 new_cat->last = cat_iter->last;
3268 }
3269 }
3270
3271 return new_config;
3272
3273fail:
3274 ast_config_destroy(new_config);
3275 return NULL;
3276}
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: main/config.c:1612
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: main/config.c:1479
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
Definition: main/config.c:1079
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
Definition: main/config.c:1156
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:543
struct ast_category * root
Definition: main/config.c:251

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

1613{
1614 struct ast_category *cat, *catn;
1615
1616 if (!cfg)
1617 return;
1618
1620
1621 cat = cfg->root;
1622 while (cat) {
1623 catn = cat;
1624 cat = cat->next;
1626 }
1627 ast_free(cfg);
1628}
static void ast_includes_destroy(struct ast_config_include *incls)
Definition: main/config.c:1224
struct ast_config_include * includes
Definition: main/config.c:258

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

3174{
3175 struct ast_config_engine *ptr, *last=NULL;
3176
3178
3179 for (ptr = config_engine_list; ptr; ptr=ptr->next) {
3180 if (ptr == del) {
3181 if (last)
3182 last->next = ptr->next;
3183 else
3184 config_engine_list = ptr->next;
3185 break;
3186 }
3187 last = ptr;
3188 }
3189
3190 return 0;
3191}
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:214
static struct ast_config_engine * config_engine_list
Definition: main/config.c:215
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 3157 of file main/config.c.

3158{
3159 struct ast_config_engine *ptr;
3160
3162
3163 if (!config_engine_list) {
3164 config_engine_list = new;
3165 } else {
3166 for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
3167 ptr->next = new;
3168 }
3169
3170 return 1;
3171}

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

1631{
1632 return cfg->current;
1633}
struct ast_category * current
Definition: main/config.c:254

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

4307{
4308 struct cfg_hook *hook;
4309 if (!cfg_hooks) {
4312 if (!cfg_hooks) {
4313 return -1;
4314 }
4315 }
4316
4317 if (!(hook = ao2_alloc(sizeof(*hook), hook_destroy))) {
4318 return -1;
4319 }
4320
4321 hook->hook_cb = hook_cb;
4322 hook->filename = ast_strdup(filename);
4323 hook->name = ast_strdup(name);
4324 hook->module = ast_strdup(module);
4325
4326 ao2_link(cfg_hooks, hook);
4327 ao2_ref(hook, -1);
4328 return 0;
4329}
#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:4267
static struct ao2_container * cfg_hooks
Definition: main/config.c:77
static void hook_destroy(void *obj)
Definition: main/config.c:4251
static int hook_cmp(void *obj, void *arg, int flags)
Definition: main/config.c:4259
config_hook_cb hook_cb
Definition: main/config.c:4248
const char * filename
Definition: main/config.c:4246
const char * module
Definition: main/config.c:4247
const char * name
Definition: main/config.c:4245
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 4274 of file main/config.c.

4275{
4276 struct cfg_hook tmp;
4277
4278 tmp.name = ast_strdupa(name);
4279
4281}
#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 3279 of file main/config.c.

3280{
3281 char db[256];
3282 char table[256];
3283 struct ast_config_engine *loader = &text_file_engine;
3284 struct ast_config *result;
3285
3286 /* The config file itself bumps include_level by 1 */
3287 if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
3288 ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
3289 return NULL;
3290 }
3291
3292 cfg->include_level++;
3293
3295 struct ast_config_engine *eng;
3296
3297 eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
3298
3299
3300 if (eng && eng->load_func) {
3301 loader = eng;
3302 } else {
3303 eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
3304 if (eng && eng->load_func)
3305 loader = eng;
3306 }
3307 }
3308
3309 result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
3310
3312 result->include_level--;
3313 config_hook_exec(filename, who_asked, result);
3314 } else if (result != CONFIG_STATUS_FILEINVALID) {
3315 cfg->include_level--;
3316 }
3317
3318 return result;
3319}
#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:4283
static struct ast_config_engine text_file_engine
Definition: main/config.c:3241
config_load_func * load_func
int include_level
Definition: main/config.c:256
int max_include_level
Definition: main/config.c:257
#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 3321 of file main/config.c.

3322{
3323 struct ast_config *cfg;
3324 struct ast_config *result;
3325
3326 cfg = ast_config_new();
3327 if (!cfg)
3328 return NULL;
3329
3330 result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
3332 ast_config_destroy(cfg);
3333
3334 return result;
3335}
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:3279

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

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

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

1636{
1637 /* cast below is just to silence compiler warning about dropping "const" */
1638 cfg->current = (struct ast_category *) cat;
1639}

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

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

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

2702{
2704}
@ 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:2725

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

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

3777{
3778 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3779 int res = 0;
3780 va_list ap;
3781
3782 va_start(ap, lookup);
3783 if (realtime_arguments_to_fields(ap, &fields)) {
3784 res = -1;
3785 }
3786 va_end(ap);
3787
3788 if (res) {
3789 return -1;
3790 }
3791
3792 return ast_destroy_realtime_fields(family, keyfield, lookup, fields);
3793}
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:3756
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3337
#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 3756 of file main/config.c.

3757{
3758 struct ast_config_engine *eng;
3759 int res = -1, i;
3760 char db[256];
3761 char table[256];
3762
3763 for (i = 1; ; i++) {
3764 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3765 if (eng->destroy_func && ((res = eng->destroy_func(db, table, keyfield, lookup, fields)) >= 0)) {
3766 break;
3767 }
3768 } else {
3769 break;
3770 }
3771 }
3772
3773 return res;
3774}
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 1203 of file main/config.c.

1204{
1206
1207 while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
1208 ast_free(x);
1209}
#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 475 of file main/config.c.

476{
477 struct ast_config_include *x;
478 for (x=conf->includes;x;x=x->next) {
479 if (strcmp(x->included_file,included_file) == 0)
480 return x;
481 }
482 return 0;
483}
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 335 of file main/config.c.

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

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

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

1225{
1226 struct ast_config_include *incl,*inclnext;
1227
1228 for (incl=incls; incl; incl = inclnext) {
1229 inclnext = incl->next;
1231 ast_free(incl->exec_file);
1232 ast_free(incl->included_file);
1233 ast_free(incl);
1234 }
1235}

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

3507{
3508 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3509 int field_res = 0;
3510 va_list ap;
3511
3512 va_start(ap, family);
3513 if (realtime_arguments_to_fields(ap, &fields)) {
3514 field_res = -1;
3515 }
3516 va_end(ap);
3517
3518 if (field_res) {
3519 return NULL;
3520 }
3521
3522 if (!fields) {
3523 return NULL;
3524 }
3525
3526 return ast_load_realtime_fields(family, fields);
3527}
struct ast_variable * ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3471

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

3455{
3456 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3457 struct ast_variable *res = NULL;
3458 va_list ap;
3459
3460 va_start(ap, family);
3461 realtime_arguments_to_fields(ap, &fields);
3462 va_end(ap);
3463
3464 if (fields) {
3465 res = ast_load_realtime_all_fields(family, fields);
3466 }
3467
3468 return res;
3469}
struct ast_variable * ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
Definition: main/config.c:3433

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

3434{
3435 struct ast_config_engine *eng;
3436 char db[256];
3437 char table[256];
3438 struct ast_variable *res=NULL;
3439 int i;
3440
3441 for (i = 1; ; i++) {
3442 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3443 if (eng->realtime_func && (res = eng->realtime_func(db, table, fields))) {
3444 return res;
3445 }
3446 } else {
3447 return NULL;
3448 }
3449 }
3450
3451 return res;
3452}
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 3471 of file main/config.c.

3472{
3473 struct ast_variable *res;
3474 struct ast_variable *cur;
3475 struct ast_variable **prev;
3476
3477 res = ast_load_realtime_all_fields(family, fields);
3478
3479 /* Filter the list. */
3480 prev = &res;
3481 cur = res;
3482 while (cur) {
3483 if (ast_strlen_zero(cur->value)) {
3484 /* Eliminate empty entries */
3485 struct ast_variable *next;
3486
3487 next = cur->next;
3488 *prev = next;
3490 cur = next;
3491 } else {
3492 /* Make blank entries empty and keep them. */
3493 if (cur->value[0] == ' ' && cur->value[1] == '\0') {
3494 char *vptr = (char *) cur->value;
3495
3496 vptr[0] = '\0';
3497 }
3498
3499 prev = &cur->next;
3500 cur = cur->next;
3501 }
3502 }
3503 return res;
3504}

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

3623{
3624 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3625 va_list ap;
3626
3627 va_start(ap, family);
3628 realtime_arguments_to_fields(ap, &fields);
3629 va_end(ap);
3630
3631 if (!fields) {
3632 return NULL;
3633 }
3634
3635 return ast_load_realtime_multientry_fields(family, fields);
3636}
struct ast_config * ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3596

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

3597{
3598 struct ast_config_engine *eng;
3599 char db[256];
3600 char table[256];
3601 struct ast_config *res = NULL;
3602 int i;
3603
3604 for (i = 1; ; i++) {
3605 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3606 if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, fields))) {
3607 /* If we were returned an empty cfg, destroy it and return NULL */
3608 if (!res->root) {
3609 ast_config_destroy(res);
3610 res = NULL;
3611 }
3612 break;
3613 }
3614 } else {
3615 break;
3616 }
3617 }
3618
3619 return res;
3620}
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 4352 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 3827 of file main/config.c.

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

3042{
3043 struct ast_config_map *map;
3044 char *dst;
3045 int length;
3046
3047 length = sizeof(*map);
3048 length += strlen(name) + 1;
3049 length += strlen(driver) + 1;
3050 length += strlen(database) + 1;
3051 if (table)
3052 length += strlen(table) + 1;
3053
3054 if (!(map = ast_calloc(1, length)))
3055 return -1;
3056
3057 dst = map->stuff; /* writable space starts here */
3058 map->name = strcpy(dst, name);
3059 dst += strlen(dst) + 1;
3060 map->driver = strcpy(dst, driver);
3061 dst += strlen(dst) + 1;
3062 map->database = strcpy(dst, database);
3063 if (table) {
3064 dst += strlen(dst) + 1;
3065 map->table = strcpy(dst, table);
3066 }
3067 map->priority = priority;
3068 map->next = config_maps;
3069 config_maps = map;
3070
3071 ast_verb(5, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
3072
3073 return 0;
3074}
static int priority
static struct ast_config_map * config_maps
const char * driver
Definition: main/config.c:205
struct ast_config_map * next
Definition: main/config.c:200
const char * table
Definition: main/config.c:209
const char * database
Definition: main/config.c:207
const char * name
Definition: main/config.c:203

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

3796{
3797 char *orig = chunk;
3798 for (; *chunk; chunk++) {
3799 if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
3800 sscanf(chunk + 1, "%02hhX", (unsigned char *)chunk);
3801 memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
3802 }
3803 }
3804 return orig;
3805}

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

3545{
3546 return config_maps ? 1 : 0;
3547}

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

3808{
3809 if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
3810 ast_str_set(dest, maxlen, "%s", chunk);
3811 } else {
3812 ast_str_reset(*dest);
3813 for (; *chunk; chunk++) {
3814 if (strchr(";^", *chunk)) {
3815 ast_str_append(dest, maxlen, "^%02hhX", *chunk);
3816 } else {
3817 ast_str_append(dest, maxlen, "%c", *chunk);
3818 }
3819 }
3820 }
3821 return ast_str_buffer(*dest);
3822}
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 3193 of file main/config.c.

3194{
3195 struct ast_config_map *map;
3197
3198 for (map = config_maps; map; map = map->next) {
3199 if (!strcasecmp(family, map->name)) {
3200 return 1;
3201 }
3202 }
3203 ast_debug(5, "Failed to find a realtime mapping for %s\n", family);
3204
3205 return 0;
3206}

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

3550{
3551 struct ast_config_engine *eng;
3552 char db[256];
3553 char table[256];
3554 va_list ap, aq;
3555 int res = -1, i;
3556
3557 va_start(ap, family);
3558 for (i = 1; ; i++) {
3559 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3560 va_copy(aq, ap);
3561 /* If the require succeeds, it returns 0. */
3562 if (eng->require_func && !(res = eng->require_func(db, table, aq))) {
3563 va_end(aq);
3564 break;
3565 }
3566 va_end(aq);
3567 } else {
3568 break;
3569 }
3570 }
3571 va_end(ap);
3572
3573 return res;
3574}
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 3740 of file main/config.c.

3741{
3742 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3743 va_list ap;
3744
3745 va_start(ap, family);
3746 realtime_arguments_to_fields(ap, &fields);
3747 va_end(ap);
3748
3749 if (!fields) {
3750 return -1;
3751 }
3752
3753 return ast_store_realtime_fields(family, fields);
3754}
int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
Create realtime configuration.
Definition: main/config.c:3719

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

3720{
3721 struct ast_config_engine *eng;
3722 int res = -1, i;
3723 char db[256];
3724 char table[256];
3725
3726 for (i = 1; ; i++) {
3727 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3728 /* If the store succeeds, it returns >= 0*/
3729 if (eng->store_func && ((res = eng->store_func(db, table, fields)) >= 0)) {
3730 break;
3731 }
3732 } else {
3733 break;
3734 }
3735 }
3736
3737 return res;
3738}
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 3576 of file main/config.c.

3577{
3578 struct ast_config_engine *eng;
3579 char db[256];
3580 char table[256];
3581 int res = -1, i;
3582
3583 for (i = 1; ; i++) {
3584 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3585 if (eng->unload_func) {
3586 /* Do this for ALL engines */
3587 res = eng->unload_func(db, table);
3588 }
3589 } else {
3590 break;
3591 }
3592 }
3593 return res;
3594}
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 3695 of file main/config.c.

3696{
3697 RAII_VAR(struct ast_variable *, lookup_fields, NULL, ast_variables_destroy);
3698 RAII_VAR(struct ast_variable *, update_fields, NULL, ast_variables_destroy);
3699 va_list ap;
3700
3701 va_start(ap, family);
3702 /* XXX: If we wanted to pass no lookup fields (select all), we'd be
3703 * out of luck. realtime_arguments_to_fields expects at least one key
3704 * value pair. */
3705 realtime_arguments_to_fields(ap, &lookup_fields);
3706 va_end(ap);
3707
3708 va_start(ap, family);
3709 realtime_arguments_to_fields2(ap, 1, &update_fields);
3710 va_end(ap);
3711
3712 if (!lookup_fields || !update_fields) {
3713 return -1;
3714 }
3715
3716 return ast_update2_realtime_fields(family, lookup_fields, update_fields);
3717}
static int realtime_arguments_to_fields2(va_list ap, int skip, struct ast_variable **result)
Definition: main/config.c:3352
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:3675

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

3676{
3677 struct ast_config_engine *eng;
3678 int res = -1, i;
3679 char db[256];
3680 char table[256];
3681
3682 for (i = 1; ; i++) {
3683 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3684 if (eng->update2_func && !(res = eng->update2_func(db, table, lookup_fields, update_fields))) {
3685 break;
3686 }
3687 } else {
3688 break;
3689 }
3690 }
3691
3692 return res;
3693}
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 3659 of file main/config.c.

3660{
3661 RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3662 va_list ap;
3663
3664 va_start(ap, lookup);
3665 realtime_arguments_to_fields(ap, &fields);
3666 va_end(ap);
3667
3668 if (!fields) {
3669 return -1;
3670 }
3671
3672 return ast_update_realtime_fields(family, keyfield, lookup, fields);
3673}
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:3638

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

3639{
3640 struct ast_config_engine *eng;
3641 int res = -1, i;
3642 char db[256];
3643 char table[256];
3644
3645 for (i = 1; ; i++) {
3646 if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3647 /* If the update succeeds, it returns >= 0. */
3648 if (eng->update_func && ((res = eng->update_func(db, table, keyfield, lookup, fields)) >= 0)) {
3649 break;
3650 }
3651 } else {
3652 break;
3653 }
3654 }
3655
3656 return res;
3657}
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 600 of file main/config.c.

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

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

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

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

825{
826 return ast_variable_find_in_list(category->root, variable);
827}
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:919

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

920{
921 const struct ast_variable *v;
922
923 for (v = list; v; v = v->next) {
924 if (!strcasecmp(variable, v->name)) {
925 return v->value;
926 }
927 }
928 return NULL;
929}

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

932{
933 const struct ast_variable *v;
934 const char *found = NULL;
935
936 for (v = list; v; v = v->next) {
937 if (!strcasecmp(variable, v->name)) {
938 found = v->value;
939 }
940 }
941 return found;
942}

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

830{
831 const struct ast_variable *v;
832
833 for (v = list; v; v = v->next) {
834 if (!strcasecmp(variable_name, v->name)) {
835 return v;
836 }
837 }
838 return NULL;
839}

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

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

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

647{
648 struct ast_variable *curr;
649 struct ast_variable *sh = search_hint;
650 ast_assert(head != NULL);
651
652 if (!*head) {
653 *head = newvar;
654 } else {
655 if (sh == NULL) {
656 sh = *head;
657 }
658 for (curr = sh; curr->next; curr = curr->next);
659 curr->next = newvar;
660 }
661
662 for (curr = newvar; curr->next; curr = curr->next);
663
664 return curr;
665}
#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 726 of file main/config.c.

728{
729 char item_sep;
730 char nv_sep;
731 char quote;
732 struct ast_variable *new_list = NULL;
733 struct ast_variable *new_var = NULL;
734 char *item_string;
735 char *item;
736 char *item_name;
737 char *item_value;
738
739 if (ast_strlen_zero(input)) {
740 return NULL;
741 }
742
743 item_sep = ast_strlen_zero(item_separator) ? ',' : item_separator[0];
744 nv_sep = ast_strlen_zero(name_value_separator) ? '=' : name_value_separator[0];
745 quote = ast_strlen_zero(quote_str) ? '"' : quote_str[0];
746 item_string = ast_strip(ast_strdupa(input));
747
748 while ((item = ast_strsep_quoted(&item_string, item_sep, quote, AST_STRSEP_ALL))) {
749 item_name = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL);
750 if (!item_name) {
751 ast_variables_destroy(new_list);
752 return NULL;
753 }
754
755 item_value = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL);
756
757 new_var = ast_variable_new(item_name, item_value ?: "", "");
758 if (!new_var) {
759 ast_variables_destroy(new_list);
760 return NULL;
761 }
762 ast_variable_list_append(&new_list, new_var);
763 }
764 return new_list;
765}
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 767 of file main/config.c.

769{
770 return ast_variable_list_from_quoted_string(input, item_separator, name_value_separator, NULL);
771}
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:726

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

702{
703 struct ast_variable *var = (struct ast_variable *)head;
704 struct ast_str *local_str = NULL;
705
706 if (str == NULL || *str == NULL) {
708 if (!local_str) {
709 return NULL;
710 }
711 } else {
712 local_str = *str;
713 }
714
715 for (; var; var = var->next) {
716 ast_str_append(&local_str, 0, "%s%s%s%s%s%s", var->name, name_value_separator, S_OR(quote_char, ""),
717 var->value, S_OR(quote_char, ""), var->next ? item_separator : "");
718 }
719
720 if (str != NULL) {
721 *str = local_str;
722 }
723 return local_str;
724}
#define AST_MAX_USER_FIELD
Definition: channel.h:174
#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 667 of file main/config.c.

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

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

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

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

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

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

862{
863 const struct ast_variable *field;
864 int right_count = 0;
865 int left_count = 0;
866
867 if (left == right) {
868 return 1;
869 }
870
871 if (!(left && right)) {
872 return 0;
873 }
874
875 for (field = right; field; field = field->next) {
876 char *space = strrchr(field->name, ' ');
877 const struct ast_variable *old;
878 char * name = (char *)field->name;
879
880 if (space) {
881 name = ast_strdup(field->name);
882 if (!name) {
883 return 0;
884 }
885 name[space - field->name] = '\0';
886 }
887
889 if (name != field->name) {
890 ast_free(name);
891 }
892
893 if (exact_match) {
894 if (!old || strcmp(old->value, field->value)) {
895 return 0;
896 }
897 } else {
898 if (!ast_variables_match(old, field)) {
899 return 0;
900 }
901 }
902
903 right_count++;
904 }
905
906 if (exact_match) {
907 for (field = left; field; field = field->next) {
908 left_count++;
909 }
910
911 if (right_count != left_count) {
912 return 0;
913 }
914 }
915
916 return 1;
917}
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:841
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:829

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

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

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

784{
785 struct ast_variable *v;
786
787 if (category) {
788 for (v = ast_variable_browse(config, category); v; v = v->next) {
789 if (!strcasecmp(variable, v->name)) {
790 return v->value;
791 }
792 }
793 } else {
794 struct ast_category *cat;
795
796 for (cat = config->root; cat; cat = cat->next) {
797 for (v = cat->root; v; v = v->next) {
798 if (!strcasecmp(variable, v->name)) {
799 return v->value;
800 }
801 }
802 }
803 }
804
805 return NULL;
806}
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Definition: main/config.c:600

References ast_variable_browse(), config, 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 808 of file main/config.c.

810{
811 struct ast_category *cat = NULL;
812 const char *value;
813
814 while ((cat = ast_category_browse_filtered(config, category, cat, filter))) {
815 value = ast_variable_find(cat, variable);
816 if (value) {
817 return value;
818 }
819 }
820
821 return NULL;
822}
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:824
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:1424

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

1535{
1536 struct ast_variable *cur, *prev=NULL, *newer=NULL;
1537
1538 for (cur = category->root; cur; prev = cur, cur = cur->next) {
1539 if (strcasecmp(cur->name, variable) ||
1540 (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
1541 continue;
1542
1543 if (!(newer = ast_variable_new(variable, value, cur->file)))
1544 return -1;
1545
1546 ast_variable_move(newer, cur);
1547 newer->object = newer->object || object;
1548
1549 /* Replace the old node in the list with the new node. */
1550 newer->next = cur->next;
1551 if (prev)
1552 prev->next = newer;
1553 else
1554 category->root = newer;
1555 if (category->last == cur)
1556 category->last = newer;
1557
1559
1560 return 0;
1561 }
1562
1563 /* Could not find variable to update */
1564 return -1;
1565}

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

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

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(), 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 543 of file main/config.c.

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

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

842{
843 char *op;
844
845 if (left == right) {
846 return 1;
847 }
848
849 if (!(left && right)) {
850 return 0;
851 }
852
853 op = strrchr(right->name, ' ');
854 if (op) {
855 op++;
856 }
857
858 return ast_strings_match(left->value, op ? ast_strdupa(op) : NULL, right->value);
859}
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 565 of file main/config.c.

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

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

1091{
1092 struct ast_category *cat;
1093
1094 if (pointer_match_possible) {
1095 for (cat = config->root; cat; cat = cat->next) {
1096 if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) {
1097 return cat;
1098 }
1099 }
1100 }
1101
1102 for (cat = config->root; cat; cat = cat->next) {
1103 if (does_category_match(cat, category_name, filter, sep)) {
1104 return cat;
1105 }
1106 }
1107
1108 return NULL;
1109}
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:970

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

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

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

135{
136 char *s = ast_alloca(len + 1);
137
138 memcpy(s, str, len);
139 s[len] = '\0';
140 ast_str_append(cb, 0, "%s", s);
141}
#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 143 of file main/config.c.

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

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

1706{
1707 struct cache_file_mtime cfm_buf;
1708
1709 cfmstat_save(&cfm_buf, statbuf);
1710
1711 return cfmtime->stat_size != cfm_buf.stat_size
1712 || cfmtime->stat_mtime != cfm_buf.stat_mtime
1713 || cfmtime->stat_mtime_nsec != cfm_buf.stat_mtime_nsec;
1714}
static void cfmstat_save(struct cache_file_mtime *cfmtime, struct stat *statbuf)
Definition: main/config.c:1681
unsigned long stat_size
Definition: main/config.c:102
unsigned long stat_mtime_nsec
Definition: main/config.c:104

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

1682{
1683 cfmtime->stat_size = statbuf->st_size;
1684#if defined(HAVE_STRUCT_STAT_ST_MTIM)
1685 cfmtime->stat_mtime_nsec = statbuf->st_mtim.tv_nsec;
1686#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
1687 cfmtime->stat_mtime_nsec = statbuf->st_mtimensec;
1688#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
1689 cfmtime->stat_mtime_nsec = statbuf->st_mtimespec.tv_nsec;
1690#else
1691 cfmtime->stat_mtime_nsec = 0;
1692#endif
1693 cfmtime->stat_mtime = statbuf->st_mtime;
1694}

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

1652{
1653 struct cache_file_mtime *cfmtime;
1654 char *dst;
1655
1656 cfmtime = ast_calloc(1,
1657 sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
1658 if (!cfmtime) {
1659 return NULL;
1660 }
1661 dst = cfmtime->filename; /* writable space starts here */
1662 strcpy(dst, filename); /* Safe */
1663 dst += strlen(dst) + 1;
1664 cfmtime->who_asked = strcpy(dst, who_asked); /* Safe */
1665
1666 return cfmtime;
1667}
const char * who_asked
Definition: main/config.c:109

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

3027{
3028 struct ast_config_map *map;
3029
3030 while (config_maps) {
3031 map = config_maps;
3033 ast_free(map);
3034 }
3035}

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

1772{
1773 struct cache_file_mtime *cfmtime;
1774 struct cache_file_include *cfinclude;
1775
1776 /* Find our cached entry for this configuration file */
1778 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
1779 if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
1780 break;
1781 }
1782 if (!cfmtime) {
1783 cfmtime = cfmtime_new(configfile, who_asked);
1784 if (!cfmtime) {
1786 return;
1787 }
1788 /* Note that the file mtime is initialized to 0, i.e. 1970 */
1789 AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
1790 }
1791
1792 switch (attrtype) {
1793 case ATTRIBUTE_INCLUDE:
1794 AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
1795 if (!strcmp(cfinclude->include, filename)) {
1797 return;
1798 }
1799 }
1800 cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
1801 if (!cfinclude) {
1803 return;
1804 }
1805 strcpy(cfinclude->include, filename); /* Safe */
1806 AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
1807 break;
1808 case ATTRIBUTE_EXEC:
1809 cfmtime->has_exec = 1;
1810 break;
1811 }
1813}
#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:1651
Hold the mtime for config files, so if we don't need to reread our config, don't.
Definition: main/config.c:91
struct cache_file_include::@335 list
struct cache_file_mtime::includes includes
unsigned int has_exec
Definition: main/config.c:100

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

1742{
1744 ast_free(cfmtime);
1745}
static void config_cache_flush_includes(struct cache_file_mtime *cfmtime)
Definition: main/config.c:1724

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

1725{
1726 struct cache_file_include *cfinclude;
1727
1728 while ((cfinclude = AST_LIST_REMOVE_HEAD(&cfmtime->includes, list))) {
1729 ast_free(cfinclude);
1730 }
1731}

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

1755{
1756 struct cache_file_mtime *cfmtime;
1757
1760 if (!strcmp(cfmtime->filename, filename)
1761 && !strcmp(cfmtime->who_asked, who_asked)) {
1764 break;
1765 }
1766 }
1769}
#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:1741
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 4283 of file main/config.c.

4284{
4285 struct ao2_iterator it;
4286 struct cfg_hook *hook;
4287 if (!(cfg_hooks)) {
4288 return;
4289 }
4291 while ((hook = ao2_iterator_next(&it))) {
4292 if (!strcasecmp(hook->filename, filename) &&
4293 !strcasecmp(hook->module, module)) {
4294 struct ast_config *copy = ast_config_copy(cfg);
4295 hook->hook_cb(copy);
4296 }
4297 ao2_ref(hook, -1);
4298 }
4300}
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:3246
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 4218 of file main/config.c.

4219{
4220 struct cache_file_mtime *cfmtime;
4221
4223 while ((cfmtime = AST_LIST_REMOVE_HEAD(&cfmtime_head, list))) {
4225 }
4227
4229
4231
4233 cfg_hooks = NULL;
4234}
#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:4212
static void clear_config_maps(void)
Definition: main/config.c:3026
#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 2212 of file main/config.c.

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

2643{
2644 int count = 0;
2645
2646 while (*str) {
2647 if (*str =='\n')
2648 count++;
2649 str++;
2650 }
2651 return count;
2652}

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

2655{
2656 int count = 0;
2657
2658 while (x) {
2659 count += count_linefeeds(x->cmt);
2660 x = x->next;
2661 }
2662 return count;
2663}
static int count_linefeeds(char *str)
Definition: main/config.c:2642

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

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

3210{
3211 struct ast_config_engine *eng, *ret = NULL;
3212 struct ast_config_map *map;
3213
3215
3216 for (map = config_maps; map; map = map->next) {
3217 if (!strcasecmp(family, map->name) && (priority == map->priority)) {
3218 if (database)
3219 ast_copy_string(database, map->database, dbsiz);
3220 if (table)
3221 ast_copy_string(table, map->table ? map->table : family, tabsiz);
3222 break;
3223 }
3224 }
3225
3226 /* Check if the required driver (engine) exist */
3227 if (map) {
3228 for (eng = config_engine_list; !ret && eng; eng = eng->next) {
3229 if (!strcasecmp(eng->name, map->driver))
3230 ret = eng;
3231 }
3232 }
3233
3234 /* if we found a mapping, but the engine is not available, then issue a warning */
3235 if (map && !ret)
3236 ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
3237
3238 return ret;
3239}

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

2570{
2571 char date[256]="";
2572 time_t t;
2573
2574 time(&t);
2575 ast_copy_string(date, ctime(&t), sizeof(date));
2576
2577 fprintf(f1, ";!\n");
2578 fprintf(f1, ";! Automatically generated configuration file\n");
2579 if (strcmp(configfile, fn))
2580 fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
2581 else
2582 fprintf(f1, ";! Filename: %s\n", configfile);
2583 fprintf(f1, ";! Generator: %s\n", generator);
2584 fprintf(f1, ";! Creation Date: %s", date);
2585 fprintf(f1, ";!\n");
2586}

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

4189{
4190 struct cache_file_mtime *cfmtime;
4191
4192 switch (cmd) {
4193 case CLI_INIT:
4194 e->command = "config list";
4195 e->usage =
4196 "Usage: config list\n"
4197 " Show all modules that have loaded a configuration file\n";
4198 return NULL;
4199 case CLI_GENERATE:
4200 return NULL;
4201 }
4202
4204 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4205 ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
4206 }
4208
4209 return CLI_SUCCESS;
4210}
#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 4125 of file main/config.c.

4126{
4127 struct cache_file_mtime *cfmtime;
4128 char *prev = "";
4129 int wordlen;
4130
4131 switch (cmd) {
4132 case CLI_INIT:
4133 e->command = "config reload";
4134 e->usage =
4135 "Usage: config reload <filename.conf>\n"
4136 " Reloads all modules that reference <filename.conf>\n";
4137 return NULL;
4138 case CLI_GENERATE:
4139 if (a->pos > 2) {
4140 return NULL;
4141 }
4142
4143 wordlen = strlen(a->word);
4144
4146 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4147 /* Core configs cannot be reloaded */
4148 if (ast_strlen_zero(cfmtime->who_asked)) {
4149 continue;
4150 }
4151
4152 /* Skip duplicates - this only works because the list is sorted by filename */
4153 if (!strcmp(cfmtime->filename, prev)) {
4154 continue;
4155 }
4156
4157 if (!strncmp(cfmtime->filename, a->word, wordlen)) {
4159 break;
4160 }
4161 }
4162
4163 /* Otherwise save that we've seen this filename */
4164 prev = cfmtime->filename;
4165 }
4167
4168 return NULL;
4169 }
4170
4171 if (a->argc != 3) {
4172 return CLI_SHOWUSAGE;
4173 }
4174
4176 AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4177 if (!strcmp(cfmtime->filename, a->argv[2])) {
4178 char *buf = ast_alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
4179 sprintf(buf, "module reload %s", cfmtime->who_asked);
4180 ast_cli_command(a->fd, buf);
4181 }
4182 }
4184
4185 return CLI_SUCCESS;
4186}
#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:2758
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 4088 of file main/config.c.

4089{
4090 struct ast_config_engine *eng;
4091 struct ast_config_map *map;
4092
4093 switch (cmd) {
4094 case CLI_INIT:
4095 e->command = "core show config mappings";
4096 e->usage =
4097 "Usage: core show config mappings\n"
4098 " Shows the filenames to config engines.\n";
4099 return NULL;
4100 case CLI_GENERATE:
4101 return NULL;
4102 }
4103
4104 {
4106
4107 if (!config_engine_list) {
4108 ast_cli(a->fd, "No config mappings found.\n");
4109 } else {
4110 for (eng = config_engine_list; eng; eng = eng->next) {
4111 ast_cli(a->fd, "Config Engine: %s\n", eng->name);
4112 for (map = config_maps; map; map = map->next) {
4113 if (!strcasecmp(map->driver, eng->name)) {
4114 ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
4115 map->table ? map->table : map->name);
4116 }
4117 }
4118 }
4119 }
4120 }
4121
4122 return CLI_SUCCESS;
4123}

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

1830{
1831 char buf[1024];
1832 FILE *fp;
1833 int status;
1834 struct stat output_file_info;
1835
1836 /* stderr to stdout, stdout to file */
1837 if (snprintf(buf, sizeof(buf), "%s 2>&1 > %s", command, output_file) >= sizeof(buf)) {
1838 ast_log(LOG_ERROR, "Failed to construct command string to execute %s.\n", command);
1839 return -1;
1840 }
1841
1843
1844 errno = 0;
1845
1846 fp = popen(buf, "r");
1847 if (!fp) {
1848 ast_log(LOG_ERROR, "#exec <%s>: Failed to execute: %s\n",
1849 command,
1850 strerror(errno));
1852 return 0;
1853 }
1854
1855 while (fgets(buf, sizeof(buf), fp)) {
1856 /* Ensure we have a \n at the end */
1857 if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 2] != '\n') {
1858 ast_log(LOG_ERROR, "#exec <%s>: %s... <truncated>\n",
1859 command,
1860 buf);
1861
1862 /* Consume the rest of the line */
1863 while (fgets(buf, sizeof(buf), fp)) {
1864 if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 2] == '\n') {
1865 break;
1866 }
1867 }
1868
1869 continue;
1870 }
1871
1872 /* `buf` has the newline, so we don't need to print it ourselves */
1873 ast_log(LOG_ERROR, "#exec <%s>: %s",
1874 command,
1875 buf);
1876 }
1877
1878 status = pclose(fp);
1879 if (status == -1) {
1880 ast_log(LOG_ERROR, "#exec <%s>: Failed to retrieve exit status: %s\n",
1881 command,
1882 strerror(errno));
1883 } else {
1885 if (status) {
1886 ast_log(LOG_ERROR, "#exec <%s>: Exited with return value %d\n",
1887 command,
1888 status);
1889 }
1890 }
1891
1893
1894 /* Check that the output file contains something */
1895 if (stat(output_file, &output_file_info) == -1) {
1896 ast_log(LOG_ERROR, "#exec <%s>: Unable to stat() temporary file `%s': %s\n",
1897 command,
1898 output_file,
1899 strerror(errno));
1900 } else if (output_file_info.st_size == 0) {
1901 ast_log(LOG_WARNING, "#exec <%s>: The program generated no usable output.\n",
1902 command);
1903 }
1904
1905 return 0;
1906}
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 173 of file main/config.c.

174{
175 char *str = ((struct inclfile *) obj)->fname;
176 int total;
177
178 for (total = 0; *str; str++) {
179 unsigned int tmp = total;
180 total <<= 1; /* multiply by 2 */
181 total += tmp; /* multiply by 3 */
182 total <<= 2; /* multiply by 12 */
183 total += tmp; /* multiply by 13 */
184
185 total += ((unsigned int) (*str));
186 }
187 if (total < 0) {
188 total = -total;
189 }
190 return total;
191}
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 193 of file main/config.c.

194{
195 const struct inclfile *ae = a, *be = b;
196 return !strcmp(ae->fname, be->fname) ? CMP_MATCH | CMP_STOP : 0;
197}
@ 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:169
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 4259 of file main/config.c.

4260{
4261 struct cfg_hook *hook1 = obj;
4262 struct cfg_hook *hook2 = arg;
4263
4264 return !(strcasecmp(hook1->name, hook2->name)) ? CMP_MATCH | CMP_STOP : 0;
4265}

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

4252{
4253 struct cfg_hook *hook = obj;
4254 ast_free((void *) hook->name);
4255 ast_free((void *) hook->filename);
4256 ast_free((void *) hook->module);
4257}

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

4268{
4269 const struct cfg_hook *hook = obj;
4270
4271 return ast_str_hash(hook->name);
4272}
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 2588 of file main/config.c.

2589{
2590 const struct inclfile *o = obj;
2591
2592 ast_free(o->fname);
2593}

References ast_free, and inclfile::fname.

Referenced by set_fn().

◆ init_appendbuf()

static int init_appendbuf ( void *  data)
static

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

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

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

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

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

2707{
2708 if (access(fn, F_OK)) {
2709 char *dn = dirname(ast_strdupa(fn));
2710
2711 if (access(dn, R_OK | W_OK)) {
2712 ast_log(LOG_ERROR, "Unable to write to directory %s (%s)\n", dn, strerror(errno));
2713 return 0;
2714 }
2715 } else {
2716 if (access(fn, R_OK | W_OK)) {
2717 ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
2718 return 0;
2719 }
2720 }
2721
2722 return 1;
2723}

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

4337{
4338 if (ast_opt_console) {
4339 ast_verb(0, "[ Initializing Custom Configuration Options ]\n");
4340 }
4341
4343}
static int reload_module(void)
Definition: main/config.c:3076
@ 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 2595 of file main/config.c.

2596{
2597 if (ast_strlen_zero(file)) {
2598 if (configfile[0] == '/') {
2599 ast_copy_string(fn, configfile, fn_size);
2600 } else {
2601 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
2602 }
2603 } else if (file[0] == '/') {
2604 ast_copy_string(fn, file, fn_size);
2605 } else {
2606 snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
2607 }
2608}

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

959{
960 struct ast_variable *var = old->root;
961
962 old->root = NULL;
963 /* we can just move the entire list in a single op */
965}

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

1061{
1062 struct ast_category *category;
1063
1064 category = ast_calloc(1, sizeof(*category));
1065 if (!category) {
1066 return NULL;
1067 }
1068 category->file = ast_strdup(in_file);
1069 if (!category->file) {
1070 ast_category_destroy(category);
1071 return NULL;
1072 }
1073 ast_copy_string(category->name, name, sizeof(category->name));
1074 category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
1075 category->ignored = template;
1076 return category;
1077}

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

1239{
1240 for (; cat && !does_category_match(cat, name, filter, ','); cat = cat->next);
1241
1242 return cat;
1243}

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

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

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

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

4237{
4239 /* This is separate from the module load so cleanup can happen very late. */
4241 return 0;
4242}
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:4218

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

3077{
3078 struct ast_config *config, *configtmp;
3079 struct ast_variable *v;
3080 char *driver, *table, *database, *textpri, *stringp, *tmp;
3082 int pri;
3084
3086
3087 configtmp = ast_config_new();
3088 if (!configtmp) {
3089 ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
3090 return -1;
3091 }
3092 config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
3094 return -1;
3095 } else if (!config) {
3096 ast_config_destroy(configtmp);
3097 return 0;
3098 }
3099
3100 for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
3101 char buf[512];
3102 ast_copy_string(buf, v->value, sizeof(buf));
3103 stringp = buf;
3104 driver = strsep(&stringp, ",");
3105 if (!stringp) {
3106 ast_log(LOG_WARNING, "extconfig.conf: value '%s' ignored due to wrong format\n", v->value);
3107 continue;
3108 }
3109 if ((tmp = strchr(stringp, '\"')))
3110 stringp = tmp;
3111
3112 /* check if the database text starts with a double quote */
3113 if (*stringp == '"') {
3114 stringp++;
3115 database = strsep(&stringp, "\"");
3116 strsep(&stringp, ",");
3117 } else {
3118 /* apparently this text has no quotes */
3119 database = strsep(&stringp, ",");
3120 }
3121
3122 table = strsep(&stringp, ",");
3123 textpri = strsep(&stringp, ",");
3124 if (!textpri || !(pri = atoi(textpri))) {
3125 pri = 1;
3126 }
3127
3128 if (!strcmp(v->name, extconfig_conf)) {
3129 ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
3130 continue;
3131 }
3132
3133 if (!strcmp(v->name, "asterisk.conf")) {
3134 ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
3135 continue;
3136 }
3137
3138 if (!strcmp(v->name, "logger.conf")) {
3139 ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
3140 continue;
3141 }
3142
3143 if (!driver || !database)
3144 continue;
3145 if (!strcasecmp(v->name, "iaxfriends")) {
3146 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");
3147 ast_realtime_append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
3148 ast_realtime_append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
3149 } else
3150 ast_realtime_append_mapping(v->name, driver, database, table, pri);
3151 }
3152
3154 return 0;
3155}
static char * extconfig_conf
Definition: main/config.c:75
static int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
Definition: main/config.c:3040
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 2610 of file main/config.c.

2611{
2612 struct inclfile lookup;
2613 struct inclfile *fi;
2614
2615 make_fn(fn, fn_size, file, configfile);
2616 lookup.fname = fn;
2617 fi = ao2_find(fileset, &lookup, OBJ_POINTER);
2618 if (fi) {
2619 /* Found existing include file scratch pad. */
2620 return fi;
2621 }
2622
2623 /* set up a file scratch pad */
2624 fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
2625 if (!fi) {
2626 /* Scratch pad creation failed. */
2627 return NULL;
2628 }
2629 fi->fname = ast_strdup(fn);
2630 if (!fi->fname) {
2631 /* Scratch pad creation failed. */
2632 ao2_ref(fi, -1);
2633 return NULL;
2634 }
2635 fi->lineno = 1;
2636
2637 ao2_link(fileset, fi);
2638
2639 return fi;
2640}
static void inclfile_destroy(void *obj)
Definition: main/config.c:2588

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

4332{
4333 return 0;
4334}

◆ variable_clone()

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

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

945{
946 struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
947
948 if (new) {
949 new->lineno = old->lineno;
950 new->object = old->object;
951 new->blanklines = old->blanklines;
952 /* TODO: clone comments? */
953 }
954
955 return new;
956}

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

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

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 4352 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 124 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 4352 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:4125
static char * handle_cli_core_show_config_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:4088
static char * handle_cli_config_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:4188

Definition at line 4212 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 75 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 3241 of file main/config.c.

Referenced by ast_config_internal_load().