Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Functions | Variables
res_sorcery_config.c File Reference

Sorcery Configuration File Object Wizard. More...

#include "asterisk.h"
#include <regex.h>
#include "asterisk/module.h"
#include "asterisk/sorcery.h"
#include "asterisk/astobj2.h"
#include "asterisk/config.h"
#include "asterisk/uuid.h"
#include "asterisk/hashtab.h"
Include dependency graph for res_sorcery_config.c:

Go to the source code of this file.

Data Structures

struct  sorcery_config
 Structure for storing configuration file sourced objects. More...
 
struct  sorcery_config_fields_cmp_params
 Structure used for fields comparison. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void sorcery_config_close (void *data)
 
static void sorcery_config_destructor (void *obj)
 Destructor function for sorcery config. More...
 
static int sorcery_config_fields_cmp (void *obj, void *arg, int flags)
 
static void sorcery_config_internal_load (void *data, const struct ast_sorcery *sorcery, const char *type, unsigned int reload)
 
static void sorcery_config_load (void *data, const struct ast_sorcery *sorcery, const char *type)
 
static void * sorcery_config_open (const char *data)
 
static void sorcery_config_reload (void *data, const struct ast_sorcery *sorcery, const char *type)
 
static void * sorcery_config_retrieve_fields (const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields)
 
static void * sorcery_config_retrieve_id (const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
 
static void sorcery_config_retrieve_multiple (const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)
 
static void sorcery_config_retrieve_prefix (const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *prefix, const size_t prefix_len)
 
static void sorcery_config_retrieve_regex (const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex)
 
static int sorcery_is_configuration_met (const struct ast_sorcery *sorcery, const char *type, struct ast_category *category, struct sorcery_config *config)
 Internal function which determines if criteria has been met for considering an object set applicable. More...
 
static int sorcery_is_criteria_met (struct ast_category *category, struct sorcery_config *config)
 Internal function which determines if a category matches based on criteria. More...
 
static int sorcery_is_explicit_name_met (const struct ast_sorcery *sorcery, const char *type, struct ast_category *category, struct sorcery_config *config)
 Internal function which determines if a category matches based on explicit name. More...
 
static int unload_module (void)
 

Variables

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

Detailed Description

Sorcery Configuration File Object Wizard.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file res_sorcery_config.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 567 of file res_sorcery_config.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 567 of file res_sorcery_config.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 567 of file res_sorcery_config.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 547 of file res_sorcery_config.c.

548 {
551  }
552 
554 }
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_sorcery_wizard config_object_wizard
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
Definition: sorcery.h:383

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_sorcery_wizard_register, and config_object_wizard.

◆ sorcery_config_close()

static void sorcery_config_close ( void *  data)
static

Definition at line 540 of file res_sorcery_config.c.

541 {
542  struct sorcery_config *config = data;
543 
544  ao2_ref(config, -1);
545 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static const char config[]
Definition: chan_ooh323.c:111
Structure for storing configuration file sourced objects.

References ao2_ref, and config.

◆ sorcery_config_destructor()

static void sorcery_config_destructor ( void *  obj)
static

Destructor function for sorcery config.

Definition at line 122 of file res_sorcery_config.c.

123 {
124  struct sorcery_config *config = obj;
125 
126  ao2_global_obj_release(config->objects);
127  ast_rwlock_destroy(&config->objects.lock);
128  ast_variables_destroy(config->criteria);
129  ast_free(config->explicit_name);
130 }
#define ast_free(a)
Definition: astmm.h:180
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define ast_rwlock_destroy(rwlock)
Definition: lock.h:231

References ao2_global_obj_release, ast_free, ast_rwlock_destroy, ast_variables_destroy(), and config.

Referenced by sorcery_config_open().

◆ sorcery_config_fields_cmp()

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

Definition at line 132 of file res_sorcery_config.c.

133 {
134  const struct sorcery_config_fields_cmp_params *params = arg;
135  RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
136 
137  if (params->regex) {
138  /* If a regular expression has been provided see if it matches, otherwise move on */
139  if (!regexec(params->regex, ast_sorcery_object_get_id(obj), 0, NULL, 0)) {
140  ao2_link(params->container, obj);
141  }
142  return 0;
143  } else if (params->prefix) {
144  if (!strncmp(params->prefix, ast_sorcery_object_get_id(obj), params->prefix_len)) {
145  ao2_link(params->container, obj);
146  }
147  return 0;
148  } else if (params->fields &&
149  (!(objset = ast_sorcery_objectset_create(params->sorcery, obj)) ||
150  (!ast_variable_lists_match(objset, params->fields, 0)))) {
151  /* If we can't turn the object into an object set OR if differences exist between the fields
152  * passed in and what are present on the object they are not a match.
153  */
154  return 0;
155  }
156 
157  /* We want this object */
158  if (params->container) {
159  /*
160  * We are putting the found objects into the given container instead
161  * of the normal container traversal return mechanism.
162  */
163  ao2_link(params->container, obj);
164  return 0;
165  } else {
166  return CMP_MATCH;
167  }
168 }
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ CMP_MATCH
Definition: astobj2.h:1027
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.
Definition: main/config.c:846
#define NULL
Definition: resample.c:96
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1137
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
Structure for variables, used for configurations and for channel variables.
Structure used for fields comparison.
const char * prefix
Prefix for matching object id.
struct ao2_container * container
Optional container to put object into.
const size_t prefix_len
Prefix length in bytes for matching object id.
const struct ast_sorcery * sorcery
Pointer to the sorcery structure.
const struct ast_variable * fields
Pointer to the fields to check.
regex_t * regex
Regular expression for checking object id.
#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:936

References ao2_link, ast_sorcery_object_get_id(), ast_sorcery_objectset_create, ast_variable_lists_match(), ast_variables_destroy(), CMP_MATCH, sorcery_config_fields_cmp_params::container, sorcery_config_fields_cmp_params::fields, NULL, sorcery_config_fields_cmp_params::prefix, sorcery_config_fields_cmp_params::prefix_len, RAII_VAR, sorcery_config_fields_cmp_params::regex, and sorcery_config_fields_cmp_params::sorcery.

Referenced by sorcery_config_retrieve_fields(), sorcery_config_retrieve_multiple(), sorcery_config_retrieve_prefix(), and sorcery_config_retrieve_regex().

◆ sorcery_config_internal_load()

static void sorcery_config_internal_load ( void *  data,
const struct ast_sorcery sorcery,
const char *  type,
unsigned int  reload 
)
static

Definition at line 316 of file res_sorcery_config.c.

317 {
318  struct sorcery_config *config = data;
319  struct ast_flags flags = { reload && !config->configuration_invalid && !config->has_dynamic_contents ? CONFIG_FLAG_FILEUNCHANGED : 0 };
320  struct ast_config *cfg = ast_config_load2(config->filename, config->uuid, flags);
321  struct ast_category *category = NULL;
322  RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
323  const char *id = NULL;
324  unsigned int buckets = 0;
325  unsigned int has_dynamic_contents = 0;
326 
327  if (!cfg) {
328  ast_log(LOG_ERROR, "Unable to load config file '%s'\n", config->filename);
329  return;
330  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
331  ast_debug(1, "Config file '%s' was unchanged\n", config->filename);
332  return;
333  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
334  ast_log(LOG_ERROR, "Contents of config file '%s' are invalid and cannot be parsed\n", config->filename);
335  return;
336  }
337 
338  /* When parsing the configuration assume it is valid until proven otherwise */
339  config->configuration_invalid = 0;
340 
341  if (!config->buckets) {
342  while ((category = ast_category_browse_filtered(cfg, NULL, category, NULL))) {
343 
344  /* If given configuration has not been met skip the category, it is not applicable */
345  if (!sorcery_is_configuration_met(sorcery, type, category, config)) {
346  continue;
347  }
348 
349  buckets++;
350  }
351 
352  /* Determine the optimal number of buckets */
353  while (buckets && !ast_is_prime(buckets)) {
354  /* This purposely goes backwards to ensure that the container doesn't have a ton of
355  * empty buckets for objects that will never get added.
356  */
357  buckets--;
358  }
359 
360  if (!buckets) {
361  buckets = 1;
362  }
363  } else {
364  buckets = config->buckets;
365  }
366 
367  /* For single object configurations there can only ever be one bucket, if there's more than the single
368  * object requirement has been violated.
369  */
370  if (config->single_object && buckets > 1) {
371  ast_log(LOG_ERROR, "Config file '%s' could not be loaded; configuration contains more than one object of type '%s'\n",
372  config->filename, type);
373  ast_config_destroy(cfg);
374  config->configuration_invalid = 1;
375  return;
376  }
377 
378  ast_debug(2, "Using bucket size of '%d' for objects of type '%s' from '%s'\n",
379  buckets, type, config->filename);
380 
383  if (!objects) {
384  ast_log(LOG_ERROR, "Could not create bucket for new objects from '%s', keeping existing objects\n",
385  config->filename);
386  ast_config_destroy(cfg);
387  config->configuration_invalid = 1; /* Not strictly invalid but we want to try next time */
388  return;
389  }
390 
391  while ((category = ast_category_browse_filtered(cfg, NULL, category, NULL))) {
392  RAII_VAR(void *, obj, NULL, ao2_cleanup);
393  id = ast_category_get_name(category);
394 
395  /* If given configuration has not been met skip the category, it is not applicable */
396  if (!sorcery_is_configuration_met(sorcery, type, category, config)) {
397  continue;
398  }
399 
400  /* Confirm an object with this id does not already exist in the bucket.
401  * If it exists, however, the configuration is invalid so stop
402  * processing and destroy it. */
403  obj = ao2_find(objects, id, OBJ_SEARCH_KEY);
404  if (obj) {
405  ast_log(LOG_ERROR, "Config file '%s' could not be loaded; configuration contains a duplicate object: '%s' of type '%s'\n",
406  config->filename, id, type);
407  ast_config_destroy(cfg);
408  config->configuration_invalid = 1;
409  return;
410  }
411 
412  if (!(obj = ast_sorcery_alloc(sorcery, type, id)) ||
414 
415  if (config->file_integrity) {
416  ast_log(LOG_ERROR, "Config file '%s' could not be loaded due to error with object '%s' of type '%s'\n",
417  config->filename, id, type);
418  ast_config_destroy(cfg);
419  config->configuration_invalid = 1;
420  return;
421  } else {
422  ast_log(LOG_ERROR, "Could not create an object of type '%s' with id '%s' from configuration file '%s'\n",
423  type, id, config->filename);
424  config->configuration_invalid = 1;
425  }
426 
427  ao2_cleanup(obj);
428 
429  /* To ensure we don't lose the object that already exists we retrieve it from the old objects container and add it to the new one */
430  if (!(obj = sorcery_config_retrieve_id(sorcery, data, type, id))) {
431  continue;
432  }
433 
434  ast_log(LOG_NOTICE, "Retaining existing configuration for object of type '%s' with id '%s'\n", type, id);
435  }
436 
437  /* We store the dynamic contents state until the end in case this reload or load
438  * gets rolled back.
439  */
440  has_dynamic_contents |= ast_sorcery_object_has_dynamic_contents(obj);
441 
442  ao2_link(objects, obj);
443  }
444 
445  config->has_dynamic_contents = has_dynamic_contents;
446  ao2_global_obj_replace_unref(config->objects, objects);
447  ast_config_destroy(cfg);
448 }
#define ast_log
Definition: astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
static const char type[]
Definition: chan_ooh323.c:109
int ast_is_prime(int num)
Determines if the specified number is prime.
Definition: hashtab.c:101
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1102
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:1409
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1231
@ CONFIG_FLAG_FILEUNCHANGED
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3220
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_NOTICE
static int reload(void)
static struct ast_sorcery * sorcery
static void * sorcery_config_retrieve_id(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
static int sorcery_is_configuration_met(const struct ast_sorcery *sorcery, const char *type, struct ast_category *category, struct sorcery_config *config)
Internal function which determines if criteria has been met for considering an object set applicable.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2459
unsigned int ast_sorcery_object_has_dynamic_contents(const void *object)
Get whether an object contains dynamic contents or not.
Definition: sorcery.c:2372
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
Definition: sorcery.c:1632
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
int ast_sorcery_object_id_hash(const void *obj, int flags)
ao2 object hasher based on sorcery id.
Definition: sorcery.c:2470
Generic container type.
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_hash, ao2_find, ao2_global_obj_replace_unref, ao2_link, ast_category_browse_filtered(), ast_category_first(), ast_category_get_name(), ast_config_destroy(), ast_config_load2(), ast_debug, ast_is_prime(), ast_log, ast_sorcery_alloc(), ast_sorcery_object_has_dynamic_contents(), ast_sorcery_object_id_compare(), ast_sorcery_object_id_hash(), ast_sorcery_objectset_apply(), config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, ast_flags::flags, LOG_ERROR, LOG_NOTICE, NULL, OBJ_SEARCH_KEY, RAII_VAR, reload(), sorcery, sorcery_config_retrieve_id(), sorcery_is_configuration_met(), and type.

Referenced by sorcery_config_load(), and sorcery_config_reload().

◆ sorcery_config_load()

static void sorcery_config_load ( void *  data,
const struct ast_sorcery sorcery,
const char *  type 
)
static

Definition at line 450 of file res_sorcery_config.c.

451 {
453 }
static void sorcery_config_internal_load(void *data, const struct ast_sorcery *sorcery, const char *type, unsigned int reload)

References sorcery, sorcery_config_internal_load(), and type.

◆ sorcery_config_open()

static void * sorcery_config_open ( const char *  data)
static

Definition at line 460 of file res_sorcery_config.c.

461 {
462  char *tmp;
463  char *filename;
464  char *option;
465  struct sorcery_config *config;
466 
467  if (ast_strlen_zero(data)) {
468  return NULL;
469  }
470 
471  tmp = ast_strdupa(data);
472  filename = strsep(&tmp, ",");
473 
475  return NULL;
476  }
477 
478  ast_uuid_generate_str(config->uuid, sizeof(config->uuid));
479 
480  ast_rwlock_init(&config->objects.lock);
481  strcpy(config->filename, filename);
482 
483  while ((option = strsep(&tmp, ","))) {
484  char *name = strsep(&option, "="), *value = option;
485 
486  if (!strcasecmp(name, "buckets")) {
487  if (sscanf(value, "%30u", &config->buckets) != 1) {
488  ast_log(LOG_ERROR, "Unsupported bucket size of '%s' used for configuration file '%s', defaulting to automatic determination\n",
489  value, filename);
490  }
491  } else if (!strcasecmp(name, "integrity")) {
492  if (!strcasecmp(value, "file")) {
493  config->file_integrity = 1;
494  } else if (!strcasecmp(value, "object")) {
495  config->file_integrity = 0;
496  } else {
497  ast_log(LOG_ERROR, "Unsupported integrity value of '%s' used for configuration file '%s', defaulting to 'object'\n",
498  value, filename);
499  }
500  } else if (!strcasecmp(name, "criteria")) {
501  char *field = strsep(&value, "=");
502  struct ast_variable *criteria = ast_variable_new(field, value, "");
503 
504  if (criteria) {
505  criteria->next = config->criteria;
506  config->criteria = criteria;
507  } else {
508  /* This is fatal since not following criteria would potentially yield invalid objects */
509  ast_log(LOG_ERROR, "Could not create criteria entry of field '%s' with value '%s' for configuration file '%s'\n",
510  field, value, filename);
511  ao2_ref(config, -1);
512  return NULL;
513  }
514  } else if (!strcasecmp(name, "explicit_name")) {
515  ast_free(config->explicit_name);
516  config->explicit_name = ast_strdup(value);
517  if (ast_strlen_zero(config->explicit_name)) {
518  /* This is fatal since it could stop a configuration section from getting applied */
519  ast_log(LOG_ERROR, "Could not create explicit name entry of '%s' for configuration file '%s'\n",
520  value, filename);
521  ao2_ref(config, -1);
522  return NULL;
523  }
524  } else if (!strcasecmp(name, "single_object")) {
525  if (ast_strlen_zero(value)) {
526  ast_log(LOG_ERROR, "Could not set single object value for configuration file '%s' as the value is empty\n",
527  filename);
528  ao2_ref(config, -1);
529  return NULL;
530  }
531  config->single_object = ast_true(value);
532  } else {
533  ast_log(LOG_ERROR, "Unsupported option '%s' used for configuration file '%s'\n", name, filename);
534  }
535  }
536 
537  return config;
538 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static int tmp()
Definition: bt_open.c:389
static const char name[]
Definition: format_mp3.c:68
char * strsep(char **str, const char *delims)
#define ast_variable_new(name, value, filename)
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
Definition: lock.h:222
static void sorcery_config_destructor(void *obj)
Destructor function for sorcery config.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: main/utils.c:2097
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
struct ast_variable * next
char filename[]
Filename of the configuration file.
int value
Definition: syslog.c:37
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_free, ast_log, ast_rwlock_init, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_uuid_generate_str(), ast_variable_new, config, sorcery_config::filename, LOG_ERROR, name, ast_variable::next, NULL, sorcery_config_destructor(), strsep(), tmp(), and value.

◆ sorcery_config_reload()

static void sorcery_config_reload ( void *  data,
const struct ast_sorcery sorcery,
const char *  type 
)
static

Definition at line 455 of file res_sorcery_config.c.

456 {
458 }

References sorcery, sorcery_config_internal_load(), and type.

◆ sorcery_config_retrieve_fields()

static void * sorcery_config_retrieve_fields ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const struct ast_variable fields 
)
static

Definition at line 170 of file res_sorcery_config.c.

171 {
172  struct sorcery_config *config = data;
174  struct sorcery_config_fields_cmp_params params = {
175  .sorcery = sorcery,
176  .fields = fields,
177  .container = NULL,
178  };
179 
180  /* If no fields are present return nothing, we require *something*, same goes if no objects exist yet */
181  if (!objects || !fields) {
182  return NULL;
183  }
184 
185  return ao2_callback(objects, 0, sorcery_config_fields_cmp, &params);
186 }
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static int sorcery_config_fields_cmp(void *obj, void *arg, int flags)
struct ao2_global_obj objects
Objects retrieved from the configuration file.

References ao2_callback, ao2_cleanup, ao2_global_obj_ref, config, sorcery_config_fields_cmp_params::fields, NULL, sorcery_config::objects, RAII_VAR, sorcery, sorcery_config_fields_cmp_params::sorcery, and sorcery_config_fields_cmp().

◆ sorcery_config_retrieve_id()

static void * sorcery_config_retrieve_id ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const char *  id 
)
static

Definition at line 188 of file res_sorcery_config.c.

189 {
190  struct sorcery_config *config = data;
192 
193  return objects ? ao2_find(objects, id, OBJ_SEARCH_KEY) : NULL;
194 }

References ao2_cleanup, ao2_find, ao2_global_obj_ref, config, NULL, OBJ_SEARCH_KEY, sorcery_config::objects, and RAII_VAR.

Referenced by sorcery_config_internal_load().

◆ sorcery_config_retrieve_multiple()

static void sorcery_config_retrieve_multiple ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
struct ao2_container objects,
const struct ast_variable fields 
)
static

Definition at line 196 of file res_sorcery_config.c.

197 {
198  struct sorcery_config *config = data;
199  RAII_VAR(struct ao2_container *, config_objects, ao2_global_obj_ref(config->objects), ao2_cleanup);
200  struct sorcery_config_fields_cmp_params params = {
201  .sorcery = sorcery,
202  .fields = fields,
203  .container = objects,
204  };
205 
206  if (!config_objects) {
207  return;
208  }
209 
210  ao2_callback(config_objects, OBJ_NODATA | OBJ_MULTIPLE, sorcery_config_fields_cmp, &params);
211 }
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049

References ao2_callback, ao2_cleanup, ao2_global_obj_ref, config, sorcery_config_fields_cmp_params::fields, OBJ_MULTIPLE, OBJ_NODATA, RAII_VAR, sorcery, sorcery_config_fields_cmp_params::sorcery, and sorcery_config_fields_cmp().

◆ sorcery_config_retrieve_prefix()

static void sorcery_config_retrieve_prefix ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
struct ao2_container objects,
const char *  prefix,
const size_t  prefix_len 
)
static

Definition at line 236 of file res_sorcery_config.c.

237 {
238  struct sorcery_config *config = data;
239  RAII_VAR(struct ao2_container *, config_objects, ao2_global_obj_ref(config->objects), ao2_cleanup);
240  struct sorcery_config_fields_cmp_params params = {
241  .sorcery = sorcery,
242  .container = objects,
243  .prefix = prefix,
244  .prefix_len = prefix_len,
245  };
246 
247  if (!config_objects) {
248  return;
249  }
250 
251  ao2_callback(config_objects, OBJ_NODATA | OBJ_MULTIPLE, sorcery_config_fields_cmp, &params);
252 }
static char prefix[MAX_PREFIX]
Definition: http.c:144

References ao2_callback, ao2_cleanup, ao2_global_obj_ref, config, OBJ_MULTIPLE, OBJ_NODATA, prefix, sorcery_config_fields_cmp_params::prefix_len, RAII_VAR, sorcery, sorcery_config_fields_cmp_params::sorcery, and sorcery_config_fields_cmp().

◆ sorcery_config_retrieve_regex()

static void sorcery_config_retrieve_regex ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
struct ao2_container objects,
const char *  regex 
)
static

Definition at line 213 of file res_sorcery_config.c.

214 {
215  struct sorcery_config *config = data;
216  RAII_VAR(struct ao2_container *, config_objects, ao2_global_obj_ref(config->objects), ao2_cleanup);
217  regex_t expression;
218  struct sorcery_config_fields_cmp_params params = {
219  .sorcery = sorcery,
220  .container = objects,
221  .regex = &expression,
222  };
223 
224  if (ast_strlen_zero(regex)) {
225  regex = ".";
226  }
227 
228  if (!config_objects || regcomp(&expression, regex, REG_EXTENDED | REG_NOSUB)) {
229  return;
230  }
231 
232  ao2_callback(config_objects, OBJ_NODATA | OBJ_MULTIPLE, sorcery_config_fields_cmp, &params);
233  regfree(&expression);
234 }
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)

References ao2_callback, ao2_cleanup, ao2_global_obj_ref, ast_strlen_zero(), config, OBJ_MULTIPLE, OBJ_NODATA, RAII_VAR, regex(), sorcery, sorcery_config_fields_cmp_params::sorcery, and sorcery_config_fields_cmp().

◆ sorcery_is_configuration_met()

static int sorcery_is_configuration_met ( const struct ast_sorcery sorcery,
const char *  type,
struct ast_category category,
struct sorcery_config config 
)
static

Internal function which determines if criteria has been met for considering an object set applicable.

Definition at line 300 of file res_sorcery_config.c.

302 {
303  if (!config->criteria && ast_strlen_zero(config->explicit_name)) {
304  /* Nothing is configured to allow specific matching, so accept it! */
305  return 1;
306  } else if (sorcery_is_explicit_name_met(sorcery, type, category, config)) {
307  return 1;
308  } else if (sorcery_is_criteria_met(category, config)) {
309  return 1;
310  } else {
311  /* Nothing explicitly matched so reject */
312  return 0;
313  }
314 }
static int sorcery_is_criteria_met(struct ast_category *category, struct sorcery_config *config)
Internal function which determines if a category matches based on criteria.
static int sorcery_is_explicit_name_met(const struct ast_sorcery *sorcery, const char *type, struct ast_category *category, struct sorcery_config *config)
Internal function which determines if a category matches based on explicit name.

References ast_strlen_zero(), config, sorcery, sorcery_is_criteria_met(), sorcery_is_explicit_name_met(), and type.

Referenced by sorcery_config_internal_load().

◆ sorcery_is_criteria_met()

static int sorcery_is_criteria_met ( struct ast_category category,
struct sorcery_config config 
)
static

Internal function which determines if a category matches based on criteria.

Definition at line 288 of file res_sorcery_config.c.

289 {
291 
292  if (!config->criteria) {
293  return 0;
294  }
295 
296  return (!ast_sorcery_changeset_create(ast_category_first(category), config->criteria, &diff) && !diff) ? 1 : 0;
297 }
int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
Create a changeset given two object sets.
Definition: sorcery.c:1663

References ast_category_first(), ast_sorcery_changeset_create(), ast_variables_destroy(), config, NULL, and RAII_VAR.

Referenced by sorcery_is_configuration_met().

◆ sorcery_is_explicit_name_met()

static int sorcery_is_explicit_name_met ( const struct ast_sorcery sorcery,
const char *  type,
struct ast_category category,
struct sorcery_config config 
)
static

Internal function which determines if a category matches based on explicit name.

Definition at line 255 of file res_sorcery_config.c.

257 {
258  struct ast_sorcery_object_type *object_type;
259  struct ast_variable *field;
260  int met = 1;
261 
262  if (ast_strlen_zero(config->explicit_name) || strcmp(ast_category_get_name(category), config->explicit_name)) {
263  return 0;
264  }
265 
266  object_type = ast_sorcery_get_object_type(sorcery, type);
267  if (!object_type) {
268  return 0;
269  }
270 
271  /* We iterate the configured fields to see if we don't know any, if we don't then
272  * this is likely not for the given type and we skip it. If it actually is then criteria
273  * may pick it up in which case it would just get rejected as an invalid configuration later.
274  */
275  for (field = ast_category_first(category); field; field = field->next) {
276  if (!ast_sorcery_is_object_field_registered(object_type, field->name)) {
277  met = 0;
278  break;
279  }
280  }
281 
282  ao2_ref(object_type, -1);
283 
284  return met;
285 }
int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type, const char *field_name)
Determine if a particular object field has been registered with sorcery.
Definition: sorcery.c:2509
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
Definition: sorcery.c:2489
Structure for registered object type.
Definition: sorcery.c:148

References ao2_ref, ast_category_first(), ast_category_get_name(), ast_sorcery_get_object_type(), ast_sorcery_is_object_field_registered(), ast_strlen_zero(), config, ast_variable::name, ast_variable::next, sorcery, and type.

Referenced by sorcery_is_configuration_met().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 556 of file res_sorcery_config.c.

557 {
559  return 0;
560 }
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
Definition: sorcery.c:474

Variable Documentation

◆ __mod_info

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

Definition at line 556 of file res_sorcery_config.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 567 of file res_sorcery_config.c.

◆ config_object_wizard

struct ast_sorcery_wizard config_object_wizard
static

Definition at line 105 of file res_sorcery_config.c.

Referenced by load_module().