45 char uuid[AST_UUID_STR_LEN];
96 static void *sorcery_config_open(
const char *data);
97 static void sorcery_config_load(
void *data,
const struct ast_sorcery *sorcery,
const char *type);
98 static void sorcery_config_reload(
void *data,
const struct ast_sorcery *sorcery,
const char *type);
99 static void *sorcery_config_retrieve_id(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const char *
id);
100 static void *sorcery_config_retrieve_fields(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const struct ast_variable *fields);
101 static void sorcery_config_retrieve_multiple(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
103 static void sorcery_config_retrieve_regex(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *regex);
104 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);
105 static void sorcery_config_close(
void *data);
109 .open = sorcery_config_open,
110 .load = sorcery_config_load,
111 .reload = sorcery_config_reload,
112 .force_reload = sorcery_config_load,
113 .retrieve_id = sorcery_config_retrieve_id,
114 .retrieve_fields = sorcery_config_retrieve_fields,
115 .retrieve_multiple = sorcery_config_retrieve_multiple,
116 .retrieve_regex = sorcery_config_retrieve_regex,
117 .retrieve_prefix = sorcery_config_retrieve_prefix,
118 .close = sorcery_config_close,
132 static int sorcery_config_fields_cmp(
void *obj,
void *arg,
int flags)
143 }
else if (params->
prefix) {
148 }
else if (params->
fields &&
181 if (!objects || !fields) {
185 return ao2_callback(objects, 0, sorcery_config_fields_cmp, ¶ms);
188 static void *sorcery_config_retrieve_id(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const char *
id)
203 .container = objects,
206 if (!config_objects) {
213 static void sorcery_config_retrieve_regex(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *
regex)
220 .container = objects,
221 .regex = &expression,
224 if (ast_strlen_zero(regex)) {
228 if (!config_objects || regcomp(&expression, regex, REG_EXTENDED | REG_NOSUB)) {
233 regfree(&expression);
242 .container = objects,
247 if (!config_objects) {
316 static void sorcery_config_internal_load(
void *data,
const struct ast_sorcery *sorcery,
const char *type,
unsigned int reload)
323 const char *
id = NULL;
324 unsigned int buckets = 0;
325 unsigned int has_dynamic_contents = 0;
328 ast_log(LOG_ERROR,
"Unable to load config file '%s'\n", config->
filename);
330 }
else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
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);
371 ast_log(LOG_ERROR,
"Config file '%s' could not be loaded; configuration contains more than one object of type '%s'\n",
378 ast_debug(2,
"Using bucket size of '%d' for objects of type '%s' from '%s'\n",
384 ast_log(LOG_ERROR,
"Could not create bucket for new objects from '%s', keeping existing objects\n",
392 RAII_VAR(
void *, obj, NULL, ao2_cleanup);
405 ast_log(LOG_ERROR,
"Config file '%s' could not be loaded; configuration contains a duplicate object: '%s' of type '%s'\n",
416 ast_log(LOG_ERROR,
"Config file '%s' could not be loaded due to error with object '%s' of type '%s'\n",
422 ast_log(LOG_ERROR,
"Could not create an object of type '%s' with id '%s' from configuration file '%s'\n",
430 if (!(obj = sorcery_config_retrieve_id(sorcery, data, type,
id))) {
434 ast_log(LOG_NOTICE,
"Retaining existing configuration for object of type '%s' with id '%s'\n", type,
id);
450 static void sorcery_config_load(
void *data,
const struct ast_sorcery *sorcery,
const char *type)
452 sorcery_config_internal_load(data, sorcery, type, 0);
455 static void sorcery_config_reload(
void *data,
const struct ast_sorcery *sorcery,
const char *type)
457 sorcery_config_internal_load(data, sorcery, type, 1);
460 static void *sorcery_config_open(
const char *data)
467 if (ast_strlen_zero(data)) {
472 filename = strsep(&tmp,
",");
483 while ((option = strsep(&tmp,
","))) {
484 char *name = strsep(&option,
"="), *value = option;
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",
491 }
else if (!strcasecmp(name,
"integrity")) {
492 if (!strcasecmp(value,
"file")) {
494 }
else if (!strcasecmp(value,
"object")) {
497 ast_log(LOG_ERROR,
"Unsupported integrity value of '%s' used for configuration file '%s', defaulting to 'object'\n",
500 }
else if (!strcasecmp(name,
"criteria")) {
501 char *field = strsep(&value,
"=");
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);
514 }
else if (!strcasecmp(name,
"explicit_name")) {
519 ast_log(LOG_ERROR,
"Could not create explicit name entry of '%s' for configuration file '%s'\n",
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",
533 ast_log(LOG_ERROR,
"Unsupported option '%s' used for configuration file '%s'\n", name, filename);
540 static void sorcery_config_close(
void *data)
547 static int load_module(
void)
556 static int unload_module(
void)
562 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER,
"Sorcery Configuration File Object Wizard",
563 .support_level = AST_MODULE_SUPPORT_CORE,
565 .unload = unload_module,
struct ast_variable * next
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.
Asterisk main include file. File version handling, generic pbx functions.
unsigned int ast_sorcery_object_has_dynamic_contents(const void *object)
Get whether an object contains dynamic contents or not.
struct ast_variable * criteria
Any specific variable criteria for considering a defined category for this object.
unsigned int single_object
Enable enforcement of a single configuration object of this type.
static void sorcery_config_destructor(void *obj)
Destructor function for sorcery config.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
The arg parameter is a search key, but is not an object.
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Generic (perhaps overly so) hashtable implementation Hash Table support in Asterisk.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Structure for variables, used for configurations and for channel variables.
Universally unique identifier support.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Full structure for sorcery.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
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.
#define ast_strdup(str)
A wrapper for strdup()
const size_t prefix_len
Prefix length in bytes for matching object id.
const char * name
Name of the wizard.
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.
regex_t * regex
Regular expression for checking object id.
Configuration File Parser.
const char * prefix
Prefix for matching object id.
Structure for registered object type.
const struct ast_sorcery * sorcery
Pointer to the sorcery structure.
struct ao2_container * container
Optional container to put object into.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
char uuid[AST_UUID_STR_LEN]
UUID for identifying us when opening a configuration file.
#define ast_debug(level,...)
Log a DEBUG message.
struct ao2_global_obj objects
Objects retrieved from the configuration file.
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.
Structure for storing configuration file sourced objects.
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
#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.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
const struct ast_variable * fields
Pointer to the fields to check.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
char * explicit_name
An explicit name for the configuration section, with it there can be only one.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
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.
unsigned int configuration_invalid
Configuration is invalid in some way, force reload.
unsigned int file_integrity
Enable file level integrity instead of object level.
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
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...
Module has failed to load, may be in an inconsistent state.
Structure used for fields comparison.
char filename[]
Filename of the configuration file.
Structure used to handle boolean flags.
Interface for a sorcery wizard.
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
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.
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.
int ast_sorcery_object_id_hash(const void *obj, int flags)
ao2 object hasher based on sorcery id.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
#define ASTERISK_GPL_KEY
The text the key() function should return.
unsigned int has_dynamic_contents
Configuration contains at least one object with dynamic contents.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
unsigned int buckets
Number of buckets to use for objects.
int ast_is_prime(int num)
Determines if the specified number is prime.
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Sorcery Data Access Layer API.
#define ao2_link(container, obj)
Add an object to a container.