Asterisk - The Open Source Telephony Project GIT-master-2de1a68
Data Structures | Macros | Functions | Variables
sorcery.c File Reference

Sorcery Data Access Layer API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/sorcery.h"
#include "asterisk/astobj2.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/strings.h"
#include "asterisk/config_options.h"
#include "asterisk/netsock2.h"
#include "asterisk/module.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/threadpool.h"
#include "asterisk/json.h"
#include "asterisk/vector.h"
Include dependency graph for sorcery.c:

Go to the source code of this file.

Data Structures

struct  ast_sorcery
 Full structure for sorcery. More...
 
struct  ast_sorcery_internal_wizard
 Structure for an internal wizard instance. More...
 
struct  ast_sorcery_object
 Structure for internal sorcery object information. More...
 
struct  ast_sorcery_object_field
 Structure for registered object field. More...
 
struct  ast_sorcery_object_type
 Structure for registered object type. More...
 
struct  ast_sorcery_object_type_observer
 Structure for registered object type observer. More...
 
struct  ast_sorcery_object_wizard
 Structure for a wizard instance which operates on objects. More...
 
struct  sorcery_details
 Structure used when calling create, update, or delete. More...
 
struct  sorcery_global_observer
 A global observer wrapper. More...
 
struct  sorcery_instance_observer
 An instance observer wrapper. More...
 
struct  sorcery_load_details
 Structure for passing load/reload details. More...
 
struct  sorcery_observer_invocation
 Structure used for observer invocations. More...
 
struct  sorcery_proxy
 Proxy object for sorcery. More...
 
struct  sorcery_wizard_observer
 A wizard observer wrapper. More...
 

Macros

#define INITIAL_WIZARD_VECTOR_SIZE   5
 
#define INSTANCE_BUCKETS   17
 Number of buckets for instances (should be prime for performance reasons) More...
 
#define MAX_REGEX_ERROR_LEN   128
 
#define NOTIFY_GENERIC_OBSERVERS(container, type, callback, ...)
 
#define NOTIFY_GLOBAL_OBSERVERS(container, callback, ...)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_global_observer, callback, __VA_ARGS__)
 
#define NOTIFY_INSTANCE_OBSERVERS(container, callback, ...)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_instance_observer, callback, __VA_ARGS__)
 
#define NOTIFY_WIZARD_OBSERVERS(container, callback, ...)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_wizard_observer, callback, __VA_ARGS__)
 
#define OBJECT_FIELD_BUCKETS   29
 Number of buckets for object fields (should be prime for performance reasons) More...
 
#define TYPE_BUCKETS   53
 Number of buckets for types (should be prime for performance reasons) More...
 
#define WIZARD_BUCKETS   7
 Number of buckets for wizards (should be prime for performance reasons) More...
 
#define WIZARD_COMPARE(a, b)   ((a)->wizard == (b))
 
#define WIZARD_NAME_COMPARE(a, b)   (strcmp((a)->wizard->callbacks.name, (b)) == 0)
 

Functions

enum ast_sorcery_apply_result __ast_sorcery_apply_config (struct ast_sorcery *sorcery, const char *name, const char *module)
 Apply configured wizard mappings. More...
 
enum ast_sorcery_apply_result __ast_sorcery_apply_default (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data)
 Apply default object wizard mappings. More...
 
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching)
 Internal function which creates an object type and adds a wizard mapping. More...
 
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching, int position)
 Internal function which creates an object type and inserts a wizard mapping. More...
 
int __ast_sorcery_object_field_register (struct ast_sorcery *sorcery, const char *type, const char *name, const char *default_val, enum aco_option_type opt_type, aco_option_handler config_handler, sorcery_field_handler sorcery_handler, sorcery_fields_handler multiple_handler, unsigned int flags, unsigned int no_doc, unsigned int alias, size_t argc,...)
 Register a field within an object. More...
 
int __ast_sorcery_object_register (struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
 Register an object type. More...
 
enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard (struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, enum ast_sorcery_wizard_apply_flags flags, int position, struct ast_sorcery_wizard **wizard, void **wizard_data)
 Insert an additional object wizard mapping at a specific position in the wizard list returning wizard information. More...
 
int __ast_sorcery_object_type_remove_wizard (struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args)
 Remove an object wizard mapping. More...
 
struct ast_sorcery__ast_sorcery_open (const char *module_name, const char *file, int line, const char *func)
 
int __ast_sorcery_remove_wizard_mapping (struct ast_sorcery *sorcery, const char *type, const char *module, const char *name)
 Internal function removes a wizard mapping. More...
 
int __ast_sorcery_wizard_register (const struct ast_sorcery_wizard *interface, struct ast_module *module)
 Register a sorcery wizard. More...
 
void * ast_sorcery_alloc (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Allocate an object. More...
 
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. More...
 
void * ast_sorcery_copy (const struct ast_sorcery *sorcery, const void *object)
 Create a copy of an object. More...
 
int ast_sorcery_create (const struct ast_sorcery *sorcery, void *object)
 Create and potentially persist an object using an available wizard. More...
 
int ast_sorcery_delete (const struct ast_sorcery *sorcery, void *object)
 Delete an object. More...
 
int ast_sorcery_diff (const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes)
 Create a changeset of two objects. More...
 
void ast_sorcery_force_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects, even if no changes determined. More...
 
void ast_sorcery_force_reload_object (const struct ast_sorcery *sorcery, const char *type)
 Inform any wizards of a specific object type to reload persistent objects even if no changes determined. More...
 
void * ast_sorcery_generic_alloc (size_t size, ao2_destructor_fn destructor)
 Allocate a generic sorcery capable object. More...
 
const char * ast_sorcery_get_module (const struct ast_sorcery *sorcery)
 Get the module that has opened the provided sorcery instance. More...
 
struct ast_sorcery_object_typeast_sorcery_get_object_type (const struct ast_sorcery *sorcery, const char *type)
 Get the sorcery object type given a type name. More...
 
int ast_sorcery_get_wizard_mapping (struct ast_sorcery *sorcery, const char *type, int index, struct ast_sorcery_wizard **wizard, void **data)
 By index, return a wizard mapped to an object type. More...
 
int ast_sorcery_get_wizard_mapping_count (struct ast_sorcery *sorcery, const char *type)
 Return the number of wizards mapped to an object type. More...
 
int ast_sorcery_global_observer_add (const struct ast_sorcery_global_observer *callbacks)
 Add a global observer to sorcery. More...
 
void ast_sorcery_global_observer_remove (const struct ast_sorcery_global_observer *callbacks)
 Remove a global observer from sorcery. More...
 
int ast_sorcery_init (void)
 Compare function for sorcery instances. More...
 
int ast_sorcery_instance_observer_add (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Add an observer to a sorcery instance. More...
 
void ast_sorcery_instance_observer_remove (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Remove an observer from a sorcery instance. More...
 
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. More...
 
int ast_sorcery_is_stale (const struct ast_sorcery *sorcery, void *object)
 Determine if a sorcery object is stale with respect to its backing datastore. More...
 
void ast_sorcery_load (const struct ast_sorcery *sorcery)
 Inform any wizards to load persistent objects. More...
 
void ast_sorcery_load_object (const struct ast_sorcery *sorcery, const char *type)
 Inform any wizards of a specific object type to load persistent objects. More...
 
void * ast_sorcery_lockable_alloc (size_t size, ao2_destructor_fn destructor, void *lockobj)
 Allocate a generic sorcery capable object with locking. More...
 
int ast_sorcery_object_fields_register (struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
 Register a regex for multiple fields within an object. More...
 
const struct timeval ast_sorcery_object_get_created (const void *object)
 Get when the sorcery object was created. More...
 
const char * ast_sorcery_object_get_extended (const void *object, const char *name)
 Get an extended field value from a sorcery object. More...
 
const char * ast_sorcery_object_get_id (const void *object)
 Get the unique identifier of a sorcery object. More...
 
const char * ast_sorcery_object_get_type (const void *object)
 Get the type of a sorcery object. More...
 
unsigned int ast_sorcery_object_has_dynamic_contents (const void *object)
 Get whether an object contains dynamic contents or not. More...
 
int ast_sorcery_object_id_compare (void *obj, void *arg, int flags)
 ao2 object comparator based on sorcery id. More...
 
int ast_sorcery_object_id_hash (const void *obj, int flags)
 ao2 object hasher based on sorcery id. More...
 
int ast_sorcery_object_id_sort (const void *obj, const void *arg, int flags)
 ao2 object sorter based on sorcery id. More...
 
int ast_sorcery_object_set_congestion_levels (struct ast_sorcery *sorcery, const char *type, long low_water, long high_water)
 Set the high and low alert water marks of the sorcery object type. More...
 
void ast_sorcery_object_set_copy_handler (struct ast_sorcery *sorcery, const char *type, sorcery_copy_handler copy)
 Set the copy handler for an object type. More...
 
void ast_sorcery_object_set_diff_handler (struct ast_sorcery *sorcery, const char *type, sorcery_diff_handler diff)
 Set the diff handler for an object type. More...
 
int ast_sorcery_object_set_extended (const void *object, const char *name, const char *value)
 Set an extended field value on a sorcery object. More...
 
void ast_sorcery_object_set_has_dynamic_contents (const void *object)
 Set the dynamic contents flag on a sorcery object. More...
 
int ast_sorcery_object_unregister (struct ast_sorcery *sorcery, const char *type)
 Unregister an object type. More...
 
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. More...
 
struct ast_variableast_sorcery_objectset_create2 (const struct ast_sorcery *sorcery, const void *object, enum ast_sorcery_field_handler_flags flags)
 Create an object set (KVP list) for an object. More...
 
struct ast_jsonast_sorcery_objectset_json_create (const struct ast_sorcery *sorcery, const void *object)
 Create an object set in JSON format for an object. More...
 
int ast_sorcery_observer_add (const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
 Add an observer to a specific object type. More...
 
void ast_sorcery_observer_remove (const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
 Remove an observer from a specific object type. More...
 
void ast_sorcery_ref (struct ast_sorcery *sorcery)
 Increase the reference count of a sorcery structure. More...
 
void ast_sorcery_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects. More...
 
void ast_sorcery_reload_object (const struct ast_sorcery *sorcery, const char *type)
 Inform any wizards of a specific object type to reload persistent objects. More...
 
void * ast_sorcery_retrieve_by_fields (const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
 Retrieve an object or multiple objects using specific fields. More...
 
void * ast_sorcery_retrieve_by_id (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Retrieve an object using its unique identifier. More...
 
struct ast_sorceryast_sorcery_retrieve_by_module_name (const char *module_name)
 Search function for sorcery instances. More...
 
struct ao2_containerast_sorcery_retrieve_by_prefix (const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len)
 Retrieve multiple objects whose id begins with the specified prefix. More...
 
struct ao2_containerast_sorcery_retrieve_by_regex (const struct ast_sorcery *sorcery, const char *type, const char *regex)
 Retrieve multiple objects using a regular expression on their id. More...
 
int ast_sorcery_update (const struct ast_sorcery *sorcery, void *object)
 Update an object. More...
 
int ast_sorcery_wizard_observer_add (struct ast_sorcery_wizard *interface, const struct ast_sorcery_wizard_observer *callbacks)
 Add an observer to a sorcery wizard. More...
 
void ast_sorcery_wizard_observer_remove (struct ast_sorcery_wizard *interface, const struct ast_sorcery_wizard_observer *callbacks)
 Remove an observer from a sorcery wizard. More...
 
int ast_sorcery_wizard_unregister (const struct ast_sorcery_wizard *interface)
 Unregister a sorcery wizard. More...
 
 AST_VECTOR_RW (ast_sorcery_object_wizards, struct ast_sorcery_object_wizard *)
 Interface for a sorcery object type wizards. More...
 
static int bool_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int chararray_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int codec_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int double_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static struct ast_variableget_multiple_fields_as_var_list (const void *object, struct ast_sorcery_object_field *object_field)
 
static struct ast_variableget_single_field_as_var_list (const void *object, struct ast_sorcery_object_field *object_field)
 
static int int_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int is_registered_cb (void *obj, void *arg, int flags)
 
static int sockaddr_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int sorcery_cache_create (void *obj, void *arg, int flags)
 Internal function used to create an object in caching wizards. More...
 
static void sorcery_cleanup (void)
 Hashing and comparison functions for sorcery wizards. More...
 
static void sorcery_destructor (void *obj)
 Destructor called when sorcery structure is destroyed. More...
 
static int sorcery_extended_config_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int sorcery_extended_fields_handler (const void *obj, struct ast_variable **fields)
 
static sorcery_field_handler sorcery_field_default_handler (enum aco_option_type type)
 
static int sorcery_generic_observer_remove (void *obj, void *arg, int flags)
 Internal callback function for removing a generic observer. More...
 
static void sorcery_internal_wizard_destructor (void *obj)
 
static void sorcery_object_destructor (void *object)
 
static void sorcery_object_field_destructor (void *obj)
 
static int sorcery_object_load (void *obj, void *arg, int flags)
 
static struct ast_sorcery_object_typesorcery_object_type_alloc (const char *type, const char *module)
 Internal function which allocates an object type structure. More...
 
static void sorcery_object_type_destructor (void *obj)
 Destructor function for object types. More...
 
static void sorcery_object_wizard_destructor (void *obj)
 Object wizard destructor. More...
 
static struct sorcery_observer_invocationsorcery_observer_invocation_alloc (struct ast_sorcery_object_type *object_type, void *object)
 Allocator function for observer invocation. More...
 
static void sorcery_observer_invocation_destroy (void *obj)
 Destructor for observer invocation. More...
 
static int sorcery_observer_notify_create (void *obj, void *arg, int flags)
 Internal callback function which notifies an individual observer that an object has been created. More...
 
static int sorcery_observer_notify_delete (void *obj, void *arg, int flags)
 Internal callback function which notifies an individual observer that an object has been deleted. More...
 
static int sorcery_observer_notify_loaded (void *obj, void *arg, int flags)
 Internal callback function which notifies an individual observer that an object type has been loaded. More...
 
static int sorcery_observer_notify_update (void *obj, void *arg, int flags)
 Internal callback function which notifies an individual observer that an object has been updated. More...
 
static int sorcery_observer_remove (void *obj, void *arg, int flags)
 Internal callback function for removing an observer. More...
 
static int sorcery_observers_notify_create (void *data)
 Internal callback function which notifies observers that an object has been created. More...
 
static int sorcery_observers_notify_delete (void *data)
 Internal callback function which notifies observers that an object has been deleted. More...
 
static int sorcery_observers_notify_loaded (void *data)
 Internal callback function which notifies observers that an object type has been loaded. More...
 
static int sorcery_observers_notify_update (void *data)
 Internal callback function which notifies observers that an object has been updated. More...
 
static void sorcery_proxy_cb (void *weakproxy, void *data)
 Hashing function for sorcery types. More...
 
static int sorcery_reloadable (const struct ast_sorcery *sorcery, const char *type)
 Retrieves whether or not the type is reloadable. More...
 
static int sorcery_wizard_create (const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
 Internal function which returns if the wizard has created the object. More...
 
static int sorcery_wizard_delete (const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
 Internal function which returns if a wizard has deleted the object. More...
 
static int sorcery_wizard_load (void *obj, void *arg, int flags)
 
static int sorcery_wizard_update (const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
 Internal function which returns if a wizard has updated the object. More...
 
static int stringfield_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int uint_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int yesno_handler_fn (const void *obj, const intptr_t *args, char **buf)
 

Variables

static struct ao2_containerinstances
 Registered sorcery instances. More...
 
struct ao2_containerobservers
 Registered global observers. More...
 
static struct ast_threadpoolthreadpool
 Thread pool for observers. More...
 
static struct ao2_containerwizards
 Registered sorcery wizards. More...
 

Detailed Description

Sorcery Data Access Layer API.

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

Definition in file sorcery.c.

Macro Definition Documentation

◆ INITIAL_WIZARD_VECTOR_SIZE

#define INITIAL_WIZARD_VECTOR_SIZE   5

◆ INSTANCE_BUCKETS

#define INSTANCE_BUCKETS   17

Number of buckets for instances (should be prime for performance reasons)

Definition at line 57 of file sorcery.c.

◆ MAX_REGEX_ERROR_LEN

#define MAX_REGEX_ERROR_LEN   128

◆ NOTIFY_GENERIC_OBSERVERS

#define NOTIFY_GENERIC_OBSERVERS (   container,
  type,
  callback,
  ... 
)

Definition at line 62 of file sorcery.c.

◆ NOTIFY_GLOBAL_OBSERVERS

#define NOTIFY_GLOBAL_OBSERVERS (   container,
  callback,
  ... 
)     NOTIFY_GENERIC_OBSERVERS(container, sorcery_global_observer, callback, __VA_ARGS__)

Definition at line 76 of file sorcery.c.

◆ NOTIFY_INSTANCE_OBSERVERS

#define NOTIFY_INSTANCE_OBSERVERS (   container,
  callback,
  ... 
)     NOTIFY_GENERIC_OBSERVERS(container, sorcery_instance_observer, callback, __VA_ARGS__)

Definition at line 79 of file sorcery.c.

◆ NOTIFY_WIZARD_OBSERVERS

#define NOTIFY_WIZARD_OBSERVERS (   container,
  callback,
  ... 
)     NOTIFY_GENERIC_OBSERVERS(container, sorcery_wizard_observer, callback, __VA_ARGS__)

Definition at line 82 of file sorcery.c.

◆ OBJECT_FIELD_BUCKETS

#define OBJECT_FIELD_BUCKETS   29

Number of buckets for object fields (should be prime for performance reasons)

Definition at line 60 of file sorcery.c.

◆ TYPE_BUCKETS

#define TYPE_BUCKETS   53

Number of buckets for types (should be prime for performance reasons)

Definition at line 54 of file sorcery.c.

◆ WIZARD_BUCKETS

#define WIZARD_BUCKETS   7

Number of buckets for wizards (should be prime for performance reasons)

Definition at line 51 of file sorcery.c.

◆ WIZARD_COMPARE

#define WIZARD_COMPARE (   a,
  b 
)    ((a)->wizard == (b))

◆ WIZARD_NAME_COMPARE

#define WIZARD_NAME_COMPARE (   a,
  b 
)    (strcmp((a)->wizard->callbacks.name, (b)) == 0)

Function Documentation

◆ __ast_sorcery_apply_config()

enum ast_sorcery_apply_result __ast_sorcery_apply_config ( struct ast_sorcery sorcery,
const char *  name,
const char *  module 
)

Apply configured wizard mappings.

Parameters
sorceryPointer to a sorcery structure
nameName of the category to use within the configuration file, normally the module name
moduleThe module name (AST_MODULE)

This function is called automatically by __ast_sorcery_open() using the module name as the configuration category. The only reason you should call this function is if your module wishes to apply configuration from additional sections of sorcery.conf.

If a configuration section attempts to apply the same sorcery wizard to an object type more than once, the wizard will only be applied one time.

Returns
What happened when attempting to apply the config.

Definition at line 985 of file sorcery.c.

986{
987 struct ast_flags flags = { 0 };
988 struct ast_config *config = ast_config_load2("sorcery.conf", "sorcery", flags);
989 struct ast_variable *mapping;
991
992 if (!config) {
994 }
995
998 }
999
1000 for (mapping = ast_variable_browse(config, name); mapping; mapping = mapping->next) {
1001 RAII_VAR(char *, mapping_name, ast_strdup(mapping->name), ast_free);
1002 RAII_VAR(char *, mapping_value, ast_strdup(mapping->value), ast_free);
1003 char *options = mapping_name;
1004 char *type = strsep(&options, "/");
1005 char *data = mapping_value;
1006 char *wizard = strsep(&data, ",");
1007 unsigned int caching = 0;
1008
1009 /* If no object type or wizard exists just skip, nothing we can do */
1010 if (ast_strlen_zero(type) || ast_strlen_zero(wizard)) {
1011 continue;
1012 }
1013
1014 /* If the wizard is configured as a cache treat it as such */
1015 if (!ast_strlen_zero(options) && strstr(options, "cache")) {
1016 caching = 1;
1017 }
1018
1019 /* Any error immediately causes us to stop */
1020 if (__ast_sorcery_apply_wizard_mapping(sorcery, type, module, wizard, data, caching) == AST_SORCERY_APPLY_FAIL) {
1022 break;
1023 }
1024 }
1025
1027
1028 return res;
1029}
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
static const char type[]
Definition: chan_ooh323.c:109
static const char config[]
Definition: chan_ooh323.c:111
static const char name[]
Definition: format_mp3.c:68
char * strsep(char **str, const char *delims)
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:3321
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
static struct ast_sorcery * sorcery
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching)
Internal function which creates an object type and adds a wizard mapping.
Definition: sorcery.c:977
@ AST_SORCERY_APPLY_SUCCESS
Definition: sorcery.h:427
@ AST_SORCERY_APPLY_NO_CONFIGURATION
Definition: sorcery.h:433
@ AST_SORCERY_APPLY_FAIL
Definition: sorcery.h:425
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
static struct test_options options
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References __ast_sorcery_apply_wizard_mapping(), ast_config_destroy(), ast_config_load2(), ast_free, AST_SORCERY_APPLY_FAIL, AST_SORCERY_APPLY_NO_CONFIGURATION, AST_SORCERY_APPLY_SUCCESS, ast_strdup, ast_strlen_zero(), ast_variable_browse(), config, CONFIG_STATUS_FILEINVALID, ast_flags::flags, name, ast_variable::name, ast_variable::next, options, RAII_VAR, sorcery, strsep(), type, and ast_variable::value.

Referenced by __ast_sorcery_open().

◆ __ast_sorcery_apply_default()

enum ast_sorcery_apply_result __ast_sorcery_apply_default ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name,
const char *  data 
)

Apply default object wizard mappings.

Parameters
sorceryPointer to a sorcery structure
typeType of object to apply to
moduleThe name of the module, typically AST_MODULE
nameName of the wizard to use
dataData to be passed to wizard
Returns
What occurred when applying the default
Note
This should be called after applying configuration sourced mappings
Only a single default can exist per object type

Definition at line 1031 of file sorcery.c.

1032{
1034
1035 /* Defaults can not be added if any existing mapping exists */
1036 if (object_type) {
1038 }
1039
1040 return __ast_sorcery_apply_wizard_mapping(sorcery, type, module, name, data, 0);
1041}
#define OBJ_KEY
Definition: astobj2.h:1151
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
@ AST_SORCERY_APPLY_DEFAULT_UNNECESSARY
Definition: sorcery.h:431
Structure for registered object type.
Definition: sorcery.c:148
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232

References __ast_sorcery_apply_wizard_mapping(), ao2_cleanup, ao2_find, AST_SORCERY_APPLY_DEFAULT_UNNECESSARY, name, OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

◆ __ast_sorcery_apply_wizard_mapping()

enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name,
const char *  data,
unsigned int  caching 
)

Internal function which creates an object type and adds a wizard mapping.

Apply additional object wizard mappings.

Definition at line 977 of file sorcery.c.

980{
982 data, caching, AST_SORCERY_WIZARD_POSITION_LAST);
983}
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching, int position)
Internal function which creates an object type and inserts a wizard mapping.
Definition: sorcery.c:967
@ AST_SORCERY_WIZARD_POSITION_LAST
Definition: sorcery.h:518

References __ast_sorcery_insert_wizard_mapping(), AST_SORCERY_WIZARD_POSITION_LAST, ast_sorcery_object_wizard::caching, ast_sorcery_object_wizard::data, name, sorcery, and type.

Referenced by __ast_sorcery_apply_config(), and __ast_sorcery_apply_default().

◆ __ast_sorcery_insert_wizard_mapping()

enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name,
const char *  data,
unsigned int  caching,
int  position 
)

Internal function which creates an object type and inserts a wizard mapping.

Insert an additional object wizard mapping at a specific position in the wizard list.

Definition at line 967 of file sorcery.c.

970{
973 position, NULL, NULL);
974}
#define NULL
Definition: resample.c:96
enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, enum ast_sorcery_wizard_apply_flags flags, int position, struct ast_sorcery_wizard **wizard, void **wizard_data)
Insert an additional object wizard mapping at a specific position in the wizard list returning wizard...
Definition: sorcery.c:869
@ AST_SORCERY_WIZARD_APPLY_NONE
Definition: sorcery.h:577
@ AST_SORCERY_WIZARD_APPLY_CACHING
Definition: sorcery.h:579

References __ast_sorcery_object_type_insert_wizard(), AST_SORCERY_WIZARD_APPLY_CACHING, AST_SORCERY_WIZARD_APPLY_NONE, ast_sorcery_object_wizard::caching, ast_sorcery_object_wizard::data, name, NULL, sorcery, and type.

Referenced by __ast_sorcery_apply_wizard_mapping().

◆ __ast_sorcery_object_field_register()

int __ast_sorcery_object_field_register ( struct ast_sorcery sorcery,
const char *  type,
const char *  name,
const char *  default_val,
enum aco_option_type  opt_type,
aco_option_handler  config_handler,
sorcery_field_handler  sorcery_handler,
sorcery_fields_handler  multiple_handler,
unsigned int  flags,
unsigned int  no_doc,
unsigned int  alias,
size_t  argc,
  ... 
)

Register a field within an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
config_handlerA custom handler for translating the string representation of the fields
sorcery_handlerA custom handler for translating the native representation of the fields
multiple_handlerA custom handler for translating the native representation of the fields
opt_typeOption type
flagsOption type specific flags
no_docField should not be documented
aliasInterpret and apply field value only
argc
Return values
0success
-1failure

Definition at line 1192 of file sorcery.c.

1194{
1196 RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1197 int pos;
1198 va_list args;
1199
1200 if (!strcmp(type, "id") || !object_type || !object_type->type.item_alloc) {
1201 return -1;
1202 }
1203
1204 if (!sorcery_handler) {
1205 sorcery_handler = sorcery_field_default_handler(opt_type);
1206 }
1207
1208 if (!(object_field = ao2_alloc(sizeof(*object_field) + argc * sizeof(object_field->args[0]), NULL))) {
1209 return -1;
1210 }
1211
1212 ast_copy_string(object_field->name, name, sizeof(object_field->name));
1213 object_field->handler = sorcery_handler;
1214 object_field->multiple_handler = multiple_handler;
1215
1216 va_start(args, argc);
1217 for (pos = 0; pos < argc; pos++) {
1218 object_field->args[pos] = va_arg(args, size_t);
1219 }
1220 va_end(args);
1221
1222 if (!alias) {
1223 ao2_link(object_type->fields, object_field);
1224 }
1225
1226 /* TODO: Improve this hack */
1227 if (!argc) {
1228 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc);
1229 } else if (argc == 1) {
1230 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1231 object_field->args[0]);
1232 } else if (argc == 2) {
1233 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1234 object_field->args[0], object_field->args[1]);
1235 } else if (argc == 3) {
1236 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1237 object_field->args[0], object_field->args[1], object_field->args[2]);
1238 } else {
1239 ast_assert(0); /* The hack... she does us no good for this */
1240 }
1241
1242 return 0;
1243}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
@ ACO_EXACT
int __aco_option_register(struct aco_info *info, const char *name, enum aco_matchtype match_type, struct aco_type **types, const char *default_val, enum aco_option_type type, aco_option_handler handler, unsigned int flags, unsigned int no_doc, size_t argc,...)
register a config option
static sorcery_field_handler sorcery_field_default_handler(enum aco_option_type type)
Definition: sorcery.c:341
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure for registered object field.
Definition: sorcery.c:205
const char * args
#define ast_assert(a)
Definition: utils.h:739

References __aco_option_register(), ACO_EXACT, ao2_alloc, ao2_cleanup, ao2_find, ao2_link, args, ast_assert, ast_copy_string(), ast_sorcery_object_field::multiple_handler, name, NULL, OBJ_KEY, RAII_VAR, sorcery, sorcery_field_default_handler(), type, and ast_sorcery::types.

◆ __ast_sorcery_object_register()

int __ast_sorcery_object_register ( struct ast_sorcery sorcery,
const char *  type,
unsigned int  hidden,
unsigned int  reloadable,
aco_type_item_alloc  alloc,
sorcery_transform_handler  transform,
sorcery_apply_handler  apply 
)

Register an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
hiddenAll objects of this type are internal and should not be manipulated by users
reloadableAll objects of this type are reloadable
allocRequired object allocation callback
transformOptional transformation callback
applyOptional object set apply callback
Note
In general, this function should not be used directly. One of the various macro'd versions should be used instead.
Return values
0success
-1failure

Definition at line 1080 of file sorcery.c.

1081{
1083
1084 if (!object_type || object_type->type.item_alloc) {
1085 return -1;
1086 }
1087
1088 object_type->type.name = object_type->name;
1089 object_type->type.type = ACO_ITEM;
1090 object_type->type.category = ".?";
1091 object_type->type.item_alloc = alloc;
1092 object_type->type.hidden = hidden;
1093
1094 object_type->reloadable = reloadable;
1095 object_type->transform = transform;
1096 object_type->apply = apply;
1097 object_type->file->types[0] = &object_type->type;
1098 object_type->file->types[1] = NULL;
1099
1100 if (aco_info_init(object_type->info)) {
1101 return -1;
1102 }
1103
1105 return -1;
1106 }
1107
1108 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, object_type_registered,
1110
1111 return 0;
1112}
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
@ ACO_ITEM
int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
Register a regex for multiple fields within an object.
Definition: sorcery.c:1160
static int sorcery_extended_fields_handler(const void *obj, struct ast_variable **fields)
Definition: sorcery.c:1048
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition: sorcery.c:79
static int sorcery_extended_config_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: sorcery.c:1043
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238
struct ao2_container * observers
Observers.
Definition: sorcery.c:235

References aco_info_init(), ACO_ITEM, ao2_cleanup, ao2_find, ast_sorcery_object_type::apply, ast_sorcery_object_fields_register(), ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, NULL, OBJ_KEY, ast_sorcery::observers, RAII_VAR, ast_sorcery_object_type::reloadable, sorcery, sorcery_extended_config_handler(), sorcery_extended_fields_handler(), ast_sorcery_object_type::transform, type, and ast_sorcery::types.

◆ __ast_sorcery_object_type_insert_wizard()

enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard ( struct ast_sorcery sorcery,
const char *  object_type_name,
const char *  module,
const char *  wizard_type_name,
const char *  wizard_args,
enum ast_sorcery_wizard_apply_flags  flags,
int  position,
struct ast_sorcery_wizard **  wizard,
void **  wizard_data 
)

Insert an additional object wizard mapping at a specific position in the wizard list returning wizard information.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to apply to
moduleThe name of the module, typically AST_MODULE
wizard_type_nameName of the wizard type to use
wizard_argsOpaque string to be passed to the wizard May be NULL but see note below
flagsOne or more of enum ast_sorcery_wizard_apply_flags
positionAn index to insert to or one of ast_sorcery_wizard_position
[out]wizardA variable to receive a pointer to the ast_sorcery_wizard structure. May be NULL if not needed.
[out]wizard_dataA variable to receive a pointer to the wizard's internal data. May be NULL if not needed.
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings
Although wizard_args is an optional parameter it is highly recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE flag, and you intend to ever remove a wizard mapping, you'll need wizard_args to remove specific instances of a wizard type.

Definition at line 869 of file sorcery.c.

873{
874 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, object_type_name, OBJ_KEY), ao2_cleanup);
875 RAII_VAR(struct ast_sorcery_internal_wizard *, internal_wizard, ao2_find(wizards, wizard_type_name, OBJ_KEY), ao2_cleanup);
876 RAII_VAR(struct ast_sorcery_object_wizard *, object_wizard, NULL, ao2_cleanup);
877 int created = 0;
878
879 object_wizard = ao2_alloc(sizeof(*object_wizard)
880 + (ast_strlen_zero(wizard_args) ? 0 : strlen(wizard_args) + 1),
882
883 if (!object_wizard) {
885 }
886
887 if (!internal_wizard
888 || internal_wizard->callbacks.module != ast_module_running_ref(internal_wizard->callbacks.module)) {
890 "Wizard '%s' could not be applied to object type '%s' as it was not found\n",
891 wizard_type_name, object_type_name);
893 }
894
895 if (!object_type) {
896 if (!(object_type = sorcery_object_type_alloc(object_type_name, module))) {
897 ast_module_unref(internal_wizard->callbacks.module);
899 }
900 created = 1;
901 }
902
903 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
904 if (!created) {
905 struct ast_sorcery_object_wizard *found;
906
907#define WIZARD_COMPARE(a, b) ((a)->wizard == (b))
908 found = AST_VECTOR_GET_CMP(&object_type->wizards, internal_wizard, WIZARD_COMPARE);
909#undef WIZARD_COMPARE
910 if (found
912 ast_debug(1, "Wizard %s already applied to object type %s\n",
913 internal_wizard->callbacks.name, object_type->name);
914 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
915 ast_module_unref(internal_wizard->callbacks.module);
917 }
918 }
919
920 ast_debug(5, "Calling wizard %s open callback on object type %s\n",
921 wizard_type_name, object_type->name);
922 if (internal_wizard->callbacks.open && !(object_wizard->data = internal_wizard->callbacks.open(wizard_args))) {
923 ast_log(LOG_WARNING, "Wizard '%s' failed to open mapping for object type '%s' with data: %s\n",
924 wizard_type_name, object_type->name, S_OR(wizard_args, ""));
925 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
926 ast_module_unref(internal_wizard->callbacks.module);
928 }
929
930 object_wizard->wizard = ao2_bump(internal_wizard);
931 object_wizard->caching = !!(flags & AST_SORCERY_WIZARD_APPLY_CACHING);
932 object_wizard->read_only = !!(flags & AST_SORCERY_WIZARD_APPLY_READONLY);
933 if (wizard_args) {
934 strcpy(object_wizard->wizard_args, wizard_args); /* Safe */
935 }
936
937 if (position == AST_SORCERY_WIZARD_POSITION_LAST) {
938 position = AST_VECTOR_SIZE(&object_type->wizards);
939 }
940
941 if (AST_VECTOR_INSERT_AT(&object_type->wizards, position, object_wizard) != 0) {
942 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
944 }
945 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
946 ao2_bump(object_wizard);
947
948 if (created) {
949 ao2_link(sorcery->types, object_type);
950 }
951
953 sorcery->module_name, sorcery, object_type_name, &internal_wizard->callbacks, wizard_args,
954 object_wizard->data);
955
956 if (wizard) {
957 *wizard = &internal_wizard->callbacks;
958 }
959 if (wizard_data) {
960 *wizard_data = object_wizard->data;
961 }
962
964}
#define ast_log
Definition: astobj2.c:42
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_WARNING
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
#define WIZARD_COMPARE(a, b)
static struct ao2_container * wizards
Registered sorcery wizards.
Definition: sorcery.c:257
static struct ast_sorcery_object_type * sorcery_object_type_alloc(const char *type, const char *module)
Internal function which allocates an object type structure.
Definition: sorcery.c:700
static void sorcery_object_wizard_destructor(void *obj)
Object wizard destructor.
Definition: sorcery.c:762
@ AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE
Definition: sorcery.h:583
@ AST_SORCERY_WIZARD_APPLY_READONLY
Definition: sorcery.h:581
@ AST_SORCERY_APPLY_DUPLICATE
Definition: sorcery.h:429
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
Structure for an internal wizard instance.
Definition: sorcery.c:89
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
unsigned int allow_duplicates
Wizard allows others of the same type.
Definition: sorcery.c:117
char wizard_args[0]
Wizard arguments.
Definition: sorcery.c:120
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:338
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition: vector.h:887
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:897
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:731

References ast_sorcery_object_wizard::allow_duplicates, ao2_alloc, ao2_bump, ao2_cleanup, ao2_find, ao2_link, ast_debug, ast_log, ast_module_running_ref, ast_module_unref, AST_SORCERY_APPLY_DUPLICATE, AST_SORCERY_APPLY_FAIL, AST_SORCERY_APPLY_SUCCESS, AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE, AST_SORCERY_WIZARD_APPLY_CACHING, AST_SORCERY_WIZARD_APPLY_READONLY, AST_SORCERY_WIZARD_POSITION_LAST, ast_strlen_zero(), AST_VECTOR_GET_CMP, AST_VECTOR_INSERT_AT, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, LOG_ERROR, LOG_WARNING, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, NULL, OBJ_KEY, ast_sorcery::observers, RAII_VAR, S_OR, sorcery, sorcery_object_type_alloc(), sorcery_object_wizard_destructor(), ast_sorcery::types, ast_sorcery_object_wizard::wizard, ast_sorcery_object_wizard::wizard_args, WIZARD_COMPARE, and wizards.

Referenced by __ast_sorcery_insert_wizard_mapping().

◆ __ast_sorcery_object_type_remove_wizard()

int __ast_sorcery_object_type_remove_wizard ( struct ast_sorcery sorcery,
const char *  object_type_name,
const char *  module,
const char *  wizard_type_name,
const char *  wizard_args 
)

Remove an object wizard mapping.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to remove from
moduleThe name of the module, typically AST_MODULE
wizard_type_nameThe name of the of the wizard type to remove
wizard_argsOpaque string originally passed to the wizard
Return values
0success
-1failure
Note
If there were multiple instances of the same wizard type added to this object type without using wizard_args, then only the first wizard matching wizard_type will be removed.

Definition at line 820 of file sorcery.c.

823{
824 RAII_VAR(struct ast_sorcery_object_type *, object_type,
825 ao2_find(sorcery->types, object_type_name, OBJ_SEARCH_KEY), ao2_cleanup);
826 int res = -1;
827 int i;
828
829 if (!object_type) {
830 return res;
831 }
832
833 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
834 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
835 struct ast_sorcery_object_wizard *wizard = AST_VECTOR_GET(&object_type->wizards, i);
836
837 if (strcmp(wizard->wizard->callbacks.name, wizard_type_name) == 0
838 && strcmp(S_OR(wizard->wizard_args, ""), S_OR(wizard_args, "")) == 0) {
839 ao2_cleanup(AST_VECTOR_REMOVE_ORDERED(&object_type->wizards, i));
840 res = 0;
841 break;
842 }
843 }
844 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
845
846 return res;
847}
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
const char * name
Name of the wizard.
Definition: sorcery.h:278
#define AST_VECTOR_REMOVE_ORDERED(vec, idx)
Remove an element from a vector by index while maintaining order.
Definition: vector.h:448
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

References ao2_cleanup, ao2_find, AST_VECTOR_GET, AST_VECTOR_REMOVE_ORDERED, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_wizard::name, OBJ_SEARCH_KEY, RAII_VAR, S_OR, sorcery, ast_sorcery::types, ast_sorcery_object_wizard::wizard, and ast_sorcery_object_wizard::wizard_args.

◆ __ast_sorcery_open()

struct ast_sorcery * __ast_sorcery_open ( const char *  module_name,
const char *  file,
int  line,
const char *  func 
)

Definition at line 601 of file sorcery.c.

602{
603 struct sorcery_proxy *proxy;
604 struct ast_sorcery *sorcery;
605
607
610 __PRETTY_FUNCTION__, file, line, func);
611 if (sorcery) {
613
614 return sorcery;
615 }
616
617 proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + strlen(module_name) + 1, NULL, module_name);
618 if (!proxy) {
619 goto failure_cleanup;
620 }
621 strcpy(proxy->module_name, module_name); /* Safe */
622
624 if (!sorcery) {
625 goto failure_cleanup;
626 }
627
629
630 /* We have exclusive access to proxy and sorcery, no need for locking here. */
631 if (ao2_t_weakproxy_set_object(proxy, sorcery, OBJ_NOLOCK, "weakproxy link")) {
632 goto failure_cleanup;
633 }
634
636 goto failure_cleanup;
637 }
638
640 ast_sorcery_object_type_hash_fn, NULL, ast_sorcery_object_type_cmp_fn);
641 if (!sorcery->types) {
642 goto failure_cleanup;
643 }
644
646 goto failure_cleanup;
647 }
648
650 ast_log(LOG_ERROR, "Error attempting to apply configuration %s to sorcery.\n", module_name);
651 goto failure_cleanup;
652 }
653
655 ao2_ref(proxy, -1);
656
658
660 return sorcery;
661
662failure_cleanup:
663 /* cleanup of sorcery may result in locking instances, so make sure we unlock first. */
666 ao2_cleanup(proxy);
667
668 return NULL;
669}
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Request notification when weakproxy points to NULL.
Definition: astobj2.c:934
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition: astobj2.h:365
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_wrlock(a)
Definition: astobj2.h:719
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition: astobj2.h:1554
#define ao2_t_weakproxy_alloc(data_size, destructor_fn, tag)
Definition: astobj2.h:553
#define ao2_unlock(a)
Definition: astobj2.h:729
void * __ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition: astobj2.c:768
#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
#define ao2_t_weakproxy_set_object(weakproxy, obj, flags, tag)
Definition: astobj2.h:582
#define NOTIFY_GLOBAL_OBSERVERS(container, callback,...)
Definition: sorcery.c:76
static void sorcery_destructor(void *obj)
Destructor called when sorcery structure is destroyed.
Definition: sorcery.c:581
static void sorcery_proxy_cb(void *weakproxy, void *data)
Hashing function for sorcery types.
Definition: sorcery.c:596
enum ast_sorcery_apply_result __ast_sorcery_apply_config(struct ast_sorcery *sorcery, const char *name, const char *module)
Apply configured wizard mappings.
Definition: sorcery.c:985
static struct ao2_container * instances
Registered sorcery instances.
Definition: sorcery.c:284
struct ao2_container * observers
Registered global observers.
Definition: sorcery.c:281
#define TYPE_BUCKETS
Number of buckets for types (should be prime for performance reasons)
Definition: sorcery.c:54
Full structure for sorcery.
Definition: sorcery.c:230
Proxy object for sorcery.
Definition: sorcery.c:223
char module_name[0]
The name of the module owning this sorcery instance.
Definition: sorcery.c:226

References __ao2_alloc(), __ao2_weakproxy_find(), __ast_sorcery_apply_config(), AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_cleanup, ao2_container_alloc_hash, ao2_container_alloc_list, ao2_link_flags, ao2_ref, ao2_t_weakproxy_alloc, ao2_t_weakproxy_set_object, ao2_unlock, ao2_weakproxy_subscribe(), ao2_wrlock, ast_assert, ast_log, AST_SORCERY_APPLY_FAIL, make_ari_stubs::file, instances, LOG_ERROR, sorcery_proxy::module_name, ast_sorcery::module_name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_NOLOCK, OBJ_SEARCH_KEY, ast_sorcery::observers, observers, sorcery, sorcery_destructor(), sorcery_proxy_cb(), TYPE_BUCKETS, and ast_sorcery::types.

◆ __ast_sorcery_remove_wizard_mapping()

int __ast_sorcery_remove_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
const char *  module,
const char *  name 
)

Internal function removes a wizard mapping.

Remove an object wizard mapping.

Definition at line 850 of file sorcery.c.

852{
854 int res;
855
856 if (!object_type) {
857 return -1;
858 }
859
860 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
861#define WIZARD_NAME_COMPARE(a, b) (strcmp((a)->wizard->callbacks.name, (b)) == 0)
863#undef WIZARD_NAME_COMPARE
864 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
865
866 return res;
867}
#define WIZARD_NAME_COMPARE(a, b)
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order.
Definition: vector.h:540

References ao2_cleanup, ao2_find, AST_VECTOR_REMOVE_CMP_ORDERED, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, name, OBJ_KEY, RAII_VAR, sorcery, type, ast_sorcery::types, and WIZARD_NAME_COMPARE.

◆ __ast_sorcery_wizard_register()

int __ast_sorcery_wizard_register ( const struct ast_sorcery_wizard interface,
struct ast_module module 
)

Register a sorcery wizard.

Parameters
interfacePointer to a wizard interface
modulePointer to the module implementing the interface
Return values
0success
-1failure

Definition at line 432 of file sorcery.c.

433{
434 struct ast_sorcery_internal_wizard *wizard;
435 int res = -1;
436
437 ast_assert(!ast_strlen_zero(interface->name));
438
440
441 if ((wizard = ao2_find(wizards, interface->name, OBJ_KEY | OBJ_NOLOCK))) {
442 ast_log(LOG_WARNING, "Attempted to register sorcery wizard '%s' twice\n",
443 interface->name);
444 goto done;
445 }
446
447 if (!(wizard = ao2_alloc(sizeof(*wizard), sorcery_internal_wizard_destructor))) {
448 goto done;
449 }
450
451 wizard->callbacks = *interface;
452 wizard->callbacks.module = module;
453
455 if (!wizard->observers) {
456 goto done;
457 }
458
460 res = 0;
461
462 ast_verb(5, "Sorcery registered wizard '%s'\n", interface->name);
463
464 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_registered,
465 interface->name, interface);
466
467done:
468 ao2_cleanup(wizard);
470
471 return res;
472}
#define ao2_lock(a)
Definition: astobj2.h:717
#define ast_verb(level,...)
static void sorcery_internal_wizard_destructor(void *obj)
Definition: sorcery.c:425
struct ao2_container * observers
Observers.
Definition: sorcery.c:99
struct ast_module * module
Pointer to the Asterisk module this wizard is implemented by.
Definition: sorcery.h:281
int done
Definition: test_amihooks.c:48

References ao2_alloc, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_find, ao2_link_flags, ao2_lock, ao2_unlock, ast_assert, ast_log, ast_strlen_zero(), ast_verb, ast_sorcery_internal_wizard::callbacks, done, LOG_WARNING, ast_sorcery_wizard::module, ast_sorcery_wizard::name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_KEY, OBJ_NOLOCK, ast_sorcery_internal_wizard::observers, observers, sorcery_internal_wizard_destructor(), and wizards.

Referenced by ast_bucket_init().

◆ ast_sorcery_alloc()

void * ast_sorcery_alloc ( const struct ast_sorcery sorcery,
const char *  type,
const char *  id 
)

Allocate an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object to allocate
idOptional unique identifier, if none is provided one will be generated
Return values
non-NULLsuccess
NULLfailure

Definition at line 1744 of file sorcery.c.

1745{
1747 struct ast_sorcery_object_details *details;
1748
1749 if (!object_type || !object_type->type.item_alloc ||
1750 !(details = object_type->type.item_alloc(id))) {
1751 return NULL;
1752 }
1753
1754 if (ast_strlen_zero(id)) {
1755 char uuid[AST_UUID_STR_LEN];
1756
1757 ast_uuid_generate_str(uuid, sizeof(uuid));
1758 details->object->id = ast_strdup(uuid);
1759 } else {
1760 details->object->id = ast_strdup(id);
1761 }
1762 if (!details->object->id) {
1763 ao2_ref(details, -1);
1764 return NULL;
1765 }
1766
1767 details->object->created = ast_tvnow();
1768 ast_copy_string(details->object->type, type, sizeof(details->object->type));
1769
1770 if (aco_set_defaults(&object_type->type, id, details)) {
1771 ao2_ref(details, -1);
1772 return NULL;
1773 }
1774
1775 return details;
1776}
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352
struct timeval created
Time that the object was created.
Definition: sorcery.c:141
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
char * id
Unique identifier of this object.
Definition: sorcery.c:129
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141

References aco_set_defaults(), ao2_cleanup, ao2_find, ao2_ref, ast_copy_string(), ast_strdup, ast_strlen_zero(), ast_tvnow(), ast_uuid_generate_str(), AST_UUID_STR_LEN, ast_sorcery_object::created, ast_sorcery_object::id, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, type, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by alloc_artificial_auth(), ast_ari_asterisk_update_object(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_mwi_mailbox_alloc(), ast_sip_initialize_system(), ast_sip_location_create_contact(), ast_sorcery_copy(), AST_TEST_DEFINE(), create_artificial_endpoint(), create_effective_profile(), create_object(), default_profile_create(), global_loaded_observer(), load_module(), mock_retrieve_id(), permanent_uri_handler(), sip_cli_print_global(), sip_cli_print_system(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_internal_load(), sorcery_memory_cache_thrash_update(), sorcery_realtime_retrieve_fields(), sorcery_realtime_retrieve_multiple(), sorcery_test_retrieve_id(), and subscription_persistence_create().

◆ ast_sorcery_changeset_create()

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.

Parameters
originalOriginal object set
modifiedModified object set
changesPointer to hold any changes between the object sets
Return values
0success
-1failure
Note
The returned ast_variable list must be destroyed using ast_variables_destroy

Definition at line 1663 of file sorcery.c.

1664{
1665 const struct ast_variable *field;
1666 int res = 0;
1667
1668 *changes = NULL;
1669
1670 /* Unless the ast_variable list changes when examined... it can't differ from itself */
1671 if (original == modified) {
1672 return 0;
1673 }
1674
1675 for (field = modified; field; field = field->next) {
1676 const char *old_value = ast_variable_find_in_list(original, field->name);
1677
1678 if (!old_value || strcmp(old_value, field->value)) {
1679 struct ast_variable *tmp;
1680
1681 if (!(tmp = ast_variable_new(field->name, field->value, ""))) {
1682 res = -1;
1683 break;
1684 }
1685
1686 tmp->next = *changes;
1687 *changes = tmp;
1688 }
1689 }
1690
1691 /* If an error occurred do not return a partial changeset */
1692 if (res) {
1693 ast_variables_destroy(*changes);
1694 *changes = NULL;
1695 }
1696
1697 return res;
1698}
static int tmp()
Definition: bt_open.c:389
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
Definition: main/config.c:919
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262

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

Referenced by ast_sorcery_diff(), AST_TEST_DEFINE(), can_reuse_registration(), and sorcery_is_criteria_met().

◆ ast_sorcery_copy()

void * ast_sorcery_copy ( const struct ast_sorcery sorcery,
const void *  object 
)

Create a copy of an object.

Parameters
sorceryPointer to a sorcery structure
objectExisting object
Return values
non-NULLsuccess
NULLfailure

Definition at line 1778 of file sorcery.c.

1779{
1780 const struct ast_sorcery_object_details *details = object;
1781 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1783 RAII_VAR(struct ast_variable *, objectset, NULL, ast_variables_destroy);
1784 int res = 0;
1785
1786 if (!copy) {
1787 return NULL;
1788 } else if (object_type->copy) {
1789 res = object_type->copy(object, copy);
1790 } else if ((objectset = ast_sorcery_objectset_create(sorcery, object))) {
1791 res = ast_sorcery_objectset_apply(sorcery, copy, objectset);
1792 } else {
1793 /* No native copy available and could not create an objectset, this copy has failed */
1794 res = -1;
1795 }
1796
1797 if (res) {
1799 copy = NULL;
1800 }
1801
1802 return copy;
1803}
static int copy(char *infile, char *outfile)
Utility function to copy a file.
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_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
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1137

References ao2_cleanup, ao2_find, ast_sorcery_alloc(), ast_sorcery_objectset_apply(), ast_sorcery_objectset_create, ast_variables_destroy(), copy(), ast_sorcery_object::id, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_clone(), ast_bucket_file_clone(), ast_mwi_mailbox_copy(), and AST_TEST_DEFINE().

◆ ast_sorcery_create()

int ast_sorcery_create ( const struct ast_sorcery sorcery,
void *  object 
)

Create and potentially persist an object using an available wizard.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2057 of file sorcery.c.

2058{
2059 const struct ast_sorcery_object_details *details = object;
2060 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2061 struct ast_sorcery_object_wizard *object_wizard = NULL;
2062 struct ast_sorcery_object_wizard *found_wizard;
2063 int i;
2064 struct sorcery_details sdetails = {
2065 .sorcery = sorcery,
2066 .obj = object,
2067 };
2068
2069 if (!object_type) {
2070 return -1;
2071 }
2072
2073 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2074 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2075 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2076 if (!found_wizard->caching
2077 && sorcery_wizard_create(found_wizard, &sdetails) == CMP_MATCH) {
2078 object_wizard = found_wizard;
2079 }
2080 }
2081
2082 if (object_wizard) {
2083 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2084 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2085 if (found_wizard->caching) {
2086 sorcery_wizard_create(found_wizard, &sdetails);
2087 }
2088 }
2089
2090 if (ao2_container_count(object_type->observers)) {
2091 struct sorcery_observer_invocation *invocation;
2092
2093 invocation = sorcery_observer_invocation_alloc(object_type, object);
2094 if (invocation
2096 invocation)) {
2097 ao2_cleanup(invocation);
2098 }
2099 }
2100 }
2101
2103
2104 return object_wizard ? 0 : -1;
2105}
@ CMP_MATCH
Definition: astobj2.h:1027
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static int sorcery_observers_notify_create(void *data)
Internal callback function which notifies observers that an object has been created.
Definition: sorcery.c:2047
static int sorcery_wizard_create(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if the wizard has created the object.
Definition: sorcery.c:2020
static struct sorcery_observer_invocation * sorcery_observer_invocation_alloc(struct ast_sorcery_object_type *object_type, void *object)
Allocator function for observer invocation.
Definition: sorcery.c:1292
struct ast_sorcery_object_wizards wizards
Wizard instances.
Definition: sorcery.c:165
struct ast_taskprocessor * serializer
Serializer for observers.
Definition: sorcery.c:183
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
Structure used when calling create, update, or delete.
Definition: sorcery.c:1831
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition: sorcery.c:1833
Structure used for observer invocations.
Definition: sorcery.c:196
struct ast_sorcery_object_type * object_type
Pointer to the object type.
Definition: sorcery.c:198
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:877

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery_details::sorcery, sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_create(), sorcery_wizard_create(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_create(), ast_bucket_file_create(), ast_mwi_mailbox_update(), ast_sip_location_create_contact(), AST_TEST_DEFINE(), create_effective_profile(), default_profile_create(), load_module(), and subscription_persistence_create().

◆ ast_sorcery_delete()

int ast_sorcery_delete ( const struct ast_sorcery sorcery,
void *  object 
)

Delete an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2233 of file sorcery.c.

2234{
2235 const struct ast_sorcery_object_details *details = object;
2236 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2237 struct ast_sorcery_object_wizard *object_wizard = NULL;
2238 struct ast_sorcery_object_wizard *found_wizard;
2239 int i;
2240 struct sorcery_details sdetails = {
2241 .sorcery = sorcery,
2242 .obj = object,
2243 };
2244
2245 if (!object_type) {
2246 return -1;
2247 }
2248
2249 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2250 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2251 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2252 if (!found_wizard->caching
2253 && sorcery_wizard_delete(found_wizard, &sdetails) == CMP_MATCH) {
2254 object_wizard = found_wizard;
2255 }
2256 }
2257
2258 if (object_wizard) {
2259 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2260 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2261 if (found_wizard->caching) {
2262 sorcery_wizard_delete(found_wizard, &sdetails);
2263 }
2264 }
2265
2266 if (ao2_container_count(object_type->observers)) {
2267 struct sorcery_observer_invocation *invocation;
2268
2269 invocation = sorcery_observer_invocation_alloc(object_type, object);
2270 if (invocation
2272 invocation)) {
2273 ao2_cleanup(invocation);
2274 }
2275 }
2276 }
2277
2279
2280 return object_wizard ? 0 : -1;
2281}
static int sorcery_observers_notify_delete(void *data)
Internal callback function which notifies observers that an object has been deleted.
Definition: sorcery.c:2208
static int sorcery_wizard_delete(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if a wizard has deleted the object.
Definition: sorcery.c:2219

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery_details::sorcery, sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_delete(), sorcery_wizard_delete(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by ast_ari_asterisk_delete_object(), ast_bucket_delete(), ast_bucket_file_delete(), ast_sip_location_delete_contact(), AST_TEST_DEFINE(), bucket_http_wizard_retrieve_id(), mwi_mailbox_delete(), sub_persistence_recreate(), subscription_persistence_recreate(), subscription_persistence_remove(), and unload_module().

◆ ast_sorcery_diff()

int ast_sorcery_diff ( const struct ast_sorcery sorcery,
const void *  original,
const void *  modified,
struct ast_variable **  changes 
)

Create a changeset of two objects.

Parameters
sorceryPointer to a sorcery structure
originalOriginal object
modifiedModified object
changesPointer which will be populated with changes if any exist
Return values
0success
-1failure
Note
The returned ast_variable list must be destroyed using ast_variables_destroy
While the objects must be of the same type they do not have to be the same object

Definition at line 1805 of file sorcery.c.

1806{
1808
1809 *changes = NULL;
1810
1811 if (strcmp(ast_sorcery_object_get_type(original), ast_sorcery_object_get_type(modified))) {
1812 return -1;
1813 }
1814
1815 if (original == modified) {
1816 return 0;
1817 } else if (!object_type->diff) {
1818 RAII_VAR(struct ast_variable *, objectset1, NULL, ast_variables_destroy);
1819 RAII_VAR(struct ast_variable *, objectset2, NULL, ast_variables_destroy);
1820
1821 objectset1 = ast_sorcery_objectset_create(sorcery, original);
1822 objectset2 = ast_sorcery_objectset_create(sorcery, modified);
1823
1824 return ast_sorcery_changeset_create(objectset1, objectset2, changes);
1825 } else {
1826 return object_type->diff(original, modified, changes);
1827 }
1828}
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition: sorcery.c:2324
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 ao2_cleanup, ao2_find, ast_sorcery_changeset_create(), ast_sorcery_object_get_type(), ast_sorcery_objectset_create, ast_variables_destroy(), NULL, OBJ_KEY, RAII_VAR, sorcery, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE(), and transport_apply().

◆ ast_sorcery_force_reload()

void ast_sorcery_force_reload ( const struct ast_sorcery sorcery)

Inform any wizards to reload persistent objects, even if no changes determined.

Parameters
sorceryPointer to a sorcery structure
Since
13.32.0
16.9.0
17.3.0

Definition at line 1425 of file sorcery.c.

1426{
1427 struct sorcery_load_details details = {
1428 .sorcery = sorcery,
1429 .reload = 1,
1430 .force = 1,
1431 };
1432
1433 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1435
1437
1440}
#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
@ OBJ_NODATA
Definition: astobj2.h:1044
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1336
Structure for passing load/reload details.
Definition: sorcery.c:242
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition: sorcery.c:244

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), and ast_sorcery::types.

◆ ast_sorcery_force_reload_object()

void ast_sorcery_force_reload_object ( const struct ast_sorcery sorcery,
const char *  type 
)

Inform any wizards of a specific object type to reload persistent objects even if no changes determined.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to reload
Since
13.32.0
16.9.0
17.3.0

Definition at line 1457 of file sorcery.c.

1458{
1460 struct sorcery_load_details details = {
1461 .sorcery = sorcery,
1462 .reload = 1,
1463 .force = 1,
1464 };
1465
1466 if (!object_type) {
1467 return;
1468 }
1469
1470 sorcery_object_load(object_type, &details, 0);
1471}

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), type, and ast_sorcery::types.

Referenced by acl_change_stasis_cb(), as_config_reload(), profile_reload(), tn_config_reload(), and vs_config_reload().

◆ ast_sorcery_generic_alloc()

void * ast_sorcery_generic_alloc ( size_t  size,
ao2_destructor_fn  destructor 
)

Allocate a generic sorcery capable object.

Parameters
sizeSize of the object
destructorOptional destructor function
Return values
non-NULLsuccess
NULLfailure
Note
The returned object does not support AO2 locking.

Definition at line 1728 of file sorcery.c.

1729{
1730 void *object = ao2_alloc_options(size + sizeof(struct ast_sorcery_object),
1732 struct ast_sorcery_object_details *details = object;
1733
1734 if (!object) {
1735 return NULL;
1736 }
1737
1738 details->object = object + size;
1739 details->object->destructor = destructor;
1740
1741 return object;
1742}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void sorcery_object_destructor(void *object)
Definition: sorcery.c:1700
Structure for internal sorcery object information.
Definition: sorcery.c:127
ao2_destructor_fn destructor
Optional object destructor.
Definition: sorcery.c:135

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_sorcery_object::destructor, NULL, ast_sorcery_object_details::object, and sorcery_object_destructor().

Referenced by acl_alloc(), ast_sip_endpoint_alloc(), asterisk_publication_config_alloc(), attestation_alloc(), auth_alloc(), bucket_alloc(), bucket_file_alloc(), client_config_alloc(), contact_alloc(), domain_alias_alloc(), geoloc_location_alloc(), geoloc_profile_alloc(), global_alloc(), ip_identify_alloc(), mapping_alloc(), mwi_sorcery_object_alloc(), phoneprov_alloc(), profile_alloc(), publication_resource_alloc(), resource_list_alloc(), sip_nat_hook_alloc(), sip_outbound_publish_alloc(), sip_outbound_registration_alloc(), sip_transport_alloc(), subscription_persistence_alloc(), system_alloc(), test_data_alloc(), test_sorcery_object_alloc(), tn_alloc(), and verification_alloc().

◆ ast_sorcery_get_module()

const char * ast_sorcery_get_module ( const struct ast_sorcery sorcery)

Get the module that has opened the provided sorcery instance.

Parameters
sorceryThe sorcery instance
Returns
The module

Definition at line 2531 of file sorcery.c.

2532{
2533 return sorcery->module_name;
2534}

References ast_sorcery::module_name, and sorcery.

Referenced by sorcery_memory_cache_load().

◆ ast_sorcery_get_object_type()

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.

Parameters
sorceryThe sorcery from which to retrieve the object type
typeThe type name

Definition at line 2489 of file sorcery.c.

2491{
2493}

References ao2_find, OBJ_SEARCH_KEY, sorcery, type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), AST_TEST_DEFINE(), sorcery_astdb_filter_objectset(), sorcery_is_explicit_name_met(), and sorcery_realtime_filter_objectset().

◆ ast_sorcery_get_wizard_mapping()

int ast_sorcery_get_wizard_mapping ( struct ast_sorcery sorcery,
const char *  type,
int  index,
struct ast_sorcery_wizard **  wizard,
void **  data 
)

By index, return a wizard mapped to an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
indexIndex of the wizard
wizardA pointer to receive the wizard pointer
dataA pointer to receive the data pointer
Return values
0success
-1failure
Warning
The wizard will have its reference count bumped so you must call ao2_cleanup when you're done with it.
Note
The wizard and data returned are valid only for this object type and only while the wizard is applied to the object type.
Since
13.4.0

Definition at line 790 of file sorcery.c.

792{
794 struct ast_sorcery_object_wizard *owizard;
795
796 if (!object_type) {
797 return -1;
798 }
799
800 if (index < 0 || index >= AST_VECTOR_SIZE(&object_type->wizards)) {
801 return -1;
802 }
803
804 owizard = AST_VECTOR_GET(&object_type->wizards, index);
805
806 if (wizard != NULL) {
807 *wizard = &(owizard->wizard->callbacks);
808 ao2_bump(owizard->wizard);
809 } else {
810 return -1;
811 }
812
813 if (data != NULL) {
814 *data = owizard->data;
815 }
816
817 return 0;
818}
void * data
Unique data for the wizard.
Definition: sorcery.c:108

References ao2_bump, ao2_cleanup, ao2_find, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, NULL, OBJ_KEY, RAII_VAR, sorcery, type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_get_wizard_mapping_count()

int ast_sorcery_get_wizard_mapping_count ( struct ast_sorcery sorcery,
const char *  type 
)

Return the number of wizards mapped to an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
Returns
Number of wizards or -1 for error
Since
13.4.0

Definition at line 778 of file sorcery.c.

780{
782
783 if (!object_type) {
784 return -1;
785 }
786
787 return AST_VECTOR_SIZE(&object_type->wizards);
788}

References ao2_cleanup, ao2_find, AST_VECTOR_SIZE, OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_global_observer_add()

int ast_sorcery_global_observer_add ( const struct ast_sorcery_global_observer callbacks)

Add a global observer to sorcery.

Parameters
callbacksImplementation of the global observer interface
Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 498 of file sorcery.c.

499{
500 struct sorcery_global_observer *cb;
501
502 cb = ao2_alloc(sizeof(*cb), NULL);
503 if (!cb) {
504 return -1;
505 }
506
507 cb->callbacks = callbacks;
508 ao2_link(observers, cb);
509 ao2_ref(cb, -1);
510
511 return 0;
512}
struct @468 callbacks
A global observer wrapper.
Definition: sorcery.c:266
const struct ast_sorcery_global_observer * callbacks
Definition: sorcery.c:267

References ao2_alloc, ao2_link, ao2_ref, sorcery_global_observer::callbacks, callbacks, NULL, and observers.

Referenced by AST_TEST_DEFINE(), and load_module().

◆ ast_sorcery_global_observer_remove()

void ast_sorcery_global_observer_remove ( const struct ast_sorcery_global_observer callbacks)

Remove a global observer from sorcery.

A global observer is notified... After a new wizard is registered. After a new sorcery instance is opened. Before an instance is destroyed. Before a wizard is unregistered.

Parameters
callbacksImplementation of the global observer interface

Definition at line 514 of file sorcery.c.

516{
518}
@ OBJ_UNLINK
Definition: astobj2.h:1039
static int sorcery_generic_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing a generic observer.
Definition: sorcery.c:491

References ao2_callback, callbacks, OBJ_NODATA, OBJ_UNLINK, observers, and sorcery_generic_observer_remove().

Referenced by AST_TEST_DEFINE(), and unload_module().

◆ ast_sorcery_init()

int ast_sorcery_init ( void  )

Compare function for sorcery instances.

Initialize the sorcery API.

Hashing function for sorcery instances

Definition at line 387 of file sorcery.c.

388{
391 .auto_increment = 1,
392 .max_size = 0,
393 .idle_timeout = 60,
394 .initial_size = 0,
395 };
397
399 if (!threadpool) {
400 return -1;
401 }
402
404 ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn);
405 if (!wizards) {
406 return -1;
407 }
408
410 if (!observers) {
411 return -1;
412 }
413
415 sorcery_proxy_hash_fn, NULL, sorcery_proxy_cmp_fn);
416 if (!instances) {
417 return -1;
418 }
419
421
422 return 0;
423}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define INSTANCE_BUCKETS
Number of buckets for instances (should be prime for performance reasons)
Definition: sorcery.c:57
#define WIZARD_BUCKETS
Number of buckets for wizards (should be prime for performance reasons)
Definition: sorcery.c:51
static struct ast_threadpool * threadpool
Thread pool for observers.
Definition: sorcery.c:86
static void sorcery_cleanup(void)
Hashing and comparison functions for sorcery wizards.
Definition: sorcery.c:369
struct ast_threadpool * ast_threadpool_create(const char *name, struct ast_threadpool_listener *listener, const struct ast_threadpool_options *options)
Create a new threadpool.
Definition: threadpool.c:916
#define AST_THREADPOOL_OPTIONS_VERSION
Definition: threadpool.h:71

References AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_hash, ao2_container_alloc_list, ast_assert, ast_register_cleanup(), ast_threadpool_create(), AST_THREADPOOL_OPTIONS_VERSION, INSTANCE_BUCKETS, instances, NULL, observers, options, sorcery_cleanup(), threadpool, WIZARD_BUCKETS, and wizards.

Referenced by asterisk_daemon().

◆ ast_sorcery_instance_observer_add()

int ast_sorcery_instance_observer_add ( struct ast_sorcery sorcery,
const struct ast_sorcery_instance_observer callbacks 
)

Add an observer to a sorcery instance.

Parameters
sorceryPointer to a sorcery structure
callbacksImplementation of the instance observer interface

An instance observer is notified... Before an instance is loaded or reloaded. After an instance is loaded or reloaded. After a wizard is mapped to an object type. After an object type is registered. Before an object type is loaded or reloaded. After an object type is loaded or reloaded.

Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 520 of file sorcery.c.

522{
523 struct sorcery_instance_observer *cb;
524
525 cb = ao2_alloc(sizeof(*cb), NULL);
526 if (!cb) {
527 return -1;
528 }
529
530 cb->callbacks = callbacks;
532 ao2_ref(cb, -1);
533
534 return 0;
535}
An instance observer wrapper.
Definition: sorcery.c:271
const struct ast_sorcery_instance_observer * callbacks
Definition: sorcery.c:272

References ao2_alloc, ao2_link, ao2_ref, sorcery_instance_observer::callbacks, callbacks, NULL, ast_sorcery::observers, and sorcery.

Referenced by ast_sip_initialize_sorcery_global(), AST_TEST_DEFINE(), instance_created_observer(), load_module(), and pjsip_outbound_registration_metrics_init().

◆ ast_sorcery_instance_observer_remove()

void ast_sorcery_instance_observer_remove ( struct ast_sorcery sorcery,
const struct ast_sorcery_instance_observer callbacks 
)

Remove an observer from a sorcery instance.

Parameters
sorceryPointer to a sorcery structure
callbacksImplementation of the instance observer interface

Definition at line 537 of file sorcery.c.

References ao2_callback, callbacks, OBJ_NODATA, OBJ_UNLINK, ast_sorcery::observers, sorcery, and sorcery_generic_observer_remove().

Referenced by ast_sip_destroy_sorcery_global(), AST_TEST_DEFINE(), instance_destroying_observer(), pjsip_outbound_registration_metrics_init(), pjsip_outbound_registration_metrics_unload_cb(), and unload_module().

◆ ast_sorcery_is_object_field_registered()

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.

Parameters
object_typeThe object type to check against
field_nameThe name of the field to check
Return values
0The field is not registered for this sorcery type
1The field is registered for this sorcery type

Definition at line 2509 of file sorcery.c.

2511{
2512 struct ast_sorcery_object_field *object_field;
2513 int res = 1;
2514
2515 ast_assert(object_type != NULL);
2516
2517 object_field = ao2_find(object_type->fields, field_name, OBJ_SEARCH_KEY);
2518
2519 if (!object_field) {
2520 object_field = ao2_callback(object_type->fields, 0, is_registered_cb, (char *)field_name);
2521 }
2522
2523 if (!object_field) {
2524 res = 0;
2525 }
2526
2527 ao2_cleanup(object_field);
2528 return res;
2529}
static int is_registered_cb(void *obj, void *arg, int flags)
Definition: sorcery.c:2495
struct ao2_container * fields
Object fields.
Definition: sorcery.c:168

References ao2_callback, ao2_cleanup, ao2_find, ast_assert, ast_sorcery_object_type::fields, is_registered_cb(), NULL, and OBJ_SEARCH_KEY.

Referenced by AST_TEST_DEFINE(), sorcery_astdb_filter_objectset(), sorcery_is_explicit_name_met(), and sorcery_realtime_filter_objectset().

◆ ast_sorcery_is_stale()

int ast_sorcery_is_stale ( const struct ast_sorcery sorcery,
void *  object 
)

Determine if a sorcery object is stale with respect to its backing datastore.

Since
14.0.0

This function will query the wizard(s) backing the particular sorcery object to determine if the in-memory object is now stale. No action is taken to update the object. Callers of this function may use one of the ast_sorcery_retrieve functions to obtain a new instance of the object if desired.

Return values
0the object is not stale
1the object is stale

Definition at line 2283 of file sorcery.c.

2284{
2285 const struct ast_sorcery_object_details *details = object;
2286 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2287 struct ast_sorcery_object_wizard *found_wizard;
2288 int res = 0;
2289 int i;
2290
2291 if (!object_type) {
2292 return -1;
2293 }
2294
2295 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2296 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2297 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2298
2299 if (found_wizard->wizard->callbacks.is_stale) {
2300 res |= found_wizard->wizard->callbacks.is_stale(sorcery, found_wizard->data, object);
2301 ast_debug(5, "After calling wizard '%s', object '%s' is %s\n",
2302 found_wizard->wizard->callbacks.name,
2304 res ? "stale" : "not stale");
2305 }
2306 }
2307 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2308
2309 return res;
2310}
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
int(* is_stale)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for whether or not the wizard believes the object is stale.
Definition: sorcery.h:325

References ao2_cleanup, ao2_find, ast_debug, ast_sorcery_object_get_id(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, ast_sorcery_wizard::is_stale, ast_sorcery_wizard::name, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by ast_bucket_file_is_stale(), ast_bucket_is_stale(), and AST_TEST_DEFINE().

◆ ast_sorcery_load()

void ast_sorcery_load ( const struct ast_sorcery sorcery)

Inform any wizards to load persistent objects.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1377 of file sorcery.c.

1378{
1379 struct sorcery_load_details details = {
1380 .sorcery = sorcery,
1381 .reload = 0,
1382 };
1383
1384 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1386
1388
1391}

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by ast_res_pjsip_initialize_configuration(), ast_sip_initialize_system(), AST_TEST_DEFINE(), geoloc_config_load(), and load_module().

◆ ast_sorcery_load_object()

void ast_sorcery_load_object ( const struct ast_sorcery sorcery,
const char *  type 
)

Inform any wizards of a specific object type to load persistent objects.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to load

Definition at line 1393 of file sorcery.c.

1394{
1396 struct sorcery_load_details details = {
1397 .sorcery = sorcery,
1398 .reload = 0,
1399 };
1400
1401 if (!object_type) {
1402 return;
1403 }
1404
1405 sorcery_object_load(object_type, &details, 0);
1406}

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), type, and ast_sorcery::types.

Referenced by as_config_load(), AST_TEST_DEFINE(), load_module(), profile_load(), reregister_all(), tn_config_load(), and vs_config_load().

◆ ast_sorcery_lockable_alloc()

void * ast_sorcery_lockable_alloc ( size_t  size,
ao2_destructor_fn  destructor,
void *  lockobj 
)

Allocate a generic sorcery capable object with locking.

Since
14.1.0

Sorcery objects may be replaced with new allocations during reloads. If locking is required on sorcery objects it must be shared between the old object and the new one. lockobj can be any AO2 object with locking enabled, but in most cases named locks should be used to provide stable locking.

Parameters
sizeSize of the object
destructorOptional destructor function
lockobjAn AO2 object that will provide locking.
Return values
non-NULLsuccess
NULLfailure

Definition at line 1712 of file sorcery.c.

1713{
1714 void *object = ao2_alloc_with_lockobj(size + sizeof(struct ast_sorcery_object),
1715 sorcery_object_destructor, lockobj, "");
1716 struct ast_sorcery_object_details *details = object;
1717
1718 if (!object) {
1719 return NULL;
1720 }
1721
1722 details->object = object + size;
1723 details->object->destructor = destructor;
1724
1725 return object;
1726}
#define ao2_alloc_with_lockobj(data_size, destructor_fn, lockobj, tag)
Allocate and initialize an object with separate locking.
Definition: astobj2.h:431

References ao2_alloc_with_lockobj, ast_sorcery_object::destructor, NULL, ast_sorcery_object_details::object, and sorcery_object_destructor().

Referenced by aor_alloc().

◆ ast_sorcery_object_fields_register()

int ast_sorcery_object_fields_register ( struct ast_sorcery sorcery,
const char *  type,
const char *  regex,
aco_option_handler  config_handler,
sorcery_fields_handler  sorcery_handler 
)

Register a regex for multiple fields within an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object
regexA regular expression pattern for the fields
config_handlerA custom handler for translating the string representation of the fields
sorcery_handlerA custom handler for translating the native representation of the fields
Return values
0success
-1failure

Definition at line 1160 of file sorcery.c.

1161{
1162#define MAX_REGEX_ERROR_LEN 128
1164 RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1165 int rc;
1166
1167 if (!object_type || !object_type->type.item_alloc || !config_handler
1168 || !(object_field = ao2_alloc(sizeof(*object_field), sorcery_object_field_destructor))) {
1169 return -1;
1170 }
1171
1172 ast_copy_string(object_field->name, regex, sizeof(object_field->name));
1173 object_field->multiple_handler = sorcery_handler;
1174
1175 if (!(object_field->name_regex = ast_calloc(1, sizeof(regex_t)))) {
1176 return -1;
1177 }
1178
1179 if ((rc = regcomp(object_field->name_regex, regex, REG_EXTENDED | REG_NOSUB))) {
1180 char *regerr = ast_alloca(MAX_REGEX_ERROR_LEN);
1181 regerror(rc, object_field->name_regex, regerr, MAX_REGEX_ERROR_LEN);
1182 ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n", regex, regerr);
1183 return -1;
1184 }
1185
1186 ao2_link(object_type->fields, object_field);
1187 __aco_option_register(object_type->info, regex, ACO_REGEX, object_type->file->types, "", OPT_CUSTOM_T, config_handler, 0, 1, 0);
1188
1189 return 0;
1190}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
@ ACO_REGEX
@ OPT_CUSTOM_T
Type for a custom (user-defined) option handler.
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
#define MAX_REGEX_ERROR_LEN
static void sorcery_object_field_destructor(void *obj)
Definition: sorcery.c:1150

References __aco_option_register(), ACO_REGEX, ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ast_alloca, ast_calloc, ast_copy_string(), ast_log, LOG_ERROR, MAX_REGEX_ERROR_LEN, NULL, OBJ_KEY, OPT_CUSTOM_T, RAII_VAR, regex(), sorcery, sorcery_object_field_destructor(), type, and ast_sorcery::types.

Referenced by __ast_sorcery_object_register(), AST_TEST_DEFINE(), and load_module().

◆ ast_sorcery_object_get_created()

const struct timeval ast_sorcery_object_get_created ( const void *  object)

Get when the sorcery object was created.

Since
14.0.0
Parameters
objectPointer to a sorcery object
Returns
The time when the object was created

Definition at line 2318 of file sorcery.c.

2319{
2320 const struct ast_sorcery_object_details *details = object;
2321 return details->object->created;
2322}

References ast_sorcery_object::created, and ast_sorcery_object_details::object.

◆ ast_sorcery_object_get_extended()

const char * ast_sorcery_object_get_extended ( const void *  object,
const char *  name 
)

Get an extended field value from a sorcery object.

Parameters
objectPointer to a sorcery object
nameName of the extended field value
Return values
non-NULLif found
NULLif not found
Note
The returned string does NOT need to be freed and is guaranteed to remain valid for the lifetime of the object

Definition at line 2330 of file sorcery.c.

2331{
2332 const struct ast_sorcery_object_details *details = object;
2333 struct ast_variable *field;
2334
2335 for (field = details->object->extended; field; field = field->next) {
2336 if (!strcmp(field->name + 1, name)) {
2337 return field->value;
2338 }
2339 }
2340
2341 return NULL;
2342}
struct ast_variable * extended
Extended object fields.
Definition: sorcery.c:138

References ast_sorcery_object::extended, name, ast_variable::name, ast_variable::next, NULL, ast_sorcery_object_details::object, and ast_variable::value.

Referenced by AST_TEST_DEFINE(), asterisk_start_devicestate_publishing(), asterisk_start_mwi_publishing(), delete_existing_cb(), and publisher_start().

◆ ast_sorcery_object_get_id()

const char * ast_sorcery_object_get_id ( const void *  object)

Get the unique identifier of a sorcery object.

Parameters
objectPointer to a sorcery object
Returns
unique identifier

Definition at line 2312 of file sorcery.c.

2313{
2314 const struct ast_sorcery_object_details *details = object;
2315 return details->object->id;
2316}

References ast_sorcery_object::id, and ast_sorcery_object_details::object.

Referenced by __print_debug_details(), aeap_cli_show(), aeap_tab_complete_name(), allocate_subscription_tree(), allow_and_or_replace_unsolicited(), ami_outbound_registration_task(), ami_show_registration_contact_statuses(), anonymous_identify(), aor_deleted_observer(), apply_acls(), ast_bucket_file_json(), ast_bucket_json(), ast_geoloc_eprofile_create_from_profile(), ast_mwi_mailbox_get_id(), ast_mwi_mailbox_update(), ast_res_pjsip_find_or_create_contact_status(), ast_res_pjsip_initialize_configuration(), ast_sip_create_dialog_uac(), ast_sip_create_subscription(), ast_sip_for_each_contact(), ast_sip_format_contact_ami(), ast_sip_get_contact_status(), ast_sip_get_device_state(), ast_sip_initialize_sorcery_auth(), ast_sip_initialize_sorcery_transport(), ast_sip_location_create_contact(), ast_sip_location_retrieve_aor_contacts_nolock_filtered(), ast_sip_session_alloc(), ast_sip_session_create_outgoing(), ast_sip_session_get_name(), ast_sip_set_tpselector_from_transport(), ast_sip_subscription_destroy(), ast_sorcery_is_stale(), ast_sorcery_object_id_hash(), ast_sorcery_object_id_sort(), AST_TEST_DEFINE(), asterisk_publication_devicestate(), asterisk_publication_devicestate_refresh(), asterisk_publication_devicestate_state_change(), asterisk_publication_mailboxstate(), asterisk_publication_mwi_refresh(), asterisk_publication_mwi_state_change(), attestation_apply(), auth_apply(), auth_observer(), bucket_file_run_curl(), bucket_http_test_wizard_create(), bucket_http_test_wizard_delete(), bucket_http_test_wizard_update(), build_resource_tree(), can_reuse_registration(), cancel_and_unpublish(), chan_pjsip_indicate(), chan_pjsip_new(), change_outgoing_sdp_stream_media_address(), check_state(), cli_aor_get_id(), cli_aor_print_body(), cli_complete_endpoint(), cli_complete_registration(), cli_complete_uri(), cli_contact_print_body(), cli_endpoint_print_body(), cli_iterator(), cli_list_subscriptions_detail(), cli_print_body(), cli_show_subscriptions_detail(), client_config_apply(), codec_prefs_handler(), common_identify(), config_object_cli_show(), config_object_tab_complete_name(), connected_line_method_handler(), contact_apply_handler(), contact_function_get_permanent(), create_dialog_uas(), create_effective_profile(), create_out_of_dialog_request(), create_outgoing_sdp_stream(), create_rtp(), create_unsolicited_mwi_subscriptions(), current_state_reusable(), destroy_subscription(), digest_check_auth(), digest_create_request_with_auth(), direct_media_glare_mitigation_handler(), direct_media_method_handler(), domain_alias_apply(), endpt_send_request(), eprofile_apply(), expire_objects_from_cache(), file_extension_from_url_path(), find_internal_state_by_transport(), find_or_create_temporary_state(), find_registrar_aor(), format_ami_aor_handler(), format_ami_auth_handler(), format_ami_endpoint_identify(), format_ami_endpoint_transport(), from_user_handler(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_location_apply_handler(), geoloc_profile_apply_handler(), get_account_id(), get_curl_instance(), get_resource_display_name(), handle_export_primitives(), handle_incoming_request(), handle_outgoing_request(), handle_slash(), has_mwi_subscription(), header_identify_match_check(), ident_handler(), internal_state_alloc(), ip_identify_apply(), ip_identify_match_check(), ip_identify_match_handler(), line_identify(), load_engine(), load_module(), log_caps(), mark_object_as_stale_in_cache(), matches_engine(), media_cache_handle_show_item(), media_cache_item_del_from_astdb(), media_cache_item_sync_to_astdb(), media_cache_prnt_summary(), memory_cache_stale_update_object(), msg_send(), mwi_contact_changed(), mwi_observe_delete(), mwi_post_event(), mwi_subscription_alloc(), mwi_validate_for_aor(), new_subscribe(), permanent_uri_handler(), permanent_uri_sort_fn(), persistent_endpoint_find_or_create(), pjsip_aor_function_read(), profile_apply(), publish_request_initial(), publisher_start(), publisher_stop(), pubsub_on_rx_mwi_notify_request(), pubsub_on_rx_publish_request(), pubsub_on_rx_refresh(), pubsub_on_rx_subscribe_request(), qualify_contact_cb(), read_pjsip(), redirect_handler(), refer_client_on_evsub_state(), refer_incoming_attended_request(), refer_incoming_blind_request(), refer_incoming_invite_request(), refer_incoming_refer_request(), refer_progress_alloc(), refer_send(), registrar_contact_delete(), registrar_on_rx_request(), registration_deleted_observer(), registration_state_cmp(), registration_state_hash(), remove_from_cache(), remove_subscription(), resource_list_apply_handler(), rfc3326_add_reason_header(), rx_data_to_ast_msg(), session_destructor(), session_inv_on_redirected(), session_inv_on_tsx_state_changed(), session_outgoing_nat_hook(), set_outbound_authentication_credentials(), sip_aor_to_ami(), sip_endpoint_apply_handler(), sip_options_aor_alloc(), sip_options_aor_observer_deleted_task(), sip_options_aor_observer_modified_task(), sip_options_apply_aor_configuration(), sip_options_contact_status_notify_task(), sip_options_endpoint_observer_deleted_task(), sip_options_endpoint_observer_modified_task(), sip_options_endpoint_state_compositor_find_or_alloc(), sip_options_endpoint_unlink_aor_feeders(), sip_options_qualify_contact(), sip_options_remove_contact_status(), sip_options_synchronize_aor(), sip_options_synchronize_endpoint(), sip_outbound_publish_apply(), sip_outbound_publish_callback(), sip_outbound_publish_state_alloc(), sip_outbound_publish_synchronize(), sip_outbound_publisher_alloc(), sip_outbound_publisher_init(), sip_outbound_publisher_set_uris(), sip_outbound_registration_apply(), sip_outbound_registration_regc_alloc(), sip_outbound_registration_state_alloc(), sip_sorcery_object_ami_set_type_name(), sip_subscription_send_request(), sip_subscription_to_ami(), sorcery_astdb_create(), sorcery_astdb_delete(), sorcery_astdb_update(), sorcery_config_fields_cmp(), sorcery_memory_cache_complete_object_name(), sorcery_memory_cache_create(), sorcery_memory_cache_delete(), sorcery_memory_cache_fields_cmp(), sorcery_memory_cache_print_object(), sorcery_memory_cache_retrieve_id(), sorcery_memory_cached_object_cmp(), sorcery_memory_cached_object_hash(), sorcery_memory_cmp(), sorcery_memory_create(), sorcery_memory_delete(), sorcery_memory_fields_cmp(), sorcery_memory_hash(), sorcery_memory_update(), sorcery_realtime_create(), sorcery_realtime_delete(), sorcery_realtime_update(), stale_item_update(), stir_shaken_handler(), subscription_established(), subscription_persistence_create(), subscription_persistence_remove(), subscription_tree_destructor(), t38_initialize_session(), tn_apply(), tos_handler(), transport_apply(), transport_tls_file_handler(), transport_tos_handler(), unload_engine(), update_devstate(), users_apply_handler(), validate_publish_config(), and verification_apply().

◆ ast_sorcery_object_get_type()

const char * ast_sorcery_object_get_type ( const void *  object)

Get the type of a sorcery object.

Parameters
objectPointer to a sorcery object
Returns
type of object

Definition at line 2324 of file sorcery.c.

2325{
2326 const struct ast_sorcery_object_details *details = object;
2327 return details->object->type;
2328}

References ast_sorcery_object_details::object, and ast_sorcery_object::type.

Referenced by aeap_cli_show(), ast_sorcery_diff(), AST_TEST_DEFINE(), config_object_cli_show(), memory_cache_stale_check_object(), memory_cache_stale_update_object(), sip_aor_to_ami(), sip_sorcery_object_ami_set_type_name(), sorcery_astdb_create(), sorcery_astdb_delete(), sorcery_astdb_update(), and stale_item_update().

◆ ast_sorcery_object_has_dynamic_contents()

unsigned int ast_sorcery_object_has_dynamic_contents ( const void *  object)

Get whether an object contains dynamic contents or not.

Parameters
objectPointer to a sorcery object
Since
19
18.3.0
16.17.0

Definition at line 2372 of file sorcery.c.

2373{
2374 const struct ast_sorcery_object_details *details = object;
2375
2376 return details->object->has_dynamic_contents;
2377}
unsigned int has_dynamic_contents
Whether this object has dynamic contents or not.
Definition: sorcery.c:144

References ast_sorcery_object::has_dynamic_contents, and ast_sorcery_object_details::object.

Referenced by sorcery_config_internal_load().

◆ ast_sorcery_object_id_compare()

int ast_sorcery_object_id_compare ( void *  obj,
void *  arg,
int  flags 
)

ao2 object comparator based on sorcery id.

Definition at line 2459 of file sorcery.c.

2460{
2461 int cmp;
2462
2463 cmp = ast_sorcery_object_id_sort(obj, arg, flags);
2464 if (cmp) {
2465 return 0;
2466 }
2467 return CMP_MATCH;
2468}
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2435

References ast_sorcery_object_id_sort(), and CMP_MATCH.

Referenced by ast_media_cache_init(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), handle_registrations(), sip_options_aor_alloc(), and sorcery_config_internal_load().

◆ ast_sorcery_object_id_hash()

int ast_sorcery_object_id_hash ( const void *  obj,
int  flags 
)

ao2 object hasher based on sorcery id.

Definition at line 2470 of file sorcery.c.

2471{
2472 const char *key;
2473
2474 switch (flags & OBJ_SEARCH_MASK) {
2475 case OBJ_SEARCH_KEY:
2476 key = obj;
2477 break;
2478 case OBJ_SEARCH_OBJECT:
2479 key = ast_sorcery_object_get_id(obj);
2480 break;
2481 default:
2482 /* Hash can only work on something with a full key. */
2483 ast_assert(0);
2484 return 0;
2485 }
2486 return ast_str_hash(key);
2487}
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
@ OBJ_SEARCH_MASK
Search option field mask.
Definition: astobj2.h:1072
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

References ast_assert, ast_sorcery_object_get_id(), ast_str_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by ast_media_cache_init(), sip_options_aor_alloc(), and sorcery_config_internal_load().

◆ ast_sorcery_object_id_sort()

int ast_sorcery_object_id_sort ( const void *  obj,
const void *  arg,
int  flags 
)

ao2 object sorter based on sorcery id.

Definition at line 2435 of file sorcery.c.

2436{
2437 const void *object_left = obj;
2438 const void *object_right = arg;
2439 const char *right_key = arg;
2440 int cmp;
2441
2442 switch (flags & OBJ_SEARCH_MASK) {
2443 case OBJ_SEARCH_OBJECT:
2444 right_key = ast_sorcery_object_get_id(object_right);
2445 /* Fall through */
2446 case OBJ_SEARCH_KEY:
2447 cmp = strcmp(ast_sorcery_object_get_id(object_left), right_key);
2448 break;
2450 cmp = strncmp(ast_sorcery_object_get_id(object_left), right_key, strlen(right_key));
2451 break;
2452 default:
2453 cmp = 0;
2454 break;
2455 }
2456 return cmp;
2457}
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116

References ast_sorcery_object_get_id(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by ast_sorcery_object_id_compare(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_config_show_profiles(), and sip_options_aor_alloc().

◆ ast_sorcery_object_set_congestion_levels()

int ast_sorcery_object_set_congestion_levels ( struct ast_sorcery sorcery,
const char *  type,
long  low_water,
long  high_water 
)

Set the high and low alert water marks of the sorcery object type.

Since
13.10.0
Parameters
sorceryPointer to a sorcery structure
typeType of object
low_waterNew queue low water mark. (-1 to set as 90% of high_water)
high_waterNew queue high water mark.
Return values
0on success.
-1on error (water marks not changed).

Definition at line 1114 of file sorcery.c.

1115{
1116 struct ast_sorcery_object_type *object_type;
1117 int res = -1;
1118
1119 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1120 if (object_type) {
1122 low_water, high_water);
1123 ao2_ref(object_type, -1);
1124 }
1125 return res;
1126}
int ast_taskprocessor_alert_set_levels(struct ast_taskprocessor *tps, long low_water, long high_water)
Set the high and low alert water marks of the given taskprocessor queue.

References ao2_find, ao2_ref, ast_taskprocessor_alert_set_levels(), OBJ_SEARCH_KEY, ast_sorcery_object_type::serializer, sorcery, type, and ast_sorcery::types.

Referenced by ast_sip_initialize_sorcery_location().

◆ ast_sorcery_object_set_copy_handler()

void ast_sorcery_object_set_copy_handler ( struct ast_sorcery sorcery,
const char *  type,
sorcery_copy_handler  copy 
)

Set the copy handler for an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
copyCopy handler

Definition at line 1128 of file sorcery.c.

1129{
1131
1132 if (!object_type) {
1133 return;
1134 }
1135
1136 object_type->copy = copy;
1137}

References ao2_cleanup, ao2_find, copy(), OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by ast_bucket_init(), and AST_TEST_DEFINE().

◆ ast_sorcery_object_set_diff_handler()

void ast_sorcery_object_set_diff_handler ( struct ast_sorcery sorcery,
const char *  type,
sorcery_diff_handler  diff 
)

Set the diff handler for an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
diffDiff handler

Definition at line 1139 of file sorcery.c.

1140{
1142
1143 if (!object_type) {
1144 return;
1145 }
1146
1147 object_type->diff = diff;
1148}

References ao2_cleanup, ao2_find, ast_sorcery_object_type::diff, OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_object_set_extended()

int ast_sorcery_object_set_extended ( const void *  object,
const char *  name,
const char *  value 
)

Set an extended field value on a sorcery object.

Parameters
objectPointer to a sorcery object
nameName of the extended field
valueValue of the extended field
Return values
0success
-1failure
Note
The field name MUST begin with '@' to indicate it is an extended field.
If the extended field already exists it will be overwritten with the new value.

Definition at line 2344 of file sorcery.c.

2345{
2347 struct ast_variable *extended = ast_variable_new(name, value, ""), *previous = NULL;
2348 const struct ast_sorcery_object_details *details = object;
2349
2350 if (!extended) {
2351 return -1;
2352 }
2353
2354 for (field = details->object->extended; field; previous = field, field = field->next) {
2355 if (!strcmp(field->name, name)) {
2356 if (previous) {
2357 previous->next = field->next;
2358 } else {
2359 details->object->extended = field->next;
2360 }
2361 field->next = NULL;
2362 break;
2363 }
2364 }
2365
2366 extended->next = details->object->extended;
2367 details->object->extended = extended;
2368
2369 return 0;
2370}
int value
Definition: syslog.c:37

References ast_variable_new, ast_variables_destroy(), ast_sorcery_object::extended, name, ast_variable::next, NULL, ast_sorcery_object_details::object, RAII_VAR, and value.

Referenced by AST_TEST_DEFINE(), and sorcery_extended_config_handler().

◆ ast_sorcery_object_set_has_dynamic_contents()

void ast_sorcery_object_set_has_dynamic_contents ( const void *  object)

Set the dynamic contents flag on a sorcery object.

Parameters
objectPointer to a sorcery object
Since
19
18.3.0
16.17.0

Definition at line 2379 of file sorcery.c.

2380{
2381 const struct ast_sorcery_object_details *details = object;
2382
2383 details->object->has_dynamic_contents = 1;
2384}

References ast_sorcery_object::has_dynamic_contents, and ast_sorcery_object_details::object.

Referenced by ip_identify_apply(), and transport_tls_file_handler().

◆ ast_sorcery_object_unregister()

int ast_sorcery_object_unregister ( struct ast_sorcery sorcery,
const char *  type 
)

Unregister an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
Return values
0success
-1failure

Definition at line 1061 of file sorcery.c.

1062{
1063 struct ast_sorcery_object_type *object_type;
1064 int res = -1;
1065
1067 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1068 if (object_type && object_type->type.type == ACO_ITEM) {
1069 ao2_unlink_flags(sorcery->types, object_type, OBJ_NOLOCK);
1070 res = 0;
1071 }
1073
1074 /* XXX may need to add an instance unregister observer callback on success. */
1075
1076 ao2_cleanup(object_type);
1077 return res;
1078}
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Definition: astobj2.h:1600
enum aco_type_t type
struct aco_type type
Type details.
Definition: sorcery.c:177

References ACO_ITEM, ao2_cleanup, ao2_find, ao2_unlink_flags, ao2_unlock, ao2_wrlock, OBJ_NOLOCK, OBJ_SEARCH_KEY, sorcery, type, aco_type::type, ast_sorcery_object_type::type, and ast_sorcery::types.

Referenced by geoloc_config_unload(), and unload_module().

◆ ast_sorcery_objectset_apply()

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.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
objectsetObject set itself
Return values
0success
-1failure
Note
This operation is not atomic. If this fails it is possible for the object to be left with a partially applied object set.

Definition at line 1632 of file sorcery.c.

1633{
1634 const struct ast_sorcery_object_details *details = object;
1635 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1636 RAII_VAR(struct ast_variable *, transformed, NULL, ast_variables_destroy);
1637 struct ast_variable *field;
1638 int res = 0;
1639
1640 if (!object_type) {
1641 return -1;
1642 }
1643
1644 if (object_type->transform && (transformed = object_type->transform(objectset))) {
1645 field = transformed;
1646 } else {
1647 field = objectset;
1648 }
1649
1650 for (; field; field = field->next) {
1651 if ((res = aco_process_var(&object_type->type, details->object->id, field, object))) {
1652 break;
1653 }
1654 }
1655
1656 if (!res && object_type->apply) {
1657 res = object_type->apply(sorcery, object);
1658 }
1659
1660 return res;
1661}
int aco_process_var(struct aco_type *type, const char *cat, struct ast_variable *var, void *obj)
Parse a single ast_variable and apply it to an object.

References aco_process_var(), ao2_cleanup, ao2_find, ast_variables_destroy(), ast_sorcery_object::id, ast_variable::next, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_update_object(), ast_sorcery_copy(), AST_TEST_DEFINE(), create_effective_profile(), create_object(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_internal_load(), sorcery_realtime_retrieve_fields(), and sorcery_realtime_retrieve_multiple().

◆ ast_sorcery_objectset_create2()

struct ast_variable * ast_sorcery_objectset_create2 ( const struct ast_sorcery sorcery,
const void *  object,
enum ast_sorcery_field_handler_flags  flags 
)

Create an object set (KVP list) for an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
flagsFlags indicating which handler to use and in what order.
Return values
non-NULLsuccess
NULLif error occurred
Note
The returned ast_variable list must be destroyed using ast_variables_destroy

Definition at line 1511 of file sorcery.c.

1513{
1514 const struct ast_sorcery_object_details *details = object;
1515 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1516 struct ao2_iterator i;
1517 struct ast_sorcery_object_field *object_field;
1518 struct ast_variable *head = NULL;
1519 struct ast_variable *tail = NULL;
1520
1521 if (!object_type) {
1522 return NULL;
1523 }
1524
1525 i = ao2_iterator_init(object_type->fields, 0);
1526
1527 for (; (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1528 struct ast_variable *tmp;
1529
1530 switch (flags) {
1532 if ((tmp = get_multiple_fields_as_var_list(object, object_field)) ||
1533 (tmp = get_single_field_as_var_list(object, object_field))) {
1534 break;
1535 }
1536 continue;
1538 if ((tmp = get_single_field_as_var_list(object, object_field)) ||
1539 (tmp = get_multiple_fields_as_var_list(object, object_field))) {
1540 break;
1541 }
1542 continue;
1544 if ((tmp = get_multiple_fields_as_var_list(object, object_field))) {
1545 break;
1546 }
1547 continue;
1549 if ((tmp = get_single_field_as_var_list(object, object_field))) {
1550 break;
1551 }
1552 continue;
1553 default:
1554 continue;
1555 }
1556
1557 tail = ast_variable_list_append_hint(&head, tail, tmp);
1558 }
1559
1561
1562 return head;
1563}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ast_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.
Definition: main/config.c:646
static struct ast_variable * get_single_field_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition: sorcery.c:1478
static struct ast_variable * get_multiple_fields_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition: sorcery.c:1495
@ AST_HANDLER_PREFER_STRING
Try both handlers, string first.
Definition: sorcery.h:131
@ AST_HANDLER_PREFER_LIST
Try both handlers, list first.
Definition: sorcery.h:134
@ AST_HANDLER_ONLY_LIST
Use list handler only.
Definition: sorcery.h:140
@ AST_HANDLER_ONLY_STRING
Use string handler only.
Definition: sorcery.h:137
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

References ao2_cleanup, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_HANDLER_ONLY_LIST, AST_HANDLER_ONLY_STRING, AST_HANDLER_PREFER_LIST, AST_HANDLER_PREFER_STRING, ast_variable_list_append_hint(), get_multiple_fields_as_var_list(), get_single_field_as_var_list(), NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, tmp(), ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_sip_sorcery_object_to_ami(), config_object_cli_show(), and sip_aor_to_ami().

◆ ast_sorcery_objectset_json_create()

struct ast_json * ast_sorcery_objectset_json_create ( const struct ast_sorcery sorcery,
const void *  object 
)

Create an object set in JSON format for an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
non-NULLsuccess
NULLif error occurred
Note
The returned ast_json object must be unreferenced using ast_json_unref

Definition at line 1565 of file sorcery.c.

1566{
1567 const struct ast_sorcery_object_details *details = object;
1568 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1569 struct ao2_iterator i;
1570 struct ast_sorcery_object_field *object_field;
1571 struct ast_json *json = ast_json_object_create();
1572 int res = 0;
1573
1574 if (!object_type || !json) {
1575 ast_json_unref(json);
1576 return NULL;
1577 }
1578
1579 i = ao2_iterator_init(object_type->fields, 0);
1580
1581 for (; !res && (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1582 if (object_field->multiple_handler) {
1583 struct ast_variable *tmp = NULL;
1584 struct ast_variable *field;
1585
1586 if ((res = object_field->multiple_handler(object, &tmp))) {
1588 ao2_ref(object_field, -1);
1589 break;
1590 }
1591
1592 for (field = tmp; field; field = field->next) {
1593 struct ast_json *value = ast_json_string_create(field->value);
1594
1595 if (!value || ast_json_object_set(json, field->name, value)) {
1596 res = -1;
1597 break;
1598 }
1599 }
1600
1602 } else if (object_field->handler) {
1603 char *buf = NULL;
1604 struct ast_json *value = NULL;
1605
1606 if (object_field->handler(object, object_field->args, &buf)
1608 || ast_json_object_set(json, object_field->name, value)) {
1609 ast_free(buf);
1610 ast_debug(5, "Skipping field '%s' for object type '%s'\n",
1611 object_field->name, object_type->name);
1612 continue;
1613 }
1614
1615 ast_free(buf);
1616 } else {
1617 continue;
1618 }
1619 }
1620
1622
1623 /* If any error occurs we destroy the JSON object so a partial objectset is not returned */
1624 if (res) {
1625 ast_json_unref(json);
1626 json = NULL;
1627 }
1628
1629 return json;
1630}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:278
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
Definition: json.c:399
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:414
Abstract JSON element (object, array, string, int, ...).

References ao2_cleanup, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_sorcery_object_field::args, ast_debug, ast_free, ast_json_object_create(), ast_json_object_set(), ast_json_string_create(), ast_json_unref(), ast_variables_destroy(), buf, ast_sorcery_object_field::handler, ast_sorcery_object_field::multiple_handler, ast_variable::name, ast_sorcery_object_field::name, ast_variable::next, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, tmp(), ast_sorcery_object::type, ast_sorcery::types, ast_variable::value, and value.

Referenced by ast_bucket_file_json(), ast_bucket_json(), AST_TEST_DEFINE(), and sorcery_astdb_create().

◆ ast_sorcery_observer_add()

int ast_sorcery_observer_add ( const struct ast_sorcery sorcery,
const char *  type,
const struct ast_sorcery_observer callbacks 
)

Add an observer to a specific object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object that should be observed
callbacksImplementation of the observer interface
Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 2386 of file sorcery.c.

2387{
2390 int res;
2391
2392 if (!object_type || !callbacks) {
2393 return -1;
2394 }
2395
2396 if (!(observer = ao2_alloc(sizeof(*observer), NULL))) {
2397 return -1;
2398 }
2399
2400 observer->callbacks = callbacks;
2401 res = 0;
2402 if (!ao2_link(object_type->observers, observer)) {
2403 res = -1;
2404 }
2405 ao2_ref(observer, -1);
2406
2407 return res;
2408}
struct ast_sorcery_instance_observer observer
Structure for registered object type observer.
Definition: sorcery.c:190

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ao2_ref, callbacks, NULL, OBJ_KEY, observer, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by ast_bucket_file_observer_add(), ast_bucket_observer_add(), ast_res_pjsip_initialize_configuration(), ast_sip_initialize_distributor(), ast_sip_initialize_sorcery_location(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), load_module(), pjsip_outbound_registration_metrics_init(), and sip_options_init_task().

◆ ast_sorcery_observer_remove()

void ast_sorcery_observer_remove ( const struct ast_sorcery sorcery,
const char *  type,
const struct ast_sorcery_observer callbacks 
)

Remove an observer from a specific object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object that should no longer be observed
callbacksImplementation of the observer interface

Definition at line 2418 of file sorcery.c.

2419{
2420 RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
2421 struct ast_sorcery_observer *cbs = (struct ast_sorcery_observer *) callbacks;/* Remove const for traversal. */
2422
2423 if (!sorcery) {
2424 return;
2425 }
2426 object_type = ao2_find(sorcery->types, type, OBJ_KEY);
2427 if (!object_type) {
2428 return;
2429 }
2430
2431 ao2_callback(object_type->observers, OBJ_NODATA | OBJ_UNLINK,
2433}
static int sorcery_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing an observer.
Definition: sorcery.c:2411
Interface for a sorcery object type observer.
Definition: sorcery.h:332

References ao2_callback, ao2_cleanup, ao2_find, callbacks, NULL, OBJ_KEY, OBJ_NODATA, OBJ_UNLINK, RAII_VAR, sorcery, sorcery_observer_remove(), type, and ast_sorcery::types.

Referenced by ast_bucket_file_observer_remove(), ast_bucket_observer_remove(), ast_res_pjsip_cleanup_options_handling(), ast_sip_destroy_distributor(), ast_sip_destroy_sorcery_location(), ast_sip_destroy_transport_management(), load_module(), pjsip_outbound_registration_metrics_init(), pjsip_outbound_registration_metrics_unload_cb(), and unload_module().

◆ ast_sorcery_ref()

void ast_sorcery_ref ( struct ast_sorcery sorcery)

Increase the reference count of a sorcery structure.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1473 of file sorcery.c.

1474{
1475 ao2_ref(sorcery, +1);
1476}

References ao2_ref, and sorcery.

Referenced by geoloc_get_sorcery().

◆ ast_sorcery_reload()

void ast_sorcery_reload ( const struct ast_sorcery sorcery)

Inform any wizards to reload persistent objects.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1408 of file sorcery.c.

1409{
1410 struct sorcery_load_details details = {
1411 .sorcery = sorcery,
1412 .reload = 1,
1413 };
1414
1415 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1417
1419
1422
1423}

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by ast_res_pjsip_reload_configuration(), AST_TEST_DEFINE(), geoloc_config_reload(), and reload_module().

◆ ast_sorcery_reload_object()

void ast_sorcery_reload_object ( const struct ast_sorcery sorcery,
const char *  type 
)

Inform any wizards of a specific object type to reload persistent objects.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to reload

Definition at line 1442 of file sorcery.c.

1443{
1445 struct sorcery_load_details details = {
1446 .sorcery = sorcery,
1447 .reload = 1,
1448 };
1449
1450 if (!object_type) {
1451 return;
1452 }
1453
1454 sorcery_object_load(object_type, &details, 0);
1455}

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery_load_details::sorcery, sorcery, sorcery_object_load(), type, and ast_sorcery::types.

Referenced by apply_list_configuration(), ast_sip_initialize_distributor(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), load_module(), load_users(), and reload_module().

◆ ast_sorcery_retrieve_by_fields()

void * ast_sorcery_retrieve_by_fields ( const struct ast_sorcery sorcery,
const char *  type,
unsigned int  flags,
struct ast_variable fields 
)

Retrieve an object or multiple objects using specific fields.

Since
13.9.0
Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
flagsFlags to control behavior
fieldsOptional object fields and values to match against
Return values
non-NULLif found
NULLif not found
Note
If the AST_RETRIEVE_FLAG_MULTIPLE flag is specified the returned value will be an ao2_container that must be unreferenced after use.
If the AST_RETRIEVE_FLAG_ALL flag is used you may omit fields to retrieve all objects of the given type.
The fields parameter can contain realtime-style expressions in variable->name. All operators defined for ast_strings_match can be used except for regex as there's no common support for regex in the realtime backends at this time. If multiple variables are in the fields list, all must match for an object to be returned. See ast_strings_match for more information.

Example:

The following code can be significantly faster when a realtime backend is in use because the expression "qualify_frequency > 0" is passed to the database to limit the number of rows returned.

struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", ""); struct ao2_container *aors;

if (!var) { return; }

aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "aor", AST_RETRIEVE_FLAG_MULTIPLE, var);

Definition at line 1897 of file sorcery.c.

1898{
1900 void *object = NULL;
1901 int i;
1902 unsigned int cached = 0;
1903
1904 if (!object_type) {
1905 return NULL;
1906 }
1907
1908 /* If returning multiple objects create a container to store them in */
1909 if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1911 if (!object) {
1912 return NULL;
1913 }
1914 }
1915
1916 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1917 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1919 AST_VECTOR_GET(&object_type->wizards, i);
1920
1921 if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1922 if (wizard->wizard->callbacks.retrieve_multiple) {
1923 wizard->wizard->callbacks.retrieve_multiple(sorcery, wizard->data, object_type->name, object, fields);
1924 }
1925 } else if (fields && wizard->wizard->callbacks.retrieve_fields) {
1926 if (wizard->wizard->callbacks.retrieve_fields) {
1927 object = wizard->wizard->callbacks.retrieve_fields(sorcery, wizard->data, object_type->name, fields);
1928 }
1929 }
1930
1931 if (((flags & AST_RETRIEVE_FLAG_MULTIPLE) && (!ao2_container_count(object) || !wizard->caching)) || !object) {
1932 continue;
1933 }
1934
1935 cached = wizard->caching;
1936
1937 break;
1938 }
1939
1940 /* If we are returning a single object and it came from a non-cache source create it in any caches */
1941 if (!(flags & AST_RETRIEVE_FLAG_MULTIPLE) && !cached && object) {
1942 AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, object, 0);
1943 }
1944 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1945
1946 return object;
1947}
static int sorcery_cache_create(void *obj, void *arg, int flags)
Internal function used to create an object in caching wizards.
Definition: sorcery.c:1839
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
void(* retrieve_multiple)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)
Optional callback for retrieving multiple objects using some optional field criteria.
Definition: sorcery.h:313
void *(* retrieve_fields)(const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields)
Optional callback for retrieving an object using fields.
Definition: sorcery.h:310
#define AST_VECTOR_CALLBACK(vec, callback, default_value,...)
Execute a callback on every element in a vector returning the first matched.
Definition: vector.h:765

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ao2_find, AST_RETRIEVE_FLAG_MULTIPLE, AST_VECTOR_CALLBACK, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, NULL, OBJ_KEY, RAII_VAR, ast_sorcery_wizard::retrieve_fields, ast_sorcery_wizard::retrieve_multiple, sorcery, sorcery_cache_create(), type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by acl_on_rx_msg(), ami_show_registration_contact_statuses(), ami_show_resource_lists(), ast_aeap_client_configs_get(), ast_mwi_mailbox_get_all(), ast_sip_get_endpoints(), ast_sip_initialize_sorcery_transport(), ast_sip_initialize_system(), ast_sip_location_prune_boot_contacts(), AST_TEST_DEFINE(), asterisk_publication_send_refresh(), auth_observer(), check_expiration_thread(), cli_complete_registration(), cli_contact_get_container(), cli_get_aors(), cli_get_auths(), cli_iterator(), common_identify(), create_mwi_subscriptions(), eprofile_get_all(), format_ami_endpoint_identify(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_config_show_profiles(), get_all_contacts(), get_publishes_and_update_state(), get_registrations(), get_system_cfg(), get_tn_all(), global_loaded_observer(), handle_export_primitives(), load_all_endpoints(), load_users(), memory_cache_populate(), process_nat(), profile_get_all(), sip_options_aor_observer_modified_task(), sip_options_synchronize_task(), stale_cache_update(), and subscription_persistence_load().

◆ ast_sorcery_retrieve_by_id()

void * ast_sorcery_retrieve_by_id ( const struct ast_sorcery sorcery,
const char *  type,
const char *  id 
)

Retrieve an object using its unique identifier.

Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
idUnique object identifier
Return values
non-NULLif found
NULLif not found

Definition at line 1853 of file sorcery.c.

1854{
1855 struct ast_sorcery_object_type *object_type;
1856 void *object = NULL;
1857 int i;
1858 unsigned int cached = 0;
1859
1860 if (ast_strlen_zero(id)) {
1861 return NULL;
1862 }
1863
1864 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1865 if (!object_type) {
1866 return NULL;
1867 }
1868
1869 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1870 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1872 AST_VECTOR_GET(&object_type->wizards, i);
1873
1874 if (wizard->wizard->callbacks.retrieve_id &&
1875 !(object = wizard->wizard->callbacks.retrieve_id(sorcery, wizard->data, object_type->name, id))) {
1876 continue;
1877 }
1878
1879 cached = wizard->caching;
1880 break;
1881 }
1882
1883 if (!cached && object) {
1884 struct sorcery_details sdetails = {
1885 .sorcery = sorcery,
1886 .obj = object,
1887 };
1888
1889 AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, &sdetails, 0);
1890 }
1891 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1892
1893 ao2_ref(object_type, -1);
1894 return object;
1895}
char name[MAX_OBJECT_TYPE]
Unique name of the object type.
Definition: sorcery.c:150
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
Definition: sorcery.h:296

References ao2_find, ao2_ref, ast_strlen_zero(), AST_VECTOR_CALLBACK, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_type::name, NULL, OBJ_SEARCH_KEY, ast_sorcery_wizard::retrieve_id, sorcery_details::sorcery, sorcery, sorcery_cache_create(), type, ast_sorcery::types, ast_sorcery_object_wizard::wizard, and ast_sorcery_object_type::wizards.

Referenced by add_security_headers(), ami_show_endpoint(), ami_sip_qualify(), anonymous_identify(), as_get_cfg(), as_is_config_loaded(), ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), ast_bucket_file_retrieve(), ast_bucket_retrieve(), ast_geoloc_datastore_create_from_profile_name(), ast_geoloc_eprofile_refresh_location(), ast_geoloc_get_location(), ast_geoloc_get_profile(), ast_mwi_mailbox_get(), ast_mwi_mailbox_update(), ast_sip_default_outbound_endpoint(), ast_sip_for_each_auth(), ast_sip_location_retrieve_aor(), ast_sip_location_retrieve_contact(), ast_sip_retrieve_auths(), ast_sip_retrieve_auths_vector(), ast_sip_rewrite_uri_to_local(), ast_sip_set_tpselector_from_transport_name(), AST_TEST_DEFINE(), asterisk_publication_devicestate_state_change(), asterisk_publication_mwi_state_change(), asterisk_publication_new(), chan_pjsip_devicestate(), check_state(), cli_aor_retrieve_by_id(), cli_endpoint_retrieve_by_id(), cli_iterate(), cli_qualify(), cli_reload_qualify_aor(), cli_reload_qualify_endpoint(), cli_retrieve_by_id(), cli_show_qualify_endpoint(), client_config_get(), common_identify(), contact_observer_updated(), create_effective_profile(), create_rtp(), eprofile_get_cfg(), find_aor_name(), find_endpoint(), format_ami_endpoint_transport(), geoloc_profile_apply_handler(), get_log_mappings(), get_write_timeout(), handle_atsign(), handle_registration_response(), handle_single_token(), handle_slash(), line_identify(), load_endpoint(), mwi_contact_changed(), mwi_contact_deleted(), mwi_subscription_shutdown(), on_rx_process_symmetric_transport(), pjsip_acf_dial_contacts_read(), pjsip_aor_function_read(), pjsip_contact_function_read(), pjsip_endpoint_function_read(), process_nat(), profile_get_cfg(), publish_request_initial(), push_notify(), request(), retrieve_resource_list(), send_unsolicited_mwi_notify(), sip_options_contact_add_management_task(), sip_options_qualify_contact(), sorcery_function_read(), sorcery_memory_cache_thrash_retrieve(), stale_item_update(), sub_persistence_recreate(), t38_initialize_session(), tn_get_cfg(), tn_get_etn(), transfer(), vs_get_cfg(), and vs_is_config_loaded().

◆ ast_sorcery_retrieve_by_module_name()

struct ast_sorcery * ast_sorcery_retrieve_by_module_name ( const char *  module_name)

Search function for sorcery instances.

Retrieves an existing sorcery instance by module name.

Definition at line 672 of file sorcery.c.

673{
674 return ao2_weakproxy_find(instances, module_name, OBJ_SEARCH_KEY, "");
675}
#define ao2_weakproxy_find(c, arg, flags, tag)
Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.
Definition: astobj2.h:1748

References ao2_weakproxy_find, instances, ast_sorcery::module_name, and OBJ_SEARCH_KEY.

Referenced by ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), AST_TEST_DEFINE(), and sorcery_function_read().

◆ ast_sorcery_retrieve_by_prefix()

struct ao2_container * ast_sorcery_retrieve_by_prefix ( const struct ast_sorcery sorcery,
const char *  type,
const char *  prefix,
const size_t  prefix_len 
)

Retrieve multiple objects whose id begins with the specified prefix.

Since
13.19.0
Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
prefixObject id prefix
prefix_lenThe length of prefix in bytes
Return values
non-NULLif error occurs
NULLsuccess
Note
The prefix is matched in a case sensitive manner.

Definition at line 1984 of file sorcery.c.

1985{
1987 struct ao2_container *objects;
1988 int i;
1989
1990 if (!object_type) {
1991 return NULL;
1992 }
1993
1995 if (!objects) {
1996 return NULL;
1997 }
1998
1999 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2000 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2002 AST_VECTOR_GET(&object_type->wizards, i);
2003
2004 if (!wizard->wizard->callbacks.retrieve_prefix) {
2005 continue;
2006 }
2007
2008 wizard->wizard->callbacks.retrieve_prefix(sorcery, wizard->data, object_type->name, objects, prefix, prefix_len);
2009
2010 if (wizard->caching && ao2_container_count(objects)) {
2011 break;
2012 }
2013 }
2014 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2015
2016 return objects;
2017}
static char prefix[MAX_PREFIX]
Definition: http.c:144
Generic container type.
void(* retrieve_prefix)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *prefix, const size_t prefix_len)
Optional callback for retrieving multiple objects by matching their id with a prefix.
Definition: sorcery.h:302

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ao2_find, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, NULL, OBJ_KEY, prefix, RAII_VAR, ast_sorcery_wizard::retrieve_prefix, sorcery, type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by aor_deleted_observer(), ast_sip_location_retrieve_aor_contacts_nolock_filtered(), cli_complete_endpoint(), and sip_options_apply_aor_configuration().

◆ ast_sorcery_retrieve_by_regex()

struct ao2_container * ast_sorcery_retrieve_by_regex ( const struct ast_sorcery sorcery,
const char *  type,
const char *  regex 
)

Retrieve multiple objects using a regular expression on their id.

Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
regexRegular expression
Return values
non-NULLif error occurs
NULLsuccess
Note
The provided regex is treated as extended case sensitive.

Definition at line 1949 of file sorcery.c.

1950{
1952 struct ao2_container *objects;
1953 int i;
1954
1955 if (!object_type) {
1956 return NULL;
1957 }
1958
1960 if (!objects) {
1961 return NULL;
1962 }
1963
1964 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1965 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1967 AST_VECTOR_GET(&object_type->wizards, i);
1968
1969 if (!wizard->wizard->callbacks.retrieve_regex) {
1970 continue;
1971 }
1972
1973 wizard->wizard->callbacks.retrieve_regex(sorcery, wizard->data, object_type->name, objects, regex);
1974
1975 if (wizard->caching && ao2_container_count(objects)) {
1976 break;
1977 }
1978 }
1979 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1980
1981 return objects;
1982}
void(* retrieve_regex)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex)
Callback for retrieving multiple objects using a regex on their id.
Definition: sorcery.h:299

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ao2_find, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, NULL, OBJ_KEY, RAII_VAR, regex(), ast_sorcery_wizard::retrieve_regex, sorcery, type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by ast_mwi_mailbox_get_by_regex(), AST_TEST_DEFINE(), cli_aor_get_container(), cli_contact_get_container(), cli_endpoint_get_container(), cli_get_container(), geoloc_config_list_locations(), geoloc_config_list_profiles(), and geoloc_config_show_profiles().

◆ ast_sorcery_update()

int ast_sorcery_update ( const struct ast_sorcery sorcery,
void *  object 
)

Update an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2145 of file sorcery.c.

2146{
2147 const struct ast_sorcery_object_details *details = object;
2148 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2149 struct ast_sorcery_object_wizard *object_wizard = NULL;
2150 struct ast_sorcery_object_wizard *found_wizard;
2151 int i;
2152 struct sorcery_details sdetails = {
2153 .sorcery = sorcery,
2154 .obj = object,
2155 };
2156
2157 if (!object_type) {
2158 return -1;
2159 }
2160
2161 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2162 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2163 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2164 if (!found_wizard->caching
2165 && sorcery_wizard_update(found_wizard, &sdetails) == CMP_MATCH) {
2166 object_wizard = found_wizard;
2167 }
2168 }
2169
2170 if (object_wizard) {
2171 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2172 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2173 if (found_wizard->caching) {
2174 sorcery_wizard_update(found_wizard, &sdetails);
2175 }
2176 }
2177
2178 if (ao2_container_count(object_type->observers)) {
2179 struct sorcery_observer_invocation *invocation;
2180
2181 invocation = sorcery_observer_invocation_alloc(object_type, object);
2182 if (invocation
2184 invocation)) {
2185 ao2_cleanup(invocation);
2186 }
2187 }
2188 }
2189
2191
2192 return object_wizard ? 0 : -1;
2193}
static int sorcery_wizard_update(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if a wizard has updated the object.
Definition: sorcery.c:2131
static int sorcery_observers_notify_update(void *data)
Internal callback function which notifies observers that an object has been updated.
Definition: sorcery.c:2120

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery_details::sorcery, sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_update(), sorcery_wizard_update(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_file_update(), ast_mwi_mailbox_update(), ast_sip_location_update_contact(), AST_TEST_DEFINE(), create_effective_profile(), sorcery_memory_cache_thrash_update(), and subscription_persistence_update().

◆ ast_sorcery_wizard_observer_add()

int ast_sorcery_wizard_observer_add ( struct ast_sorcery_wizard wizard,
const struct ast_sorcery_wizard_observer callbacks 
)

Add an observer to a sorcery wizard.

Parameters
wizardPointer to a previously registered wizard structure
callbacksImplementation of the wizard observer interface

A wizard observer is notified... Before a wizard is loaded or reloaded. After a wizard is loaded or reloaded.

Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 543 of file sorcery.c.

545{
546 RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
547 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
549
550 if (wizard) {
551 struct sorcery_wizard_observer *cb;
552
553 cb = ao2_alloc(sizeof(*cb), NULL);
554 if (!cb) {
555 return -1;
556 }
557
558 cb->callbacks = callbacks;
559 ao2_link(wizard->observers, cb);
560 ao2_ref(cb, -1);
561
562 return 0;
563 }
564
565 return -1;
566}
A wizard observer wrapper.
Definition: sorcery.c:276
const struct ast_sorcery_wizard_observer * callbacks
Definition: sorcery.c:277

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ao2_ref, sorcery_wizard_observer::callbacks, callbacks, ast_sorcery_wizard::name, NULL, OBJ_SEARCH_KEY, RAII_VAR, and wizards.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_wizard_observer_remove()

void ast_sorcery_wizard_observer_remove ( struct ast_sorcery_wizard interface,
const struct ast_sorcery_wizard_observer callbacks 
)

Remove an observer from a sorcery wizard.

Parameters
interfacePointer to a sorcery structure
callbacksImplementation of the wizard observer interface

Definition at line 568 of file sorcery.c.

570{
571 RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
572 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
574
575 if (wizard) {
577 }
578}

References ao2_callback, ao2_cleanup, ao2_find, callbacks, ast_sorcery_wizard::name, NULL, OBJ_NODATA, OBJ_SEARCH_KEY, OBJ_UNLINK, RAII_VAR, sorcery_generic_observer_remove(), and wizards.

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_wizard_unregister()

int ast_sorcery_wizard_unregister ( const struct ast_sorcery_wizard interface)

Unregister a sorcery wizard.

Parameters
interfacePointer to the wizard interface
Return values
0success
-1failure

Definition at line 474 of file sorcery.c.

475{
476 struct ast_sorcery_internal_wizard *wizard =
477 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL;
478
479 if (wizard) {
480 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_unregistering, wizard->callbacks.name, &wizard->callbacks);
481 ao2_unlink(wizards, wizard);
482 ao2_ref(wizard, -1);
483 ast_verb(5, "Sorcery unregistered wizard '%s'\n", interface->name);
484 return 0;
485 } else {
486 return -1;
487 }
488}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578

References ao2_find, ao2_ref, ao2_unlink, ast_verb, ast_sorcery_internal_wizard::callbacks, if(), name, ast_sorcery_wizard::name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_SEARCH_KEY, observers, and wizards.

Referenced by AST_TEST_DEFINE(), bucket_cleanup(), sorcery_memory_cache_thrash_destroy(), and unload_module().

◆ AST_VECTOR_RW()

AST_VECTOR_RW ( ast_sorcery_object_wizards  ,
struct ast_sorcery_object_wizard  
)

Interface for a sorcery object type wizards.

◆ bool_handler_fn()

static int bool_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 310 of file sorcery.c.

311{
312 unsigned int *field = (unsigned int *)(obj + args[0]);
313 return !(*buf = ast_strdup(*field ? "true" : "false")) ? -1 : 0;
314}

References args, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

◆ chararray_handler_fn()

static int chararray_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 328 of file sorcery.c.

329{
330 char *field = (char *)(obj + args[0]);
331 return !(*buf = ast_strdup(field)) ? -1 : 0;
332}

References args, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

◆ codec_handler_fn()

static int codec_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 334 of file sorcery.c.

335{
337 struct ast_format_cap **cap = (struct ast_format_cap **)(obj + args[0]);
338 return !(*buf = ast_strdup(ast_format_cap_get_names(*cap, &codec_buf)));
339}
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
#define ast_str_alloca(init_len)
Definition: strings.h:848
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Support for dynamic strings.
Definition: strings.h:623

References args, ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_str_alloca, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

◆ double_handler_fn()

static int double_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 298 of file sorcery.c.

299{
300 double *field = (double *)(obj + args[0]);
301 return (ast_asprintf(buf, "%f", *field) < 0) ? -1 : 0;
302}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267

References args, ast_asprintf, and buf.

Referenced by sorcery_field_default_handler().

◆ get_multiple_fields_as_var_list()

static struct ast_variable * get_multiple_fields_as_var_list ( const void *  object,
struct ast_sorcery_object_field object_field 
)
static

Definition at line 1495 of file sorcery.c.

1496{
1497 struct ast_variable *tmp = NULL;
1498
1499 if (!object_field->multiple_handler) {
1500 return NULL;
1501 }
1502
1503 if (object_field->multiple_handler(object, &tmp)) {
1505 tmp = NULL;
1506 }
1507
1508 return tmp;
1509}
sorcery_fields_handler multiple_handler
Callback function for translation of multiple values.
Definition: sorcery.c:216

References ast_variables_destroy(), ast_sorcery_object_field::multiple_handler, NULL, and tmp().

Referenced by ast_sorcery_objectset_create2().

◆ get_single_field_as_var_list()

static struct ast_variable * get_single_field_as_var_list ( const void *  object,
struct ast_sorcery_object_field object_field 
)
static

Definition at line 1478 of file sorcery.c.

1479{
1480 struct ast_variable *tmp = NULL;
1481 char *buf = NULL;
1482
1483 if (!object_field->handler) {
1484 return NULL;
1485 }
1486
1487 if (!(object_field->handler(object, object_field->args, &buf))) {
1488 tmp = ast_variable_new(object_field->name, S_OR(buf, ""), "");
1489 }
1490 ast_free(buf);
1491
1492 return tmp;
1493}
sorcery_field_handler handler
Callback function for translation of a single value.
Definition: sorcery.c:213
intptr_t args[]
Position of the field.
Definition: sorcery.c:219
char name[MAX_OBJECT_FIELD]
Name of the field.
Definition: sorcery.c:207

References ast_sorcery_object_field::args, ast_free, ast_variable_new, buf, ast_sorcery_object_field::handler, ast_sorcery_object_field::name, NULL, S_OR, and tmp().

Referenced by ast_sorcery_objectset_create2().

◆ int_handler_fn()

static int int_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 286 of file sorcery.c.

287{
288 int *field = (int *)(obj + args[0]);
289 return (ast_asprintf(buf, "%d", *field) < 0) ? -1 : 0;
290}

References args, ast_asprintf, and buf.

Referenced by sorcery_field_default_handler().

◆ is_registered_cb()

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

Definition at line 2495 of file sorcery.c.

2496{
2497 struct ast_sorcery_object_field *object_field = obj;
2498 char *name = arg;
2499 int rc = 0;
2500
2501 if (object_field->name_regex
2502 && !regexec(object_field->name_regex, name, 0, NULL, 0)) {
2503 rc = CMP_MATCH;
2504 }
2505
2506 return rc;
2507}
regex_t * name_regex
The compiled name regex if name is a regex.
Definition: sorcery.c:210

References CMP_MATCH, name, ast_sorcery_object_field::name_regex, and NULL.

Referenced by ast_sorcery_is_object_field_registered().

◆ sockaddr_handler_fn()

static int sockaddr_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 322 of file sorcery.c.

323{
324 struct ast_sockaddr *field = (struct ast_sockaddr *)(obj + args[0]);
325 return !(*buf = ast_strdup(ast_sockaddr_stringify(field))) ? -1 : 0;
326}
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
Socket address structure.
Definition: netsock2.h:97

References args, ast_sockaddr_stringify(), ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

◆ sorcery_cache_create()

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

Internal function used to create an object in caching wizards.

Definition at line 1839 of file sorcery.c.

1840{
1841 const struct ast_sorcery_object_wizard *object_wizard = obj;
1842 const struct sorcery_details *details = arg;
1843
1844 if (!object_wizard->caching || !object_wizard->wizard->callbacks.create) {
1845 return 0;
1846 }
1847
1848 object_wizard->wizard->callbacks.create(details->sorcery, object_wizard->data, details->obj);
1849
1850 return 0;
1851}
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Definition: sorcery.h:293
void * obj
Pointer to the object itself.
Definition: sorcery.c:1835

References ast_sorcery_object_wizard::caching, ast_sorcery_internal_wizard::callbacks, ast_sorcery_wizard::create, ast_sorcery_object_wizard::data, sorcery_details::obj, sorcery_details::sorcery, and ast_sorcery_object_wizard::wizard.

Referenced by ast_sorcery_retrieve_by_fields(), and ast_sorcery_retrieve_by_id().

◆ sorcery_cleanup()

static void sorcery_cleanup ( void  )
static

Hashing and comparison functions for sorcery wizards.

Cleanup function for graceful shutdowns

Definition at line 369 of file sorcery.c.

370{
374 wizards = NULL;
376 observers = NULL;
378 instances = NULL;
379}
void ast_threadpool_shutdown(struct ast_threadpool *pool)
Shut down a threadpool and destroy it.
Definition: threadpool.c:966

References ao2_cleanup, ast_threadpool_shutdown(), instances, NULL, observers, threadpool, and wizards.

Referenced by ast_sorcery_init().

◆ sorcery_destructor()

static void sorcery_destructor ( void *  obj)
static

Destructor called when sorcery structure is destroyed.

Definition at line 581 of file sorcery.c.

582{
583 struct ast_sorcery *sorcery = obj;
584
585 if (sorcery->observers) {
587 }
590}

References ao2_cleanup, ast_sorcery::module_name, NOTIFY_GLOBAL_OBSERVERS, ast_sorcery::observers, observers, sorcery, and ast_sorcery::types.

Referenced by __ast_sorcery_open().

◆ sorcery_extended_config_handler()

static int sorcery_extended_config_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 1043 of file sorcery.c.

1044{
1045 return ast_sorcery_object_set_extended(obj, var->name, var->value);
1046}
#define var
Definition: ast_expr2f.c:605
int ast_sorcery_object_set_extended(const void *object, const char *name, const char *value)
Set an extended field value on a sorcery object.
Definition: sorcery.c:2344

References ast_sorcery_object_set_extended(), and var.

Referenced by __ast_sorcery_object_register().

◆ sorcery_extended_fields_handler()

static int sorcery_extended_fields_handler ( const void *  obj,
struct ast_variable **  fields 
)
static

Definition at line 1048 of file sorcery.c.

1049{
1050 const struct ast_sorcery_object_details *details = obj;
1051
1052 if (details->object->extended) {
1053 *fields = ast_variables_dup(details->object->extended);
1054 } else {
1055 *fields = NULL;
1056 }
1057
1058 return 0;
1059}
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:543

References ast_variables_dup(), ast_sorcery_object::extended, NULL, and ast_sorcery_object_details::object.

Referenced by __ast_sorcery_object_register().

◆ sorcery_field_default_handler()

static sorcery_field_handler sorcery_field_default_handler ( enum aco_option_type  type)
static

Definition at line 341 of file sorcery.c.

342{
343 switch(type) {
344 case OPT_BOOL_T: return bool_handler_fn;
345 case OPT_YESNO_T: return yesno_handler_fn;
347 case OPT_CODEC_T: return codec_handler_fn;
348 case OPT_DOUBLE_T: return double_handler_fn;
349 case OPT_INT_T: return int_handler_fn;
352 case OPT_UINT_T: return uint_handler_fn;
353
354 default:
355 case OPT_CUSTOM_T: return NULL;
356 }
357
358 return NULL;
359}
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_CODEC_T
Type for default option handler for format capabilities.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_CHAR_ARRAY_T
Type for default option handler for character array strings.
@ OPT_SOCKADDR_T
Type for default handler for ast_sockaddrs.
@ OPT_YESNO_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_INT_T
Type for default option handler for signed integers.
@ OPT_DOUBLE_T
Type for default option handler for doubles.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
static int int_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:286
static int chararray_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:328
static int stringfield_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:304
static int codec_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:334
static int yesno_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:316
static int bool_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:310
static int uint_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:292
static int sockaddr_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:322
static int double_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition: sorcery.c:298

References bool_handler_fn(), chararray_handler_fn(), codec_handler_fn(), double_handler_fn(), int_handler_fn(), NULL, OPT_BOOL_T, OPT_CHAR_ARRAY_T, OPT_CODEC_T, OPT_CUSTOM_T, OPT_DOUBLE_T, OPT_INT_T, OPT_SOCKADDR_T, OPT_STRINGFIELD_T, OPT_UINT_T, OPT_YESNO_T, sockaddr_handler_fn(), stringfield_handler_fn(), type, uint_handler_fn(), and yesno_handler_fn().

Referenced by __ast_sorcery_object_field_register().

◆ sorcery_generic_observer_remove()

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

Internal callback function for removing a generic observer.

Definition at line 491 of file sorcery.c.

492{
493 const struct sorcery_global_observer *observer = obj;
494
495 return (observer->callbacks == arg) ? CMP_MATCH : 0;
496}

References CMP_MATCH, and observer.

Referenced by ast_sorcery_global_observer_remove(), ast_sorcery_instance_observer_remove(), and ast_sorcery_wizard_observer_remove().

◆ sorcery_internal_wizard_destructor()

static void sorcery_internal_wizard_destructor ( void *  obj)
static

Definition at line 425 of file sorcery.c.

426{
427 struct ast_sorcery_internal_wizard *wizard = obj;
428
429 ao2_cleanup(wizard->observers);
430}

References ao2_cleanup, and ast_sorcery_internal_wizard::observers.

Referenced by __ast_sorcery_wizard_register().

◆ sorcery_object_destructor()

static void sorcery_object_destructor ( void *  object)
static

Definition at line 1700 of file sorcery.c.

1701{
1702 struct ast_sorcery_object_details *details = object;
1703
1704 if (details->object->destructor) {
1705 details->object->destructor(object);
1706 }
1707
1709 ast_free(details->object->id);
1710}

References ast_free, ast_variables_destroy(), ast_sorcery_object::destructor, ast_sorcery_object::extended, ast_sorcery_object::id, and ast_sorcery_object_details::object.

Referenced by ast_sorcery_generic_alloc(), and ast_sorcery_lockable_alloc().

◆ sorcery_object_field_destructor()

static void sorcery_object_field_destructor ( void *  obj)
static

Definition at line 1150 of file sorcery.c.

1151{
1152 struct ast_sorcery_object_field *object_field = obj;
1153
1154 if (object_field->name_regex) {
1155 regfree(object_field->name_regex);
1156 ast_free(object_field->name_regex);
1157 }
1158}

References ast_free, and ast_sorcery_object_field::name_regex.

Referenced by ast_sorcery_object_fields_register().

◆ sorcery_object_load()

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

Definition at line 1336 of file sorcery.c.

1337{
1338 struct ast_sorcery_object_type *type = obj;
1339 struct sorcery_load_details *details = arg;
1340
1341 if (!type->type.item_alloc) {
1342 return 0;
1343 }
1344
1345 details->type = type->name;
1346
1347 if (details->reload && !sorcery_reloadable(details->sorcery, details->type)) {
1348 ast_log(LOG_NOTICE, "Type '%s' is not reloadable, maintaining previous values\n",
1349 details->type);
1350 return 0;
1351 }
1352
1353 NOTIFY_INSTANCE_OBSERVERS(details->sorcery->observers, object_type_loading,
1354 details->sorcery->module_name, details->sorcery, type->name, details->reload);
1355
1356 AST_VECTOR_RW_RDLOCK(&type->wizards);
1357 AST_VECTOR_CALLBACK(&type->wizards, sorcery_wizard_load, NULL, details, 0);
1358 AST_VECTOR_RW_UNLOCK(&type->wizards);
1359
1360 NOTIFY_INSTANCE_OBSERVERS(details->sorcery->observers, object_type_loaded,
1361 details->sorcery->module_name, details->sorcery, type->name, details->reload);
1362
1363 if (ao2_container_count(type->observers)) {
1364 struct sorcery_observer_invocation *invocation;
1365
1367 if (invocation
1369 invocation)) {
1370 ao2_cleanup(invocation);
1371 }
1372 }
1373
1374 return 0;
1375}
#define LOG_NOTICE
static int sorcery_wizard_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1253
static int sorcery_reloadable(const struct ast_sorcery *sorcery, const char *type)
Retrieves whether or not the type is reloadable.
Definition: sorcery.c:1246
static int sorcery_observers_notify_loaded(void *data)
Internal callback function which notifies observers that an object type has been loaded.
Definition: sorcery.c:1326
const char * type
Type of object being loaded.
Definition: sorcery.c:247
unsigned int reload
Whether this is a reload or not.
Definition: sorcery.c:250

References ao2_cleanup, ao2_container_count(), ast_log, ast_taskprocessor_push(), AST_VECTOR_CALLBACK, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, LOG_NOTICE, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, NULL, ast_sorcery::observers, sorcery_load_details::reload, sorcery_load_details::sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_loaded(), sorcery_reloadable(), sorcery_wizard_load(), type, and sorcery_load_details::type.

Referenced by ast_sorcery_force_reload(), ast_sorcery_force_reload_object(), ast_sorcery_load(), ast_sorcery_load_object(), ast_sorcery_reload(), and ast_sorcery_reload_object().

◆ sorcery_object_type_alloc()

static struct ast_sorcery_object_type * sorcery_object_type_alloc ( const char *  type,
const char *  module 
)
static

Internal function which allocates an object type structure.

Definition at line 700 of file sorcery.c.

701{
702#define INITIAL_WIZARD_VECTOR_SIZE 5
703 struct ast_sorcery_object_type *object_type;
704 char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
705
706 if (!(object_type = ao2_alloc(sizeof(*object_type), sorcery_object_type_destructor))) {
707 return NULL;
708 }
709
710 /* Order matters for object wizards */
711 if (AST_VECTOR_RW_INIT(&object_type->wizards, INITIAL_WIZARD_VECTOR_SIZE) != 0) {
712 ao2_ref(object_type, -1);
713 return NULL;
714 }
715
717 OBJECT_FIELD_BUCKETS, ast_sorcery_object_field_hash_fn, NULL, ast_sorcery_object_field_cmp_fn);
718 if (!object_type->fields) {
719 ao2_ref(object_type, -1);
720 return NULL;
721 }
722
724 NULL, NULL);
725 if (!object_type->observers) {
726 ao2_ref(object_type, -1);
727 return NULL;
728 }
729
730 object_type->info = ast_calloc(1,
731 sizeof(*object_type->info) + 2 * sizeof(object_type->info->files[0]));
732 if (!object_type->info) {
733 ao2_ref(object_type, -1);
734 return NULL;
735 }
736
737 object_type->file = ast_calloc(1,
738 sizeof(*object_type->file) + 2 * sizeof(object_type->file->types[0]));
739 if (!object_type->file) {
740 ao2_ref(object_type, -1);
741 return NULL;
742 }
743
744 /* Create name with seq number appended. */
745 ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "sorcery/%s", type);
746
747 if (!(object_type->serializer = ast_threadpool_serializer(tps_name, threadpool))) {
748 ao2_ref(object_type, -1);
749 return NULL;
750 }
751
752 object_type->info->files[0] = object_type->file;
753 object_type->info->files[1] = NULL;
754 object_type->info->module = module;
755
756 ast_copy_string(object_type->name, type, sizeof(object_type->name));
757
758 return object_type;
759}
#define INITIAL_WIZARD_VECTOR_SIZE
static void sorcery_object_type_destructor(void *obj)
Destructor function for object types.
Definition: sorcery.c:678
#define OBJECT_FIELD_BUCKETS
Number of buckets for object fields (should be prime for performance reasons)
Definition: sorcery.c:60
struct aco_type * types[]
struct aco_file * files[]
const char * module
struct aco_file * file
Configuration framework file information.
Definition: sorcery.c:174
struct ao2_container * observers
Observers.
Definition: sorcery.c:180
struct aco_info * info
Configuration framework general information.
Definition: sorcery.c:171
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:61
struct ast_taskprocessor * ast_threadpool_serializer(const char *name, struct ast_threadpool *pool)
Serialized execution of tasks within a ast_threadpool.
Definition: threadpool.c:1428
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Definition: vector.h:158

References ao2_alloc, AO2_ALLOC_OPT_LOCK_NOLOCK, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_hash, ao2_container_alloc_list, ao2_ref, ast_calloc, ast_copy_string(), ast_taskprocessor_build_name(), AST_TASKPROCESSOR_MAX_NAME, ast_threadpool_serializer(), AST_VECTOR_RW_INIT, ast_sorcery_object_type::fields, ast_sorcery_object_type::file, aco_info::files, ast_sorcery_object_type::info, INITIAL_WIZARD_VECTOR_SIZE, aco_info::module, ast_sorcery_object_type::name, NULL, OBJECT_FIELD_BUCKETS, ast_sorcery_object_type::observers, ast_sorcery_object_type::serializer, sorcery_object_type_destructor(), threadpool, type, aco_file::types, and ast_sorcery_object_type::wizards.

Referenced by __ast_sorcery_object_type_insert_wizard().

◆ sorcery_object_type_destructor()

static void sorcery_object_type_destructor ( void *  obj)
static

Destructor function for object types.

Definition at line 678 of file sorcery.c.

679{
680 struct ast_sorcery_object_type *object_type = obj;
681
682 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
684 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
685 AST_VECTOR_RW_FREE(&object_type->wizards);
686 ao2_cleanup(object_type->fields);
687 ao2_cleanup(object_type->observers);
688
689 if (object_type->info) {
690 aco_info_destroy(object_type->info);
691 ast_free(object_type->info);
692 }
693
694 ast_free(object_type->file);
695
697}
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
Definition: vector.h:202
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:862

References aco_info_destroy(), ao2_cleanup, ast_free, ast_taskprocessor_unreference(), AST_VECTOR_CALLBACK_VOID, AST_VECTOR_RW_FREE, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, ast_sorcery_object_type::fields, ast_sorcery_object_type::file, ast_sorcery_object_type::info, ast_sorcery_object_type::observers, ast_sorcery_object_type::serializer, and ast_sorcery_object_type::wizards.

Referenced by sorcery_object_type_alloc().

◆ sorcery_object_wizard_destructor()

static void sorcery_object_wizard_destructor ( void *  obj)
static

Object wizard destructor.

Definition at line 762 of file sorcery.c.

763{
764 struct ast_sorcery_object_wizard *object_wizard = obj;
765
766 if (object_wizard->data && object_wizard->wizard->callbacks.close) {
767 object_wizard->wizard->callbacks.close(object_wizard->data);
768 }
769
770 if (object_wizard->wizard) {
771 ast_module_unref(object_wizard->wizard->callbacks.module);
772 }
773
774 ao2_cleanup(object_wizard->wizard);
775}
void(* close)(void *data)
Callback for closing a wizard.
Definition: sorcery.h:322

References ao2_cleanup, ast_module_unref, ast_sorcery_internal_wizard::callbacks, ast_sorcery_wizard::close, ast_sorcery_object_wizard::data, ast_sorcery_wizard::module, and ast_sorcery_object_wizard::wizard.

Referenced by __ast_sorcery_object_type_insert_wizard().

◆ sorcery_observer_invocation_alloc()

static struct sorcery_observer_invocation * sorcery_observer_invocation_alloc ( struct ast_sorcery_object_type object_type,
void *  object 
)
static

Allocator function for observer invocation.

Definition at line 1292 of file sorcery.c.

1293{
1294 struct sorcery_observer_invocation *invocation;
1295
1296 invocation = ao2_alloc_options(sizeof(*invocation),
1298 if (!invocation) {
1299 return NULL;
1300 }
1301
1302 ao2_ref(object_type, +1);
1303 invocation->object_type = object_type;
1304
1305 if (object) {
1306 ao2_ref(object, +1);
1307 invocation->object = object;
1308 }
1309
1310 return invocation;
1311}
static void sorcery_observer_invocation_destroy(void *obj)
Destructor for observer invocation.
Definition: sorcery.c:1283
void * object
Pointer to the object.
Definition: sorcery.c:201

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, NULL, sorcery_observer_invocation::object, sorcery_observer_invocation::object_type, and sorcery_observer_invocation_destroy().

Referenced by ast_sorcery_create(), ast_sorcery_delete(), ast_sorcery_update(), and sorcery_object_load().

◆ sorcery_observer_invocation_destroy()

static void sorcery_observer_invocation_destroy ( void *  obj)
static

Destructor for observer invocation.

Definition at line 1283 of file sorcery.c.

1284{
1285 struct sorcery_observer_invocation *invocation = obj;
1286
1287 ao2_cleanup(invocation->object_type);
1288 ao2_cleanup(invocation->object);
1289}

References ao2_cleanup, sorcery_observer_invocation::object, and sorcery_observer_invocation::object_type.

Referenced by sorcery_observer_invocation_alloc().

◆ sorcery_observer_notify_create()

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

Internal callback function which notifies an individual observer that an object has been created.

Definition at line 2035 of file sorcery.c.

2036{
2037 const struct ast_sorcery_object_type_observer *observer = obj;
2038
2039 if (observer->callbacks->created) {
2040 observer->callbacks->created(arg);
2041 }
2042
2043 return 0;
2044}

References observer.

Referenced by sorcery_observers_notify_create().

◆ sorcery_observer_notify_delete()

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

Internal callback function which notifies an individual observer that an object has been deleted.

Definition at line 2196 of file sorcery.c.

2197{
2198 const struct ast_sorcery_object_type_observer *observer = obj;
2199
2200 if (observer->callbacks->deleted) {
2201 observer->callbacks->deleted(arg);
2202 }
2203
2204 return 0;
2205}

References observer.

Referenced by sorcery_observers_notify_delete().

◆ sorcery_observer_notify_loaded()

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

Internal callback function which notifies an individual observer that an object type has been loaded.

Definition at line 1314 of file sorcery.c.

1315{
1316 const struct ast_sorcery_object_type_observer *observer = obj;
1317
1318 if (observer->callbacks->loaded) {
1319 observer->callbacks->loaded(arg);
1320 }
1321
1322 return 0;
1323}

References observer.

Referenced by sorcery_observers_notify_loaded().

◆ sorcery_observer_notify_update()

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

Internal callback function which notifies an individual observer that an object has been updated.

Definition at line 2108 of file sorcery.c.

2109{
2110 const struct ast_sorcery_object_type_observer *observer = obj;
2111
2112 if (observer->callbacks->updated) {
2113 observer->callbacks->updated(arg);
2114 }
2115
2116 return 0;
2117}

References observer.

Referenced by sorcery_observers_notify_update().

◆ sorcery_observer_remove()

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

Internal callback function for removing an observer.

Definition at line 2411 of file sorcery.c.

2412{
2413 const struct ast_sorcery_object_type_observer *observer = obj;
2414
2415 return (observer->callbacks == arg) ? CMP_MATCH : 0;
2416}

References CMP_MATCH, and observer.

Referenced by ast_sorcery_observer_remove().

◆ sorcery_observers_notify_create()

static int sorcery_observers_notify_create ( void *  data)
static

Internal callback function which notifies observers that an object has been created.

Definition at line 2047 of file sorcery.c.

2048{
2049 struct sorcery_observer_invocation *invocation = data;
2050
2052 ao2_cleanup(invocation);
2053
2054 return 0;
2055}
static int sorcery_observer_notify_create(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object has been created.
Definition: sorcery.c:2035

References ao2_callback, ao2_cleanup, OBJ_NODATA, sorcery_observer_invocation::object, sorcery_observer_invocation::object_type, ast_sorcery_object_type::observers, and sorcery_observer_notify_create().

Referenced by ast_sorcery_create().

◆ sorcery_observers_notify_delete()

static int sorcery_observers_notify_delete ( void *  data)
static

Internal callback function which notifies observers that an object has been deleted.

Definition at line 2208 of file sorcery.c.

2209{
2210 struct sorcery_observer_invocation *invocation = data;
2211
2213 ao2_cleanup(invocation);
2214
2215 return 0;
2216}
static int sorcery_observer_notify_delete(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object has been deleted.
Definition: sorcery.c:2196

References ao2_callback, ao2_cleanup, OBJ_NODATA, sorcery_observer_invocation::object, sorcery_observer_invocation::object_type, ast_sorcery_object_type::observers, and sorcery_observer_notify_delete().

Referenced by ast_sorcery_delete().

◆ sorcery_observers_notify_loaded()

static int sorcery_observers_notify_loaded ( void *  data)
static

Internal callback function which notifies observers that an object type has been loaded.

Definition at line 1326 of file sorcery.c.

1327{
1328 struct sorcery_observer_invocation *invocation = data;
1329
1331 ao2_cleanup(invocation);
1332
1333 return 0;
1334}
static int sorcery_observer_notify_loaded(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object type has been loaded.
Definition: sorcery.c:1314

References ao2_callback, ao2_cleanup, ast_sorcery_object_type::name, OBJ_NODATA, sorcery_observer_invocation::object_type, ast_sorcery_object_type::observers, and sorcery_observer_notify_loaded().

Referenced by sorcery_object_load().

◆ sorcery_observers_notify_update()

static int sorcery_observers_notify_update ( void *  data)
static

Internal callback function which notifies observers that an object has been updated.

Definition at line 2120 of file sorcery.c.

2121{
2122 struct sorcery_observer_invocation *invocation = data;
2123
2125 ao2_cleanup(invocation);
2126
2127 return 0;
2128}
static int sorcery_observer_notify_update(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object has been updated.
Definition: sorcery.c:2108

References ao2_callback, ao2_cleanup, OBJ_NODATA, sorcery_observer_invocation::object, sorcery_observer_invocation::object_type, ast_sorcery_object_type::observers, and sorcery_observer_notify_update().

Referenced by ast_sorcery_update().

◆ sorcery_proxy_cb()

static void sorcery_proxy_cb ( void *  weakproxy,
void *  data 
)
static

Hashing function for sorcery types.

Definition at line 596 of file sorcery.c.

597{
598 ao2_unlink(instances, weakproxy);
599}

References ao2_unlink, and instances.

Referenced by __ast_sorcery_open().

◆ sorcery_reloadable()

static int sorcery_reloadable ( const struct ast_sorcery sorcery,
const char *  type 
)
static

Retrieves whether or not the type is reloadable.

Definition at line 1246 of file sorcery.c.

1247{
1248 RAII_VAR(struct ast_sorcery_object_type *, object_type,
1250 return object_type && object_type->reloadable;
1251}

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery, type, and ast_sorcery::types.

Referenced by sorcery_object_load().

◆ sorcery_wizard_create()

static int sorcery_wizard_create ( const struct ast_sorcery_object_wizard object_wizard,
const struct sorcery_details details 
)
static

Internal function which returns if the wizard has created the object.

Definition at line 2020 of file sorcery.c.

2021{
2022 if (!object_wizard->wizard->callbacks.create || object_wizard->read_only) {
2023 ast_debug(5, "Sorcery wizard '%s' does not support creation\n", object_wizard->wizard->callbacks.name);
2024 return 0;
2025 }
2026
2027 if (object_wizard->wizard->callbacks.create(details->sorcery, object_wizard->data, details->obj)) {
2028 return 0;
2029 }
2030
2031 return CMP_MATCH;
2032}
unsigned int read_only
Wizard is read_only.
Definition: sorcery.c:114

References ast_debug, ast_sorcery_internal_wizard::callbacks, CMP_MATCH, ast_sorcery_wizard::create, ast_sorcery_object_wizard::data, ast_sorcery_wizard::name, sorcery_details::obj, ast_sorcery_object_wizard::read_only, sorcery_details::sorcery, and ast_sorcery_object_wizard::wizard.

Referenced by ast_sorcery_create().

◆ sorcery_wizard_delete()

static int sorcery_wizard_delete ( const struct ast_sorcery_object_wizard object_wizard,
const struct sorcery_details details 
)
static

Internal function which returns if a wizard has deleted the object.

Definition at line 2219 of file sorcery.c.

2220{
2221 if (!object_wizard->wizard->callbacks.delete || object_wizard->read_only) {
2222 ast_debug(5, "Sorcery wizard '%s' does not support deletion\n", object_wizard->wizard->callbacks.name);
2223 return 0;
2224 }
2225
2226 if (object_wizard->wizard->callbacks.delete(details->sorcery, object_wizard->data, details->obj)) {
2227 return 0;
2228 }
2229
2230 return CMP_MATCH;
2231}
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
Definition: sorcery.h:319

References ast_debug, ast_sorcery_internal_wizard::callbacks, CMP_MATCH, ast_sorcery_object_wizard::data, ast_sorcery_wizard::delete, ast_sorcery_wizard::name, sorcery_details::obj, ast_sorcery_object_wizard::read_only, sorcery_details::sorcery, and ast_sorcery_object_wizard::wizard.

Referenced by ast_sorcery_delete().

◆ sorcery_wizard_load()

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

Definition at line 1253 of file sorcery.c.

1254{
1255 struct ast_sorcery_object_wizard *wizard = obj;
1256 struct sorcery_load_details *details = arg;
1257 void (*load)(void *data, const struct ast_sorcery *sorcery, const char *type);
1258
1259 if (details->reload) {
1260 if (details->force && wizard->wizard->callbacks.force_reload) {
1261 load = wizard->wizard->callbacks.force_reload;
1262 } else {
1263 load = wizard->wizard->callbacks.reload;
1264 }
1265 } else {
1266 load = wizard->wizard->callbacks.load;
1267 }
1268
1269 if (load) {
1270 NOTIFY_WIZARD_OBSERVERS(wizard->wizard->observers, wizard_loading,
1271 wizard->wizard->callbacks.name, &wizard->wizard->callbacks, details->type, details->reload);
1272
1273 load(wizard->data, details->sorcery, details->type);
1274
1275 NOTIFY_WIZARD_OBSERVERS(wizard->wizard->observers, wizard_loaded,
1276 wizard->wizard->callbacks.name, &wizard->wizard->callbacks, details->type, details->reload);
1277 }
1278
1279 return 0;
1280}
#define NOTIFY_WIZARD_OBSERVERS(container, callback,...)
Definition: sorcery.c:82
void(* load)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for loading persistent objects.
Definition: sorcery.h:287
void(* force_reload)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for forcing a reload to occur, even if wizard has determined no changes.
Definition: sorcery.h:328
void(* reload)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for reloading persistent objects.
Definition: sorcery.h:290
unsigned int force
Whether this is forced or not.
Definition: sorcery.c:253

References ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, sorcery_load_details::force, ast_sorcery_wizard::force_reload, ast_sorcery_wizard::load, ast_sorcery_wizard::name, NOTIFY_WIZARD_OBSERVERS, ast_sorcery_internal_wizard::observers, ast_sorcery_wizard::reload, sorcery_load_details::reload, sorcery_load_details::sorcery, sorcery, type, sorcery_load_details::type, and ast_sorcery_object_wizard::wizard.

Referenced by sorcery_object_load().

◆ sorcery_wizard_update()

static int sorcery_wizard_update ( const struct ast_sorcery_object_wizard object_wizard,
const struct sorcery_details details 
)
static

Internal function which returns if a wizard has updated the object.

Definition at line 2131 of file sorcery.c.

2132{
2133 if (!object_wizard->wizard->callbacks.update || object_wizard->read_only) {
2134 ast_debug(5, "Sorcery wizard '%s' does not support updating\n", object_wizard->wizard->callbacks.name);
2135 return 0;
2136 }
2137
2138 if (object_wizard->wizard->callbacks.update(details->sorcery, object_wizard->data, details->obj)) {
2139 return 0;
2140 }
2141
2142 return CMP_MATCH;
2143}
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
Definition: sorcery.h:316

References ast_debug, ast_sorcery_internal_wizard::callbacks, CMP_MATCH, ast_sorcery_object_wizard::data, ast_sorcery_wizard::name, sorcery_details::obj, ast_sorcery_object_wizard::read_only, sorcery_details::sorcery, ast_sorcery_wizard::update, and ast_sorcery_object_wizard::wizard.

Referenced by ast_sorcery_update().

◆ stringfield_handler_fn()

static int stringfield_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 304 of file sorcery.c.

305{
306 ast_string_field *field = (const char **)(obj + args[0]);
307 return !(*buf = ast_strdup(*field)) ? -1 : 0;
308}
const char * ast_string_field
Definition: stringfields.h:190

References args, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

◆ uint_handler_fn()

static int uint_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 292 of file sorcery.c.

293{
294 unsigned int *field = (unsigned int *)(obj + args[0]);
295 return (ast_asprintf(buf, "%u", *field) < 0) ? -1 : 0;
296}

References args, ast_asprintf, and buf.

Referenced by sorcery_field_default_handler().

◆ yesno_handler_fn()

static int yesno_handler_fn ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 316 of file sorcery.c.

317{
318 unsigned int *field = (unsigned int *)(obj + args[0]);
319 return !(*buf = ast_strdup(*field ? "yes" : "no")) ? -1 : 0;
320}

References args, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

Variable Documentation

◆ instances

struct ao2_container* instances
static

Registered sorcery instances.

Definition at line 284 of file sorcery.c.

Referenced by __ast_sorcery_open(), ast_sorcery_init(), ast_sorcery_retrieve_by_module_name(), sorcery_cleanup(), and sorcery_proxy_cb().

◆ observers

struct ao2_container* observers

◆ threadpool

struct ast_threadpool* threadpool
static

◆ wizards

struct ao2_container* wizards
static