Asterisk - The Open Source Telephony Project  18.5.0
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)
 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...
 
int ast_realtime_append_mapping (const char *name, const char *driver, const char *database, const char *table, int priority)
 Add an explicit mapping for a family. More...
 
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...
 
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...
 
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 *v)
 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 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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 http://wiki.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.

Referenced by config_text_file_load().

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

Referenced by config_text_file_load().

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

Referenced by config_text_file_load().

◆ MAX_INCLUDE_LEVEL

#define MAX_INCLUDE_LEVEL   10

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

Referenced by ast_config_new().

◆ MAX_NESTED_COMMENTS

#define MAX_NESTED_COMMENTS   128

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

Referenced by config_text_file_load().

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

Referenced by _ast_variable_new().

◆ realtime_arguments_to_fields

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

◆ UTF8_BOM

#define UTF8_BOM   "\xEF\xBB\xBF"

Referenced by config_text_file_load().

Enumeration Type Documentation

◆ config_cache_attribute_enum

Enumerator
ATTRIBUTE_INCLUDE 
ATTRIBUTE_EXEC 

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

1580  {
1581  ATTRIBUTE_INCLUDE = 0,
1582  ATTRIBUTE_EXEC = 1,
1583 };

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

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

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

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) {
297  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:1635
Structure for variables, used for configurations and for channel variables.
int value
Definition: syslog.c:37
char stuff[0]
Contents of file, name, and value in that order stuffed here.
static const char name[]
Definition: cdr_mysql.c:74
#define MIN_VARIABLE_FNAME_SPACE
Definition: main/config.c:73

◆ ALLOC_COMMENT()

static struct ast_comment* ALLOC_COMMENT ( struct ast_str buffer)
static

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

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

Referenced by config_text_file_load(), and process_text_line().

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 }
Structure to keep comments for rewriting configuration files.
Definition: main/config.c:84
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
char cmt[0]
Definition: main/config.c:87
#define NULL
Definition: resample.c:96
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688

◆ 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
catcategory to insert

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

References ast_config::current, ast_category::include_level, ast_config::include_level, ast_config::last, ast_category::next, NULL, ast_category::prev, and ast_config::root.

Referenced by add_cfg_entry(), add_rt_multi_cfg_entry(), 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().

1068 {
1069  if (config->last) {
1070  config->last->next = category;
1071  category->prev = config->last;
1072  } else {
1073  config->root = category;
1074  category->prev = NULL;
1075  }
1076  category->next = NULL;
1077  category->include_level = config->include_level;
1078 
1079  config->last = category;
1080  config->current = category;
1081 }
struct ast_category * next
Definition: main/config.c:246
int include_level
Definition: main/config.c:256
struct ast_category * prev
Definition: main/config.c:244
#define NULL
Definition: resample.c:96
struct ast_category * last
Definition: main/config.c:253
struct ast_category * current
Definition: main/config.c:254
struct ast_category * root
Definition: main/config.c:251

◆ ast_category_browse()

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

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

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

Referenced by __init_manager(), __queues_show(), actual_load_config(), ast_cli_perms_init(), AST_TEST_DEFINE(), complete_sip_notify(), conf_exec(), config_load(), find_queue_by_name_rt(), find_realtime(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), iax_provision_reload(), internal_process_ast_config(), load_config(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_realtime_musiconhold(), load_realtime_rules(), load_tech_calendars(), load_users(), mbl_load_config(), misdn_cfg_init(), named_acl_find_realtime(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), realtime_directory(), realtime_sorcery(), realtime_sorcery_multi(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), search_directory(), search_directory_sub(), set_config(), set_member_value(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), test_config_validity(), update_realtime_members(), and vm_change_password().

1290 {
1291  struct ast_category *cat;
1292 
1293  if (!prev) {
1294  /* First time browse. */
1295  cat = config->root;
1296  } else if (config->last_browse && (config->last_browse->name == prev)) {
1297  /* Simple last browse found. */
1298  cat = config->last_browse->next;
1299  } else {
1300  /*
1301  * Config changed since last browse.
1302  *
1303  * First try cheap last browse search. (Rebrowsing a different
1304  * previous category?)
1305  */
1306  for (cat = config->root; cat; cat = cat->next) {
1307  if (cat->name == prev) {
1308  /* Found it. */
1309  cat = cat->next;
1310  break;
1311  }
1312  }
1313  if (!cat) {
1314  /*
1315  * Have to do it the hard way. (Last category was deleted and
1316  * re-added?)
1317  */
1318  for (cat = config->root; cat; cat = cat->next) {
1319  if (!strcasecmp(cat->name, prev)) {
1320  /* Found it. */
1321  cat = cat->next;
1322  break;
1323  }
1324  }
1325  }
1326  }
1327 
1328  if (cat)
1329  cat = next_available_category(cat, NULL, NULL);
1330 
1331  config->last_browse = cat;
1332  return (cat) ? cat->name : NULL;
1333 }
struct ast_category * next
Definition: main/config.c:246
struct ast_category * prev
Definition: main/config.c:244
static struct ast_category * next_available_category(struct ast_category *cat, const char *name, const char *filter)
Definition: main/config.c:1148
#define NULL
Definition: resample.c:96
struct ast_category * last_browse
Definition: main/config.c:255
char name[80]
Definition: main/config.c:226
struct ast_category * root
Definition: main/config.c:251

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

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

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

1337 {
1338  struct ast_category *cat;
1339 
1340  if (!prev) {
1341  prev = config->root;
1342  } else {
1343  prev = prev->next;
1344  }
1345 
1346  cat = next_available_category(prev, category_name, filter);
1347 
1348  return cat;
1349 }
struct ast_category * next
Definition: main/config.c:246
static struct ast_category * next_available_category(struct ast_category *cat, const char *name, const char *filter)
Definition: main/config.c:1148
struct ast_category * root
Definition: main/config.c:251
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709

◆ ast_category_delete()

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

Delete a category.

Parameters
configwhich config to use
categorycategory 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 1478 of file main/config.c.

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

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

1480 {
1481  struct ast_category *prev;
1482 
1483  if (!config || !category) {
1484  return NULL;
1485  }
1486 
1487  if (category->prev) {
1488  category->prev->next = category->next;
1489  } else {
1490  config->root = category->next;
1491  }
1492 
1493  if (category->next) {
1494  category->next->prev = category->prev;
1495  } else {
1496  config->last = category->prev;
1497  }
1498 
1499  prev = category->prev;
1500 
1501  if (config->last_browse == category) {
1502  config->last_browse = prev;
1503  }
1504 
1505  ast_category_destroy(category);
1506 
1507  return prev;
1508 }
struct ast_category * next
Definition: main/config.c:246
struct ast_category * prev
Definition: main/config.c:244
#define NULL
Definition: resample.c:96
struct ast_category * last
Definition: main/config.c:253
void ast_category_destroy(struct ast_category *cat)
Definition: main/config.c:1122
struct ast_category * last_browse
Definition: main/config.c:255
struct ast_category * root
Definition: main/config.c:251

◆ ast_category_destroy()

void ast_category_destroy ( struct ast_category cat)

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

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

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

1123 {
1125  cat->root = NULL;
1126  cat->last = NULL;
1131  ast_free(cat->file);
1132  ast_free(cat);
1133 }
struct ast_comment * sameline
Definition: main/config.c:237
static void ast_destroy_template_list(struct ast_category *cat)
Definition: main/config.c:1114
char * file
The file name from whence this declaration was read.
Definition: main/config.c:233
#define NULL
Definition: resample.c:96
struct ast_comment * trailing
Definition: main/config.c:238
struct ast_variable * root
Definition: main/config.c:240
struct ast_comment * precomments
Definition: main/config.c:236
static void ast_comment_destroy(struct ast_comment **comment)
Definition: main/config.c:525
#define ast_free(a)
Definition: astmm.h:182
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591
struct ast_variable * last
Definition: main/config.c:242

◆ ast_category_detach_variables()

struct ast_variable* ast_category_detach_variables ( struct ast_category cat)

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

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

Referenced by realtime_switch_common(), and sorcery_realtime_retrieve_multiple().

1352 {
1353  struct ast_variable *v;
1354 
1355  v = cat->root;
1356  cat->root = NULL;
1357  cat->last = NULL;
1358 
1359  return v;
1360 }
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
struct ast_variable * root
Definition: main/config.c:240
struct ast_variable * last
Definition: main/config.c:242

◆ 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 categopry is NULL

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

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

Referenced by AST_TEST_DEFINE(), and handle_updates().

1511 {
1512  if (!category) {
1513  return -1;
1514  }
1515 
1516  ast_variables_destroy(category->root);
1517  category->root = NULL;
1518  category->last = NULL;
1519 
1520  return 0;
1521 }
#define NULL
Definition: resample.c:96
struct ast_variable * root
Definition: main/config.c:240
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591
struct ast_variable * last
Definition: main/config.c:242

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

References ast_category_get().

Referenced by realtime_sorcery_store().

1063 {
1064  return !!ast_category_get(config, category_name, filter);
1065 }
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:1022
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709

◆ ast_category_first()

struct ast_variable* ast_category_first ( struct ast_category cat)

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

return the first var of a category

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

References NULL, and ast_category::root.

Referenced by acl_order_comparator(), action_getconfig(), action_getconfigjson(), handle_aor(), handle_auth(), handle_endpoint(), handle_identify(), handle_phoneprov(), handle_registrations(), object_type_loaded_observer(), process_text_line(), sorcery_config_internal_load(), sorcery_is_criteria_met(), sorcery_is_explicit_name_met(), and wizard_apply_handler().

1158 {
1159  return (cat) ? cat->root : NULL;
1160 }
#define NULL
Definition: resample.c:96
struct ast_variable * root
Definition: main/config.c:240

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

References category_get_sep().

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

1024 {
1025  return category_get_sep(config, category_name, filter, ',', 1);
1026 }
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:1000
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709

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

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

1029 {
1030  return category->name;
1031 }
char name[80]
Definition: main/config.c:226

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

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

Referenced by action_getconfig(), and action_getconfigjson().

1039 {
1040  struct ast_category_template_instance *template;
1041  struct ast_str *str;
1042  int first = 1;
1043 
1044  if (AST_LIST_EMPTY(&category->template_instances)) {
1045  return NULL;
1046  }
1047 
1048  str = ast_str_create(128);
1049  if (!str) {
1050  return NULL;
1051  }
1052 
1053  AST_LIST_TRAVERSE(&category->template_instances, template, next) {
1054  ast_str_append(&str, 0, "%s%s", first ? "" : ",", template->name);
1055  first = 0;
1056  }
1057 
1058  return str;
1059 }
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:1091
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
struct ast_category::template_instance_list template_instances
struct ast_category_template_instance * next
Definition: main/config.c:222
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

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_comment::next, ast_variable::next, ast_category::root, var, and variable_clone().

Referenced by handle_updates(), and process_text_line().

1368 {
1369  struct ast_variable *var;
1371 
1372  x = ast_calloc(1, sizeof(*x));
1373  if (!x) {
1374  return -1;
1375  }
1376  strcpy(x->name, base->name);
1377  x->inst = base;
1379  for (var = base->root; var; var = var->next) {
1380  struct ast_variable *cloned = variable_clone(var);
1381  if (!cloned) {
1382  return -1;
1383  }
1384  cloned->inherited = 1;
1385  ast_variable_append(new, cloned);
1386  }
1387  return 0;
1388 }
struct ast_variable * next
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: main/config.c:488
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
const struct ast_category * inst
Definition: main/config.c:221
struct ast_category::template_instance_list template_instances
struct ast_variable * root
Definition: main/config.c:240
struct ast_category_template_instance * next
Definition: main/config.c:222
static struct ast_variable * variable_clone(const struct ast_variable *old)
Definition: main/config.c:855
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char name[80]
Definition: main/config.c:226

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

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

Referenced by AST_TEST_DEFINE(), and handle_updates().

1084 {
1085  struct ast_category *cur_category;
1086 
1087  if (!config || !config->root || !cat || !match) {
1088  return -1;
1089  }
1090 
1091  if (!strcasecmp(config->root->name, match)) {
1092  cat->next = config->root;
1093  cat->prev = NULL;
1094  config->root->prev = cat;
1095  config->root = cat;
1096  return 0;
1097  }
1098 
1099  for (cur_category = config->root->next; cur_category; cur_category = cur_category->next) {
1100  if (!strcasecmp(cur_category->name, match)) {
1101  cat->prev = cur_category->prev;
1102  cat->prev->next = cat;
1103 
1104  cat->next = cur_category;
1105  cur_category->prev = cat;
1106 
1107  return 0;
1108  }
1109  }
1110 
1111  return -1;
1112 }
struct ast_category * next
Definition: main/config.c:246
struct ast_category * prev
Definition: main/config.c:244
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:2315
#define NULL
Definition: resample.c:96
char name[80]
Definition: main/config.c:226
struct ast_category * root
Definition: main/config.c:251

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

References ast_category::ignored.

Referenced by action_getconfig(), and action_getconfigjson().

1034 {
1035  return category->ignored;
1036 }

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

References new_category().

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

991 {
992  return new_category(name, in_file, lineno, 0);
993 }
static struct ast_category * new_category(const char *name, const char *in_file, int lineno, int template)
Definition: main/config.c:971
static const char name[]
Definition: cdr_mysql.c:74

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

References new_category().

Referenced by AST_TEST_DEFINE(), and handle_updates().

996 {
997  return new_category(name, in_file, lineno, 1);
998 }
static struct ast_category * new_category(const char *name, const char *in_file, int lineno, int template)
Definition: main/config.c:971
static const char name[]
Definition: cdr_mysql.c:74

◆ ast_category_rename()

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

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

References ast_copy_string(), and ast_category::name.

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

1363 {
1364  ast_copy_string(cat->name, name, sizeof(cat->name));
1365 }
static const char name[]
Definition: cdr_mysql.c:74
char name[80]
Definition: main/config.c:226
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

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

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

Referenced by config_function_read(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), realtime_sorcery(), realtime_sorcery_multi(), and register_realtime_peers_with_callbackextens().

1163 {
1164  struct ast_category *category = ast_category_get(config, cat, NULL);
1165 
1166  if (category)
1167  return category->root;
1168  return NULL;
1169 }
#define NULL
Definition: resample.c:96
struct ast_variable * root
Definition: main/config.c:240
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:1022

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

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

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

3364 {
3365  struct ast_config_engine *eng;
3366  if (!ast_realtime_enabled()) {
3367  return 0; /* There are no engines at all so fail early */
3368  }
3369 
3370  eng = find_engine(family, 1, NULL, 0, NULL, 0);
3371  if (eng)
3372  return 1;
3373  return 0;
3374 }
int ast_realtime_enabled(void)
Check if there&#39;s any realtime engines loaded.
Definition: main/config.c:3377
#define NULL
Definition: resample.c:96
Configuration engine structure, used to define realtime drivers.
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:3042

◆ ast_comment_destroy()

static void ast_comment_destroy ( struct ast_comment **  comment)
static

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

References ast_free, ast_comment::next, and NULL.

Referenced by ast_category_destroy(), and ast_variable_destroy().

526 {
527  struct ast_comment *n, *p;
528 
529  for (p = *comment; p; p = n) {
530  n = p->next;
531  ast_free(p);
532  }
533 
534  *comment = NULL;
535 }
Structure to keep comments for rewriting configuration files.
Definition: main/config.c:84
struct ast_comment * next
Definition: main/config.c:85
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182

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

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

Referenced by AST_TEST_DEFINE(), and config_hook_exec().

3080 {
3081  struct ast_config *new_config = ast_config_new();
3082  struct ast_category *cat_iter;
3083 
3084  if (!new_config) {
3085  return NULL;
3086  }
3087 
3088  for (cat_iter = old->root; cat_iter; cat_iter = cat_iter->next) {
3089  struct ast_category *new_cat =
3090  ast_category_new(cat_iter->name, cat_iter->file, cat_iter->lineno);
3091  if (!new_cat) {
3092  goto fail;
3093  }
3094  ast_category_append(new_config, new_cat);
3095  if (cat_iter->root) {
3096  new_cat->root = ast_variables_dup(cat_iter->root);
3097  if (!new_cat->root) {
3098  goto fail;
3099  }
3100  new_cat->last = cat_iter->last;
3101  }
3102  }
3103 
3104  return new_config;
3105 
3106 fail:
3107  ast_config_destroy(new_config);
3108  return NULL;
3109 }
struct ast_category * next
Definition: main/config.c:246
char * file
The file name from whence this declaration was read.
Definition: main/config.c:233
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
Definition: main/config.c:1067
#define NULL
Definition: resample.c:96
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:545
struct ast_variable * root
Definition: main/config.c:240
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: main/config.c:1523
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: main/config.c:1390
char name[80]
Definition: main/config.c:226
struct ast_variable * last
Definition: main/config.c:242
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
Definition: main/config.c:990
struct ast_category * root
Definition: main/config.c:251

◆ ast_config_destroy()

void ast_config_destroy ( struct ast_config cfg)

Destroys a config.

Parameters
configpointer to config data structure

Free memory associated with a given config

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

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

Referenced by __ast_http_load(), __ast_http_post_load(), __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(), ast_xmldoc_load_documentation(), build_cfg(), conf_exec(), config_function_read(), config_load(), config_module(), deinitialize_sorcery(), directory_exec(), do_reload(), festival_exec(), find_conf(), find_load_queue_rt_friendly(), find_realtime(), forward_message(), get_defaults(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), handle_cli_dialplan_save(), hook_cb(), iax_provision_reload(), ineligible_configuration(), init_logger_chain(), initialize_cc_devstate_map(), initialize_cc_max_requests(), load_asterisk_conf(), load_config(), load_config_meetme(), load_indications(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_realtime_musiconhold(), load_realtime_rules(), load_values_config(), loader_config_init(), make_email_file(), mbl_load_config(), message_range_and_existence_check(), misdn_cfg_init(), my_load_module(), named_acl_find_realtime(), notify_new_message(), object_type_loaded_observer(), odbc_load_module(), osp_load(), 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_handler(), realtime_multi_mysql(), realtime_multi_pgsql(), realtime_sorcery_multi(), realtime_sqlite3_multi(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), reload(), reload_config(), reload_followme(), reload_module(), reload_queue_rules(), reload_queues(), rtp_reload(), run_startup_commands(), set_config(), setup_dahdi_int(), show_users_realtime(), sla_load_config(), smdi_load(), 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(), and write_password_to_file().

1524 {
1525  struct ast_category *cat, *catn;
1526 
1527  if (!cfg)
1528  return;
1529 
1531 
1532  cat = cfg->root;
1533  while (cat) {
1534  catn = cat;
1535  cat = cat->next;
1536  ast_category_destroy(catn);
1537  }
1538  ast_free(cfg);
1539 }
struct ast_category * next
Definition: main/config.c:246
struct ast_config_include * includes
Definition: main/config.c:258
static void ast_includes_destroy(struct ast_config_include *incls)
Definition: main/config.c:1135
void ast_category_destroy(struct ast_category *cat)
Definition: main/config.c:1122
#define ast_free(a)
Definition: astmm.h:182
struct ast_category * root
Definition: main/config.c:251

◆ ast_config_engine_deregister()

int ast_config_engine_deregister ( struct ast_config_engine del)

Deregister config engine.

Return values
0Always

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

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

Referenced by unload_module().

3007 {
3008  struct ast_config_engine *ptr, *last=NULL;
3009 
3011 
3012  for (ptr = config_engine_list; ptr; ptr=ptr->next) {
3013  if (ptr == del) {
3014  if (last)
3015  last->next = ptr->next;
3016  else
3017  config_engine_list = ptr->next;
3018  break;
3019  }
3020  last = ptr;
3021  }
3022 
3023  return 0;
3024 }
#define NULL
Definition: resample.c:96
Configuration engine structure, used to define realtime drivers.
struct ast_config_engine * next
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
struct sla_ringing_trunk * last
Definition: app_meetme.c:1092
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t config_lock
Definition: main/config.c:214
static struct ast_config_engine * config_engine_list
Definition: main/config.c:215

◆ ast_config_engine_register()

int ast_config_engine_register ( struct ast_config_engine newconfig)

Register config engine.

Return values
1Always

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

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

Referenced by load_module().

2991 {
2992  struct ast_config_engine *ptr;
2993 
2995 
2996  if (!config_engine_list) {
2997  config_engine_list = new;
2998  } else {
2999  for (ptr = config_engine_list; ptr->next; ptr=ptr->next);
3000  ptr->next = new;
3001  }
3002 
3003  return 1;
3004 }
Configuration engine structure, used to define realtime drivers.
struct ast_config_engine * next
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t config_lock
Definition: main/config.c:214
static struct ast_config_engine * config_engine_list
Definition: main/config.c:215

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

References ast_config::current.

Referenced by config_text_file_load().

1542 {
1543  return cfg->current;
1544 }
struct ast_category * current
Definition: main/config.c:254

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

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

Referenced by AST_TEST_DEFINE().

4137 {
4138  struct cfg_hook *hook;
4139  if (!cfg_hooks) {
4141  hook_hash, NULL, hook_cmp);
4142  if (!cfg_hooks) {
4143  return -1;
4144  }
4145  }
4146 
4147  if (!(hook = ao2_alloc(sizeof(*hook), hook_destroy))) {
4148  return -1;
4149  }
4150 
4151  hook->hook_cb = hook_cb;
4152  hook->filename = ast_strdup(filename);
4153  hook->name = ast_strdup(name);
4154  hook->module = ast_strdup(module);
4155 
4156  ao2_link(cfg_hooks, hook);
4157  ao2_ref(hook, -1);
4158  return 0;
4159 }
static int hook_hash(const void *obj, const int flags)
Definition: main/config.c:4097
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
config_hook_cb hook_cb
Definition: main/config.c:4078
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int hook_cmp(void *obj, void *arg, int flags)
Definition: main/config.c:4089
static struct ao2_container * cfg_hooks
Definition: main/config.c:77
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static void hook_destroy(void *obj)
Definition: main/config.c:4081
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
const char * filename
Definition: main/config.c:4076
static int hook_cb(struct ast_config *cfg)
Definition: test_config.c:875
const char * module
Definition: main/config.c:4077
const char * name
Definition: main/config.c:4075
#define ao2_link(container, obj)
Definition: astobj2.h:1549

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

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

Referenced by AST_TEST_DEFINE().

4105 {
4106  struct cfg_hook tmp;
4107 
4108  tmp.name = ast_strdupa(name);
4109 
4111 }
#define OBJ_POINTER
Definition: astobj2.h:1154
static int tmp()
Definition: bt_open.c:389
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ao2_container * cfg_hooks
Definition: main/config.c:77
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

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

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

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

3113 {
3114  char db[256];
3115  char table[256];
3116  struct ast_config_engine *loader = &text_file_engine;
3117  struct ast_config *result;
3118 
3119  /* The config file itself bumps include_level by 1 */
3120  if (cfg->max_include_level > 0 && cfg->include_level == cfg->max_include_level + 1) {
3121  ast_log(LOG_WARNING, "Maximum Include level (%d) exceeded\n", cfg->max_include_level);
3122  return NULL;
3123  }
3124 
3125  cfg->include_level++;
3126 
3128  struct ast_config_engine *eng;
3129 
3130  eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
3131 
3132 
3133  if (eng && eng->load_func) {
3134  loader = eng;
3135  } else {
3136  eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
3137  if (eng && eng->load_func)
3138  loader = eng;
3139  }
3140  }
3141 
3142  result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
3143 
3144  if (result && result != CONFIG_STATUS_FILEINVALID && result != CONFIG_STATUS_FILEUNCHANGED) {
3145  result->include_level--;
3146  config_hook_exec(filename, who_asked, result);
3147  } else if (result != CONFIG_STATUS_FILEINVALID) {
3148  cfg->include_level--;
3149  }
3150 
3151  return result;
3152 }
static struct ast_config_engine text_file_engine
Definition: main/config.c:3074
#define ast_test_flag(p, flag)
Definition: utils.h:63
static sqlite3 * db
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
int include_level
Definition: main/config.c:256
#define NULL
Definition: resample.c:96
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
#define ast_log
Definition: astobj2.c:42
#define CONFIG_STATUS_FILEUNCHANGED
static struct ast_config_engine * config_engine_list
Definition: main/config.c:215
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:3042
config_load_func * load_func
static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg)
Definition: main/config.c:4113
static PGresult * result
Definition: cel_pgsql.c:88
int max_include_level
Definition: main/config.c:257

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

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(), ast_xmldoc_load_documentation(), 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(), misdn_cfg_init(), object_type_loaded_observer(), private_enum_init(), read_pjproject_startup_options(), rtp_reload(), run_startup_commands(), set_config(), and sorcery_config_internal_load().

3155 {
3156  struct ast_config *cfg;
3157  struct ast_config *result;
3158 
3159  cfg = ast_config_new();
3160  if (!cfg)
3161  return NULL;
3162 
3163  result = ast_config_internal_load(filename, cfg, flags, "", who_asked);
3164  if (!result || result == CONFIG_STATUS_FILEUNCHANGED || result == CONFIG_STATUS_FILEINVALID)
3165  ast_config_destroy(cfg);
3166 
3167  return result;
3168 }
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:3112
#define CONFIG_STATUS_FILEINVALID
#define NULL
Definition: resample.c:96
#define CONFIG_STATUS_FILEUNCHANGED
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: main/config.c:1523
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: main/config.c:1390
static PGresult * result
Definition: cel_pgsql.c:88

◆ ast_config_new()

struct ast_config* ast_config_new ( void  )

Create a new base configuration structure.

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

References ast_calloc, config, MAX_INCLUDE_LEVEL, and ast_config::max_include_level.

Referenced by alloc_and_initialize_sorcery(), ast_config_copy(), ast_config_load2(), AST_TEST_DEFINE(), build_cfg(), find_load_queue_rt_friendly(), realtime_multi_curl(), realtime_multi_handler(), realtime_multi_ldap(), realtime_multi_mysql(), realtime_multi_odbc(), realtime_multi_pgsql(), realtime_sorcery_multi(), realtime_sqlite3_multi(), reload_module(), setup_dahdi_int(), and write_password_to_file().

1391 {
1392  struct ast_config *config;
1393 
1394  if ((config = ast_calloc(1, sizeof(*config))))
1396  return config;
1397 }
char * config
Definition: conf2ael.c:66
#define MAX_INCLUDE_LEVEL
Definition: main/config.c:217
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
int max_include_level
Definition: main/config.c:257

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

References ast_variable_retrieve(), and tmp().

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

685 {
686  const char *tmp;
687  tmp = ast_variable_retrieve(cfg, cat, var);
688  if (!tmp) {
689  tmp = ast_variable_retrieve(cfg, "general", var);
690  }
691  return tmp;
692 }
static int tmp()
Definition: bt_open.c:389
#define var
Definition: ast_expr2f.c:614
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694

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

References ast_config::current.

Referenced by process_text_line().

1547 {
1548  /* cast below is just to silence compiler warning about dropping "const" */
1549  cfg->current = (struct ast_category *) cat;
1550 }
struct ast_category * current
Definition: main/config.c:254

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

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

Referenced by named_acl_find_realtime(), and realtime_switch_common().

1173 {
1174  /*
1175  * The contents of this function are adapted from
1176  * an example of linked list merge sorting
1177  * copyright 2001 Simon Tatham.
1178  *
1179  * Permission is hereby granted, free of charge, to any person
1180  * obtaining a copy of this software and associated documentation
1181  * files (the "Software"), to deal in the Software without
1182  * restriction, including without limitation the rights to use,
1183  * copy, modify, merge, publish, distribute, sublicense, and/or
1184  * sell copies of the Software, and to permit persons to whom the
1185  * Software is furnished to do so, subject to the following
1186  * conditions:
1187  *
1188  * The above copyright notice and this permission notice shall be
1189  * included in all copies or substantial portions of the Software.
1190  *
1191  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1192  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1193  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1194  * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
1195  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
1196  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1197  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1198  * SOFTWARE.
1199  */
1200 
1201  int insize = 1;
1202  struct ast_category *p, *q, *e, *tail;
1203  int nmerges, psize, qsize, i;
1204 
1205  /* If the descending flag was sent, we'll apply inversion to the comparison function's return. */
1206  if (descending) {
1207  descending = -1;
1208  } else {
1209  descending = 1;
1210  }
1211 
1212  if (!config->root) {
1213  return;
1214  }
1215 
1216  while (1) {
1217  p = config->root;
1218  config->root = NULL;
1219  tail = NULL;
1220 
1221  nmerges = 0; /* count number of merges we do in this pass */
1222 
1223  while (p) {
1224  nmerges++; /* there exists a merge to be done */
1225 
1226  /* step `insize' places along from p */
1227  q = p;
1228  psize = 0;
1229  for (i = 0; i < insize; i++) {
1230  psize++;
1231  q = q->next;
1232  if (!q) {
1233  break;
1234  }
1235  }
1236 
1237  /* if q hasn't fallen off end, we have two lists to merge */
1238  qsize = insize;
1239 
1240  /* now we have two lists; merge them */
1241  while (psize > 0 || (qsize > 0 && q)) {
1242  /* decide whether next element of merge comes from p or q */
1243  if (psize == 0) {
1244  /* p is empty; e must come from q. */
1245  e = q;
1246  q = q->next;
1247  qsize--;
1248  } else if (qsize == 0 || !q) {
1249  /* q is empty; e must come from p. */
1250  e = p; p = p->next; psize--;
1251  } else if ((comparator(p,q) * descending) <= 0) {
1252  /* First element of p is lower (or same) e must come from p. */
1253  e = p;
1254  p = p->next;
1255  psize--;
1256  } else {
1257  /* First element of q is lower; e must come from q. */
1258  e = q;
1259  q = q->next;
1260  qsize--;
1261  }
1262 
1263  /* add the next element to the merged list */
1264  if (tail) {
1265  tail->next = e;
1266  } else {
1267  config->root = e;
1268  }
1269  tail = e;
1270  }
1271 
1272  /* now p has stepped `insize' places along, and q has too */
1273  p = q;
1274  }
1275 
1276  tail->next = NULL;
1277 
1278  /* If we have done only one merge, we're finished. */
1279  if (nmerges <= 1) { /* allow for nmerges==0, the empty list case */
1280  return;
1281  }
1282 
1283  /* Otherwise repeat, merging lists twice the size */
1284  insize *= 2;
1285  }
1286 
1287 }
struct ast_category * next
Definition: main/config.c:246
#define NULL
Definition: resample.c:96
struct ast_category * root
Definition: main/config.c:251

◆ 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
Returns
0 on success or -1 on failure.

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

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

2532 {
2534 }
static struct ast_generator generator
Definition: app_fax.c:359
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:2555

◆ 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
Returns
0 on success or -1 on failure.

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

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_variable::blanklines, ast_comment::cmt, config_hook_exec(), CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT, errno, ast_config_include::exec, ast_config_include::exec_file, ast_variable::file, ast_category::file, gen_header(), hash_string(), hashtab_compare_strings(), ast_category::ignored, ast_config_include::include_location_file, ast_config_include::include_location_lineno, ast_config_include::included_file, ast_config::includes, ast_variable::inherited, insert_leading_blank_lines(), ast_category_template_instance::inst, is_writable(), ast_variable::lineno, ast_category::lineno, LOG_ERROR, make_fn(), ast_variable::name, ast_category_template_instance::name, ast_category::name, ast_comment::next, ast_variable::next, ast_category::next, ast_config_include::next, NULL, ast_variable::object, ast_config_include::output, PATH_MAX, ast_variable::precomments, ast_category::precomments, ast_category::root, ast_config::root, ast_variable::sameline, ast_category::sameline, set_fn(), ast_category::template_instances, ast_variable::trailing, ast_category::trailing, ast_variable::value, and var.

Referenced by action_updateconfig(), and ast_config_text_file_save().

2556 {
2557  FILE *f;
2558  char fn[PATH_MAX];
2559  struct ast_variable *var;
2560  struct ast_category *cat;
2561  struct ast_comment *cmt;
2562  struct ast_config_include *incl;
2563  int blanklines = 0;
2564  struct ao2_container *fileset;
2565  struct inclfile *fi;
2566 
2569  if (!fileset) {
2570  /* Container creation failed. */
2571  return -1;
2572  }
2573 
2574  /* Check all the files for write access before attempting to modify any of them */
2575  for (incl = cfg->includes; incl; incl = incl->next) {
2576  /* reset all the output flags in case this isn't our first time saving this data */
2577  incl->output = 0;
2578 
2579  if (!incl->exec) {
2580  /* now make sure we have write access to the include file or its parent directory */
2581  make_fn(fn, sizeof(fn), incl->included_file, configfile);
2582  /* If the file itself doesn't exist, make sure we have write access to the directory */
2583  if (!is_writable(fn)) {
2584  return -1;
2585  }
2586  }
2587  }
2588 
2589  /* now make sure we have write access to the main config file or its parent directory */
2590  make_fn(fn, sizeof(fn), 0, configfile);
2591  if (!is_writable(fn)) {
2592  return -1;
2593  }
2594 
2595  /* Now that we know we have write access to all files, it's safe to start truncating them */
2596 
2597  /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions)
2598  are all truncated to zero bytes and have that nice header*/
2599  for (incl = cfg->includes; incl; incl = incl->next) {
2600  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*/
2601  /* normally, fn is just set to incl->included_file, prepended with config dir if relative */
2602  fi = set_fn(fn, sizeof(fn), incl->included_file, configfile, fileset);
2603  f = fopen(fn, "w");
2604  if (f) {
2605  gen_header(f, configfile, fn, generator);
2606  fclose(f); /* this should zero out the file */
2607  } else {
2608  ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
2609  }
2610  if (fi) {
2611  ao2_ref(fi, -1);
2612  }
2613  }
2614  }
2615 
2616  /* just set fn to absolute ver of configfile */
2617  fi = set_fn(fn, sizeof(fn), 0, configfile, fileset);
2618  if (
2619 #ifdef __CYGWIN__
2620  (f = fopen(fn, "w+"))
2621 #else
2622  (f = fopen(fn, "w"))
2623 #endif
2624  ) {
2625  ast_verb(2, "Saving '%s'\n", fn);
2626  gen_header(f, configfile, fn, generator);
2627  cat = cfg->root;
2628  fclose(f);
2629  if (fi) {
2630  ao2_ref(fi, -1);
2631  }
2632 
2633  /* from here out, we open each involved file and concat the stuff we need to add to the end and immediately close... */
2634  /* since each var, cat, and associated comments can come from any file, we have to be
2635  mobile, and open each file, print, and close it on an entry-by-entry basis */
2636 
2637  while (cat) {
2638  fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset);
2639  f = fopen(fn, "a");
2640  if (!f) {
2641  ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
2642  if (fi) {
2643  ao2_ref(fi, -1);
2644  }
2645  ao2_ref(fileset, -1);
2646  return -1;
2647  }
2648 
2649  /* dump any includes that happen before this category header */
2650  for (incl=cfg->includes; incl; incl = incl->next) {
2651  if (strcmp(incl->include_location_file, cat->file) == 0){
2652  if (cat->lineno > incl->include_location_lineno && !incl->output) {
2653  if (incl->exec)
2654  fprintf(f,"#exec \"%s\"\n", incl->exec_file);
2655  else
2656  fprintf(f,"#include \"%s\"\n", incl->included_file);
2657  incl->output = 1;
2658  }
2659  }
2660  }
2661 
2662  insert_leading_blank_lines(f, fi, cat->precomments, cat->lineno);
2663  /* Dump section with any appropriate comment */
2664  for (cmt = cat->precomments; cmt; cmt=cmt->next) {
2665  char *cmtp = cmt->cmt;
2666  while (cmtp && *cmtp == ';' && *(cmtp+1) == '!') {
2667  char *cmtp2 = strchr(cmtp+1, '\n');
2668  if (cmtp2)
2669  cmtp = cmtp2+1;
2670  else cmtp = 0;
2671  }
2672  if (cmtp)
2673  fprintf(f,"%s", cmtp);
2674  }
2675  fprintf(f, "[%s]", cat->name);
2676  if (cat->ignored || !AST_LIST_EMPTY(&cat->template_instances)) {
2677  fprintf(f, "(");
2678  if (cat->ignored) {
2679  fprintf(f, "!");
2680  }
2681  if (cat->ignored && !AST_LIST_EMPTY(&cat->template_instances)) {
2682  fprintf(f, ",");
2683  }
2684  if (!AST_LIST_EMPTY(&cat->template_instances)) {
2687  fprintf(f,"%s",x->name);
2688  if (x != AST_LIST_LAST(&cat->template_instances))
2689  fprintf(f,",");
2690  }
2691  }
2692  fprintf(f, ")");
2693  }
2694  for(cmt = cat->sameline; cmt; cmt=cmt->next)
2695  {
2696  fprintf(f,"%s", cmt->cmt);
2697  }
2698  if (!cat->sameline)
2699  fprintf(f,"\n");
2700  for (cmt = cat->trailing; cmt; cmt=cmt->next) {
2701  if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
2702  fprintf(f,"%s", cmt->cmt);
2703  }
2704  fclose(f);
2705  if (fi) {
2706  ao2_ref(fi, -1);
2707  }
2708 
2709  var = cat->root;
2710  while (var) {
2712  int found = 0;
2713 
2715  struct ast_variable *v;
2716  for (v = x->inst->root; v; v = v->next) {
2717 
2719  if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
2720  found = 1;
2721  break;
2722  }
2723  } else {
2724  if (var->inherited) {
2725  found = 1;
2726  break;
2727  } else {
2728  if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
2729  found = 1;
2730  break;
2731  }
2732  }
2733  }
2734  }
2735  if (found) {
2736  break;
2737  }
2738  }
2739  if (found) {
2740  var = var->next;
2741  continue;
2742  }
2743  fi = set_fn(fn, sizeof(fn), var->file, configfile, fileset);
2744  f = fopen(fn, "a");
2745  if (!f) {
2746  ast_debug(1, "Unable to open for writing: %s\n", fn);
2747  ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
2748  if (fi) {
2749  ao2_ref(fi, -1);
2750  }
2751  ao2_ref(fileset, -1);
2752  return -1;
2753  }
2754 
2755  /* dump any includes that happen before this category header */
2756  for (incl=cfg->includes; incl; incl = incl->next) {
2757  if (strcmp(incl->include_location_file, var->file) == 0){
2758  if (var->lineno > incl->include_location_lineno && !incl->output) {
2759  if (incl->exec)
2760  fprintf(f,"#exec \"%s\"\n", incl->exec_file);
2761  else
2762  fprintf(f,"#include \"%s\"\n", incl->included_file);
2763  incl->output = 1;
2764  }
2765  }
2766  }
2767 
2768  insert_leading_blank_lines(f, fi, var->precomments, var->lineno);
2769  for (cmt = var->precomments; cmt; cmt=cmt->next) {
2770  if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
2771  fprintf(f,"%s", cmt->cmt);
2772  }
2773 
2774  { /* Block for 'escaped' scope */
2775  int escaped_len = 2 * strlen(var->value) + 1;
2776  char escaped[escaped_len];
2777 
2778  ast_escape_semicolons(var->value, escaped, escaped_len);
2779 
2780  if (var->sameline) {
2781  fprintf(f, "%s %s %s %s", var->name, (var->object ? "=>" : "="),
2782  escaped, var->sameline->cmt);
2783  } else {
2784  fprintf(f, "%s %s %s\n", var->name, (var->object ? "=>" : "="),
2785  escaped);
2786  }
2787  }
2788 
2789  for (cmt = var->trailing; cmt; cmt=cmt->next) {
2790  if (cmt->cmt[0] != ';' || cmt->cmt[1] != '!')
2791  fprintf(f,"%s", cmt->cmt);
2792  }
2793  if (var->blanklines) {
2794  blanklines = var->blanklines;
2795  while (blanklines--)
2796  fprintf(f, "\n");
2797  }
2798 
2799  fclose(f);
2800  if (fi) {
2801  ao2_ref(fi, -1);
2802  }
2803 
2804  var = var->next;
2805  }
2806  cat = cat->next;
2807  }
2808  ast_verb(2, "Saving '%s': saved\n", fn);
2809  } else {
2810  ast_debug(1, "Unable to open for writing: %s\n", fn);
2811  ast_verb(2, "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  /* Now, for files with trailing #include/#exec statements,
2820  we have to make sure every entry is output */
2821  for (incl=cfg->includes; incl; incl = incl->next) {
2822  if (!incl->output) {
2823  /* open the respective file */
2824  fi = set_fn(fn, sizeof(fn), incl->include_location_file, configfile, fileset);
2825  f = fopen(fn, "a");
2826  if (!f) {
2827  ast_debug(1, "Unable to open for writing: %s\n", fn);
2828  ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno));
2829  if (fi) {
2830  ao2_ref(fi, -1);
2831  }
2832  ao2_ref(fileset, -1);
2833  return -1;
2834  }
2835 
2836  /* output the respective include */
2837  if (incl->exec)
2838  fprintf(f,"#exec \"%s\"\n", incl->exec_file);
2839  else
2840  fprintf(f,"#include \"%s\"\n", incl->included_file);
2841  fclose(f);
2842  incl->output = 1;
2843  if (fi) {
2844  ao2_ref(fi, -1);
2845  }
2846  }
2847  }
2848  ao2_ref(fileset, -1); /* this should destroy the hash container */
2849 
2850  /* pass new configuration to any config hooks */
2851  config_hook_exec(configfile, generator, cfg);
2852 
2853  return 0;
2854 }
struct ast_variable * next
struct ast_category * next
Definition: main/config.c:246
struct ast_comment * sameline
Definition: main/config.c:237
Structure to keep comments for rewriting configuration files.
Definition: main/config.c:84
char * file
The file name from whence this declaration was read.
Definition: main/config.c:233
struct ast_comment * next
Definition: main/config.c:85
char * include_location_file
file name in which the include occurs
Definition: main/config.c:266
struct ast_config_include * includes
Definition: main/config.c:258
char cmt[0]
Definition: main/config.c:87
Structure for variables, used for configurations and for channel variables.
struct ast_comment * sameline
#define var
Definition: ast_expr2f.c:614
const struct ast_category * inst
Definition: main/config.c:221
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
Definition: main/utils.c:665
#define NULL
Definition: resample.c:96
char * exec_file
if it&#39;s an exec, you&#39;ll have both the /var/tmp to read, and the original script
Definition: main/config.c:273
static void gen_header(FILE *f1, const char *configfile, const char *fn, const char *generator)
Definition: main/config.c:2399
#define ast_verb(level,...)
Definition: logger.h:463
static void make_fn(char *fn, size_t fn_size, const char *file, const char *configfile)
Definition: main/config.c:2425
struct ast_comment * trailing
static int is_writable(const char *fn)
Definition: main/config.c:2536
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_category::template_instance_list template_instances
struct ast_comment * trailing
Definition: main/config.c:238
char * included_file
file name included
Definition: main/config.c:278
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_variable * root
Definition: main/config.c:240
struct ast_comment * precomments
Definition: main/config.c:236
struct ast_category_template_instance * next
Definition: main/config.c:222
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static struct ast_generator generator
Definition: app_fax.c:359
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:2440
int errno
struct ast_comment * precomments
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
static int hash_string(const void *obj, const int flags)
Definition: main/config.c:173
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char name[80]
Definition: main/config.c:226
struct ast_config_include * next
Definition: main/config.c:282
static void config_hook_exec(const char *filename, const char *module, const struct ast_config *cfg)
Definition: main/config.c:4113
#define PATH_MAX
Definition: asterisk.h:40
Generic container type.
static int hashtab_compare_strings(void *a, void *b, int flags)
Definition: main/config.c:193
struct ast_category * root
Definition: main/config.c:251
static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast_comment *precomments, int lineno)
Definition: main/config.c:2495

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

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

3607 {
3608  RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3609  int res = 0;
3610  va_list ap;
3611 
3612  va_start(ap, lookup);
3613  if (realtime_arguments_to_fields(ap, &fields)) {
3614  res = -1;
3615  }
3616  va_end(ap);
3617 
3618  if (res) {
3619  return -1;
3620  }
3621 
3622  return ast_destroy_realtime_fields(family, keyfield, lookup, fields);
3623 }
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:3586
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3170
#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:911
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591

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

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

Referenced by ast_destroy_realtime(), and sorcery_realtime_delete().

3587 {
3588  struct ast_config_engine *eng;
3589  int res = -1, i;
3590  char db[256];
3591  char table[256];
3592 
3593  for (i = 1; ; i++) {
3594  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3595  if (eng->destroy_func && ((res = eng->destroy_func(db, table, keyfield, lookup, fields)) >= 0)) {
3596  break;
3597  }
3598  } else {
3599  break;
3600  }
3601  }
3602 
3603  return res;
3604 }
realtime_destroy * destroy_func
static sqlite3 * db
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
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:3042

◆ ast_destroy_template_list()

static void ast_destroy_template_list ( struct ast_category cat)
static

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

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

Referenced by ast_category_destroy().

1115 {
1117 
1118  while ((x = AST_LIST_REMOVE_HEAD(&cat->template_instances, next)))
1119  ast_free(x);
1120 }
struct ast_category::template_instance_list template_instances
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_category_template_instance * next
Definition: main/config.c:222
#define ast_free(a)
Definition: astmm.h:182

◆ ast_include_find()

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

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

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

Referenced by ast_include_new().

478 {
479  struct ast_config_include *x;
480  for (x=conf->includes;x;x=x->next) {
481  if (strcmp(x->included_file,included_file) == 0)
482  return x;
483  }
484  return 0;
485 }
struct ast_config_include * includes
Definition: main/config.c:258
char * included_file
file name included
Definition: main/config.c:278
struct ast_config_include * next
Definition: main/config.c:282

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

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

Referenced by AST_TEST_DEFINE(), and process_text_line().

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

◆ ast_include_rename()

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

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

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

Referenced by action_updateconfig().

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

◆ ast_includes_destroy()

static void ast_includes_destroy ( struct ast_config_include incls)
static

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

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

1136 {
1137  struct ast_config_include *incl,*inclnext;
1138 
1139  for (incl=incls; incl; incl = inclnext) {
1140  inclnext = incl->next;
1142  ast_free(incl->exec_file);
1143  ast_free(incl->included_file);
1144  ast_free(incl);
1145  }
1146 }
char * include_location_file
file name in which the include occurs
Definition: main/config.c:266
char * exec_file
if it&#39;s an exec, you&#39;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
#define ast_free(a)
Definition: astmm.h:182
struct ast_config_include * next
Definition: main/config.c:282

◆ ast_load_realtime()

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

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

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_realtime_gw(), find_user_realtime(), leave_queue(), load_realtime_musiconhold(), queue_function_queuegetchannel(), queue_function_queuewaitingcount(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_switch_common(), realtime_user(), rt_extend_conf(), and vm_allocate_dh().

3340 {
3341  RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3342  int field_res = 0;
3343  va_list ap;
3344 
3345  va_start(ap, family);
3346  if (realtime_arguments_to_fields(ap, &fields)) {
3347  field_res = -1;
3348  }
3349  va_end(ap);
3350 
3351  if (field_res) {
3352  return NULL;
3353  }
3354 
3355  if (!fields) {
3356  return NULL;
3357  }
3358 
3359  return ast_load_realtime_fields(family, fields);
3360 }
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3170
#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:911
struct ast_variable * ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3304
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591

◆ ast_load_realtime_all()

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

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

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

3288 {
3289  RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3290  struct ast_variable *res = NULL;
3291  va_list ap;
3292 
3293  va_start(ap, family);
3294  realtime_arguments_to_fields(ap, &fields);
3295  va_end(ap);
3296 
3297  if (fields) {
3298  res = ast_load_realtime_all_fields(family, fields);
3299  }
3300 
3301  return res;
3302 }
Structure for variables, used for configurations and for channel variables.
struct ast_variable * ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
Definition: main/config.c:3266
#define NULL
Definition: resample.c:96
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3170
#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:911
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591

◆ ast_load_realtime_all_fields()

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

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

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

Referenced by ast_load_realtime_all(), and ast_load_realtime_fields().

3267 {
3268  struct ast_config_engine *eng;
3269  char db[256];
3270  char table[256];
3271  struct ast_variable *res=NULL;
3272  int i;
3273 
3274  for (i = 1; ; i++) {
3275  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3276  if (eng->realtime_func && (res = eng->realtime_func(db, table, fields))) {
3277  return res;
3278  }
3279  } else {
3280  return NULL;
3281  }
3282  }
3283 
3284  return res;
3285 }
static sqlite3 * db
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
realtime_var_get * realtime_func
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
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:3042

◆ 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

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

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

Referenced by ast_load_realtime(), and sorcery_realtime_retrieve_fields().

3305 {
3306  struct ast_variable *res;
3307  struct ast_variable *cur;
3308  struct ast_variable **prev;
3309 
3310  res = ast_load_realtime_all_fields(family, fields);
3311 
3312  /* Filter the list. */
3313  prev = &res;
3314  cur = res;
3315  while (cur) {
3316  if (ast_strlen_zero(cur->value)) {
3317  /* Eliminate empty entries */
3318  struct ast_variable *next;
3319 
3320  next = cur->next;
3321  *prev = next;
3322  ast_variable_destroy(cur);
3323  cur = next;
3324  } else {
3325  /* Make blank entries empty and keep them. */
3326  if (cur->value[0] == ' ' && cur->value[1] == '\0') {
3327  char *vptr = (char *) cur->value;
3328 
3329  vptr[0] = '\0';
3330  }
3331 
3332  prev = &cur->next;
3333  cur = cur->next;
3334  }
3335  }
3336  return res;
3337 }
struct ast_variable * next
static void ast_variable_destroy(struct ast_variable *doomed)
Definition: main/config.c:537
Structure for variables, used for configurations and for channel variables.
struct ast_variable * ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
Definition: main/config.c:3266
#define ast_strlen_zero(foo)
Definition: strings.h:52

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

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(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), load_module(), load_realtime_musiconhold(), load_realtime_rules(), named_acl_find_realtime(), realtime_directory(), realtime_switch_common(), register_realtime_peers_with_callbackextens(), set_member_value(), show_users_realtime(), and update_realtime_members().

3453 {
3454  RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3455  va_list ap;
3456 
3457  va_start(ap, family);
3458  realtime_arguments_to_fields(ap, &fields);
3459  va_end(ap);
3460 
3461  if (!fields) {
3462  return NULL;
3463  }
3464 
3465  return ast_load_realtime_multientry_fields(family, fields);
3466 }
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3170
#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:911
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591
struct ast_config * ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Definition: main/config.c:3426

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

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

Referenced by ast_load_realtime_multientry(), and sorcery_realtime_retrieve_multiple().

3427 {
3428  struct ast_config_engine *eng;
3429  char db[256];
3430  char table[256];
3431  struct ast_config *res = NULL;
3432  int i;
3433 
3434  for (i = 1; ; i++) {
3435  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3436  if (eng->realtime_multi_func && (res = eng->realtime_multi_func(db, table, fields))) {
3437  /* If we were returned an empty cfg, destroy it and return NULL */
3438  if (!res->root) {
3439  ast_config_destroy(res);
3440  res = NULL;
3441  }
3442  break;
3443  }
3444  } else {
3445  break;
3446  }
3447  }
3448 
3449  return res;
3450 }
static sqlite3 * db
realtime_multi_get * realtime_multi_func
#define NULL
Definition: resample.c:96
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: main/config.c:1523
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:3042
struct ast_category * root
Definition: main/config.c:251

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

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

References ahp, ast_app_parse_timelen(), ast_debug, ast_gethostbyname(), ast_inet_ntoa(), ast_skip_blanks(), ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_strdupa, ast_strlen_zero, buf, errno, error(), hp, 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(), 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(), load_values_config(), new_realtime_sqlite3_db(), realtime_peer(), reload_config(), rtp_reload(), set_config(), setup_rtp_connection(), setup_rtp_remote(), setup_udptl_connection(), sockaddr_handler_fn(), timelen_handler_fn(), uint_handler_fn(), and xfer_set().

3659 {
3660  va_list ap;
3661  int error = 0;
3662 
3663  va_start(ap, p_result);
3664  switch (flags & PARSE_TYPE) {
3665  case PARSE_INT32:
3666  {
3667  long int x = 0;
3668  int32_t *result = p_result;
3669  int32_t def = result ? *result : 0, high = INT32_MAX, low = INT32_MIN;
3670  char *endptr = NULL;
3671 
3672  /* optional arguments: default value and/or (low, high) */
3673  if (flags & PARSE_DEFAULT) {
3674  def = va_arg(ap, int32_t);
3675  }
3676  if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
3677  low = va_arg(ap, int32_t);
3678  high = va_arg(ap, int32_t);
3679  }
3680  if (ast_strlen_zero(arg)) {
3681  error = 1;
3682  goto int32_done;
3683  }
3684  errno = 0;
3685  x = strtol(arg, &endptr, 0);
3686  if (*endptr || errno || x < INT32_MIN || x > INT32_MAX) {
3687  /* Parse error, or type out of int32_t bounds */
3688  error = 1;
3689  goto int32_done;
3690  }
3691  error = (x < low) || (x > high);
3692  if (flags & PARSE_RANGE_DEFAULTS) {
3693  if (x < low) {
3694  def = low;
3695  } else if (x > high) {
3696  def = high;
3697  }
3698  }
3699  if (flags & PARSE_OUT_RANGE) {
3700  error = !error;
3701  }
3702 int32_done:
3703  if (result) {
3704  *result = error ? def : x;
3705  }
3706 
3707  ast_debug(3, "extract int from [%s] in [%d, %d] gives [%ld](%d)\n",
3708  arg, low, high, result ? *result : x, error);
3709  break;
3710  }
3711 
3712  case PARSE_UINT32:
3713  {
3714  unsigned long int x = 0;
3715  uint32_t *result = p_result;
3716  uint32_t def = result ? *result : 0, low = 0, high = UINT32_MAX;
3717  char *endptr = NULL;
3718 
3719  /* optional argument: first default value, then range */
3720  if (flags & PARSE_DEFAULT) {
3721  def = va_arg(ap, uint32_t);
3722  }
3723  if (flags & (PARSE_IN_RANGE|PARSE_OUT_RANGE)) {
3724  /* range requested, update bounds */
3725  low = va_arg(ap, uint32_t);
3726  high = va_arg(ap, uint32_t);
3727  }
3728 
3729  if (ast_strlen_zero(arg)) {
3730  error = 1;
3731  goto uint32_done;
3732  }
3733  /* strtoul will happilly and silently negate negative numbers */
3734  arg = ast_skip_blanks(arg);
3735  if (*arg == '-') {
3736  error = 1;
3737  goto uint32_done;
3738  }
3739  errno = 0;
3740  x = strtoul(arg, &endptr, 0);
3741  if (*endptr || errno || x > UINT32_MAX) {
3742  error = 1;
3743  goto uint32_done;
3744  }
3745  error = (x < low) || (x > high);
3746  if (flags & PARSE_RANGE_DEFAULTS) {
3747  if (x < low) {
3748  def = low;
3749  } else if (x > high) {
3750  def = high;
3751  }
3752  }
3753  if (flags & PARSE_OUT_RANGE) {
3754  error = !error;
3755  }
3756 uint32_done:
3757  if (result) {
3758  *result = error ? def : x;
3759  }
3760  ast_debug(3, "extract uint from [%s] in [%u, %u] gives [%lu](%d)\n",
3761  arg, low, high, result ? *result : x, error);
3762  break;
3763  }
3764 
3765  case PARSE_TIMELEN:
3766  {
3767  int x = 0;
3768  int *result = p_result;
3769  int def = result ? *result : 0;
3770  int high = INT_MAX;
3771  int low = INT_MIN;
3772  enum ast_timelen defunit;
3773 
3774  defunit = va_arg(ap, enum ast_timelen);
3775  /* optional arguments: default value and/or (low, high) */
3776  if (flags & PARSE_DEFAULT) {
3777  def = va_arg(ap, int);
3778  }
3779  if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
3780  low = va_arg(ap, int);
3781  high = va_arg(ap, int);
3782  }
3783  if (ast_strlen_zero(arg)) {
3784  error = 1;
3785  goto timelen_done;
3786  }
3787  error = ast_app_parse_timelen(arg, &x, defunit);
3788  if (error || x < INT_MIN || x > INT_MAX) {
3789  /* Parse error, or type out of int bounds */
3790  error = 1;
3791  goto timelen_done;
3792  }
3793  error = (x < low) || (x > high);
3794  if (flags & PARSE_RANGE_DEFAULTS) {
3795  if (x < low) {
3796  def = low;
3797  } else if (x > high) {
3798  def = high;
3799  }
3800  }
3801  if (flags & PARSE_OUT_RANGE) {
3802  error = !error;
3803  }
3804 timelen_done:
3805  if (result) {
3806  *result = error ? def : x;
3807  }
3808 
3809  ast_debug(3, "extract timelen from [%s] in [%d, %d] gives [%d](%d)\n",
3810  arg, low, high, result ? *result : x, error);
3811  break;
3812  }
3813 
3814  case PARSE_DOUBLE:
3815  {
3816  double *result = p_result;
3817  double x = 0, def = result ? *result : 0, low = -HUGE_VAL, high = HUGE_VAL;
3818  char *endptr = NULL;
3819 
3820  /* optional argument: first default value, then range */
3821  if (flags & PARSE_DEFAULT) {
3822  def = va_arg(ap, double);
3823  }
3824  if (flags & (PARSE_IN_RANGE | PARSE_OUT_RANGE)) {
3825  /* range requested, update bounds */
3826  low = va_arg(ap, double);
3827  high = va_arg(ap, double);
3828  }
3829  if (ast_strlen_zero(arg)) {
3830  error = 1;
3831  goto double_done;
3832  }
3833  errno = 0;
3834  x = strtod(arg, &endptr);
3835  if (*endptr || errno == ERANGE) {
3836  error = 1;
3837  goto double_done;
3838  }
3839  error = (x < low) || (x > high);
3840  if (flags & PARSE_OUT_RANGE) {
3841  error = !error;
3842  }
3843 double_done:
3844  if (result) {
3845  *result = error ? def : x;
3846  }
3847  ast_debug(3, "extract double from [%s] in [%f, %f] gives [%f](%d)\n",
3848  arg, low, high, result ? *result : x, error);
3849  break;
3850  }
3851  case PARSE_ADDR:
3852  {
3853  struct ast_sockaddr *addr = (struct ast_sockaddr *)p_result;
3854 
3855  if (!ast_sockaddr_parse(addr, arg, flags & PARSE_PORT_MASK)) {
3856  error = 1;
3857  }
3858 
3859  ast_debug(3, "extract addr from %s gives %s(%d)\n",
3860  arg, ast_sockaddr_stringify(addr), error);
3861 
3862  break;
3863  }
3864  case PARSE_INADDR: /* TODO Remove this (use PARSE_ADDR instead). */
3865  {
3866  char *port, *buf;
3867  struct sockaddr_in _sa_buf; /* buffer for the result */
3868  struct sockaddr_in *sa = p_result ?
3869  (struct sockaddr_in *)p_result : &_sa_buf;
3870  /* default is either the supplied value or the result itself */
3871  struct sockaddr_in *def = (flags & PARSE_DEFAULT) ?
3872  va_arg(ap, struct sockaddr_in *) : sa;
3873  struct hostent *hp;
3874  struct ast_hostent ahp;
3875 
3876  memset(&_sa_buf, '\0', sizeof(_sa_buf)); /* clear buffer */
3877  /* duplicate the string to strip away the :port */
3878  port = ast_strdupa(arg);
3879  buf = strsep(&port, ":");
3880  sa->sin_family = AF_INET; /* assign family */
3881  /*
3882  * honor the ports flag setting, assign default value
3883  * in case of errors or field unset.
3884  */
3885  flags &= PARSE_PORT_MASK; /* the only flags left to process */
3886  if (port) {
3887  if (flags == PARSE_PORT_FORBID) {
3888  error = 1; /* port was forbidden */
3889  sa->sin_port = def->sin_port;
3890  } else if (flags == PARSE_PORT_IGNORE)
3891  sa->sin_port = def->sin_port;
3892  else /* accept or require */
3893  sa->sin_port = htons(strtol(port, NULL, 0));
3894  } else {
3895  sa->sin_port = def->sin_port;
3896  if (flags == PARSE_PORT_REQUIRE)
3897  error = 1;
3898  }
3899  /* Now deal with host part, even if we have errors before. */
3900  hp = ast_gethostbyname(buf, &ahp);
3901  if (hp) /* resolved successfully */
3902  memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr));
3903  else {
3904  error = 1;
3905  sa->sin_addr = def->sin_addr;
3906  }
3907  ast_debug(3,
3908  "extract inaddr from [%s] gives [%s:%d](%d)\n",
3909  arg, ast_inet_ntoa(sa->sin_addr),
3910  ntohs(sa->sin_port), error);
3911  break;
3912  }
3913  }
3914  va_end(ap);
3915  return error;
3916 }
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define UINT32_MAX
Definition: ast_expr2f.c:87
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
#define INT32_MAX
Definition: ast_expr2f.c:78
Socket address structure.
Definition: netsock2.h:97
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define INT32_MIN
Definition: ast_expr2f.c:69
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct ast_hostent ahp
Definition: chan_skinny.c:1235
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: main/utils.c:782
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
Definition: main/utils.c:197
char * strsep(char **str, const char *delims)
static PGresult * result
Definition: cel_pgsql.c:88
int error(const char *format,...)
Definition: utils/frame.c:999
int int32_t
Definition: db.h:60
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:3113
static struct hostent * hp
Definition: chan_skinny.c:1236

◆ ast_realtime_append_mapping()

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

Add an explicit mapping for a family.

Parameters
nameFamily name
driverDriver to use
databaseDatabase to access
tableTable to use
priorityPriority of this mapping

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

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

Referenced by load_module(), and reload_module().

2872 {
2873  struct ast_config_map *map;
2874  char *dst;
2875  int length;
2876 
2877  length = sizeof(*map);
2878  length += strlen(name) + 1;
2879  length += strlen(driver) + 1;
2880  length += strlen(database) + 1;
2881  if (table)
2882  length += strlen(table) + 1;
2883 
2884  if (!(map = ast_calloc(1, length)))
2885  return -1;
2886 
2887  dst = map->stuff; /* writable space starts here */
2888  map->name = strcpy(dst, name);
2889  dst += strlen(dst) + 1;
2890  map->driver = strcpy(dst, driver);
2891  dst += strlen(dst) + 1;
2892  map->database = strcpy(dst, database);
2893  if (table) {
2894  dst += strlen(dst) + 1;
2895  map->table = strcpy(dst, table);
2896  }
2897  map->priority = priority;
2898  map->next = config_maps;
2899  config_maps = map;
2900 
2901  ast_verb(2, "Binding %s to %s/%s/%s\n", map->name, map->driver, map->database, map->table ? map->table : map->name);
2902 
2903  return 0;
2904 }
struct ast_config_map * next
Definition: main/config.c:200
static int * map
Definition: misdn_config.c:438
const char * database
Definition: main/config.c:207
static struct ast_config_map * config_maps
const char * table
Definition: main/config.c:209
static int priority
#define ast_verb(level,...)
Definition: logger.h:463
static char * table
Definition: cdr_odbc.c:58
const char * name
Definition: main/config.c:203
static const char name[]
Definition: cdr_mysql.c:74
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
const char * driver
Definition: main/config.c:205

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

Referenced by realtime_multi_pgsql(), and realtime_pgsql().

3626 {
3627  char *orig = chunk;
3628  for (; *chunk; chunk++) {
3629  if (*chunk == '^' && strchr("0123456789ABCDEFabcdef", chunk[1]) && strchr("0123456789ABCDEFabcdef", chunk[2])) {
3630  sscanf(chunk + 1, "%02hhX", (unsigned char *)chunk);
3631  memmove(chunk + 1, chunk + 3, strlen(chunk + 3) + 1);
3632  }
3633  }
3634  return orig;
3635 }

◆ ast_realtime_enabled()

int ast_realtime_enabled ( void  )

Check if there's any realtime engines loaded.

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

References config_maps.

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

3378 {
3379  return config_maps ? 1 : 0;
3380 }
static struct ast_config_map * config_maps

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

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

3638 {
3639  if (!strchr(chunk, ';') && !strchr(chunk, '^')) {
3640  ast_str_set(dest, maxlen, "%s", chunk);
3641  } else {
3642  ast_str_reset(*dest);
3643  for (; *chunk; chunk++) {
3644  if (strchr(";^", *chunk)) {
3645  ast_str_append(dest, maxlen, "^%02hhX", *chunk);
3646  } else {
3647  ast_str_append(dest, maxlen, "%c", *chunk);
3648  }
3649  }
3650  }
3651  return ast_str_buffer(*dest);
3652 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
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:1091
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:1065
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:653

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

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

Referenced by ast_named_acl_find(), and sorcery_realtime_open().

3027 {
3028  struct ast_config_map *map;
3030 
3031  for (map = config_maps; map; map = map->next) {
3032  if (!strcasecmp(family, map->name)) {
3033  return 1;
3034  }
3035  }
3036  ast_debug(5, "Failed to find a realtime mapping for %s\n", family);
3037 
3038  return 0;
3039 }
struct ast_config_map * next
Definition: main/config.c:200
static int * map
Definition: misdn_config.c:438
static struct ast_config_map * config_maps
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t config_lock
Definition: main/config.c:214
const char * name
Definition: main/config.c:203

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

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

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

3383 {
3384  struct ast_config_engine *eng;
3385  char db[256];
3386  char table[256];
3387  va_list ap;
3388  int res = -1, i;
3389 
3390  va_start(ap, family);
3391  for (i = 1; ; i++) {
3392  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3393  /* If the require succeeds, it returns 0. */
3394  if (eng->require_func && !(res = eng->require_func(db, table, ap))) {
3395  break;
3396  }
3397  } else {
3398  break;
3399  }
3400  }
3401  va_end(ap);
3402 
3403  return res;
3404 }
static sqlite3 * db
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
realtime_require * require_func
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:3042

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

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

3571 {
3572  RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3573  va_list ap;
3574 
3575  va_start(ap, family);
3576  realtime_arguments_to_fields(ap, &fields);
3577  va_end(ap);
3578 
3579  if (!fields) {
3580  return -1;
3581  }
3582 
3583  return ast_store_realtime_fields(family, fields);
3584 }
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3170
#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:911
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591
int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
Create realtime configuration.
Definition: main/config.c:3549

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

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

Referenced by ast_store_realtime(), and sorcery_realtime_create().

3550 {
3551  struct ast_config_engine *eng;
3552  int res = -1, i;
3553  char db[256];
3554  char table[256];
3555 
3556  for (i = 1; ; i++) {
3557  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3558  /* If the store succeeds, it returns >= 0*/
3559  if (eng->store_func && ((res = eng->store_func(db, table, fields)) >= 0)) {
3560  break;
3561  }
3562  } else {
3563  break;
3564  }
3565  }
3566 
3567  return res;
3568 }
static sqlite3 * db
realtime_store * store_func
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
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:3042

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

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

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

3407 {
3408  struct ast_config_engine *eng;
3409  char db[256];
3410  char table[256];
3411  int res = -1, i;
3412 
3413  for (i = 1; ; i++) {
3414  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3415  if (eng->unload_func) {
3416  /* Do this for ALL engines */
3417  res = eng->unload_func(db, table);
3418  }
3419  } else {
3420  break;
3421  }
3422  }
3423  return res;
3424 }
static sqlite3 * db
realtime_unload * unload_func
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
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:3042

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

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

3526 {
3527  RAII_VAR(struct ast_variable *, lookup_fields, NULL, ast_variables_destroy);
3528  RAII_VAR(struct ast_variable *, update_fields, NULL, ast_variables_destroy);
3529  va_list ap;
3530 
3531  va_start(ap, family);
3532  /* XXX: If we wanted to pass no lookup fields (select all), we'd be
3533  * out of luck. realtime_arguments_to_fields expects at least one key
3534  * value pair. */
3535  realtime_arguments_to_fields(ap, &lookup_fields);
3536  va_end(ap);
3537 
3538  va_start(ap, family);
3539  realtime_arguments_to_fields2(ap, 1, &update_fields);
3540  va_end(ap);
3541 
3542  if (!lookup_fields || !update_fields) {
3543  return -1;
3544  }
3545 
3546  return ast_update2_realtime_fields(family, lookup_fields, update_fields);
3547 }
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:3505
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3170
static int realtime_arguments_to_fields2(va_list ap, int skip, struct ast_variable **result)
Definition: main/config.c:3185
#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:911
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591

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

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

Referenced by ast_update2_realtime().

3506 {
3507  struct ast_config_engine *eng;
3508  int res = -1, i;
3509  char db[256];
3510  char table[256];
3511 
3512  for (i = 1; ; i++) {
3513  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3514  if (eng->update2_func && !(res = eng->update2_func(db, table, lookup_fields, update_fields))) {
3515  break;
3516  }
3517  } else {
3518  break;
3519  }
3520  }
3521 
3522  return res;
3523 }
static sqlite3 * db
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
realtime_update2 * update2_func
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:3042

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

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

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

3490 {
3491  RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
3492  va_list ap;
3493 
3494  va_start(ap, lookup);
3495  realtime_arguments_to_fields(ap, &fields);
3496  va_end(ap);
3497 
3498  if (!fields) {
3499  return -1;
3500  }
3501 
3502  return ast_update_realtime_fields(family, keyfield, lookup, fields);
3503 }
Structure for variables, used for configurations and for channel variables.
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:3468
#define NULL
Definition: resample.c:96
#define realtime_arguments_to_fields(ap, result)
Definition: main/config.c:3170
#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:911
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591

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

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

Referenced by ast_update_realtime(), and sorcery_realtime_update().

3469 {
3470  struct ast_config_engine *eng;
3471  int res = -1, i;
3472  char db[256];
3473  char table[256];
3474 
3475  for (i = 1; ; i++) {
3476  if ((eng = find_engine(family, i, db, sizeof(db), table, sizeof(table)))) {
3477  /* If the update succeeds, it returns >= 0. */
3478  if (eng->update_func && ((res = eng->update_func(db, table, keyfield, lookup, fields)) >= 0)) {
3479  break;
3480  }
3481  } else {
3482  break;
3483  }
3484  }
3485 
3486  return res;
3487 }
static sqlite3 * db
realtime_update * update_func
Configuration engine structure, used to define realtime drivers.
static char * table
Definition: cdr_odbc.c:58
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:3042

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

References ast_category_get(), ast_config::last_browse, ast_category::name, 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(), ast_xmldoc_load_documentation(), build_calendar(), build_device(), caldav_load_calendar(), conf_exec(), config_load(), config_module(), do_reload(), do_say(), ewscal_load_calendar(), exchangecal_load_calendar(), find_conf(), get_defaults(), handle_cli_dialplan_save(), iax_template_parse(), ical_load_calendar(), init_logger_chain(), load_aliases(), load_asterisk_conf(), load_config(), load_general_config(), load_module(), load_moh_classes(), load_odbc_config(), load_pktccops_config(), load_users(), load_values_config(), load_zonemessages(), loader_config_init(), mbl_load_adapter(), mbl_load_config(), mbl_load_device(), misdn_cfg_init(), my_connect_db(), my_load_module(), new_realtime_sqlite3_db(), odbc_load_module(), osp_create_provider(), 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(), sip_cli_notify(), sla_build_station(), sla_build_trunk(), smdi_load(), store_config(), tds_load_module(), and test_config_validity().

603 {
604  struct ast_category *cat;
605 
606  if (config->last_browse && (config->last_browse->name == category)) {
607  cat = config->last_browse;
608  } else {
609  cat = ast_category_get(config, category, NULL);
610  }
611 
612  return (cat) ? cat->root : NULL;
613 }
#define NULL
Definition: resample.c:96
struct ast_variable * root
Definition: main/config.c:240
struct ast_category * last_browse
Definition: main/config.c:255
char name[80]
Definition: main/config.c:226
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:1022

◆ ast_variable_delete()

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

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

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

Referenced by handle_updates().

1400 {
1401  struct ast_variable *cur, *prev=NULL, *curn;
1402  int res = -1;
1403  int num_item = 0;
1404  int req_item;
1405 
1406  req_item = -1;
1407  if (!ast_strlen_zero(line)) {
1408  /* Requesting to delete by item number. */
1409  if (sscanf(line, "%30d", &req_item) != 1
1410  || req_item < 0) {
1411  /* Invalid item number to delete. */
1412  return -1;
1413  }
1414  }
1415 
1416  prev = NULL;
1417  cur = category->root;
1418  while (cur) {
1419  curn = cur->next;
1420  /* Delete by item number or by variable name with optional value. */
1421  if ((0 <= req_item && num_item == req_item)
1422  || (req_item < 0 && !strcasecmp(cur->name, variable)
1423  && (ast_strlen_zero(match) || !strcasecmp(cur->value, match)))) {
1424  if (prev) {
1425  prev->next = cur->next;
1426  if (cur == category->last)
1427  category->last = prev;
1428  } else {
1429  category->root = cur->next;
1430  if (cur == category->last)
1431  category->last = NULL;
1432  }
1433  ast_variable_destroy(cur);
1434  res = 0;
1435  } else
1436  prev = cur;
1437 
1438  cur = curn;
1439  ++num_item;
1440  }
1441  return res;
1442 }
struct ast_variable * next
static void ast_variable_destroy(struct ast_variable *doomed)
Definition: main/config.c:537
Structure for variables, used for configurations and for channel variables.
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:2315
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_variable * root
Definition: main/config.c:240
struct ast_variable * last
Definition: main/config.c:242

◆ ast_variable_destroy()

static void ast_variable_destroy ( struct ast_variable doomed)
static

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

References ast_comment_destroy(), ast_free, ast_variable::precomments, ast_variable::sameline, and ast_variable::trailing.

Referenced by ast_include_rename(), ast_load_realtime_fields(), ast_variable_delete(), ast_variable_update(), and ast_variables_destroy().

538 {
540  ast_comment_destroy(&doomed->sameline);
541  ast_comment_destroy(&doomed->trailing);
542  ast_free(doomed);
543 }
struct ast_comment * sameline
struct ast_comment * trailing
struct ast_comment * precomments
static void ast_comment_destroy(struct ast_comment **comment)
Definition: main/config.c:525
#define ast_free(a)
Definition: astmm.h:182

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

References ast_variable_find_in_list(), and ast_category::root.

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

736 {
737  return ast_variable_find_in_list(category->root, variable);
738 }
struct ast_variable * root
Definition: main/config.c:240
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:830

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

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

Referenced by ast_ari_callback(), ast_sorcery_changeset_create(), AST_TEST_DEFINE(), ast_variable_find(), handle_export_primitives(), and load_realtime_musiconhold().

831 {
832  const struct ast_variable *v;
833 
834  for (v = list; v; v = v->next) {
835  if (!strcasecmp(variable, v->name)) {
836  return v->value;
837  }
838  }
839  return NULL;
840 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96

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

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

843 {
844  const struct ast_variable *v;
845  const char *found = NULL;
846 
847  for (v = list; v; v = v->next) {
848  if (!strcasecmp(variable, v->name)) {
849  found = v->value;
850  }
851  }
852  return found;
853 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96

◆ 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
variablename 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 740 of file main/config.c.

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

Referenced by ast_variable_lists_match(), and realtime_sorcery_store().

741 {
742  const struct ast_variable *v;
743 
744  for (v = list; v; v = v->next) {
745  if (!strcasecmp(variable_name, v->name)) {
746  return v;
747  }
748  }
749  return NULL;
750 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96

◆ ast_variable_insert()

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

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

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

Referenced by AST_TEST_DEFINE(), and handle_updates().

502 {
503  struct ast_variable *cur = category->root;
504  int lineno;
505  int insertline;
506 
507  if (!variable || sscanf(line, "%30d", &insertline) != 1) {
508  return;
509  }
510  if (!insertline) {
511  variable->next = category->root;
512  category->root = variable;
513  } else {
514  for (lineno = 1; lineno < insertline; lineno++) {
515  cur = cur->next;
516  if (!cur->next) {
517  break;
518  }
519  }
520  variable->next = cur->next;
521  cur->next = variable;
522  }
523 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
struct ast_variable * root
Definition: main/config.c:240

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

References ast_assert, ast_variable::next, and NULL.

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

649 {
650  struct ast_variable *curr;
651  ast_assert(head != NULL);
652 
653  if (!*head) {
654  *head = newvar;
655  } else {
656  if (search_hint == NULL) {
657  search_hint = *head;
658  }
659  for (curr = search_hint; curr->next; curr = curr->next);
660  curr->next = newvar;
661  }
662 
663  for (curr = newvar; curr->next; curr = curr->next);
664 
665  return curr;
666 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96

◆ ast_variable_list_replace()

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

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

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

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

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

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

669 {
670  struct ast_variable *v, **prev = head;
671 
672  for (v = *head; v; prev = &v->next, v = v->next) {
673  if (!strcmp(v->name, replacement->name)) {
674  replacement->next = v->next;
675  *prev = replacement;
676  ast_free(v);
677  return 0;
678  }
679  }
680 
681  return -1;
682 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define ast_free(a)
Definition: astmm.h:182

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

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

Referenced by ast_sip_cli_print_sorcery_objectset(), and stir_shaken_cli_show().

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

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

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

773 {
774  const struct ast_variable *field;
775  int right_count = 0;
776  int left_count = 0;
777 
778  if (left == right) {
779  return 1;
780  }
781 
782  if (!(left && right)) {
783  return 0;
784  }
785 
786  for (field = right; field; field = field->next) {
787  char *space = strrchr(field->name, ' ');
788  const struct ast_variable *old;
789  char * name = (char *)field->name;
790 
791  if (space) {
792  name = ast_strdup(field->name);
793  if (!name) {
794  return 0;
795  }
796  name[space - field->name] = '\0';
797  }
798 
799  old = ast_variable_find_variable_in_list(left, name);
800  if (name != field->name) {
801  ast_free(name);
802  }
803 
804  if (exact_match) {
805  if (!old || strcmp(old->value, field->value)) {
806  return 0;
807  }
808  } else {
809  if (!ast_variables_match(old, field)) {
810  return 0;
811  }
812  }
813 
814  right_count++;
815  }
816 
817  if (exact_match) {
818  for (field = left; field; field = field->next) {
819  left_count++;
820  }
821 
822  if (right_count != left_count) {
823  return 0;
824  }
825  }
826 
827  return 1;
828 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
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:752
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
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:740

◆ ast_variable_move()

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

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

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

325 {
326  dst_var->lineno = src_var->lineno;
327  dst_var->object = src_var->object;
328  dst_var->blanklines = src_var->blanklines;
329  dst_var->precomments = src_var->precomments;
330  src_var->precomments = NULL;
331  dst_var->sameline = src_var->sameline;
332  src_var->sameline = NULL;
333  dst_var->trailing = src_var->trailing;
334  src_var->trailing = NULL;
335 }
struct ast_comment * sameline
#define NULL
Definition: resample.c:96
struct ast_comment * trailing
struct ast_comment * precomments

◆ ast_variable_retrieve()

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

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

References ast_variable_browse(), ast_variable::name, ast_variable::next, ast_category::next, NULL, ast_category::root, ast_config::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(), conf_exec(), config_module(), directory_exec(), festival_exec(), find_realtime(), forward_message(), get_defaults(), get_insecure_variable_from_config(), get_insecure_variable_from_sipregs(), iax_template_parse(), ineligible_configuration(), 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_rules(), load_tech_calendars(), load_values_config(), loader_config_init(), make_email_file(), mbl_load_adapter(), mbl_load_device(), message_range_and_existence_check(), my_load_config_number(), my_load_config_string(), named_acl_find_realtime(), notify_new_message(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), 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_allocate_dh(), vm_change_password(), vm_forwardoptions(), vm_msg_forward(), vm_msg_play(), and vm_msg_snapshot_create().

695 {
696  struct ast_variable *v;
697 
698  if (category) {
699  for (v = ast_variable_browse(config, category); v; v = v->next) {
700  if (!strcasecmp(variable, v->name)) {
701  return v->value;
702  }
703  }
704  } else {
705  struct ast_category *cat;
706 
707  for (cat = config->root; cat; cat = cat->next) {
708  for (v = cat->root; v; v = v->next) {
709  if (!strcasecmp(variable, v->name)) {
710  return v->value;
711  }
712  }
713  }
714  }
715 
716  return NULL;
717 }
struct ast_variable * next
struct ast_category * next
Definition: main/config.c:246
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
struct ast_variable * root
Definition: main/config.c:240
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Definition: main/config.c:602
struct ast_category * root
Definition: main/config.c:251

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

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

721 {
722  struct ast_category *cat = NULL;
723  const char *value;
724 
725  while ((cat = ast_category_browse_filtered(config, category, cat, filter))) {
726  value = ast_variable_find(cat, variable);
727  if (value) {
728  return value;
729  }
730  }
731 
732  return NULL;
733 }
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
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:735
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709
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:1335

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

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

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

1446 {
1447  struct ast_variable *cur, *prev=NULL, *newer=NULL;
1448 
1449  for (cur = category->root; cur; prev = cur, cur = cur->next) {
1450  if (strcasecmp(cur->name, variable) ||
1451  (!ast_strlen_zero(match) && strcasecmp(cur->value, match)))
1452  continue;
1453 
1454  if (!(newer = ast_variable_new(variable, value, cur->file)))
1455  return -1;
1456 
1457  ast_variable_move(newer, cur);
1458  newer->object = newer->object || object;
1459 
1460  /* Replace the old node in the list with the new node. */
1461  newer->next = cur->next;
1462  if (prev)
1463  prev->next = newer;
1464  else
1465  category->root = newer;
1466  if (category->last == cur)
1467  category->last = newer;
1468 
1469  ast_variable_destroy(cur);
1470 
1471  return 0;
1472  }
1473 
1474  /* Could not find variable to update */
1475  return -1;
1476 }
struct ast_variable * next
static void ast_variable_destroy(struct ast_variable *doomed)
Definition: main/config.c:537
Structure for variables, used for configurations and for channel variables.
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:2315
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_variable_new(name, value, filename)
struct ast_variable * root
Definition: main/config.c:240
struct ast_variable * last
Definition: main/config.c:242
static void ast_variable_move(struct ast_variable *dst_var, struct ast_variable *src_var)
Definition: main/config.c:324

◆ ast_variables_destroy()

void ast_variables_destroy ( struct ast_variable v)

Free variable list.

Parameters
varthe linked list of variables to free

This function frees a list of variables.

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

References ast_variable_destroy(), and ast_variable::next.

Referenced by __init_manager(), aco_set_defaults(), action_messagesend(), action_originate(), add_message_id(), announce_to_dial(), ast_ari_asterisk_update_object(), ast_ari_callback(), ast_ari_channels_originate(), ast_ari_channels_originate_with_id(), 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_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_variables_dup(), auth_http_callback(), build_gateway(), build_peer(), calendar_destructor(), can_reuse_registration(), check_expiration_thread(), check_peer_ok(), cli_contact_get_container(), cli_realtime_load(), conf_run(), copy_plain_file(), create_mwi_subscriptions(), destroy_dahdi_pvt(), destroy_endpoint(), 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_realtime_gw(), find_user_realtime(), free_entry(), free_outgoing(), free_user(), function_realtime_read(), function_realtime_readdestroy(), generic_http_callback(), get_insecure_variable_from_sipregs(), 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_notify_channel(), manager_notify_endpoint(), manager_notify_uri(), manager_sipnotify(), 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_handler(), realtime_ldap_base(), realtime_ldap_base_ap(), realtime_ldap_result_to_vars(), realtime_matchmore(), realtime_odbc(), realtime_peer(), realtime_peer_by_addr(), realtime_peer_by_name(), realtime_peer_get_sippeer_helper(), realtime_user(), realtimefield_read(), registration_deleted_observer(), return_sorcery_object(), row_to_varlist(), rt_extend_conf(), session_destructor(), sip_aor_to_ami(), sip_destroy_peer(), sip_pvt_dtor(), 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(), stir_shaken_cli_show(), table_configs_free(), test_sorcery_object_destroy(), test_sorcery_transform(), transport_apply(), update_ldap(), user_destructor(), and vm_allocate_dh().

592 {
593  struct ast_variable *vn;
594 
595  while (v) {
596  vn = v;
597  v = v->next;
599  }
600 }
struct ast_variable * next
static void ast_variable_destroy(struct ast_variable *doomed)
Definition: main/config.c:537
Structure for variables, used for configurations and for channel variables.

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

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

Referenced by action_originate(), ast_ari_callback(), ast_config_copy(), authenticate(), get_insecure_variable_from_sippeers(), get_insecure_variable_from_sipregs(), 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().

546 {
547  struct ast_variable *cloned;
548  struct ast_variable *tmp;
549 
550  if (!(cloned = ast_variable_new(var->name, var->value, var->file))) {
551  return NULL;
552  }
553 
554  tmp = cloned;
555 
556  while ((var = var->next)) {
557  if (!(tmp->next = ast_variable_new(var->name, var->value, var->file))) {
558  ast_variables_destroy(cloned);
559  return NULL;
560  }
561  tmp = tmp->next;
562  }
563 
564  return cloned;
565 }
struct ast_variable * next
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591

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

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

Referenced by ast_variable_lists_match().

753 {
754  char *op;
755 
756  if (left == right) {
757  return 1;
758  }
759 
760  if (!(left && right)) {
761  return 0;
762  }
763 
764  op = strrchr(right->name, ' ');
765  if (op) {
766  op++;
767  }
768 
769  return ast_strings_match(left->value, op ? ast_strdupa(op) : NULL, right->value);
770 }
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_strings_match(const char *left, const char *op, const char *right)
Compares 2 strings using realtime-style operators.
Definition: strings.c:248

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

References ast_comment::next, ast_variable::next, NULL, and var.

Referenced by astman_get_variables_order().

568 {
569  struct ast_variable *var1, *var2;
570 
571  var1 = var;
572 
573  if (!var1 || !var1->next) {
574  return var1;
575  }
576 
577  var2 = var1->next;
578  var1->next = NULL;
579 
580  while (var2) {
581  struct ast_variable *next = var2->next;
582 
583  var2->next = var1;
584  var1 = var2;
585  var2 = next;
586  }
587 
588  return var1;
589 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96

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

References does_category_match(), ast_category::name, ast_category::next, NULL, and ast_config::root.

Referenced by ast_category_get(), and process_text_line().

1002 {
1003  struct ast_category *cat;
1004 
1005  if (pointer_match_possible) {
1006  for (cat = config->root; cat; cat = cat->next) {
1007  if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) {
1008  return cat;
1009  }
1010  }
1011  }
1012 
1013  for (cat = config->root; cat; cat = cat->next) {
1014  if (does_category_match(cat, category_name, filter, sep)) {
1015  return cat;
1016  }
1017  }
1018 
1019  return NULL;
1020 }
struct ast_category * next
Definition: main/config.c:246
#define NULL
Definition: resample.c:96
char name[80]
Definition: main/config.c:226
struct ast_category * root
Definition: main/config.c:251
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709
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:881

◆ CB_ADD()

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

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

References ast_str_append().

Referenced by config_text_file_load().

130 {
131  ast_str_append(cb, 0, "%s", str);
132 }
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:1091
const char * str
Definition: app_jack.c:147

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

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

Referenced by config_text_file_load().

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 }
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:1091
const char * str
Definition: app_jack.c:147
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ CB_RESET()

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

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

References ast_str_reset().

Referenced by config_text_file_load(), and process_text_line().

144 {
145  if (cb) {
146  ast_str_reset(cb);
147  }
148  if (llb) {
149  ast_str_reset(llb);
150  }
151 }
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:653

◆ cfmstat_cmp()

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

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

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

1619 {
1620  struct cache_file_mtime cfm_buf;
1621 
1622  cfmstat_save(&cfm_buf, statbuf);
1623 
1624  return cfmtime->stat_size != cfm_buf.stat_size
1625  || cfmtime->stat_mtime != cfm_buf.stat_mtime
1626  || cfmtime->stat_mtime_nsec != cfm_buf.stat_mtime_nsec;
1627 }
static void cfmstat_save(struct cache_file_mtime *cfmtime, struct stat *statbuf)
Definition: main/config.c:1594
unsigned long stat_size
Definition: main/config.c:102
unsigned long stat_mtime_nsec
Definition: main/config.c:104

◆ cfmstat_save()

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

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

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

1595 {
1596  cfmtime->stat_size = statbuf->st_size;
1597 #if defined(HAVE_STRUCT_STAT_ST_MTIM)
1598  cfmtime->stat_mtime_nsec = statbuf->st_mtim.tv_nsec;
1599 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
1600  cfmtime->stat_mtime_nsec = statbuf->st_mtimensec;
1601 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
1602  cfmtime->stat_mtime_nsec = statbuf->st_mtimespec.tv_nsec;
1603 #else
1604  cfmtime->stat_mtime_nsec = 0;
1605 #endif
1606  cfmtime->stat_mtime = statbuf->st_mtime;
1607 }
unsigned long stat_size
Definition: main/config.c:102
unsigned long stat_mtime_nsec
Definition: main/config.c:104

◆ cfmtime_new()

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

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

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

Referenced by config_cache_attribute(), and config_text_file_load().

1563 {
1564  struct cache_file_mtime *cfmtime;
1565  char *dst;
1566 
1567  cfmtime = ast_calloc(1,
1568  sizeof(*cfmtime) + strlen(filename) + 1 + strlen(who_asked) + 1);
1569  if (!cfmtime) {
1570  return NULL;
1571  }
1572  dst = cfmtime->filename; /* writable space starts here */
1573  strcpy(dst, filename); /* Safe */
1574  dst += strlen(dst) + 1;
1575  cfmtime->who_asked = strcpy(dst, who_asked); /* Safe */
1576 
1577  return cfmtime;
1578 }
#define NULL
Definition: resample.c:96
const char * who_asked
Definition: main/config.c:109
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ clear_config_maps()

static void clear_config_maps ( void  )
static

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

References ast_free, config_maps, map, and ast_config_map::next.

Referenced by config_shutdown(), and reload_module().

2857 {
2858  struct ast_config_map *map;
2859 
2860  while (config_maps) {
2861  map = config_maps;
2863  ast_free(map);
2864  }
2865 }
struct ast_config_map * next
Definition: main/config.c:200
static int * map
Definition: misdn_config.c:438
static struct ast_config_map * config_maps
#define ast_free(a)
Definition: astmm.h:182

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

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

1691 {
1692  struct cache_file_mtime *cfmtime;
1693  struct cache_file_include *cfinclude;
1694 
1695  /* Find our cached entry for this configuration file */
1697  AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
1698  if (!strcmp(cfmtime->filename, configfile) && !strcmp(cfmtime->who_asked, who_asked))
1699  break;
1700  }
1701  if (!cfmtime) {
1702  cfmtime = cfmtime_new(configfile, who_asked);
1703  if (!cfmtime) {
1705  return;
1706  }
1707  /* Note that the file mtime is initialized to 0, i.e. 1970 */
1708  AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
1709  }
1710 
1711  switch (attrtype) {
1712  case ATTRIBUTE_INCLUDE:
1713  AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
1714  if (!strcmp(cfinclude->include, filename)) {
1716  return;
1717  }
1718  }
1719  cfinclude = ast_calloc(1, sizeof(*cfinclude) + strlen(filename) + 1);
1720  if (!cfinclude) {
1722  return;
1723  }
1724  strcpy(cfinclude->include, filename); /* Safe */
1725  AST_LIST_INSERT_TAIL(&cfmtime->includes, cfinclude, list);
1726  break;
1727  case ATTRIBUTE_EXEC:
1728  cfmtime->has_exec = 1;
1729  break;
1730  }
1732 }
unsigned int has_exec
Definition: main/config.c:100
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Hold the mtime for config files, so if we don&#39;t need to reread our config, don&#39;t. ...
Definition: main/config.c:91
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield)
Inserts a list entry into a alphabetically sorted list.
Definition: linkedlists.h:750
const char * who_asked
Definition: main/config.c:109
struct cache_file_include::@373 list
struct cache_file_mtime::includes includes
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static struct cache_file_mtime * cfmtime_new(const char *filename, const char *who_asked)
Definition: main/config.c:1562

◆ config_cache_destroy_entry()

static void config_cache_destroy_entry ( struct cache_file_mtime cfmtime)
static

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

References ast_free, and config_cache_flush_includes().

Referenced by config_cache_remove(), and config_shutdown().

1659 {
1660  config_cache_flush_includes(cfmtime);
1661  ast_free(cfmtime);
1662 }
static void config_cache_flush_includes(struct cache_file_mtime *cfmtime)
Definition: main/config.c:1639
#define ast_free(a)
Definition: astmm.h:182

◆ config_cache_flush_includes()

static void config_cache_flush_includes ( struct cache_file_mtime cfmtime)
static

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

References ast_free, AST_LIST_REMOVE_HEAD, and cache_file_mtime::includes.

Referenced by config_cache_destroy_entry(), and config_text_file_load().

1640 {
1641  struct cache_file_include *cfinclude;
1642 
1643  while ((cfinclude = AST_LIST_REMOVE_HEAD(&cfmtime->includes, list))) {
1644  ast_free(cfinclude);
1645  }
1646 }
Hold the mtime for config files, so if we don&#39;t need to reread our config, don&#39;t. ...
Definition: main/config.c:91
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct cache_file_include::@373 list
struct cache_file_mtime::includes includes
#define ast_free(a)
Definition: astmm.h:182

◆ config_cache_remove()

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

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

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

1674 {
1675  struct cache_file_mtime *cfmtime;
1676 
1679  if (!strcmp(cfmtime->filename, filename)
1680  && !strcmp(cfmtime->who_asked, who_asked)) {
1682  config_cache_destroy_entry(cfmtime);
1683  break;
1684  }
1685  }
1688 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
const char * who_asked
Definition: main/config.c:109
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
static void config_cache_destroy_entry(struct cache_file_mtime *cfmtime)
Definition: main/config.c:1658
struct cache_file_mtime::@374 list
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ config_hook_exec()

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

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

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

Referenced by ast_config_internal_load(), and ast_config_text_file_save2().

4114 {
4115  struct ao2_iterator it;
4116  struct cfg_hook *hook;
4117  if (!(cfg_hooks)) {
4118  return;
4119  }
4120  it = ao2_iterator_init(cfg_hooks, 0);
4121  while ((hook = ao2_iterator_next(&it))) {
4122  if (!strcasecmp(hook->filename, filename) &&
4123  !strcasecmp(hook->module, module)) {
4124  struct ast_config *copy = ast_config_copy(cfg);
4125  hook->hook_cb(copy);
4126  }
4127  ao2_ref(hook, -1);
4128  }
4129  ao2_iterator_destroy(&it);
4130 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int copy(char *infile, char *outfile)
Utility function to copy a file.
config_hook_cb hook_cb
Definition: main/config.c:4078
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct ao2_container * cfg_hooks
Definition: main/config.c:77
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ast_config * ast_config_copy(const struct ast_config *old)
Copies the contents of one ast_config into another.
Definition: main/config.c:3079
const char * filename
Definition: main/config.c:4076
const char * module
Definition: main/config.c:4077
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ config_shutdown()

static void config_shutdown ( void  )
static

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

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

Referenced by register_config_cli().

4049 {
4050  struct cache_file_mtime *cfmtime;
4051 
4053  while ((cfmtime = AST_LIST_REMOVE_HEAD(&cfmtime_head, list))) {
4054  config_cache_destroy_entry(cfmtime);
4055  }
4057 
4059 
4061 
4063  cfg_hooks = NULL;
4064 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void clear_config_maps(void)
Definition: main/config.c:2856
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define NULL
Definition: resample.c:96
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
static struct ao2_container * cfg_hooks
Definition: main/config.c:77
static void config_cache_destroy_entry(struct cache_file_mtime *cfmtime)
Definition: main/config.c:1658
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct cache_file_mtime::@374 list
static struct ast_cli_entry cli_config[]
Definition: main/config.c:4042

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

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

2043 {
2044  char fn[256];
2045 #if defined(LOW_MEMORY)
2046  char buf[512];
2047 #else
2048  char buf[8192];
2049 #endif
2050  char *new_buf, *comment_p, *process_buf;
2051  FILE *f;
2052  int lineno=0;
2053  int comment = 0, nest[MAX_NESTED_COMMENTS];
2054  struct ast_category *cat = NULL;
2055  int count = 0;
2056  struct stat statbuf;
2057  struct cache_file_mtime *cfmtime = NULL;
2058  struct cache_file_include *cfinclude;
2059  struct ast_variable *last_var = NULL;
2060  struct ast_category *last_cat = NULL;
2061  /*! Growable string buffer */
2062  struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/
2063  struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */
2064  int glob_ret;
2065  glob_t globbuf;
2066 
2067  if (cfg) {
2069  }
2070 
2071  if (filename[0] == '/') {
2072  ast_copy_string(fn, filename, sizeof(fn));
2073  } else {
2074  snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
2075  }
2076 
2077  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
2078  comment_buffer = ast_str_create(CB_SIZE);
2079  if (comment_buffer) {
2080  lline_buffer = ast_str_create(CB_SIZE);
2081  }
2082  if (!lline_buffer) {
2083  ast_free(comment_buffer);
2084  ast_log(LOG_ERROR, "Failed to initialize the comment buffer!\n");
2085  return NULL;
2086  }
2087  }
2088 
2089  globbuf.gl_offs = 0; /* initialize it to silence gcc */
2090  glob_ret = glob(fn, MY_GLOB_FLAGS, NULL, &globbuf);
2091  if (glob_ret == GLOB_NOSPACE) {
2093  "Glob Expansion of pattern '%s' failed: Not enough memory\n", fn);
2094  } else if (glob_ret == GLOB_ABORTED) {
2096  "Glob Expansion of pattern '%s' failed: Read error\n", fn);
2097  } else {
2098  /* loop over expanded files */
2099  int i;
2100 
2101  if (!cfg && (globbuf.gl_pathc != 1 || strcmp(fn, globbuf.gl_pathv[0]))) {
2102  /*
2103  * We just want a file changed answer and since we cannot
2104  * tell if a file was deleted with wildcard matching we will
2105  * assume that something has always changed. Also without
2106  * a lot of refactoring we couldn't check more than one file
2107  * for changes in the glob loop anyway.
2108  */
2109  globfree(&globbuf);
2110  ast_free(comment_buffer);
2111  ast_free(lline_buffer);
2112  return NULL;
2113  }
2114  for (i=0; i<globbuf.gl_pathc; i++) {
2115  ast_copy_string(fn, globbuf.gl_pathv[i], sizeof(fn));
2116 
2117  /*
2118  * The following is not a loop, but just a convenient way to define a block
2119  * (using do { } while(0) ), and be able to exit from it with 'continue'
2120  * or 'break' in case of errors. Nice trick.
2121  */
2122  do {
2123  if (stat(fn, &statbuf)) {
2124  if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
2125  config_cache_remove(fn, who_asked);
2126  }
2127  continue;
2128  }
2129 
2130  if (!S_ISREG(statbuf.st_mode)) {
2131  ast_log(LOG_WARNING, "'%s' is not a regular file, ignoring\n", fn);
2132  if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
2133  config_cache_remove(fn, who_asked);
2134  }
2135  continue;
2136  }
2137 
2138  if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE)) {
2139  /* Find our cached entry for this configuration file */
2141  AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
2142  if (!strcmp(cfmtime->filename, fn) && !strcmp(cfmtime->who_asked, who_asked)) {
2143  break;
2144  }
2145  }
2146  if (!cfmtime) {
2147  cfmtime = cfmtime_new(fn, who_asked);
2148  if (!cfmtime) {
2150  continue;
2151  }
2152  /* Note that the file mtime is initialized to 0, i.e. 1970 */
2153  AST_LIST_INSERT_SORTALPHA(&cfmtime_head, cfmtime, list, filename);
2154  }
2155  }
2156 
2157  if (cfmtime
2158  && !cfmtime->has_exec
2159  && !cfmstat_cmp(cfmtime, &statbuf)
2161  int unchanged = 1;
2162 
2163  /* File is unchanged, what about the (cached) includes (if any)? */
2164  AST_LIST_TRAVERSE(&cfmtime->includes, cfinclude, list) {
2165  if (!config_text_file_load(NULL, NULL, cfinclude->include,
2166  NULL, flags, "", who_asked)) {
2167  /* One change is enough to short-circuit and reload the whole shebang */
2168  unchanged = 0;
2169  break;
2170  }
2171  }
2172 
2173  if (unchanged) {
2175  globfree(&globbuf);
2176  ast_free(comment_buffer);
2177  ast_free(lline_buffer);
2179  }
2180  }
2181 
2182  /* If cfg is NULL, then we just want a file changed answer. */
2183  if (cfg == NULL) {
2184  if (cfmtime) {
2186  }
2187  continue;
2188  }
2189 
2190  if (cfmtime) {
2191  /* Forget about what we thought we knew about this file's includes. */
2192  cfmtime->has_exec = 0;
2193  config_cache_flush_includes(cfmtime);
2194 
2195  cfmstat_save(cfmtime, &statbuf);
2197  }
2198 
2199  if (!(f = fopen(fn, "r"))) {
2200  ast_debug(1, "No file to parse: %s\n", fn);
2201  ast_verb(2, "Parsing '%s': Not found (%s)\n", fn, strerror(errno));
2202  continue;
2203  }
2204  count++;
2205  /* If we get to this point, then we're loading regardless */
2207  ast_debug(1, "Parsing %s\n", fn);
2208  while (!feof(f)) {
2209  lineno++;
2210  if (fgets(buf, sizeof(buf), f)) {
2211  /* Skip lines that are too long */
2212  if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 2] != '\n') {
2213  ast_log(LOG_WARNING, "Line %d too long, skipping. It begins with: %.32s...\n", lineno, buf);
2214  while (fgets(buf, sizeof(buf), f)) {
2215  if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 2] == '\n') {
2216  break;
2217  }
2218  }
2219  continue;
2220  }
2221 
2222  /* If there is a UTF-8 BOM, skip over it */
2223  if (lineno == 1) {
2224 #define UTF8_BOM "\xEF\xBB\xBF"
2225  size_t line_bytes = strlen(buf);
2226  size_t bom_bytes = sizeof(UTF8_BOM) - 1;
2227  if (line_bytes >= bom_bytes
2228  && !memcmp(buf, UTF8_BOM, bom_bytes)) {
2229  memmove(buf, &buf[bom_bytes], line_bytes - bom_bytes + 1);
2230  }
2231 #undef UTF8_BOM
2232  }
2233 
2235  && lline_buffer
2236  && ast_str_strlen(lline_buffer)) {
2237  CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
2238  ast_str_reset(lline_buffer); /* erase the lline buffer */
2239  }
2240 
2241  new_buf = buf;
2242  if (comment) {
2243  process_buf = NULL;
2244  } else {
2245  process_buf = buf;
2246  }
2247 
2249  && comment_buffer
2250  && ast_str_strlen(comment_buffer)
2251  && (ast_strlen_zero(buf) || strlen(buf) == strspn(buf," \t\n\r"))) {
2252  /* blank line? really? Can we add it to an existing comment and maybe preserve inter- and post- comment spacing? */
2253  CB_ADD(&comment_buffer, "\n"); /* add a newline to the comment buffer */
2254  continue; /* go get a new line, then */
2255  }
2256 
2257  while ((comment_p = strchr(new_buf, COMMENT_META))) {
2258  if ((comment_p > new_buf) && (*(comment_p - 1) == '\\')) {
2259  /* Escaped semicolons aren't comments. */
2260  new_buf = comment_p;
2261  /* write over the \ and bring the null terminator with us */
2262  memmove(comment_p - 1, comment_p, strlen(comment_p) + 1);
2263  } else if (comment_p[1] == COMMENT_TAG && comment_p[2] == COMMENT_TAG && (comment_p[3] != '-')) {
2264  /* Meta-Comment start detected ";--" */
2265  if (comment < MAX_NESTED_COMMENTS) {
2266  *comment_p = '\0';
2267  new_buf = comment_p + 3;
2268  comment++;
2269  nest[comment-1] = lineno;
2270  } else {
2271  ast_log(LOG_ERROR, "Maximum nest limit of %d reached.\n", MAX_NESTED_COMMENTS);
2272  }
2273  } else if ((comment_p >= new_buf + 2) &&
2274  (*(comment_p - 1) == COMMENT_TAG) &&
2275  (*(comment_p - 2) == COMMENT_TAG)) {
2276  /* Meta-Comment end detected "--;" */
2277  comment--;
2278  new_buf = comment_p + 1;
2279  if (!comment) {
2280  /* Back to non-comment now */
2281  if (process_buf) {
2282  /* Actually have to move what's left over the top, then continue */
2283  char *oldptr;
2284 
2285  oldptr = process_buf + strlen(process_buf);
2286  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
2287  CB_ADD(&comment_buffer, ";");
2288  CB_ADD_LEN(&comment_buffer, oldptr+1, new_buf-oldptr-1);
2289  }
2290 
2291  memmove(oldptr, new_buf, strlen(new_buf) + 1);
2292  new_buf = oldptr;
2293  } else {
2294  process_buf = new_buf;
2295  }
2296  }
2297  } else {
2298  if (!comment) {
2299  /* If ; is found, and we are not nested in a comment,
2300  we immediately stop all comment processing */
2301  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
2302  CB_ADD(&lline_buffer, comment_p);
2303  }
2304  *comment_p = '\0';
2305  new_buf = comment_p;
2306  } else {
2307  new_buf = comment_p + 1;
2308  }
2309  }
2310  }
2311  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment && !process_buf ) {
2312  CB_ADD(&comment_buffer, buf); /* the whole line is a comment, store it */
2313  }
2314 
2315  if (process_buf) {
2316  char *buffer = ast_strip(process_buf);
2317 
2318  if (!ast_strlen_zero(buffer)) {
2319  if (process_text_line(cfg, &cat, buffer, lineno, fn,
2320  flags, comment_buffer, lline_buffer,
2321  suggested_include_file, &last_cat, &last_var,
2322  who_asked)) {
2324  break;
2325  }
2326  }
2327  }
2328  }
2329  }
2330  /* end of file-- anything in a comment buffer? */
2331  if (last_cat) {
2332  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
2333  if (lline_buffer && ast_str_strlen(lline_buffer)) {
2334  CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
2335  ast_str_reset(lline_buffer); /* erase the lline buffer */
2336  }
2337  last_cat->trailing = ALLOC_COMMENT(comment_buffer);
2338  }
2339  } else if (last_var) {
2340  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
2341  if (lline_buffer && ast_str_strlen(lline_buffer)) {
2342  CB_ADD(&comment_buffer, ast_str_buffer(lline_buffer)); /* add the current lline buffer to the comment buffer */
2343  ast_str_reset(lline_buffer); /* erase the lline buffer */
2344  }
2345  last_var->trailing = ALLOC_COMMENT(comment_buffer);
2346  }
2347  } else {
2348  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS) && comment_buffer && ast_str_strlen(comment_buffer)) {
2349  ast_debug(1, "Nothing to attach comments to, discarded: %s\n", ast_str_buffer(comment_buffer));
2350  }
2351  }
2352  if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
2353  CB_RESET(comment_buffer, lline_buffer);
2354  }
2355 
2356  fclose(f);
2357  } while (0);
2358  if (comment) {
2359  ast_log(LOG_WARNING,"Unterminated comment detected beginning on line %d\n", nest[comment - 1]);
2360  }
2361  if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) {
2362  break;
2363  }
2364  }
2365  globfree(&globbuf);
2366  }
2367 
2368  ast_free(comment_buffer);
2369  ast_free(lline_buffer);
2370 
2371  if (count == 0) {
2372  return NULL;
2373  }
2374 
2375  return cfg;
2376 }
static void cfmstat_save(struct cache_file_mtime *cfmtime, struct stat *statbuf)
Definition: main/config.c:1594
unsigned int has_exec
Definition: main/config.c:100
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define UTF8_BOM
static void CB_ADD_LEN(struct ast_str **cb, const char *str, int len)
Definition: main/config.c:134
static void CB_ADD(struct ast_str **cb, const char *str)
Definition: main/config.c:129
#define ast_test_flag(p, flag)
Definition: utils.h:63
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int cfmstat_cmp(struct cache_file_mtime *cfmtime, struct stat *statbuf)
Definition: main/config.c:1618
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct ast_comment * ALLOC_COMMENT(struct ast_str *buffer)
Definition: main/config.c:153
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define CONFIG_STATUS_FILEINVALID
#define CB_SIZE
Definition: main/config.c:127
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define COMMENT_TAG
Definition: main/config.c:66
struct ast_category * ast_config_get_current_category(const struct ast_config *cfg)
Retrieve the current category name being built.
Definition: main/config.c:1541
#define COMMENT_META
Definition: main/config.c:65
#define ast_verb(level,...)
Definition: logger.h:463
Hold the mtime for config files, so if we don&#39;t need to reread our config, don&#39;t. ...
Definition: main/config.c:91
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield)
Inserts a list entry into a alphabetically sorted list.
Definition: linkedlists.h:750
static char * lline_buffer
Definition: extconf.c:708
struct ast_comment * trailing
const char * who_asked
Definition: main/config.c:109
#define MAX_NESTED_COMMENTS
Definition: main/config.c:62
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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:1741
struct ast_comment * trailing
Definition: main/config.c:238
static void config_cache_flush_includes(struct cache_file_mtime *cfmtime)
Definition: main/config.c:1639
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
#define MY_GLOB_FLAGS
#define CONFIG_STATUS_FILEUNCHANGED
static char * comment_buffer
Definition: extconf.c:705
struct cache_file_mtime::includes includes
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
int errno
#define comment
Definition: ael_lex.c:976
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
#define GLOB_ABORTED
Definition: ael_lex.c:839
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:2042
#define ast_clear_flag(p, flag)
Definition: utils.h:77
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:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static void config_cache_remove(const char *filename, const char *who_asked)
Definition: main/config.c:1673
static void CB_RESET(struct ast_str *cb, struct ast_str *llb)
Definition: main/config.c:143
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
static struct cache_file_mtime * cfmtime_new(const char *filename, const char *who_asked)
Definition: main/config.c:1562

◆ count_linefeeds()

static int count_linefeeds ( char *  str)
static

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

Referenced by count_linefeeds_in_comments().

2473 {
2474  int count = 0;
2475 
2476  while (*str) {
2477  if (*str =='\n')
2478  count++;
2479  str++;
2480  }
2481  return count;
2482 }
const char * str
Definition: app_jack.c:147

◆ count_linefeeds_in_comments()

static int count_linefeeds_in_comments ( struct ast_comment x)
static

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

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

Referenced by insert_leading_blank_lines().

2485 {
2486  int count = 0;
2487 
2488  while (x) {
2489  count += count_linefeeds(x->cmt);
2490  x = x->next;
2491  }
2492  return count;
2493 }
struct ast_comment * next
Definition: main/config.c:85
char cmt[0]
Definition: main/config.c:87
static int count_linefeeds(char *str)
Definition: main/config.c:2472

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

References ast_alloca, ast_log, ast_strdupa, ast_strlen_zero, ast_strsep(), AST_STRSEP_STRIP, ast_category::ignored, LOG_ERROR, 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().

883 {
884  char *dupmatch;
885  char *nvp = NULL;
886  int match_found = 0, match_expressions = 0;
887  int template_ok = 0;
888 
889  /* Only match on category name if it's not a NULL or empty string */
890  if (!ast_strlen_zero(category_name) && strcasecmp(cat->name, category_name)) {
891  return 0;
892  }
893 
894  /* If match is NULL or empty, automatically match if not a template */
895  if (ast_strlen_zero(match)) {
896  return !cat->ignored;
897  }
898 
899  dupmatch = ast_strdupa(match);
900 
901  while ((nvp = ast_strsep(&dupmatch, sep, AST_STRSEP_STRIP))) {
902  struct ast_variable *v;
903  char *match_name;
904  char *match_value = NULL;
905  char *regerr;
906  int rc;
907  regex_t r_name, r_value;
908 
909  match_expressions++;
910 
911  match_name = ast_strsep(&nvp, '=', AST_STRSEP_STRIP);
912  match_value = ast_strsep(&nvp, '=', AST_STRSEP_STRIP);
913 
914  /* an empty match value is OK. A NULL match value (no =) is NOT. */
915  if (match_value == NULL) {
916  break;
917  }
918 
919  if (!strcmp("TEMPLATES", match_name)) {
920  if (!strcasecmp("include", match_value)) {
921  if (cat->ignored) {
922  template_ok = 1;
923  }
924  match_found++;
925  } else if (!strcasecmp("restrict", match_value)) {
926  if (cat->ignored) {
927  match_found++;
928  template_ok = 1;
929  } else {
930  break;
931  }
932  }
933  continue;
934  }
935 
936  if ((rc = regcomp(&r_name, match_name, REG_EXTENDED | REG_NOSUB))) {
937  regerr = ast_alloca(128);
938  regerror(rc, &r_name, regerr, 128);
939  ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n",
940  match_name, regerr);
941  regfree(&r_name);
942  return 0;
943  }
944  if ((rc = regcomp(&r_value, match_value, REG_EXTENDED | REG_NOSUB))) {
945  regerr = ast_alloca(128);
946  regerror(rc, &r_value, regerr, 128);
947  ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n",
948  match_value, regerr);
949  regfree(&r_name);
950  regfree(&r_value);
951  return 0;
952  }
953 
954  for (v = cat->root; v; v = v->next) {
955  if (!regexec(&r_name, v->name, 0, NULL, 0)
956  && !regexec(&r_value, v->value, 0, NULL, 0)) {
957  match_found++;
958  break;
959  }
960  }
961  regfree(&r_name);
962  regfree(&r_value);
963  }
964  if (match_found == match_expressions && (!cat->ignored || template_ok)) {
965  return 1;
966  }
967  return 0;
968 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
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:2315
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: main/utils.c:1656
struct ast_variable * root
Definition: main/config.c:240
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
char name[80]
Definition: main/config.c:226

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

References ast_copy_string(), ast_log, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, lock, LOG_WARNING, map, ast_config_map::name, ast_config_engine::next, ast_config_map::next, NULL, ast_config_map::priority, SCOPED_MUTEX, 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().

3043 {
3044  struct ast_config_engine *eng, *ret = NULL;
3045  struct ast_config_map *map;
3046 
3048 
3049  for (map = config_maps; map; map = map->next) {
3050  if (!strcasecmp(family, map->name) && (priority == map->priority)) {
3051  if (database)
3052  ast_copy_string(database, map->database, dbsiz);
3053  if (table)
3054  ast_copy_string(table, map->table ? map->table : family, tabsiz);
3055  break;
3056  }
3057  }
3058 
3059  /* Check if the required driver (engine) exist */
3060  if (map) {
3061  for (eng = config_engine_list; !ret && eng; eng = eng->next) {
3062  if (!strcasecmp(eng->name, map->driver))
3063  ret = eng;
3064  }
3065  }
3066 
3067  /* if we found a mapping, but the engine is not available, then issue a warning */
3068  if (map && !ret)
3069  ast_log(LOG_WARNING, "Realtime mapping for '%s' found to engine '%s', but the engine is not available\n", map->name, map->driver);
3070 
3071  return ret;
3072 }
struct ast_config_map * next
Definition: main/config.c:200
static int * map
Definition: misdn_config.c:438
#define LOG_WARNING
Definition: logger.h:274
const char * database
Definition: main/config.c:207
static struct ast_config_map * config_maps
#define NULL
Definition: resample.c:96
const char * table
Definition: main/config.c:209
static int priority
Configuration engine structure, used to define realtime drivers.
struct ast_config_engine * next
static char * table
Definition: cdr_odbc.c:58
#define ast_log
Definition: astobj2.c:42
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t config_lock
Definition: main/config.c:214
const char * name
Definition: main/config.c:203
static struct ast_config_engine * config_engine_list
Definition: main/config.c:215
const char * driver
Definition: main/config.c:205
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ gen_header()

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

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

References ast_copy_string().

Referenced by ast_config_text_file_save2().

2400 {
2401  char date[256]="";
2402  time_t t;
2403 
2404  time(&t);
2405  ast_copy_string(date, ctime(&t), sizeof(date));
2406 
2407  fprintf(f1, ";!\n");
2408  fprintf(f1, ";! Automatically generated configuration file\n");
2409  if (strcmp(configfile, fn))
2410  fprintf(f1, ";! Filename: %s (%s)\n", configfile, fn);
2411  else
2412  fprintf(f1, ";! Filename: %s\n", configfile);
2413  fprintf(f1, ";! Generator: %s\n", generator);
2414  fprintf(f1, ";! Creation Date: %s", date);
2415  fprintf(f1, ";!\n");
2416 }
static struct ast_generator generator
Definition: app_fax.c:359
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

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

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

4019 {
4020  struct cache_file_mtime *cfmtime;
4021 
4022  switch (cmd) {
4023  case CLI_INIT:
4024  e->command = "config list";
4025  e->usage =
4026  "Usage: config list\n"
4027  " Show all modules that have loaded a configuration file\n";
4028  return NULL;
4029  case CLI_GENERATE:
4030  return NULL;
4031  }
4032 
4034  AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4035  ast_cli(a->fd, "%-20.20s %-50s\n", S_OR(cfmtime->who_asked, "core"), cfmtime->filename);
4036  }
4038 
4039  return CLI_SUCCESS;
4040 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * who_asked
Definition: main/config.c:109
const int fd
Definition: cli.h:159
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct cache_file_mtime::@374 list

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

References ast_cli_args::argc, ast_cli_args::argv, 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, ast_cli_args::fd, cache_file_mtime::filename, NULL, ast_cli_args::pos, ast_category::prev, ast_cli_entry::usage, cache_file_mtime::who_asked, and ast_cli_args::word.

3956 {
3957  struct cache_file_mtime *cfmtime;
3958  char *prev = "";
3959  int wordlen;
3960 
3961  switch (cmd) {
3962  case CLI_INIT:
3963  e->command = "config reload";
3964  e->usage =
3965  "Usage: config reload <filename.conf>\n"
3966  " Reloads all modules that reference <filename.conf>\n";
3967  return NULL;
3968  case CLI_GENERATE:
3969  if (a->pos > 2) {
3970  return NULL;
3971  }
3972 
3973  wordlen = strlen(a->word);
3974 
3976  AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
3977  /* Core configs cannot be reloaded */
3978  if (ast_strlen_zero(cfmtime->who_asked)) {
3979  continue;
3980  }
3981 
3982  /* Skip duplicates - this only works because the list is sorted by filename */
3983  if (!strcmp(cfmtime->filename, prev)) {
3984  continue;
3985  }
3986 
3987  if (!strncmp(cfmtime->filename, a->word, wordlen)) {
3988  if (ast_cli_completion_add(ast_strdup(cfmtime->filename))) {
3989  break;
3990  }
3991  }
3992 
3993  /* Otherwise save that we've seen this filename */
3994  prev = cfmtime->filename;
3995  }
3997 
3998  return NULL;
3999  }
4000 
4001  if (a->argc != 3) {
4002  return CLI_SHOWUSAGE;
4003  }
4004 
4006  AST_LIST_TRAVERSE(&cfmtime_head, cfmtime, list) {
4007  if (!strcmp(cfmtime->filename, a->argv[2])) {
4008  char *buf = ast_alloca(strlen("module reload ") + strlen(cfmtime->who_asked) + 1);
4009  sprintf(buf, "module reload %s", cfmtime->who_asked);
4010  ast_cli_command(a->fd, buf);
4011  }
4012  }
4014 
4015  return CLI_SUCCESS;
4016 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const int argc
Definition: cli.h:160
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: cli.h:152
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * who_asked
Definition: main/config.c:109
const int fd
Definition: cli.h:159
ast_cli_command
calling arguments for new-style handlers.
Definition: cli.h:151
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct cache_file_mtime::@374 list
const int pos
Definition: cli.h:164
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726

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

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, config_lock, config_maps, ast_config_map::database, ast_config_map::driver, ast_cli_args::fd, lock, map, 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.

3919 {
3920  struct ast_config_engine *eng;
3921  struct ast_config_map *map;
3922 
3923  switch (cmd) {
3924  case CLI_INIT:
3925  e->command = "core show config mappings";
3926  e->usage =
3927  "Usage: core show config mappings\n"
3928  " Shows the filenames to config engines.\n";
3929  return NULL;
3930  case CLI_GENERATE:
3931  return NULL;
3932  }
3933 
3934  {
3936 
3937  if (!config_engine_list) {
3938  ast_cli(a->fd, "No config mappings found.\n");
3939  } else {
3940  for (eng = config_engine_list; eng; eng = eng->next) {
3941  ast_cli(a->fd, "Config Engine: %s\n", eng->name);
3942  for (map = config_maps; map; map = map->next) {
3943  if (!strcasecmp(map->driver, eng->name)) {
3944  ast_cli(a->fd, "===> %s (db=%s, table=%s)\n", map->name, map->database,
3945  map->table ? map->table : map->name);
3946  }
3947  }
3948  }
3949  }
3950  }
3951 
3952  return CLI_SUCCESS;
3953 }
struct ast_config_map * next
Definition: main/config.c:200
static int * map
Definition: misdn_config.c:438
const char * database
Definition: main/config.c:207
Definition: cli.h:152
static struct ast_config_map * config_maps
#define NULL
Definition: resample.c:96
const char * table
Definition: main/config.c:209
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
Configuration engine structure, used to define realtime drivers.
struct ast_config_engine * next
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
const int fd
Definition: cli.h:159
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t config_lock
Definition: main/config.c:214
const char * name
Definition: main/config.c:203
char * command
Definition: cli.h:186
static struct ast_config_engine * config_engine_list
Definition: main/config.c:215
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const char * driver
Definition: main/config.c:205

◆ hash_string()

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

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

References str, tmp(), and total.

Referenced by ast_config_text_file_save2().

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 tmp()
Definition: bt_open.c:389
const char * str
Definition: app_jack.c:147
static int total
Definition: res_adsi.c:968

◆ hashtab_compare_strings()

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

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

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

Referenced by ast_config_text_file_save2().

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

◆ hook_cmp()

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

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

References CMP_MATCH, CMP_STOP, and cfg_hook::name.

Referenced by ast_config_hook_register().

4090 {
4091  struct cfg_hook *hook1 = obj;
4092  struct cfg_hook *hook2 = arg;
4093 
4094  return !(strcasecmp(hook1->name, hook2->name)) ? CMP_MATCH | CMP_STOP : 0;
4095 }
const char * name
Definition: main/config.c:4075

◆ hook_destroy()

static void hook_destroy ( void *  obj)
static

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

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

Referenced by ast_config_hook_register().

4082 {
4083  struct cfg_hook *hook = obj;
4084  ast_free((void *) hook->name);
4085  ast_free((void *) hook->filename);
4086  ast_free((void *) hook->module);
4087 }
#define ast_free(a)
Definition: astmm.h:182
const char * filename
Definition: main/config.c:4076
const char * module
Definition: main/config.c:4077
const char * name
Definition: main/config.c:4075

◆ hook_hash()

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

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

References ast_str_hash(), and cfg_hook::name.

Referenced by ast_config_hook_register().

4098 {
4099  const struct cfg_hook *hook = obj;
4100 
4101  return ast_str_hash(hook->name);
4102 }
const char * name
Definition: main/config.c:4075
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ inclfile_destroy()

static void inclfile_destroy ( void *  obj)
static

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

References ast_free, and inclfile::fname.

Referenced by set_fn().

2419 {
2420  const struct inclfile *o = obj;
2421 
2422  ast_free(o->fname);
2423 }
#define ast_free(a)
Definition: astmm.h:182
char * fname
Definition: main/config.c:169

◆ init_appendbuf()

static int init_appendbuf ( void *  data)
static

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

References ast_str_create, and str.

118 {
119  struct ast_str **str = data;
120  *str = ast_str_create(16);
121  return *str ? 0 : -1;
122 }
const char * str
Definition: app_jack.c:147
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

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

References count_linefeeds_in_comments(), and inclfile::lineno.

Referenced by ast_config_text_file_save2().

2496 {
2497  int precomment_lines;
2498  int i;
2499 
2500  if (!fi) {
2501  /* No file scratch pad object so insert no blank lines. */
2502  return;
2503  }
2504 
2505  precomment_lines = count_linefeeds_in_comments(precomments);
2506 
2507  /* I don't have to worry about those ;! comments, they are
2508  stored in the precomments, but not printed back out.
2509  I did have to make sure that comments following
2510  the ;! header comments were not also deleted in the process */
2511  if (lineno - precomment_lines - fi->lineno < 0) { /* insertions can mess up the line numbering and produce negative numbers that mess things up */
2512  return;
2513  } else if (lineno == 0) {
2514  /* Line replacements also mess things up */
2515  return;
2516  } else if (lineno - precomment_lines - fi->lineno < 5) {
2517  /* Only insert less than 5 blank lines; if anything more occurs,
2518  * it's probably due to context deletion. */
2519  for (i = fi->lineno; i < lineno - precomment_lines; i++) {
2520  fprintf(fp, "\n");
2521  }
2522  } else {
2523  /* Deletion occurred - insert a single blank line, for separation of
2524  * contexts. */
2525  fprintf(fp, "\n");
2526  }
2527 
2528  fi->lineno = lineno + 1; /* Advance the file lineno */
2529 }
static int count_linefeeds_in_comments(struct ast_comment *x)
Definition: main/config.c:2484
int lineno
Definition: main/config.c:170

◆ is_writable()

static int is_writable ( const char *  fn)
static

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

References ast_log, ast_strdupa, errno, and LOG_ERROR.

Referenced by ast_config_text_file_save2().

2537 {
2538  if (access(fn, F_OK)) {
2539  char *dn = dirname(ast_strdupa(fn));
2540 
2541  if (access(dn, R_OK | W_OK)) {
2542  ast_log(LOG_ERROR, "Unable to write to directory %s (%s)\n", dn, strerror(errno));
2543  return 0;
2544  }
2545  } else {
2546  if (access(fn, R_OK | W_OK)) {
2547  ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno));
2548  return 0;
2549  }
2550  }
2551 
2552  return 1;
2553 }
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
int errno

◆ load_module()

static int load_module ( void  )
static

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

References AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODULE_INFO(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ast_opt_console, ast_verb, ASTERISK_GPL_KEY, reload(), reload_module(), and unload_module().

4167 {
4168  if (ast_opt_console) {
4169  ast_verb(0, "[ Initializing Custom Configuration Options ]\n");
4170  }
4171 
4173 }
static int reload_module(void)
Definition: main/config.c:2906
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_opt_console
Definition: options.h:109
Module could not be loaded properly.
Definition: module.h:102

◆ make_fn()

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

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

References ast_config_AST_CONFIG_DIR, ast_copy_string(), and ast_strlen_zero.

Referenced by ast_config_text_file_save2(), and set_fn().

2426 {
2427  if (ast_strlen_zero(file)) {
2428  if (configfile[0] == '/') {
2429  ast_copy_string(fn, configfile, fn_size);
2430  } else {
2431  snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile);
2432  }
2433  } else if (file[0] == '/') {
2434  ast_copy_string(fn, file, fn_size);
2435  } else {
2436  snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file);
2437  }
2438 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ move_variables()

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

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

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

Referenced by process_text_line().

870 {
871  struct ast_variable *var = old->root;
872 
873  old->root = NULL;
874  /* we can just move the entire list in a single op */
875  ast_variable_append(new, var);
876 }
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: main/config.c:488
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
struct ast_variable * root
Definition: main/config.c:240

◆ new_category()

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

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

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

Referenced by ast_category_new(), and ast_category_new_template().

972 {
973  struct ast_category *category;
974 
975  category = ast_calloc(1, sizeof(*category));
976  if (!category) {
977  return NULL;
978  }
979  category->file = ast_strdup(in_file);
980  if (!category->file) {
981  ast_category_destroy(category);
982  return NULL;
983  }
984  ast_copy_string(category->name, name, sizeof(category->name));
985  category->lineno = lineno; /* if you don't know the lineno, set it to 999999 or something real big */
986  category->ignored = template;
987  return category;
988 }
char * file
The file name from whence this declaration was read.
Definition: main/config.c:233
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_category_destroy(struct ast_category *cat)
Definition: main/config.c:1122
static const char name[]
Definition: cdr_mysql.c:74
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char name[80]
Definition: main/config.c:226
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ next_available_category()

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

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

References does_category_match(), and ast_category::next.

Referenced by ast_category_browse(), and ast_category_browse_filtered().

1150 {
1151  for (; cat && !does_category_match(cat, name, filter, ','); cat = cat->next);
1152 
1153  return cat;
1154 }
struct ast_category * next
Definition: main/config.c:246
static const char name[]
Definition: cdr_mysql.c:74
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709
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:881

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

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_safe_system(), 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(), config_cache_attribute(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, filter(), ast_category::ignored, ast_config::include_level, ast_variable::lineno, ast_category::lineno, LOG_ERROR, LOG_WARNING, move_variables(), ast_variable::name, ast_variable::next, NULL, ast_variable::object, ast_variable::precomments, ast_category::precomments, replace(), S_OR, ast_variable::sameline, ast_category::sameline, str, strsep(), astconfigparser::try_include(), ast_variable::value, and var.

Referenced by config_text_file_load().

1747 {
1748  char *c;
1749  char *cur = buf;
1750  struct ast_variable *v;
1751  char exec_file[512];
1752 
1753  /* Actually parse the entry */
1754  if (cur[0] == '[') { /* A category header */
1755  /* format is one of the following:
1756  * [foo] define a new category named 'foo'
1757  * [foo](!) define a new template category named 'foo'
1758  * [foo](+) append to category 'foo', error if foo does not exist.
1759  * [foo](a) define a new category and inherit from category or template a.
1760  * You can put a comma-separated list of categories and templates
1761  * and '!' and '+' between parentheses, with obvious meaning.
1762  */
1763  struct ast_category *newcat;
1764  char *catname;
1765 
1766  c = strchr(cur, ']');
1767  if (!c) {
1768  ast_log(LOG_WARNING, "parse error: no closing ']', line %d of %s\n", lineno, configfile);
1769  return -1;
1770  }
1771  *c++ = '\0';
1772  cur++;
1773  if (*c++ != '(')
1774  c = NULL;
1775  catname = cur;
1776  *cat = newcat = ast_category_new(catname,
1777  S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile),
1778  lineno);
1779  if (!newcat) {
1780  return -1;
1781  }
1782  (*cat)->lineno = lineno;
1783 
1784  /* add comments */
1786  newcat->precomments = ALLOC_COMMENT(comment_buffer);
1788  newcat->sameline = ALLOC_COMMENT(lline_buffer);
1790  CB_RESET(comment_buffer, lline_buffer);
1791 
1792  /* If there are options or categories to inherit from, process them now */
1793  if (c) {
1794  if (!(cur = strchr(c, ')'))) {
1795  ast_category_destroy(newcat);
1796  ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile);
1797  return -1;
1798  }
1799  *cur = '\0';
1800  while ((cur = strsep(&c, ","))) {
1801  if (!strcasecmp(cur, "!")) {
1802  (*cat)->ignored = 1;
1803  } else if (cur[0] == '+') {
1804  char *filter = NULL;
1805 
1806  if (cur[1] != ',') {
1807  filter = &cur[1];
1808  }
1809  *cat = category_get_sep(cfg, catname, filter, '&', 0);
1810  if (!(*cat)) {
1811  if (newcat) {
1812  ast_category_destroy(newcat);
1813  }
1814  ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile);
1815  return -1;
1816  }
1817  if (newcat) {
1819  (*cat)->ignored |= newcat->ignored;
1820  move_variables(newcat, *cat);
1821  ast_category_destroy(newcat);
1822  newcat = NULL;
1823  }
1824  } else {
1825  struct ast_category *base;
1826 
1827  base = category_get_sep(cfg, cur, "TEMPLATES=include", ',', 0);
1828  if (!base) {
1829  if (newcat) {
1830  ast_category_destroy(newcat);
1831  }
1832  ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile);
1833  return -1;
1834  }
1835  if (ast_category_inherit(*cat, base)) {
1836  if (newcat) {
1837  ast_category_destroy(newcat);
1838  }
1839  ast_log(LOG_ERROR, "Inheritence requested, but allocation failed\n");
1840  return -1;
1841  }
1842  }
1843  }
1844  }
1845 
1846  /*
1847  * We need to set *last_cat to newcat here regardless. If the
1848  * category is being appended to we have no place for trailing
1849  * comments on the appended category. The appended category
1850  * may be in another file or it already has trailing comments
1851  * that we would then leak.
1852  */
1853  *last_var = NULL;
1854  *last_cat = newcat;
1855  if (newcat) {
1856  ast_category_append(cfg, newcat);
1857  }
1858  } else if (cur[0] == '#') { /* A directive - #include or #exec */
1859  char *cur2;
1860  char real_inclusion_name[256];
1861  int do_include = 0; /* otherwise, it is exec */
1862  int try_include = 0;
1863 
1864  cur++;
1865  c = cur;
1866  while (*c && (*c > 32)) {
1867  c++;
1868  }
1869 
1870  if (*c) {
1871  *c = '\0';
1872  /* Find real argument */
1873  c = ast_strip(c + 1);
1874  if (!(*c)) {
1875  c = NULL;
1876  }
1877  } else {
1878  c = NULL;
1879  }
1880  if (!strcasecmp(cur, "include")) {
1881  do_include = 1;
1882  } else if (!strcasecmp(cur, "tryinclude")) {
1883  do_include = 1;
1884  try_include = 1;
1885  } else if (!strcasecmp(cur, "exec")) {
1886  if (!ast_opt_exec_includes) {
1887  ast_log(LOG_WARNING, "Cannot perform #exec unless execincludes option is enabled in asterisk.conf (options section)!\n");
1888  return 0; /* XXX is this correct ? or we should return -1 ? */
1889  }
1890  } else {
1891  ast_log(LOG_WARNING, "Unknown directive '#%s' at line %d of %s\n", cur, lineno, configfile);
1892  return 0; /* XXX is this correct ? or we should return -1 ? */
1893  }
1894 
1895  if (c == NULL) {
1896  ast_log(LOG_WARNING, "Directive '#%s' needs an argument (%s) at line %d of %s\n",
1897  do_include ? "include / tryinclude" : "exec",
1898  do_include ? "filename" : "/path/to/executable",
1899  lineno,
1900  configfile);
1901  return 0; /* XXX is this correct ? or we should return -1 ? */
1902  }
1903 
1904  cur = c;
1905  /* Strip off leading and trailing "'s and <>'s */
1906  /* Dequote */
1907  if ((*c == '"') || (*c == '<')) {
1908  char quote_char = *c;
1909  if (quote_char == '<') {
1910  quote_char = '>';
1911  }
1912 
1913  if (*(c + strlen(c) - 1) == quote_char) {
1914  cur++;
1915  *(c + strlen(c) - 1) = '\0';
1916  }
1917  }
1918  cur2 = cur;
1919 
1920  /* #exec </path/to/executable>
1921  We create a tmp file, then we #include it, then we delete it. */
1922  if (!do_include) {
1923  struct timeval now = ast_tvnow();
1924  char cmd[1024];
1925 
1926  if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
1927  config_cache_attribute(configfile, ATTRIBUTE_EXEC, NULL, who_asked);
1928  snprintf(exec_file, sizeof(exec_file), "/var/tmp/exec.%d%d.%ld", (int)now.tv_sec, (int)now.tv_usec, (long)pthread_self());
1929  if (snprintf(cmd, sizeof(cmd), "%s > %s 2>&1", cur, exec_file) >= sizeof(cmd)) {
1930  ast_log(LOG_ERROR, "Failed to construct command string to execute %s.\n", cur);
1931 
1932  return -1;
1933  }
1934  ast_safe_system(cmd);
1935  cur = exec_file;
1936  } else {
1937  if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
1938  config_cache_attribute(configfile, ATTRIBUTE_INCLUDE, cur, who_asked);
1939  exec_file[0] = '\0';
1940  }
1941  /* A #include */
1942  /* record this inclusion */
1943  ast_include_new(cfg, cfg->include_level == 1 ? "" : configfile, cur, !do_include, cur2, lineno, real_inclusion_name, sizeof(real_inclusion_name));
1944 
1945  do_include = ast_config_internal_load(cur, cfg, flags, real_inclusion_name, who_asked) ? 1 : 0;
1946  if (!ast_strlen_zero(exec_file))
1947  unlink(exec_file);
1948  if (!do_include && !try_include) {
1949  ast_log(LOG_ERROR, "The file '%s' was listed as a #include but it does not exist.\n", cur);
1950  return -1;
1951  }
1952  /* XXX otherwise what ? the default return is 0 anyways */
1953 
1954  } else {
1955  /* Just a line (variable = value) */
1956  int object = 0;
1957  int is_escaped;
1958 
1959  if (!(*cat)) {
1961  "parse error: No category context for line %d of %s\n", lineno, configfile);
1962  return -1;
1963  }
1964 
1965  is_escaped = cur[0] == '\\';
1966  if (is_escaped) {
1967  /* First character is escaped. */
1968  ++cur;
1969  if (cur[0] < 33) {
1970  ast_log(LOG_ERROR, "Invalid escape in line %d of %s\n", lineno, configfile);
1971  return -1;
1972  }
1973  }
1974  c = strchr(cur + is_escaped, '=');
1975 
1976  if (c && c > cur + is_escaped && (*(c - 1) == '+')) {
1977  struct ast_variable *var, *replace = NULL;
1978  struct ast_str **str = ast_threadstorage_get(&appendbuf, sizeof(*str));
1979 
1980  if (!str || !*str) {
1981  return -1;
1982  }
1983 
1984  *(c - 1) = '\0';
1985  c++;
1986  cur = ast_strip(cur);
1987 
1988  /* Must iterate through category until we find last variable of same name (since there could be multiple) */
1989  for (var = ast_category_first(*cat); var; var = var->next) {
1990  if (!strcmp(var->name, cur)) {
1991  replace = var;
1992  }
1993  }
1994 
1995  if (!replace) {
1996  /* Nothing to replace; just set a variable normally. */
1997  goto set_new_variable;
1998  }
1999 
2000  ast_str_set(str, 0, "%s", replace->value);
2001  ast_str_append(str, 0, "%s", c);
2002  ast_str_trim_blanks(*str);
2003  ast_variable_update(*cat, replace->name, ast_skip_blanks(ast_str_buffer(*str)), replace->value, object);
2004  } else if (c) {
2005  *c = 0;
2006  c++;
2007  /* Ignore > in => */
2008  if (*c== '>') {
2009  object = 1;
2010  c++;
2011  }
2012  cur = ast_strip(cur);
2013 set_new_variable:
2014  if (ast_strlen_zero(cur)) {
2015  ast_log(LOG_WARNING, "No variable name in line %d of %s\n", lineno, configfile);
2016  } else if ((v = ast_variable_new(cur, ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) {
2017  v->lineno = lineno;
2018  v->object = object;
2019  *last_cat = NULL;
2020  *last_var = v;
2021  /* Put and reset comments */
2022  v->blanklines = 0;
2023  ast_variable_append(*cat, v);
2024  /* add comments */
2026  v->precomments = ALLOC_COMMENT(comment_buffer);
2028  v->sameline = ALLOC_COMMENT(lline_buffer);
2030  CB_RESET(comment_buffer, lline_buffer);
2031 
2032  } else {
2033  return -1;
2034  }
2035  } else {
2036  ast_log(LOG_WARNING, "No '=' (equal sign) in line %d of %s\n", lineno, configfile);
2037  }
2038  }
2039  return 0;
2040 }
struct ast_variable * next
struct ast_comment * sameline
Definition: main/config.c:237
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: main/config.c:488
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
Definition: main/config.c:1067
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_category_inherit(struct ast_category *new, const struct ast_category *base)
Applies base (template) to category.
Definition: main/config.c:1367
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:3112
#define LOG_WARNING
Definition: logger.h:274
static struct ast_comment * ALLOC_COMMENT(struct ast_str *buffer)
Definition: main/config.c:153
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int include_level
Definition: main/config.c:256
Structure for variables, used for configurations and for channel variables.
struct ast_comment * sameline
#define var
Definition: ast_expr2f.c:614
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:1091
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static struct test_val c
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:1065
#define ast_opt_exec_includes
Definition: options.h:106
#define ast_log
Definition: astobj2.c:42
void ast_category_destroy(struct ast_category *cat)
Definition: main/config.c:1122
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:219
static struct ast_threadstorage appendbuf
Definition: main/config.c:124
#define ast_variable_new(name, value, filename)
struct ast_comment * precomments
Definition: main/config.c:236
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
struct ast_comment * precomments
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
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:1546
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:790
def try_include(line)
char * strsep(char **str, const char *delims)
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category.
Definition: main/config.c:990
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:1000
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1157
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:337
void ast_str_trim_blanks(struct ast_str *buf)
Trims trailing whitespace characters from an ast_str string.
Definition: strings.h:678
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709
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:1690
static void CB_RESET(struct ast_str *cb, struct ast_str *llb)
Definition: main/config.c:143
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:1444
static void move_variables(struct ast_category *old, struct ast_category *new)
Definition: main/config.c:869

◆ realtime_arguments_to_fields2()

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

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

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

Referenced by ast_update2_realtime().

3186 {
3187  struct ast_variable *first, *fields = NULL;
3188  const char *newparam;
3189  const char *newval;
3190 
3191  /*
3192  * Previously we would do:
3193  *
3194  * va_start(ap, last);
3195  * x = realtime_arguments_to_fields(ap);
3196  * y = realtime_arguments_to_fields(ap);
3197  * va_end(ap);
3198  *
3199  * While this works on generic amd64 machines (2014), it doesn't on the
3200  * raspberry PI. The va_arg() manpage says:
3201  *
3202  * If ap is passed to a function that uses va_arg(ap,type) then
3203  * the value of ap is undefined after the return of that function.
3204  *
3205  * On the raspberry, ap seems to get reset after the call: the contents
3206  * of y would be equal to the contents of x.
3207  *
3208  * So, instead we allow the caller to skip past earlier argument sets
3209  * using the skip parameter:
3210  *
3211  * va_start(ap, last);
3212  * if (realtime_arguments_to_fields(ap, &x)) {
3213  * // FAILURE CONDITIONS
3214  * }
3215  * va_end(ap);
3216  * va_start(ap, last);
3217  * if (realtime_arguments_to_fields2(ap, 1, &y)) {
3218  * // FAILURE CONDITIONS
3219  * }
3220  * va_end(ap);
3221  */
3222  while (skip--) {
3223  /* There must be at least one argument. */
3224  newparam = va_arg(ap, const char *);
3225  newval = va_arg(ap, const char *);
3226  while ((newparam = va_arg(ap, const char *))) {
3227  newval = va_arg(ap, const char *);
3228  }
3229  }
3230 
3231  /* Load up the first vars. */
3232  newparam = va_arg(ap, const char *);
3233  if (!newparam) {
3234  *result = NULL;
3235  return 0;
3236  }
3237  newval = va_arg(ap, const char *);
3238 
3239  if (!(first = ast_variable_new(newparam, newval, ""))) {
3240  *result = NULL;
3241  return -1;
3242  }
3243 
3244  while ((newparam = va_arg(ap, const char *))) {
3245  struct ast_variable *field;
3246 
3247  newval = va_arg(ap, const char *);
3248  if (!(field = ast_variable_new(newparam, newval, ""))) {
3249  ast_variables_destroy(fields);
3250  ast_variables_destroy(first);
3251  *result = NULL;
3252  return -1;
3253  }
3254 
3255  field->next = fields;
3256  fields = field;
3257  }
3258 
3259  first->next = fields;
3260  fields = first;
3261 
3262  *result = fields;
3263  return 0;
3264 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define ast_variable_new(name, value, filename)
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
void ast_variables_destroy(struct ast_variable *v)
Free variable list.
Definition: main/config.c:591

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

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

Referenced by asterisk_daemon().

4067 {
4069  /* This is separate from the module load so cleanup can happen very late. */
4071  return 0;
4072 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static void config_shutdown(void)
Definition: main/config.c:4048
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static struct ast_cli_entry cli_config[]
Definition: main/config.c:4042

◆ reload_module()

static int reload_module ( void  )
static

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

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

2907 {
2908  struct ast_config *config, *configtmp;
2909  struct ast_variable *v;
2910  char *driver, *table, *database, *textpri, *stringp, *tmp;
2911  struct ast_flags flags = { CONFIG_FLAG_NOREALTIME };
2912  int pri;
2914 
2916 
2917  configtmp = ast_config_new();
2918  if (!configtmp) {
2919  ast_log(LOG_ERROR, "Unable to allocate memory for new config\n");
2920  return -1;
2921  }
2922  config = ast_config_internal_load(extconfig_conf, configtmp, flags, "", "extconfig");
2923  if (config == CONFIG_STATUS_FILEINVALID) {
2924  return -1;
2925  } else if (!config) {
2926  ast_config_destroy(configtmp);
2927  return 0;
2928  }
2929 
2930  for (v = ast_variable_browse(config, "settings"); v; v = v->next) {
2931  char buf[512];
2932  ast_copy_string(buf, v->value, sizeof(buf));
2933  stringp = buf;
2934  driver = strsep(&stringp, ",");
2935  if (!stringp) {
2936  ast_log(LOG_WARNING, "extconfig.conf: value '%s' ignored due to wrong format\n", v->value);
2937  continue;
2938  }
2939  if ((tmp = strchr(stringp, '\"')))
2940  stringp = tmp;
2941 
2942  /* check if the database text starts with a double quote */
2943  if (*stringp == '"') {
2944  stringp++;
2945  database = strsep(&stringp, "\"");
2946  strsep(&stringp, ",");
2947  } else {
2948  /* apparently this text has no quotes */
2949  database = strsep(&stringp, ",");
2950  }
2951 
2952  table = strsep(&stringp, ",");
2953  textpri = strsep(&stringp, ",");
2954  if (!textpri || !(pri = atoi(textpri))) {
2955  pri = 1;
2956  }
2957 
2958  if (!strcmp(v->name, extconfig_conf)) {
2959  ast_log(LOG_WARNING, "Cannot bind '%s'!\n", extconfig_conf);
2960  continue;
2961  }
2962 
2963  if (!strcmp(v->name, "asterisk.conf")) {
2964  ast_log(LOG_WARNING, "Cannot bind 'asterisk.conf'!\n");
2965  continue;
2966  }
2967 
2968  if (!strcmp(v->name, "logger.conf")) {
2969  ast_log(LOG_WARNING, "Cannot bind 'logger.conf'!\n");
2970  continue;
2971  }
2972 
2973  if (!driver || !database)
2974  continue;
2975  if (!strcasecmp(v->name, "sipfriends")) {
2976  ast_log(LOG_WARNING, "The 'sipfriends' table is obsolete, update your config to use sippeers instead.\n");
2977  ast_realtime_append_mapping("sippeers", driver, database, table ? table : "sipfriends", pri);
2978  } else if (!strcasecmp(v->name, "iaxfriends")) {
2979  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");
2980  ast_realtime_append_mapping("iaxusers", driver, database, table ? table : "iaxfriends", pri);
2981  ast_realtime_append_mapping("iaxpeers", driver, database, table ? table : "iaxfriends", pri);
2982  } else
2983  ast_realtime_append_mapping(v->name, driver, database, table, pri);
2984  }
2985 
2986  ast_config_destroy(config);
2987  return 0;
2988 }
struct ast_variable * next
char * config
Definition: conf2ael.c:66
static void clear_config_maps(void)
Definition: main/config.c:2856
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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:3112
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
static int tmp()
Definition: bt_open.c:389
unsigned int flags
Definition: utils.h:200
Structure for variables, used for configurations and for channel variables.
int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority)
Add an explicit mapping for a family.
Definition: main/config.c:2868
static char * table
Definition: cdr_odbc.c:58
#define ast_log
Definition: astobj2.c:42
static char * extconfig_conf
Definition: main/config.c:75
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
static ast_mutex_t config_lock
Definition: main/config.c:214
#define LOG_ERROR
Definition: logger.h:285
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: main/config.c:1523
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Definition: main/config.c:602
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: main/config.c:1390
Structure used to handle boolean flags.
Definition: utils.h:199
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

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

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

Referenced by ast_config_text_file_save2().

2441 {
2442  struct inclfile lookup;
2443  struct inclfile *fi;
2444 
2445  make_fn(fn, fn_size, file, configfile);
2446  lookup.fname = fn;
2447  fi = ao2_find(fileset, &lookup, OBJ_POINTER);
2448  if (fi) {
2449  /* Found existing include file scratch pad. */
2450  return fi;
2451  }
2452 
2453  /* set up a file scratch pad */
2454  fi = ao2_alloc(sizeof(struct inclfile), inclfile_destroy);
2455  if (!fi) {
2456  /* Scratch pad creation failed. */
2457  return NULL;
2458  }
2459  fi->fname = ast_strdup(fn);
2460  if (!fi->fname) {
2461  /* Scratch pad creation failed. */
2462  ao2_ref(fi, -1);
2463  return NULL;
2464  }
2465  fi->lineno = 1;
2466 
2467  ao2_link(fileset, fi);
2468 
2469  return fi;
2470 }
#define OBJ_POINTER
Definition: astobj2.h:1154
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static void inclfile_destroy(void *obj)
Definition: main/config.c:2418
static void make_fn(char *fn, size_t fn_size, const char *file, const char *configfile)
Definition: main/config.c:2425
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
char * fname
Definition: main/config.c:169
#define ao2_link(container, obj)
Definition: astobj2.h:1549
int lineno
Definition: main/config.c:170

◆ unload_module()

static int unload_module ( void  )
static

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

Referenced by load_module().

4162 {
4163  return 0;
4164 }

◆ variable_clone()

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

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

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

856 {
857  struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
858 
859  if (new) {
860  new->lineno = old->lineno;
861  new->object = old->object;
862  new->blanklines = old->blanklines;
863  /* TODO: clone comments? */
864  }
865 
866  return new;
867 }
Structure for variables, used for configurations and for channel variables.
#define ast_variable_new(name, value, filename)

◆ variable_list_switch()

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

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

References ast_variable::next.

Referenced by ast_variable_list_sort().

616 {
617  l1->next = l2->next;
618  l2->next = l1;
619  return l2;
620 }
struct ast_variable * next

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = 0, }
static

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

◆ cfg_hooks

struct ao2_container* cfg_hooks
static

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

◆ 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_core_show_config_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:3918
static char * handle_cli_config_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:3955
static char * handle_cli_config_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/config.c:4018

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

◆ config_engine_list

struct ast_config_engine* config_engine_list
static

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

◆ 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,
}
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:2042

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

Referenced by ast_config_internal_load().