Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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/taskpool.h"
#include "asterisk/json.h"
#include "asterisk/vector.h"
#include "asterisk/cli.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)
 
#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)
 
#define TYPE_BUCKETS   53
 Number of buckets for types (should be prime for performance reasons)
 
#define WIZARD_BUCKETS   7
 Number of buckets for wizards (should be prime for performance reasons)
 
#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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
int __ast_sorcery_wizard_register (const struct ast_sorcery_wizard *interface, struct ast_module *module)
 Register a sorcery wizard.
 
void * ast_sorcery_alloc (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Allocate an object.
 
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.
 
void * ast_sorcery_copy (const struct ast_sorcery *sorcery, const void *object)
 Create a copy of an object.
 
int ast_sorcery_create (const struct ast_sorcery *sorcery, void *object)
 Create and potentially persist an object using an available wizard.
 
int ast_sorcery_delete (const struct ast_sorcery *sorcery, void *object)
 Delete an object.
 
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.
 
void ast_sorcery_force_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects, even if no changes determined.
 
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.
 
void * ast_sorcery_generic_alloc (size_t size, ao2_destructor_fn destructor)
 Allocate a generic sorcery capable object.
 
const char * ast_sorcery_get_module (const struct ast_sorcery *sorcery)
 Get the module that has opened the provided sorcery instance.
 
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.
 
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.
 
int ast_sorcery_get_wizard_mapping_count (struct ast_sorcery *sorcery, const char *type)
 Return the number of wizards mapped to an object type.
 
int ast_sorcery_global_observer_add (const struct ast_sorcery_global_observer *callbacks)
 Add a global observer to sorcery.
 
void ast_sorcery_global_observer_remove (const struct ast_sorcery_global_observer *callbacks)
 Remove a global observer from sorcery.
 
int ast_sorcery_init (void)
 Initialize the sorcery API.
 
int ast_sorcery_instance_observer_add (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Add an observer to a sorcery instance.
 
void ast_sorcery_instance_observer_remove (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Remove an observer from a sorcery instance.
 
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.
 
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.
 
void ast_sorcery_load (const struct ast_sorcery *sorcery)
 Inform any wizards to load persistent objects.
 
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.
 
void * ast_sorcery_lockable_alloc (size_t size, ao2_destructor_fn destructor, void *lockobj)
 Allocate a generic sorcery capable object with locking.
 
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.
 
const struct timeval ast_sorcery_object_get_created (const void *object)
 Get when the sorcery object was created.
 
const char * ast_sorcery_object_get_extended (const void *object, const char *name)
 Get an extended field value from a sorcery object.
 
const char * ast_sorcery_object_get_id (const void *object)
 Get the unique identifier of a sorcery object.
 
const char * ast_sorcery_object_get_type (const void *object)
 Get the type of a sorcery object.
 
unsigned int ast_sorcery_object_has_dynamic_contents (const void *object)
 Get whether an object contains dynamic contents or not.
 
int ast_sorcery_object_id_compare (void *obj, void *arg, int flags)
 ao2 object comparator based on sorcery id.
 
int ast_sorcery_object_id_hash (const void *obj, int flags)
 ao2 object hasher based on sorcery id.
 
int ast_sorcery_object_id_sort (const void *obj, const void *arg, int flags)
 ao2 object sorter based on sorcery id.
 
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.
 
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.
 
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.
 
int ast_sorcery_object_set_extended (const void *object, const char *name, const char *value)
 Set an extended field value on a sorcery object.
 
void ast_sorcery_object_set_has_dynamic_contents (const void *object)
 Set the dynamic contents flag on a sorcery object.
 
int ast_sorcery_object_unregister (struct ast_sorcery *sorcery, const char *type)
 Unregister an object type.
 
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.
 
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.
 
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.
 
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.
 
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.
 
void ast_sorcery_ref (struct ast_sorcery *sorcery)
 Increase the reference count of a sorcery structure.
 
void ast_sorcery_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects.
 
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.
 
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.
 
void * ast_sorcery_retrieve_by_id (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Retrieve an object using its unique identifier.
 
struct ast_sorceryast_sorcery_retrieve_by_module_name (const char *module_name)
 Search function for sorcery instances.
 
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.
 
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.
 
int ast_sorcery_update (const struct ast_sorcery *sorcery, void *object)
 Update an object.
 
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.
 
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.
 
int ast_sorcery_wizard_unregister (const struct ast_sorcery_wizard *interface)
 Unregister a sorcery wizard.
 
 AST_VECTOR_RW (ast_sorcery_object_wizards, struct ast_sorcery_object_wizard *)
 Interface for a sorcery object type wizards.
 
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 char * cli_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Hashing and comparison functions for sorcery wizards.
 
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 void parse_general_options (void)
 Compare function for sorcery instances.
 
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.
 
static void sorcery_cleanup (void)
 Cleanup function for graceful shutdowns.
 
static void sorcery_destructor (void *obj)
 Destructor called when sorcery structure is destroyed.
 
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.
 
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.
 
static void sorcery_object_type_destructor (void *obj)
 Destructor function for object types.
 
static void sorcery_object_wizard_destructor (void *obj)
 Object wizard destructor.
 
static struct sorcery_observer_invocationsorcery_observer_invocation_alloc (struct ast_sorcery_object_type *object_type, void *object)
 Allocator function for observer invocation.
 
static void sorcery_observer_invocation_destroy (void *obj)
 Destructor for observer invocation.
 
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.
 
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.
 
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.
 
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.
 
static int sorcery_observer_remove (void *obj, void *arg, int flags)
 Internal callback function for removing an observer.
 
static int sorcery_observers_notify_create (void *data)
 Internal callback function which notifies observers that an object has been created.
 
static int sorcery_observers_notify_delete (void *data)
 Internal callback function which notifies observers that an object has been deleted.
 
static int sorcery_observers_notify_loaded (void *data)
 Internal callback function which notifies observers that an object type has been loaded.
 
static int sorcery_observers_notify_update (void *data)
 Internal callback function which notifies observers that an object has been updated.
 
static void sorcery_proxy_cb (void *weakproxy, void *data)
 Hashing function for sorcery types.
 
static int sorcery_reloadable (const struct ast_sorcery *sorcery, const char *type)
 Retrieves whether or not the type is reloadable.
 
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.
 
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.
 
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.
 
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

int ast_sorcery_update_or_create_on_update_miss = 0
 Global control for optional update->create fallback in backends.
 
static struct ast_cli_entry cli_commands []
 
static struct ao2_containerinstances
 Registered sorcery instances.
 
struct ao2_containerobservers
 Registered global observers.
 
static struct ast_taskpooltaskpool
 Taskpool for observers.
 
static struct ao2_containerwizards
 Registered sorcery wizards.
 

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 58 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 63 of file sorcery.c.

63 { \
65 struct type *observer; \
66 ao2_rdlock(container); \
67 while ((observer = ao2_iterator_next(&i))) { \
68 if (observer->callbacks->callback) { \
69 observer->callbacks->callback(__VA_ARGS__); \
70 } \
71 ao2_cleanup(observer); \
72 } \
73 ao2_unlock(container); \
74 ao2_iterator_cleanup(&i); \
75})
#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.
static const char type[]
struct ao2_container * container
Definition res_fax.c:603
struct ast_sorcery_instance_observer observer
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821

◆ NOTIFY_GLOBAL_OBSERVERS

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

Definition at line 77 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 80 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 83 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 61 of file sorcery.c.

◆ TYPE_BUCKETS

#define TYPE_BUCKETS   53

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

Definition at line 55 of file sorcery.c.

◆ WIZARD_BUCKETS

#define WIZARD_BUCKETS   7

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

Definition at line 52 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 1049 of file sorcery.c.

1050{
1051 struct ast_flags flags = { 0 };
1052 struct ast_config *config = ast_config_load2("sorcery.conf", "sorcery", flags);
1053 struct ast_variable *mapping;
1054 int res = AST_SORCERY_APPLY_SUCCESS;
1055
1056 if (!config) {
1058 }
1059
1062 }
1063
1064 for (mapping = ast_variable_browse(config, name); mapping; mapping = mapping->next) {
1065 RAII_VAR(char *, mapping_name, ast_strdup(mapping->name), ast_free);
1066 RAII_VAR(char *, mapping_value, ast_strdup(mapping->value), ast_free);
1067 char *options = mapping_name;
1068 char *type = strsep(&options, "/");
1069 char *data = mapping_value;
1070 char *wizard = strsep(&data, ",");
1071 unsigned int caching = 0;
1072
1073 /* If no object type or wizard exists just skip, nothing we can do */
1074 if (ast_strlen_zero(type) || ast_strlen_zero(wizard)) {
1075 continue;
1076 }
1077
1078 /* If the wizard is configured as a cache treat it as such */
1079 if (!ast_strlen_zero(options) && strstr(options, "cache")) {
1080 caching = 1;
1081 }
1082
1083 /* Any error immediately causes us to stop */
1084 if (__ast_sorcery_apply_wizard_mapping(sorcery, type, module, wizard, data, caching) == AST_SORCERY_APPLY_FAIL) {
1086 break;
1087 }
1088 }
1089
1091
1092 return res;
1093}
char * strsep(char **str, const char *delims)
#define ast_free(a)
Definition astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
static const char config[]
static const char name[]
Definition format_mp3.c:68
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition extconf.c:1213
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:1041
@ 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:220
unsigned int flags
Definition utils.h:221
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:981

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 1095 of file sorcery.c.

1096{
1098
1099 /* Defaults can not be added if any existing mapping exists */
1100 if (object_type) {
1102 }
1103
1104 return __ast_sorcery_apply_wizard_mapping(sorcery, type, module, name, data, 0);
1105}
#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:149
struct ao2_container * types
Container for known object types.
Definition sorcery.c:233

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 1041 of file sorcery.c.

1044{
1046 data, caching, AST_SORCERY_WIZARD_POSITION_LAST);
1047}
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:1031
@ 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 1031 of file sorcery.c.

1034{
1037 position, NULL, NULL);
1038}
#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:933
@ 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 1256 of file sorcery.c.

1258{
1260 RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1261 int pos;
1262 va_list args;
1263
1264 if (!strcmp(type, "id") || !object_type || !object_type->type.item_alloc) {
1265 return -1;
1266 }
1267
1268 if (!sorcery_handler) {
1269 sorcery_handler = sorcery_field_default_handler(opt_type);
1270 }
1271
1272 if (!(object_field = ao2_alloc(sizeof(*object_field) + argc * sizeof(object_field->args[0]), NULL))) {
1273 return -1;
1274 }
1275
1276 ast_copy_string(object_field->name, name, sizeof(object_field->name));
1277 object_field->handler = sorcery_handler;
1278 object_field->multiple_handler = multiple_handler;
1279
1280 va_start(args, argc);
1281 for (pos = 0; pos < argc; pos++) {
1282 object_field->args[pos] = va_arg(args, size_t);
1283 }
1284 va_end(args);
1285
1286 if (!alias) {
1287 ao2_link(object_type->fields, object_field);
1288 }
1289
1290 /* TODO: Improve this hack */
1291 if (!argc) {
1292 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc);
1293 } else if (argc == 1) {
1294 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1295 object_field->args[0]);
1296 } else if (argc == 2) {
1297 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1298 object_field->args[0], object_field->args[1]);
1299 } else if (argc == 3) {
1300 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1301 object_field->args[0], object_field->args[1], object_field->args[2]);
1302 } else {
1303 ast_assert(0); /* The hack... she does us no good for this */
1304 }
1305
1306 return 0;
1307}
#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 struct @519 args
static sorcery_field_handler sorcery_field_default_handler(enum aco_option_type type)
Definition sorcery.c:345
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:206
#define ast_assert(a)
Definition utils.h:779

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 1144 of file sorcery.c.

1145{
1147
1148 if (!object_type || object_type->type.item_alloc) {
1149 return -1;
1150 }
1151
1152 object_type->type.name = object_type->name;
1153 object_type->type.type = ACO_ITEM;
1154 object_type->type.category = ".?";
1155 object_type->type.item_alloc = alloc;
1156 object_type->type.hidden = hidden;
1157
1158 object_type->reloadable = reloadable;
1159 object_type->transform = transform;
1160 object_type->apply = apply;
1161 object_type->file->types[0] = &object_type->type;
1162 object_type->file->types[1] = NULL;
1163
1164 if (aco_info_init(object_type->info)) {
1165 return -1;
1166 }
1167
1169 return -1;
1170 }
1171
1172 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, object_type_registered,
1174
1175 return 0;
1176}
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:1224
static int sorcery_extended_fields_handler(const void *obj, struct ast_variable **fields)
Definition sorcery.c:1112
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition sorcery.c:80
static int sorcery_extended_config_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition sorcery.c:1107
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition sorcery.c:239
struct ao2_container * observers
Observers.
Definition sorcery.c:236

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 933 of file sorcery.c.

937{
938 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, object_type_name, OBJ_KEY), ao2_cleanup);
939 RAII_VAR(struct ast_sorcery_internal_wizard *, internal_wizard, ao2_find(wizards, wizard_type_name, OBJ_KEY), ao2_cleanup);
940 RAII_VAR(struct ast_sorcery_object_wizard *, object_wizard, NULL, ao2_cleanup);
941 int created = 0;
942
943 object_wizard = ao2_alloc(sizeof(*object_wizard)
944 + (ast_strlen_zero(wizard_args) ? 0 : strlen(wizard_args) + 1),
946
947 if (!object_wizard) {
949 }
950
951 if (!internal_wizard
952 || internal_wizard->callbacks.module != ast_module_running_ref(internal_wizard->callbacks.module)) {
954 "Wizard '%s' could not be applied to object type '%s' as it was not found\n",
955 wizard_type_name, object_type_name);
957 }
958
959 if (!object_type) {
960 if (!(object_type = sorcery_object_type_alloc(object_type_name, module))) {
961 ast_module_unref(internal_wizard->callbacks.module);
963 }
964 created = 1;
965 }
966
967 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
968 if (!created) {
969 struct ast_sorcery_object_wizard *found;
970
971#define WIZARD_COMPARE(a, b) ((a)->wizard == (b))
972 found = AST_VECTOR_GET_CMP(&object_type->wizards, internal_wizard, WIZARD_COMPARE);
973#undef WIZARD_COMPARE
974 if (found
976 ast_debug(1, "Wizard %s already applied to object type %s\n",
977 internal_wizard->callbacks.name, object_type->name);
978 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
979 ast_module_unref(internal_wizard->callbacks.module);
981 }
982 }
983
984 ast_debug(5, "Calling wizard %s open callback on object type %s\n",
985 wizard_type_name, object_type->name);
986 if (internal_wizard->callbacks.open && !(object_wizard->data = internal_wizard->callbacks.open(wizard_args))) {
987 ast_log(LOG_WARNING, "Wizard '%s' failed to open mapping for object type '%s' with data: %s\n",
988 wizard_type_name, object_type->name, S_OR(wizard_args, ""));
989 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
990 ast_module_unref(internal_wizard->callbacks.module);
992 }
993
994 object_wizard->wizard = ao2_bump(internal_wizard);
995 object_wizard->caching = !!(flags & AST_SORCERY_WIZARD_APPLY_CACHING);
996 object_wizard->read_only = !!(flags & AST_SORCERY_WIZARD_APPLY_READONLY);
997 if (wizard_args) {
998 strcpy(object_wizard->wizard_args, wizard_args); /* Safe */
999 }
1000
1001 if (position == AST_SORCERY_WIZARD_POSITION_LAST) {
1002 position = AST_VECTOR_SIZE(&object_type->wizards);
1003 }
1004
1005 if (AST_VECTOR_INSERT_AT(&object_type->wizards, position, object_wizard) != 0) {
1006 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1008 }
1009 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1010 ao2_bump(object_wizard);
1011
1012 if (created) {
1013 ao2_link(sorcery->types, object_type);
1014 }
1015
1017 sorcery->module_name, sorcery, object_type_name, &internal_wizard->callbacks, wizard_args,
1018 object_wizard->data);
1019
1020 if (wizard) {
1021 *wizard = &internal_wizard->callbacks;
1022 }
1023 if (wizard_data) {
1024 *wizard_data = object_wizard->data;
1025 }
1026
1028}
#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:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition module.h:469
#define WIZARD_COMPARE(a, b)
static struct ao2_container * wizards
Registered sorcery wizards.
Definition sorcery.c:258
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:764
static void sorcery_object_wizard_destructor(void *obj)
Object wizard destructor.
Definition sorcery.c:826
@ 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:90
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition sorcery.c:97
Structure for a wizard instance which operates on objects.
Definition sorcery.c:104
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition sorcery.c:106
unsigned int allow_duplicates
Wizard allows others of the same type.
Definition sorcery.c:118
char wizard_args[0]
Wizard arguments.
Definition sorcery.c:121
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:620
#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:349
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition vector.h:898
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition vector.h:908
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition vector.h:742

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 884 of file sorcery.c.

887{
888 RAII_VAR(struct ast_sorcery_object_type *, object_type,
889 ao2_find(sorcery->types, object_type_name, OBJ_SEARCH_KEY), ao2_cleanup);
890 int res = -1;
891 int i;
892
893 if (!object_type) {
894 return res;
895 }
896
897 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
898 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
899 struct ast_sorcery_object_wizard *wizard = AST_VECTOR_GET(&object_type->wizards, i);
900
901 if (strcmp(wizard->wizard->callbacks.name, wizard_type_name) == 0
902 && strcmp(S_OR(wizard->wizard_args, ""), S_OR(wizard_args, "")) == 0) {
903 ao2_cleanup(AST_VECTOR_REMOVE_ORDERED(&object_type->wizards, i));
904 res = 0;
905 break;
906 }
907 }
908 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
909
910 return res;
911}
@ 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:459
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:691

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 665 of file sorcery.c.

666{
667 struct sorcery_proxy *proxy;
668 struct ast_sorcery *sorcery;
669
671
674 __PRETTY_FUNCTION__, file, line, func);
675 if (sorcery) {
677
678 return sorcery;
679 }
680
681 proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + strlen(module_name) + 1, NULL, module_name);
682 if (!proxy) {
683 goto failure_cleanup;
684 }
685 strcpy(proxy->module_name, module_name); /* Safe */
686
688 if (!sorcery) {
689 goto failure_cleanup;
690 }
691
693
694 /* We have exclusive access to proxy and sorcery, no need for locking here. */
695 if (ao2_t_weakproxy_set_object(proxy, sorcery, OBJ_NOLOCK, "weakproxy link")) {
696 goto failure_cleanup;
697 }
698
700 goto failure_cleanup;
701 }
702
704 ast_sorcery_object_type_hash_fn, NULL, ast_sorcery_object_type_cmp_fn);
705 if (!sorcery->types) {
706 goto failure_cleanup;
707 }
708
710 goto failure_cleanup;
711 }
712
714 ast_log(LOG_ERROR, "Error attempting to apply configuration %s to sorcery.\n", module_name);
715 goto failure_cleanup;
716 }
717
719 ao2_ref(proxy, -1);
720
722
724 return sorcery;
725
726failure_cleanup:
727 /* cleanup of sorcery may result in locking instances, so make sure we unlock first. */
730 ao2_cleanup(proxy);
731
732 return NULL;
733}
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:77
static void sorcery_destructor(void *obj)
Destructor called when sorcery structure is destroyed.
Definition sorcery.c:645
static void sorcery_proxy_cb(void *weakproxy, void *data)
Hashing function for sorcery types.
Definition sorcery.c:660
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:1049
static struct ao2_container * instances
Registered sorcery instances.
Definition sorcery.c:285
struct ao2_container * observers
Registered global observers.
Definition sorcery.c:282
#define TYPE_BUCKETS
Number of buckets for types (should be prime for performance reasons)
Definition sorcery.c:55
Full structure for sorcery.
Definition sorcery.c:231
Proxy object for sorcery.
Definition sorcery.c:224
char module_name[0]
The name of the module owning this sorcery instance.
Definition sorcery.c:227

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, 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 914 of file sorcery.c.

916{
918 int res;
919
920 if (!object_type) {
921 return -1;
922 }
923
924 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
925#define WIZARD_NAME_COMPARE(a, b) (strcmp((a)->wizard->callbacks.name, (b)) == 0)
927#undef WIZARD_NAME_COMPARE
928 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
929
930 return res;
931}
#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:551

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 496 of file sorcery.c.

497{
498 struct ast_sorcery_internal_wizard *wizard;
499 int res = -1;
500
501 ast_assert(!ast_strlen_zero(interface->name));
502
504
505 if ((wizard = ao2_find(wizards, interface->name, OBJ_KEY | OBJ_NOLOCK))) {
506 ast_log(LOG_WARNING, "Attempted to register sorcery wizard '%s' twice\n",
507 interface->name);
508 goto done;
509 }
510
511 if (!(wizard = ao2_alloc(sizeof(*wizard), sorcery_internal_wizard_destructor))) {
512 goto done;
513 }
514
515 wizard->callbacks = *interface;
516 wizard->callbacks.module = module;
517
519 if (!wizard->observers) {
520 goto done;
521 }
522
524 res = 0;
525
526 ast_verb(5, "Sorcery registered wizard '%s'\n", interface->name);
527
528 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_registered,
529 interface->name, interface);
530
531done:
532 ao2_cleanup(wizard);
534
535 return res;
536}
#define ao2_lock(a)
Definition astobj2.h:717
#define ast_verb(level,...)
static void sorcery_internal_wizard_destructor(void *obj)
Definition sorcery.c:489
struct ao2_container * observers
Observers.
Definition sorcery.c:100
int done

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::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 1808 of file sorcery.c.

1809{
1811 struct ast_sorcery_object_details *details;
1812
1813 if (!object_type || !object_type->type.item_alloc ||
1814 !(details = object_type->type.item_alloc(id))) {
1815 return NULL;
1816 }
1817
1818 if (ast_strlen_zero(id)) {
1819 char uuid[AST_UUID_STR_LEN];
1820
1822 details->object->id = ast_strdup(uuid);
1823 } else {
1824 details->object->id = ast_strdup(id);
1825 }
1826 if (!details->object->id) {
1827 ao2_ref(details, -1);
1828 return NULL;
1829 }
1830
1831 details->object->created = ast_tvnow();
1832 ast_copy_string(details->object->type, type, sizeof(details->object->type));
1833
1834 if (aco_set_defaults(&object_type->type, id, details)) {
1835 ao2_ref(details, -1);
1836 return NULL;
1837 }
1838
1839 return details;
1840}
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
static int uuid(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition func_uuid.c:52
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:142
char type[MAX_OBJECT_TYPE]
Type of object.
Definition sorcery.c:133
char * id
Unique identifier of this object.
Definition sorcery.c:130
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, ast_sorcery::types, and uuid().

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), create_artificial_endpoint(), create_effective_profile(), create_object(), default_profile_create(), global_loaded_observer(), load_module(), 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 1727 of file sorcery.c.

1728{
1729 const struct ast_variable *field;
1730 int res = 0;
1731
1732 *changes = NULL;
1733
1734 /* Unless the ast_variable list changes when examined... it can't differ from itself */
1735 if (original == modified) {
1736 return 0;
1737 }
1738
1739 for (field = modified; field; field = field->next) {
1740 const char *old_value = ast_variable_find_in_list(original, field->name);
1741
1742 if (!old_value || strcmp(old_value, field->value)) {
1743 struct ast_variable *tmp;
1744
1745 if (!(tmp = ast_variable_new(field->name, field->value, ""))) {
1746 res = -1;
1747 break;
1748 }
1749
1750 tmp->next = *changes;
1751 *changes = tmp;
1752 }
1753 }
1754
1755 /* If an error occurred do not return a partial changeset */
1756 if (res) {
1757 ast_variables_destroy(*changes);
1758 *changes = NULL;
1759 }
1760
1761 return res;
1762}
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.
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260

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

Referenced by ast_sorcery_diff(), AST_TEST_DEFINE(), 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 1842 of file sorcery.c.

1843{
1844 const struct ast_sorcery_object_details *details = object;
1845 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1847 RAII_VAR(struct ast_variable *, objectset, NULL, ast_variables_destroy);
1848 int res = 0;
1849
1850 if (!copy) {
1851 return NULL;
1852 } else if (object_type->copy) {
1853 res = object_type->copy(object, copy);
1854 } else if ((objectset = ast_sorcery_objectset_create(sorcery, object))) {
1855 res = ast_sorcery_objectset_apply(sorcery, copy, objectset);
1856 } else {
1857 /* No native copy available and could not create an objectset, this copy has failed */
1858 res = -1;
1859 }
1860
1861 if (res) {
1863 copy = NULL;
1864 }
1865
1866 return copy;
1867}
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:1808
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:1696
#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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and register_aor_core().

◆ 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 2126 of file sorcery.c.

2127{
2128 const struct ast_sorcery_object_details *details = object;
2129 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2130 struct ast_sorcery_object_wizard *object_wizard = NULL;
2131 struct ast_sorcery_object_wizard *found_wizard;
2132 int i;
2133 struct sorcery_details sdetails = {
2134 .sorcery = sorcery,
2135 .obj = object,
2136 };
2137
2138 if (!object_type) {
2139 return -1;
2140 }
2141
2142 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2143 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2144 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2145 if (!found_wizard->caching
2146 && sorcery_wizard_create(found_wizard, &sdetails) == CMP_MATCH) {
2147 object_wizard = found_wizard;
2148 }
2149 }
2150
2151 if (object_wizard) {
2152 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2153 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2154 if (found_wizard->caching) {
2155 sorcery_wizard_create(found_wizard, &sdetails);
2156 }
2157 }
2158
2159 if (ao2_container_count(object_type->observers)) {
2160 struct sorcery_observer_invocation *invocation;
2161
2162 invocation = sorcery_observer_invocation_alloc(object_type, object);
2163 if (invocation
2165 invocation)) {
2166 ao2_cleanup(invocation);
2167 }
2168 }
2169 }
2170
2172
2173 return object_wizard ? 0 : -1;
2174}
@ 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:2116
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:2089
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:1356
struct ast_sorcery_object_wizards wizards
Wizard instances.
Definition sorcery.c:166
struct ast_taskprocessor * serializer
Serializer for observers.
Definition sorcery.c:184
unsigned int caching
Wizard is acting as an object cache.
Definition sorcery.c:112
Structure used when calling create, update, or delete.
Definition sorcery.c:1895
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition sorcery.c:1897
Structure used for observer invocations.
Definition sorcery.c:197
struct ast_sorcery_object_type * object_type
Pointer to the object type.
Definition sorcery.c:199
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:888

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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 2302 of file sorcery.c.

2303{
2304 const struct ast_sorcery_object_details *details = object;
2305 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2306 struct ast_sorcery_object_wizard *object_wizard = NULL;
2307 struct ast_sorcery_object_wizard *found_wizard;
2308 int i;
2309 struct sorcery_details sdetails = {
2310 .sorcery = sorcery,
2311 .obj = object,
2312 };
2313
2314 if (!object_type) {
2315 return -1;
2316 }
2317
2318 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2319 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2320 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2321 if (!found_wizard->caching
2322 && sorcery_wizard_delete(found_wizard, &sdetails) == CMP_MATCH) {
2323 object_wizard = found_wizard;
2324 }
2325 }
2326
2327 if (object_wizard) {
2328 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2329 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2330 if (found_wizard->caching) {
2331 sorcery_wizard_delete(found_wizard, &sdetails);
2332 }
2333 }
2334
2335 if (ao2_container_count(object_type->observers)) {
2336 struct sorcery_observer_invocation *invocation;
2337
2338 invocation = sorcery_observer_invocation_alloc(object_type, object);
2339 if (invocation
2341 invocation)) {
2342 ao2_cleanup(invocation);
2343 }
2344 }
2345 }
2346
2348
2349 return object_wizard ? 0 : -1;
2350}
static int sorcery_observers_notify_delete(void *data)
Internal callback function which notifies observers that an object has been deleted.
Definition sorcery.c:2277
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:2288

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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 1869 of file sorcery.c.

1870{
1872
1873 *changes = NULL;
1874
1875 if (strcmp(ast_sorcery_object_get_type(original), ast_sorcery_object_get_type(modified))) {
1876 return -1;
1877 }
1878
1879 if (original == modified) {
1880 return 0;
1881 } else if (!object_type->diff) {
1882 RAII_VAR(struct ast_variable *, objectset1, NULL, ast_variables_destroy);
1883 RAII_VAR(struct ast_variable *, objectset2, NULL, ast_variables_destroy);
1884
1885 objectset1 = ast_sorcery_objectset_create(sorcery, original);
1886 objectset2 = ast_sorcery_objectset_create(sorcery, modified);
1887
1888 return ast_sorcery_changeset_create(objectset1, objectset2, changes);
1889 } else {
1890 return object_type->diff(original, modified, changes);
1891 }
1892}
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition sorcery.c:2393
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:1727

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 ari_conf_owc_detect_changes(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_get_field_diff(), 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 1489 of file sorcery.c.

1490{
1491 struct sorcery_load_details details = {
1492 .sorcery = sorcery,
1493 .reload = 1,
1494 .force = 1,
1495 };
1496
1497 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1499
1501
1504}
#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:1400
Structure for passing load/reload details.
Definition sorcery.c:243
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition sorcery.c:245

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 1521 of file sorcery.c.

1522{
1524 struct sorcery_load_details details = {
1525 .sorcery = sorcery,
1526 .reload = 1,
1527 .force = 1,
1528 };
1529
1530 if (!object_type) {
1531 return;
1532 }
1533
1534 sorcery_object_load(object_type, &details, 0);
1535}

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(), acl_change_stasis_cb(), as_config_reload(), global_loaded(), profile_reload(), tn_config_reload(), vs_config_reload(), and ws_client_load().

◆ 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 1792 of file sorcery.c.

1793{
1794 void *object = ao2_alloc_options(size + sizeof(struct ast_sorcery_object),
1796 struct ast_sorcery_object_details *details = object;
1797
1798 if (!object) {
1799 return NULL;
1800 }
1801
1802 details->object = object + size;
1803 details->object->destructor = destructor;
1804
1805 return object;
1806}
@ 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:1764
Structure for internal sorcery object information.
Definition sorcery.c:128
ao2_destructor_fn destructor
Optional object destructor.
Definition sorcery.c:136

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(), general_alloc(), geoloc_location_alloc(), geoloc_profile_alloc(), global_alloc(), ip_identify_alloc(), mapping_alloc(), mwi_sorcery_object_alloc(), outbound_websocket_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(), test_sorcery_object_alloc(), test_sorcery_object_alloc(), tn_alloc(), user_alloc(), verification_alloc(), and wc_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 2600 of file sorcery.c.

2601{
2602 return sorcery->module_name;
2603}

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 2558 of file sorcery.c.

2560{
2562}

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(), load_module(), 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 854 of file sorcery.c.

856{
858 struct ast_sorcery_object_wizard *owizard;
859
860 if (!object_type) {
861 return -1;
862 }
863
864 if (index < 0 || index >= AST_VECTOR_SIZE(&object_type->wizards)) {
865 return -1;
866 }
867
868 owizard = AST_VECTOR_GET(&object_type->wizards, index);
869
870 if (wizard != NULL) {
871 *wizard = &(owizard->wizard->callbacks);
872 ao2_bump(owizard->wizard);
873 } else {
874 return -1;
875 }
876
877 if (data != NULL) {
878 *data = owizard->data;
879 }
880
881 return 0;
882}
void * data
Unique data for the wizard.
Definition sorcery.c:109

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 842 of file sorcery.c.

844{
846
847 if (!object_type) {
848 return -1;
849 }
850
851 return AST_VECTOR_SIZE(&object_type->wizards);
852}

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

Referenced by AST_TEST_DEFINE(), and 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 562 of file sorcery.c.

563{
564 struct sorcery_global_observer *cb;
565
566 cb = ao2_alloc(sizeof(*cb), NULL);
567 if (!cb) {
568 return -1;
569 }
570
571 cb->callbacks = callbacks;
572 ao2_link(observers, cb);
573 ao2_ref(cb, -1);
574
575 return 0;
576}
struct @506 callbacks
A global observer wrapper.
Definition sorcery.c:267
const struct ast_sorcery_global_observer * callbacks
Definition sorcery.c:268

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 578 of file sorcery.c.

580{
582}
@ 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:555

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  )

Initialize the sorcery API.

Return values
0success
-1failure

Definition at line 444 of file sorcery.c.

445{
448 .auto_increment = 1,
449 .max_size = 0,
450 .idle_timeout = 60,
451 .initial_size = 1,
452 .minimum_size = 1,
453 };
455
457
458 taskpool = ast_taskpool_create("sorcery", &options);
459 if (!taskpool) {
460 return -1;
461 }
462
464 ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn);
465 if (!wizards) {
466 return -1;
467 }
468
470 if (!observers) {
471 return -1;
472 }
473
475 sorcery_proxy_hash_fn, NULL, sorcery_proxy_cmp_fn);
476 if (!instances) {
477 return -1;
478 }
479
481 return -1;
482 }
483
485
486 return 0;
487}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition clicompat.c:19
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
#define INSTANCE_BUCKETS
Number of buckets for instances (should be prime for performance reasons)
Definition sorcery.c:58
static void parse_general_options(void)
Compare function for sorcery instances.
Definition sorcery.c:425
static struct ast_cli_entry cli_commands[]
Definition sorcery.c:397
#define WIZARD_BUCKETS
Number of buckets for wizards (should be prime for performance reasons)
Definition sorcery.c:52
static struct ast_taskpool * taskpool
Taskpool for observers.
Definition sorcery.c:87
static void sorcery_cleanup(void)
Cleanup function for graceful shutdowns.
Definition sorcery.c:402
#define AST_TASKPOOL_OPTIONS_VERSION
Definition taskpool.h:69
struct ast_taskpool * ast_taskpool_create(const char *name, const struct ast_taskpool_options *options)
Create a new taskpool.
Definition taskpool.c:324
#define ARRAY_LEN(a)
Definition utils.h:706

References AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_hash, ao2_container_alloc_list, ARRAY_LEN, ast_assert, ast_cli_register_multiple, ast_register_cleanup(), ast_taskpool_create(), AST_TASKPOOL_OPTIONS_VERSION, cli_commands, INSTANCE_BUCKETS, instances, NULL, observers, options, parse_general_options(), sorcery_cleanup(), taskpool, 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 584 of file sorcery.c.

586{
587 struct sorcery_instance_observer *cb;
588
589 cb = ao2_alloc(sizeof(*cb), NULL);
590 if (!cb) {
591 return -1;
592 }
593
594 cb->callbacks = callbacks;
596 ao2_ref(cb, -1);
597
598 return 0;
599}
An instance observer wrapper.
Definition sorcery.c:272
const struct ast_sorcery_instance_observer * callbacks
Definition sorcery.c:273

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(), 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 601 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 2578 of file sorcery.c.

2580{
2581 struct ast_sorcery_object_field *object_field;
2582 int res = 1;
2583
2584 ast_assert(object_type != NULL);
2585
2586 object_field = ao2_find(object_type->fields, field_name, OBJ_SEARCH_KEY);
2587
2588 if (!object_field) {
2589 object_field = ao2_callback(object_type->fields, 0, is_registered_cb, (char *)field_name);
2590 }
2591
2592 if (!object_field) {
2593 res = 0;
2594 }
2595
2596 ao2_cleanup(object_field);
2597 return res;
2598}
static int is_registered_cb(void *obj, void *arg, int flags)
Definition sorcery.c:2564
struct ao2_container * fields
Object fields.
Definition sorcery.c:169

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 2352 of file sorcery.c.

2353{
2354 const struct ast_sorcery_object_details *details = object;
2355 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2356 struct ast_sorcery_object_wizard *found_wizard;
2357 int res = 0;
2358 int i;
2359
2360 if (!object_type) {
2361 return -1;
2362 }
2363
2364 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2365 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2366 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2367
2368 if (found_wizard->wizard->callbacks.is_stale) {
2369 res |= found_wizard->wizard->callbacks.is_stale(sorcery, found_wizard->data, object);
2370 ast_debug(5, "After calling wizard '%s', object '%s' is %s\n",
2371 found_wizard->wizard->callbacks.name,
2373 res ? "stale" : "not stale");
2374 }
2375 }
2376 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2377
2378 return res;
2379}
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
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)

◆ 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 1457 of file sorcery.c.

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

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

Referenced by ari_conf_load(), as_config_load(), ast_sip_initialize_sorcery_global(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), load_module(), load_module(), load_module(), 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 1776 of file sorcery.c.

1777{
1778 void *object = ao2_alloc_with_lockobj(size + sizeof(struct ast_sorcery_object),
1779 sorcery_object_destructor, lockobj, "");
1780 struct ast_sorcery_object_details *details = object;
1781
1782 if (!object) {
1783 return NULL;
1784 }
1785
1786 details->object = object + size;
1787 details->object->destructor = destructor;
1788
1789 return object;
1790}
#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 1224 of file sorcery.c.

1225{
1226#define MAX_REGEX_ERROR_LEN 128
1228 RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1229 int rc;
1230
1231 if (!object_type || !object_type->type.item_alloc || !config_handler
1232 || !(object_field = ao2_alloc(sizeof(*object_field), sorcery_object_field_destructor))) {
1233 return -1;
1234 }
1235
1236 ast_copy_string(object_field->name, regex, sizeof(object_field->name));
1237 object_field->multiple_handler = sorcery_handler;
1238
1239 if (!(object_field->name_regex = ast_calloc(1, sizeof(regex_t)))) {
1240 return -1;
1241 }
1242
1243 if ((rc = regcomp(object_field->name_regex, regex, REG_EXTENDED | REG_NOSUB))) {
1244 char *regerr = ast_alloca(MAX_REGEX_ERROR_LEN);
1245 regerror(rc, object_field->name_regex, regerr, MAX_REGEX_ERROR_LEN);
1246 ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n", regex, regerr);
1247 return -1;
1248 }
1249
1250 ao2_link(object_type->fields, object_field);
1251 __aco_option_register(object_type->info, regex, ACO_REGEX, object_type->file->types, "", OPT_CUSTOM_T, config_handler, 0, 1, 0);
1252
1253 return 0;
1254}
#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:1214

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), load_module(), 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 2387 of file sorcery.c.

2388{
2389 const struct ast_sorcery_object_details *details = object;
2390 return details->object->created;
2391}

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 2399 of file sorcery.c.

2400{
2401 const struct ast_sorcery_object_details *details = object;
2402 struct ast_variable *field;
2403
2404 for (field = details->object->extended; field; field = field->next) {
2405 if (!strcmp(field->name + 1, name)) {
2406 return field->value;
2407 }
2408 }
2409
2410 return NULL;
2411}
struct ast_variable * extended
Extended object fields.
Definition sorcery.c:139

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 2381 of file sorcery.c.

2382{
2383 const struct ast_sorcery_object_details *details = object;
2384 return details->object->id;
2385}

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(), ari_conf_get_owc_for_app(), ari_conf_owc_detect_changes(), ari_show_owc(), ari_show_user(), ast_ari_create_per_call_websocket(), 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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_connect(), ast_websocket_client_get_field_diff(), 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(), challenge(), chan_pjsip_indicate(), chan_pjsip_new(), change_outgoing_sdp_stream_media_address(), change_outgoing_sdp_stream_media_address(), check_algorithm(), 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_print_body(), cli_print_body(), cli_print_body(), cli_show_subscriptions_detail(), client_config_apply(), codec_prefs_handler(), common_identify(), complete_sorcery_object(), 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(), digest_lookup(), 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_authorization(), 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_creds_for_header(), get_curl_instance(), get_resource_display_name(), handle_export_primitives(), handle_incoming_request(), 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(), 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(), outbound_session_apply_config(), outbound_session_create(), outbound_websocket_apply(), outbound_websocket_dtor(), outbound_websocket_validate_cb(), outbound_websocket_websocket_client_id_from_str(), password_digest_handler(), 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_method_handler(), refer_client_on_evsub_state(), refer_incoming_ari_request(), refer_incoming_attended_request(), refer_incoming_blind_request(), refer_incoming_invite_request(), refer_incoming_refer_request(), refer_progress_alloc(), refer_send(), register_aor_core(), registrar_contact_delete(), registrar_on_rx_request(), registration_deleted_observer(), registration_state_cmp(), registration_state_hash(), remove_from_cache(), remove_subscription(), request_identify_match_check(), 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(), show_owc_cb(), show_users_cb(), 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(), tn_get_etn(), tos_handler(), transport_apply(), transport_tls_file_handler(), transport_tos_handler(), uac_algorithms_handler(), uas_algorithms_handler(), unload_engine(), update_devstate(), user_apply(), user_dtor(), users_apply_handler(), validate_publish_config(), verification_apply(), verify(), wc_apply(), and wc_dtor().

◆ 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 2393 of file sorcery.c.

2394{
2395 const struct ast_sorcery_object_details *details = object;
2396 return details->object->type;
2397}

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 2441 of file sorcery.c.

2442{
2443 const struct ast_sorcery_object_details *details = object;
2444
2445 return details->object->has_dynamic_contents;
2446}
unsigned int has_dynamic_contents
Whether this object has dynamic contents or not.
Definition sorcery.c:145

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 2528 of file sorcery.c.

2529{
2530 int cmp;
2531
2532 cmp = ast_sorcery_object_id_sort(obj, arg, flags);
2533 if (cmp) {
2534 return 0;
2535 }
2536 return CMP_MATCH;
2537}
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition sorcery.c:2504

References ast_sorcery_object_id_sort(), and CMP_MATCH.

Referenced by ast_media_cache_init(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_prefix(), ast_sorcery_retrieve_by_regex(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), handle_registrations(), register_aor_core(), 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 2539 of file sorcery.c.

2540{
2541 const char *key;
2542
2543 switch (flags & OBJ_SEARCH_MASK) {
2544 case OBJ_SEARCH_KEY:
2545 key = obj;
2546 break;
2547 case OBJ_SEARCH_OBJECT:
2548 key = ast_sorcery_object_get_id(obj);
2549 break;
2550 default:
2551 /* Hash can only work on something with a full key. */
2552 ast_assert(0);
2553 return 0;
2554 }
2555 return ast_str_hash(key);
2556}
@ 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 2504 of file sorcery.c.

2505{
2506 const void *object_left = obj;
2507 const void *object_right = arg;
2508 const char *right_key = arg;
2509 int cmp;
2510
2511 switch (flags & OBJ_SEARCH_MASK) {
2512 case OBJ_SEARCH_OBJECT:
2513 right_key = ast_sorcery_object_get_id(object_right);
2514 /* Fall through */
2515 case OBJ_SEARCH_KEY:
2516 cmp = strcmp(ast_sorcery_object_get_id(object_left), right_key);
2517 break;
2519 cmp = strncmp(ast_sorcery_object_get_id(object_left), right_key, strlen(right_key));
2520 break;
2521 default:
2522 cmp = 0;
2523 break;
2524 }
2525 return cmp;
2526}
@ 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(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_prefix(), ast_sorcery_retrieve_by_regex(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_get_container(), cli_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 1178 of file sorcery.c.

1179{
1180 struct ast_sorcery_object_type *object_type;
1181 int res = -1;
1182
1183 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1184 if (object_type) {
1186 low_water, high_water);
1187 ao2_ref(object_type, -1);
1188 }
1189 return res;
1190}
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 1192 of file sorcery.c.

1193{
1195
1196 if (!object_type) {
1197 return;
1198 }
1199
1200 object_type->copy = copy;
1201}

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 1203 of file sorcery.c.

1204{
1206
1207 if (!object_type) {
1208 return;
1209 }
1210
1211 object_type->diff = diff;
1212}

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 2413 of file sorcery.c.

2414{
2416 struct ast_variable *extended = ast_variable_new(name, value, ""), *previous = NULL;
2417 const struct ast_sorcery_object_details *details = object;
2418
2419 if (!extended) {
2420 return -1;
2421 }
2422
2423 for (field = details->object->extended; field; previous = field, field = field->next) {
2424 if (!strcmp(field->name, name)) {
2425 if (previous) {
2426 previous->next = field->next;
2427 } else {
2428 details->object->extended = field->next;
2429 }
2430 field->next = NULL;
2431 break;
2432 }
2433 }
2434
2435 extended->next = details->object->extended;
2436 details->object->extended = extended;
2437
2438 return 0;
2439}
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 2448 of file sorcery.c.

2449{
2450 const struct ast_sorcery_object_details *details = object;
2451
2452 details->object->has_dynamic_contents = 1;
2453}

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 1125 of file sorcery.c.

1126{
1127 struct ast_sorcery_object_type *object_type;
1128 int res = -1;
1129
1131 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1132 if (object_type && object_type->type.type == ACO_ITEM) {
1133 ao2_unlink_flags(sorcery->types, object_type, OBJ_NOLOCK);
1134 res = 0;
1135 }
1137
1138 /* XXX may need to add an instance unregister observer callback on success. */
1139
1140 ao2_cleanup(object_type);
1141 return res;
1142}
#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:178

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(), unload_module(), unload_module(), 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 1696 of file sorcery.c.

1697{
1698 const struct ast_sorcery_object_details *details = object;
1699 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1700 RAII_VAR(struct ast_variable *, transformed, NULL, ast_variables_destroy);
1701 struct ast_variable *field;
1702 int res = 0;
1703
1704 if (!object_type) {
1705 return -1;
1706 }
1707
1708 if (object_type->transform && (transformed = object_type->transform(objectset))) {
1709 field = transformed;
1710 } else {
1711 field = objectset;
1712 }
1713
1714 for (; field; field = field->next) {
1715 if ((res = aco_process_var(&object_type->type, details->object->id, field, object))) {
1716 break;
1717 }
1718 }
1719
1720 if (!res && object_type->apply) {
1721 res = object_type->apply(sorcery, object);
1722 }
1723
1724 return res;
1725}
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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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 1575 of file sorcery.c.

1577{
1578 const struct ast_sorcery_object_details *details = object;
1579 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1580 struct ao2_iterator i;
1581 struct ast_sorcery_object_field *object_field;
1582 struct ast_variable *head = NULL;
1583 struct ast_variable *tail = NULL;
1584
1585 if (!object_type) {
1586 return NULL;
1587 }
1588
1589 i = ao2_iterator_init(object_type->fields, 0);
1590
1591 for (; (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1592 struct ast_variable *tmp;
1593
1594 switch (flags) {
1596 if ((tmp = get_multiple_fields_as_var_list(object, object_field)) ||
1597 (tmp = get_single_field_as_var_list(object, object_field))) {
1598 break;
1599 }
1600 continue;
1602 if ((tmp = get_single_field_as_var_list(object, object_field)) ||
1603 (tmp = get_multiple_fields_as_var_list(object, object_field))) {
1604 break;
1605 }
1606 continue;
1608 if ((tmp = get_multiple_fields_as_var_list(object, object_field))) {
1609 break;
1610 }
1611 continue;
1613 if ((tmp = get_single_field_as_var_list(object, object_field))) {
1614 break;
1615 }
1616 continue;
1617 default:
1618 continue;
1619 }
1620
1621 tail = ast_variable_list_append_hint(&head, tail, tmp);
1622 }
1623
1625
1626 return head;
1627}
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.
static struct ast_variable * get_single_field_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition sorcery.c:1542
static struct ast_variable * get_multiple_fields_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition sorcery.c:1559
@ 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

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, 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 1629 of file sorcery.c.

1630{
1631 const struct ast_sorcery_object_details *details = object;
1632 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1633 struct ao2_iterator i;
1634 struct ast_sorcery_object_field *object_field;
1635 struct ast_json *json = ast_json_object_create();
1636 int res = 0;
1637
1638 if (!object_type || !json) {
1639 ast_json_unref(json);
1640 return NULL;
1641 }
1642
1643 i = ao2_iterator_init(object_type->fields, 0);
1644
1645 for (; !res && (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1646 if (object_field->multiple_handler) {
1647 struct ast_variable *tmp = NULL;
1648 struct ast_variable *field;
1649
1650 if ((res = object_field->multiple_handler(object, &tmp))) {
1652 ao2_ref(object_field, -1);
1653 break;
1654 }
1655
1656 for (field = tmp; field; field = field->next) {
1657 struct ast_json *value = ast_json_string_create(field->value);
1658
1659 if (!value || ast_json_object_set(json, field->name, value)) {
1660 res = -1;
1661 break;
1662 }
1663 }
1664
1666 } else if (object_field->handler) {
1667 char *buf = NULL;
1668 struct ast_json *value = NULL;
1669
1670 if (object_field->handler(object, object_field->args, &buf)
1672 || ast_json_object_set(json, object_field->name, value)) {
1673 ast_free(buf);
1674 ast_debug(5, "Skipping field '%s' for object type '%s'\n",
1675 object_field->name, object_type->name);
1676 continue;
1677 }
1678
1679 ast_free(buf);
1680 } else {
1681 continue;
1682 }
1683 }
1684
1686
1687 /* If any error occurs we destroy the JSON object so a partial objectset is not returned */
1688 if (res) {
1689 ast_json_unref(json);
1690 json = NULL;
1691 }
1692
1693 return json;
1694}
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, 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 2455 of file sorcery.c.

2456{
2459 int res;
2460
2461 if (!object_type || !callbacks) {
2462 return -1;
2463 }
2464
2465 if (!(observer = ao2_alloc(sizeof(*observer), NULL))) {
2466 return -1;
2467 }
2468
2469 observer->callbacks = callbacks;
2470 res = 0;
2471 if (!ao2_link(object_type->observers, observer)) {
2472 res = -1;
2473 }
2474 ao2_ref(observer, -1);
2475
2476 return res;
2477}
Structure for registered object type observer.
Definition sorcery.c:191

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 ari_conf_init(), ari_sorcery_observer_add(), ast_bucket_file_observer_add(), ast_bucket_observer_add(), ast_res_pjsip_initialize_configuration(), ast_sip_initialize_distributor(), ast_sip_initialize_sorcery_auth(), ast_sip_initialize_sorcery_location(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), ast_websocket_client_observer_add(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), 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 2487 of file sorcery.c.

2488{
2489 RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
2490 struct ast_sorcery_observer *cbs = (struct ast_sorcery_observer *) callbacks;/* Remove const for traversal. */
2491
2492 if (!sorcery) {
2493 return;
2494 }
2495 object_type = ao2_find(sorcery->types, type, OBJ_KEY);
2496 if (!object_type) {
2497 return;
2498 }
2499
2500 ao2_callback(object_type->observers, OBJ_NODATA | OBJ_UNLINK,
2502}
static int sorcery_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing an observer.
Definition sorcery.c:2480
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 ari_sorcery_observer_remove(), ast_bucket_file_observer_remove(), ast_bucket_observer_remove(), ast_res_pjsip_cleanup_options_handling(), ast_sip_destroy_distributor(), ast_sip_destroy_sorcery_auth(), ast_sip_destroy_sorcery_location(), ast_sip_destroy_transport_management(), ast_websocket_client_observer_remove(), load_module(), pjsip_outbound_registration_metrics_init(), pjsip_outbound_registration_metrics_unload_cb(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), 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 1537 of file sorcery.c.

1538{
1539 ao2_ref(sorcery, +1);
1540}

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 1472 of file sorcery.c.

1473{
1474 struct sorcery_load_details details = {
1475 .sorcery = sorcery,
1476 .reload = 1,
1477 };
1478
1479 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1481
1483
1486
1487}

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(), AST_TEST_DEFINE(), ast_websocket_client_reload(), geoloc_config_reload(), load_module(), reload_module(), reload_module(), reload_module(), 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 1506 of file sorcery.c.

1507{
1509 struct sorcery_load_details details = {
1510 .sorcery = sorcery,
1511 .reload = 1,
1512 };
1513
1514 if (!object_type) {
1515 return;
1516 }
1517
1518 sorcery_object_load(object_type, &details, 0);
1519}

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(), ari_conf_load(), ast_sip_initialize_distributor(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_users(), reload_module(), reload_module(), reload_module(), 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 1961 of file sorcery.c.

1962{
1964 void *object = NULL;
1965 int i;
1966 unsigned int cached = 0;
1967
1968 if (!object_type) {
1969 return NULL;
1970 }
1971
1972 /* If returning multiple objects create a container to store them in */
1973 if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1975 if (!object) {
1976 return NULL;
1977 }
1978 }
1979
1980 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1981 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1983 AST_VECTOR_GET(&object_type->wizards, i);
1984
1985 if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1986 if (wizard->wizard->callbacks.retrieve_multiple) {
1987 wizard->wizard->callbacks.retrieve_multiple(sorcery, wizard->data, object_type->name, object, fields);
1988 }
1989 } else if (fields && wizard->wizard->callbacks.retrieve_fields) {
1990 if (wizard->wizard->callbacks.retrieve_fields) {
1991 object = wizard->wizard->callbacks.retrieve_fields(sorcery, wizard->data, object_type->name, fields);
1992 }
1993 }
1994
1995 if (((flags & AST_RETRIEVE_FLAG_MULTIPLE) && (!ao2_container_count(object) || !wizard->caching)) || !object) {
1996 continue;
1997 }
1998
1999 cached = wizard->caching;
2000
2001 break;
2002 }
2003
2004 /* If we are returning a single object and it came from a non-cache source create it in any caches */
2005 if (!(flags & AST_RETRIEVE_FLAG_MULTIPLE) && !cached && object) {
2006 struct sorcery_details sdetails = {
2007 .sorcery = sorcery,
2008 .obj = object,
2009 };
2010
2011 AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, &sdetails, 0);
2012 }
2013 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2014
2015 return object;
2016}
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
Definition astobj2.h:1188
static int sorcery_cache_create(void *obj, void *arg, int flags)
Internal function used to create an object in caching wizards.
Definition sorcery.c:1903
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition sorcery.c:2528
@ 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:776

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_container_count(), ao2_find, AST_RETRIEVE_FLAG_MULTIPLE, ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), 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_details::sorcery, 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(), ari_conf_get_owcs(), ari_conf_get_users(), 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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_retrieve_all(), 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 1917 of file sorcery.c.

1918{
1919 struct ast_sorcery_object_type *object_type;
1920 void *object = NULL;
1921 int i;
1922 unsigned int cached = 0;
1923
1924 if (ast_strlen_zero(id)) {
1925 return NULL;
1926 }
1927
1928 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1929 if (!object_type) {
1930 return NULL;
1931 }
1932
1933 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1934 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1936 AST_VECTOR_GET(&object_type->wizards, i);
1937
1938 if (wizard->wizard->callbacks.retrieve_id &&
1939 !(object = wizard->wizard->callbacks.retrieve_id(sorcery, wizard->data, object_type->name, id))) {
1940 continue;
1941 }
1942
1943 cached = wizard->caching;
1944 break;
1945 }
1946
1947 if (!cached && object) {
1948 struct sorcery_details sdetails = {
1949 .sorcery = sorcery,
1950 .obj = object,
1951 };
1952
1953 AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, &sdetails, 0);
1954 }
1955 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1956
1957 ao2_ref(object_type, -1);
1958 return object;
1959}
char name[MAX_OBJECT_TYPE]
Unique name of the object type.
Definition sorcery.c:151
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(), ari_conf_get_general(), ari_conf_get_owc(), ari_conf_get_user(), ari_conf_validate_user(), 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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_websocket_client_retrieve_by_id(), 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_retrieve_by_id(), cli_retrieve_by_id(), 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_aor2(), 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(), outbound_websocket_validate_cb(), 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 736 of file sorcery.c.

737{
738 return ao2_weakproxy_find(instances, module_name, OBJ_SEARCH_KEY, "");
739}
#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 2053 of file sorcery.c.

2054{
2056 struct ao2_container *objects;
2057 int i;
2058
2059 if (!object_type) {
2060 return NULL;
2061 }
2062
2064 if (!objects) {
2065 return NULL;
2066 }
2067
2068 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2069 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2071 AST_VECTOR_GET(&object_type->wizards, i);
2072
2073 if (!wizard->wizard->callbacks.retrieve_prefix) {
2074 continue;
2075 }
2076
2077 wizard->wizard->callbacks.retrieve_prefix(sorcery, wizard->data, object_type->name, objects, prefix, prefix_len);
2078
2079 if (wizard->caching && ao2_container_count(objects)) {
2080 break;
2081 }
2082 }
2083 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2084
2085 return objects;
2086}
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_ALLOC_OPT_DUPS_REJECT, ao2_container_count(), ao2_find, ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), 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 2018 of file sorcery.c.

2019{
2021 struct ao2_container *objects;
2022 int i;
2023
2024 if (!object_type) {
2025 return NULL;
2026 }
2027
2029 if (!objects) {
2030 return NULL;
2031 }
2032
2033 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2034 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2036 AST_VECTOR_GET(&object_type->wizards, i);
2037
2038 if (!wizard->wizard->callbacks.retrieve_regex) {
2039 continue;
2040 }
2041
2042 wizard->wizard->callbacks.retrieve_regex(sorcery, wizard->data, object_type->name, objects, regex);
2043
2044 if (wizard->caching && ao2_container_count(objects)) {
2045 break;
2046 }
2047 }
2048 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2049
2050 return objects;
2051}
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_ALLOC_OPT_DUPS_REJECT, ao2_container_count(), ao2_find, ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), 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(), AST_TEST_DEFINE(), cli_aor_get_container(), cli_contact_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_get_container(), cli_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 2214 of file sorcery.c.

2215{
2216 const struct ast_sorcery_object_details *details = object;
2217 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2218 struct ast_sorcery_object_wizard *object_wizard = NULL;
2219 struct ast_sorcery_object_wizard *found_wizard;
2220 int i;
2221 struct sorcery_details sdetails = {
2222 .sorcery = sorcery,
2223 .obj = object,
2224 };
2225
2226 if (!object_type) {
2227 return -1;
2228 }
2229
2230 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2231 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2232 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2233 if (!found_wizard->caching
2234 && sorcery_wizard_update(found_wizard, &sdetails) == CMP_MATCH) {
2235 object_wizard = found_wizard;
2236 }
2237 }
2238
2239 if (object_wizard) {
2240 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2241 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2242 if (found_wizard->caching) {
2243 sorcery_wizard_update(found_wizard, &sdetails);
2244 }
2245 }
2246
2247 if (ao2_container_count(object_type->observers)) {
2248 struct sorcery_observer_invocation *invocation;
2249
2250 invocation = sorcery_observer_invocation_alloc(object_type, object);
2251 if (invocation
2253 invocation)) {
2254 ao2_cleanup(invocation);
2255 }
2256 }
2257 }
2258
2260
2261 return object_wizard ? 0 : -1;
2262}
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:2200
static int sorcery_observers_notify_update(void *data)
Internal callback function which notifies observers that an object has been updated.
Definition sorcery.c:2189

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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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 607 of file sorcery.c.

609{
610 RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
611 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
613
614 if (wizard) {
615 struct sorcery_wizard_observer *cb;
616
617 cb = ao2_alloc(sizeof(*cb), NULL);
618 if (!cb) {
619 return -1;
620 }
621
622 cb->callbacks = callbacks;
623 ao2_link(wizard->observers, cb);
624 ao2_ref(cb, -1);
625
626 return 0;
627 }
628
629 return -1;
630}
A wizard observer wrapper.
Definition sorcery.c:277
const struct ast_sorcery_wizard_observer * callbacks
Definition sorcery.c:278

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 632 of file sorcery.c.

634{
635 RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
636 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
638
639 if (wizard) {
641 }
642}

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 538 of file sorcery.c.

539{
540 struct ast_sorcery_internal_wizard *wizard =
541 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL;
542
543 if (wizard) {
544 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_unregistering, wizard->callbacks.name, &wizard->callbacks);
545 ao2_unlink(wizards, wizard);
546 ao2_ref(wizard, -1);
547 ast_verb(5, "Sorcery unregistered wizard '%s'\n", interface->name);
548 return 0;
549 } else {
550 return -1;
551 }
552}
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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), bucket_cleanup(), sorcery_memory_cache_thrash_destroy(), unload_module(), unload_module(), unload_module(), unload_module(), 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 314 of file sorcery.c.

315{
316 unsigned int *field = (unsigned int *)(obj + args[0]);
317 return !(*buf = ast_strdup(*field ? "true" : "false")) ? -1 : 0;
318}

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 332 of file sorcery.c.

333{
334 char *field = (char *)(obj + args[0]);
335 return !(*buf = ast_strdup(field)) ? -1 : 0;
336}

References args, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

◆ cli_show_settings()

static char * cli_show_settings ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Hashing and comparison functions for sorcery wizards.

Definition at line 376 of file sorcery.c.

377{
378 switch (cmd) {
379 case CLI_INIT:
380 e->command = "sorcery show settings";
381 e->usage = "Usage: sorcery show settings\n"
382 " Show global configuration options\n";
383 return NULL;
384 case CLI_GENERATE:
385 return NULL;
386 }
387
388 ast_cli(a->fd, "\nSorcery global settings\n");
389 ast_cli(a->fd, "-----------------\n");
390 ast_cli(a->fd, " Update->Create fallback in backends: %s\n",
391 ast_sorcery_update_or_create_on_update_miss ? "enabled" : "disabled");
392
393 return CLI_SUCCESS;
394}
#define CLI_SUCCESS
Definition cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
int ast_sorcery_update_or_create_on_update_miss
Global control for optional update->create fallback in backends.
Definition sorcery.c:288
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
static struct test_val a

References a, ast_cli(), ast_sorcery_update_or_create_on_update_miss, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, and NULL.

◆ codec_handler_fn()

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

Definition at line 338 of file sorcery.c.

339{
341 struct ast_format_cap **cap = (struct ast_format_cap **)(obj + args[0]);
342 return !(*buf = ast_strdup(ast_format_cap_get_names(*cap, &codec_buf)));
343}
#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 302 of file sorcery.c.

303{
304 double *field = (double *)(obj + args[0]);
305 return (ast_asprintf(buf, "%f", *field) < 0) ? -1 : 0;
306}
#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 1559 of file sorcery.c.

1560{
1561 struct ast_variable *tmp = NULL;
1562
1563 if (!object_field->multiple_handler) {
1564 return NULL;
1565 }
1566
1567 if (object_field->multiple_handler(object, &tmp)) {
1569 tmp = NULL;
1570 }
1571
1572 return tmp;
1573}
sorcery_fields_handler multiple_handler
Callback function for translation of multiple values.
Definition sorcery.c:217

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

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 1542 of file sorcery.c.

1543{
1544 struct ast_variable *tmp = NULL;
1545 char *buf = NULL;
1546
1547 if (!object_field->handler) {
1548 return NULL;
1549 }
1550
1551 if (!(object_field->handler(object, object_field->args, &buf))) {
1552 tmp = ast_variable_new(object_field->name, S_OR(buf, ""), "");
1553 }
1554 ast_free(buf);
1555
1556 return tmp;
1557}
sorcery_field_handler handler
Callback function for translation of a single value.
Definition sorcery.c:214
intptr_t args[]
Position of the field.
Definition sorcery.c:220
char name[MAX_OBJECT_FIELD]
Name of the field.
Definition sorcery.c:208

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

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 290 of file sorcery.c.

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

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 2564 of file sorcery.c.

2565{
2566 struct ast_sorcery_object_field *object_field = obj;
2567 char *name = arg;
2568 int rc = 0;
2569
2570 if (object_field->name_regex
2571 && !regexec(object_field->name_regex, name, 0, NULL, 0)) {
2572 rc = CMP_MATCH;
2573 }
2574
2575 return rc;
2576}
regex_t * name_regex
The compiled name regex if name is a regex.
Definition sorcery.c:211

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

Referenced by ast_sorcery_is_object_field_registered().

◆ parse_general_options()

static void parse_general_options ( void  )
static

Compare function for sorcery instances.

Hashing function for sorcery instances

Definition at line 425 of file sorcery.c.

426{
427 struct ast_flags flags = { 0 };
428 struct ast_config *cfg = ast_config_load2("sorcery.conf", "sorcery", flags);
429 const struct ast_variable *var;
430
431 if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
432 return;
433 }
434
435 for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
436 if (!strcasecmp(var->name, "update_or_create_on_update_miss")) {
438 }
439 }
440
442}
#define var
Definition ast_expr2f.c:605
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition utils.c:2235

References ast_config_destroy(), ast_config_load2(), ast_sorcery_update_or_create_on_update_miss, ast_true(), ast_variable_browse(), CONFIG_STATUS_FILEINVALID, ast_flags::flags, ast_variable::next, and var.

Referenced by ast_sorcery_init().

◆ sockaddr_handler_fn()

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

Definition at line 326 of file sorcery.c.

327{
328 struct ast_sockaddr *field = (struct ast_sockaddr *)(obj + args[0]);
329 return !(*buf = ast_strdup(ast_sockaddr_stringify(field))) ? -1 : 0;
330}
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 1903 of file sorcery.c.

1904{
1905 const struct ast_sorcery_object_wizard *object_wizard = obj;
1906 const struct sorcery_details *details = arg;
1907
1908 if (!object_wizard->caching || !object_wizard->wizard->callbacks.create) {
1909 return 0;
1910 }
1911
1912 object_wizard->wizard->callbacks.create(details->sorcery, object_wizard->data, details->obj);
1913
1914 return 0;
1915}
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:1899

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

Cleanup function for graceful shutdowns.

Definition at line 402 of file sorcery.c.

403{
406 taskpool = NULL;
408 wizards = NULL;
410 observers = NULL;
412 instances = NULL;
413}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
void ast_taskpool_shutdown(struct ast_taskpool *pool)
Shut down a taskpool and remove the underlying taskprocessors.
Definition taskpool.c:653

References ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), ast_taskpool_shutdown(), cli_commands, instances, NULL, observers, taskpool, 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 645 of file sorcery.c.

646{
647 struct ast_sorcery *sorcery = obj;
648
649 if (sorcery->observers) {
651 }
654}

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 1107 of file sorcery.c.

1108{
1109 return ast_sorcery_object_set_extended(obj, var->name, var->value);
1110}
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:2413

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 1112 of file sorcery.c.

1113{
1114 const struct ast_sorcery_object_details *details = obj;
1115
1116 if (details->object->extended) {
1117 *fields = ast_variables_dup(details->object->extended);
1118 } else {
1119 *fields = NULL;
1120 }
1121
1122 return 0;
1123}
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.

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 345 of file sorcery.c.

346{
347 switch(type) {
348 case OPT_BOOL_T: return bool_handler_fn;
349 case OPT_YESNO_T: return yesno_handler_fn;
351 case OPT_CODEC_T: return codec_handler_fn;
352 case OPT_DOUBLE_T: return double_handler_fn;
353 case OPT_INT_T: return int_handler_fn;
356 case OPT_UINT_T: return uint_handler_fn;
357
358 default:
359 case OPT_CUSTOM_T: return NULL;
360 }
361
362 return NULL;
363}
@ 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:290
static int chararray_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:332
static int stringfield_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:308
static int codec_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:338
static int yesno_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:320
static int bool_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:314
static int uint_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:296
static int sockaddr_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:326
static int double_handler_fn(const void *obj, const intptr_t *args, char **buf)
Definition sorcery.c:302

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 555 of file sorcery.c.

556{
557 const struct sorcery_global_observer *observer = obj;
558
559 return (observer->callbacks == arg) ? CMP_MATCH : 0;
560}

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 489 of file sorcery.c.

490{
491 struct ast_sorcery_internal_wizard *wizard = obj;
492
493 ao2_cleanup(wizard->observers);
494}

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 1764 of file sorcery.c.

1765{
1766 struct ast_sorcery_object_details *details = object;
1767
1768 if (details->object->destructor) {
1769 details->object->destructor(object);
1770 }
1771
1773 ast_free(details->object->id);
1774}

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 1214 of file sorcery.c.

1215{
1216 struct ast_sorcery_object_field *object_field = obj;
1217
1218 if (object_field->name_regex) {
1219 regfree(object_field->name_regex);
1220 ast_free(object_field->name_regex);
1221 }
1222}

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 1400 of file sorcery.c.

1401{
1402 struct ast_sorcery_object_type *type = obj;
1403 struct sorcery_load_details *details = arg;
1404
1405 if (!type->type.item_alloc) {
1406 return 0;
1407 }
1408
1409 details->type = type->name;
1410
1411 if (details->reload && !sorcery_reloadable(details->sorcery, details->type)) {
1412 ast_log(LOG_NOTICE, "Type '%s' is not reloadable, maintaining previous values\n",
1413 details->type);
1414 return 0;
1415 }
1416
1417 NOTIFY_INSTANCE_OBSERVERS(details->sorcery->observers, object_type_loading,
1418 details->sorcery->module_name, details->sorcery, type->name, details->reload);
1419
1420 AST_VECTOR_RW_RDLOCK(&type->wizards);
1421 AST_VECTOR_CALLBACK(&type->wizards, sorcery_wizard_load, NULL, details, 0);
1422 AST_VECTOR_RW_UNLOCK(&type->wizards);
1423
1424 NOTIFY_INSTANCE_OBSERVERS(details->sorcery->observers, object_type_loaded,
1425 details->sorcery->module_name, details->sorcery, type->name, details->reload);
1426
1427 if (ao2_container_count(type->observers)) {
1428 struct sorcery_observer_invocation *invocation;
1429
1431 if (invocation
1433 invocation)) {
1434 ao2_cleanup(invocation);
1435 }
1436 }
1437
1438 return 0;
1439}
#define LOG_NOTICE
static int sorcery_wizard_load(void *obj, void *arg, int flags)
Definition sorcery.c:1317
static int sorcery_reloadable(const struct ast_sorcery *sorcery, const char *type)
Retrieves whether or not the type is reloadable.
Definition sorcery.c:1310
static int sorcery_observers_notify_loaded(void *data)
Internal callback function which notifies observers that an object type has been loaded.
Definition sorcery.c:1390
const char * type
Type of object being loaded.
Definition sorcery.c:248
unsigned int reload
Whether this is a reload or not.
Definition sorcery.c:251

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 764 of file sorcery.c.

765{
766#define INITIAL_WIZARD_VECTOR_SIZE 5
767 struct ast_sorcery_object_type *object_type;
768 char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
769
770 if (!(object_type = ao2_alloc(sizeof(*object_type), sorcery_object_type_destructor))) {
771 return NULL;
772 }
773
774 /* Order matters for object wizards */
775 if (AST_VECTOR_RW_INIT(&object_type->wizards, INITIAL_WIZARD_VECTOR_SIZE) != 0) {
776 ao2_ref(object_type, -1);
777 return NULL;
778 }
779
781 OBJECT_FIELD_BUCKETS, ast_sorcery_object_field_hash_fn, NULL, ast_sorcery_object_field_cmp_fn);
782 if (!object_type->fields) {
783 ao2_ref(object_type, -1);
784 return NULL;
785 }
786
788 NULL, NULL);
789 if (!object_type->observers) {
790 ao2_ref(object_type, -1);
791 return NULL;
792 }
793
794 object_type->info = ast_calloc(1,
795 sizeof(*object_type->info) + 2 * sizeof(object_type->info->files[0]));
796 if (!object_type->info) {
797 ao2_ref(object_type, -1);
798 return NULL;
799 }
800
801 object_type->file = ast_calloc(1,
802 sizeof(*object_type->file) + 2 * sizeof(object_type->file->types[0]));
803 if (!object_type->file) {
804 ao2_ref(object_type, -1);
805 return NULL;
806 }
807
808 /* Create name with seq number appended. */
809 ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "sorcery/%s", type);
810
811 if (!(object_type->serializer = ast_taskpool_serializer(tps_name, taskpool))) {
812 ao2_ref(object_type, -1);
813 return NULL;
814 }
815
816 object_type->info->files[0] = object_type->file;
817 object_type->info->files[1] = NULL;
818 object_type->info->module = module;
819
820 ast_copy_string(object_type->name, type, sizeof(object_type->name));
821
822 return object_type;
823}
#define INITIAL_WIZARD_VECTOR_SIZE
static void sorcery_object_type_destructor(void *obj)
Destructor function for object types.
Definition sorcery.c:742
#define OBJECT_FIELD_BUCKETS
Number of buckets for object fields (should be prime for performance reasons)
Definition sorcery.c:61
struct aco_type * types[]
struct aco_file * files[]
struct aco_file * file
Configuration framework file information.
Definition sorcery.c:175
struct ao2_container * observers
Observers.
Definition sorcery.c:181
struct aco_info * info
Configuration framework general information.
Definition sorcery.c:172
struct ast_taskprocessor * ast_taskpool_serializer(const char *name, struct ast_taskpool *pool)
Serialized execution of tasks within a ast_taskpool.
Definition taskpool.c:819
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).
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Definition vector.h:169

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_taskpool_serializer(), ast_taskprocessor_build_name(), AST_TASKPROCESSOR_MAX_NAME, 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, ast_sorcery_object_type::name, NULL, OBJECT_FIELD_BUCKETS, ast_sorcery_object_type::observers, ast_sorcery_object_type::serializer, sorcery_object_type_destructor(), taskpool, 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 742 of file sorcery.c.

743{
744 struct ast_sorcery_object_type *object_type = obj;
745
746 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
748 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
749 AST_VECTOR_RW_FREE(&object_type->wizards);
750 ao2_cleanup(object_type->fields);
751 ao2_cleanup(object_type->observers);
752
753 if (object_type->info) {
754 aco_info_destroy(object_type->info);
755 ast_free(object_type->info);
756 }
757
758 ast_free(object_type->file);
759
761}
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:213
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition vector.h:873

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 826 of file sorcery.c.

827{
828 struct ast_sorcery_object_wizard *object_wizard = obj;
829
830 if (object_wizard->data && object_wizard->wizard->callbacks.close) {
831 object_wizard->wizard->callbacks.close(object_wizard->data);
832 }
833
834 if (object_wizard->wizard) {
835 ast_module_unref(object_wizard->wizard->callbacks.module);
836 }
837
838 ao2_cleanup(object_wizard->wizard);
839}
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, 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 1356 of file sorcery.c.

1357{
1358 struct sorcery_observer_invocation *invocation;
1359
1360 invocation = ao2_alloc_options(sizeof(*invocation),
1362 if (!invocation) {
1363 return NULL;
1364 }
1365
1366 ao2_ref(object_type, +1);
1367 invocation->object_type = object_type;
1368
1369 if (object) {
1370 ao2_ref(object, +1);
1371 invocation->object = object;
1372 }
1373
1374 return invocation;
1375}
static void sorcery_observer_invocation_destroy(void *obj)
Destructor for observer invocation.
Definition sorcery.c:1347
void * object
Pointer to the object.
Definition sorcery.c:202

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 1347 of file sorcery.c.

1348{
1349 struct sorcery_observer_invocation *invocation = obj;
1350
1351 ao2_cleanup(invocation->object_type);
1352 ao2_cleanup(invocation->object);
1353}

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 2104 of file sorcery.c.

2105{
2106 const struct ast_sorcery_object_type_observer *observer = obj;
2107
2108 if (observer->callbacks->created) {
2109 observer->callbacks->created(arg);
2110 }
2111
2112 return 0;
2113}

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 2265 of file sorcery.c.

2266{
2267 const struct ast_sorcery_object_type_observer *observer = obj;
2268
2269 if (observer->callbacks->deleted) {
2270 observer->callbacks->deleted(arg);
2271 }
2272
2273 return 0;
2274}

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 1378 of file sorcery.c.

1379{
1380 const struct ast_sorcery_object_type_observer *observer = obj;
1381
1382 if (observer->callbacks->loaded) {
1383 observer->callbacks->loaded(arg);
1384 }
1385
1386 return 0;
1387}

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 2177 of file sorcery.c.

2178{
2179 const struct ast_sorcery_object_type_observer *observer = obj;
2180
2181 if (observer->callbacks->updated) {
2182 observer->callbacks->updated(arg);
2183 }
2184
2185 return 0;
2186}

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 2480 of file sorcery.c.

2481{
2482 const struct ast_sorcery_object_type_observer *observer = obj;
2483
2484 return (observer->callbacks == arg) ? CMP_MATCH : 0;
2485}

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 2116 of file sorcery.c.

2117{
2118 struct sorcery_observer_invocation *invocation = data;
2119
2121 ao2_cleanup(invocation);
2122
2123 return 0;
2124}
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:2104

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 2277 of file sorcery.c.

2278{
2279 struct sorcery_observer_invocation *invocation = data;
2280
2282 ao2_cleanup(invocation);
2283
2284 return 0;
2285}
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:2265

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 1390 of file sorcery.c.

1391{
1392 struct sorcery_observer_invocation *invocation = data;
1393
1395 ao2_cleanup(invocation);
1396
1397 return 0;
1398}
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:1378

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 2189 of file sorcery.c.

2190{
2191 struct sorcery_observer_invocation *invocation = data;
2192
2194 ao2_cleanup(invocation);
2195
2196 return 0;
2197}
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:2177

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 660 of file sorcery.c.

661{
662 ao2_unlink(instances, weakproxy);
663}

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 1310 of file sorcery.c.

1311{
1312 RAII_VAR(struct ast_sorcery_object_type *, object_type,
1314 return object_type && object_type->reloadable;
1315}

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 2089 of file sorcery.c.

2090{
2091 if (!object_wizard->wizard->callbacks.create || object_wizard->read_only) {
2092 ast_debug(5, "Sorcery wizard '%s' does not support creation\n", object_wizard->wizard->callbacks.name);
2093 return 0;
2094 }
2095
2096 if (object_wizard->wizard->callbacks.create(details->sorcery, object_wizard->data, details->obj)) {
2097 return 0;
2098 }
2099
2100 return CMP_MATCH;
2101}
unsigned int read_only
Wizard is read_only.
Definition sorcery.c:115

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 2288 of file sorcery.c.

2289{
2290 if (!object_wizard->wizard->callbacks.delete || object_wizard->read_only) {
2291 ast_debug(5, "Sorcery wizard '%s' does not support deletion\n", object_wizard->wizard->callbacks.name);
2292 return 0;
2293 }
2294
2295 if (object_wizard->wizard->callbacks.delete(details->sorcery, object_wizard->data, details->obj)) {
2296 return 0;
2297 }
2298
2299 return CMP_MATCH;
2300}
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 1317 of file sorcery.c.

1318{
1319 struct ast_sorcery_object_wizard *wizard = obj;
1320 struct sorcery_load_details *details = arg;
1321 void (*load)(void *data, const struct ast_sorcery *sorcery, const char *type);
1322
1323 if (details->reload) {
1324 if (details->force && wizard->wizard->callbacks.force_reload) {
1325 load = wizard->wizard->callbacks.force_reload;
1326 } else {
1327 load = wizard->wizard->callbacks.reload;
1328 }
1329 } else {
1330 load = wizard->wizard->callbacks.load;
1331 }
1332
1333 if (load) {
1334 NOTIFY_WIZARD_OBSERVERS(wizard->wizard->observers, wizard_loading,
1335 wizard->wizard->callbacks.name, &wizard->wizard->callbacks, details->type, details->reload);
1336
1337 load(wizard->data, details->sorcery, details->type);
1338
1339 NOTIFY_WIZARD_OBSERVERS(wizard->wizard->observers, wizard_loaded,
1340 wizard->wizard->callbacks.name, &wizard->wizard->callbacks, details->type, details->reload);
1341 }
1342
1343 return 0;
1344}
#define NOTIFY_WIZARD_OBSERVERS(container, callback,...)
Definition sorcery.c:83
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:254

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 2200 of file sorcery.c.

2201{
2202 if (!object_wizard->wizard->callbacks.update || object_wizard->read_only) {
2203 ast_debug(5, "Sorcery wizard '%s' does not support updating\n", object_wizard->wizard->callbacks.name);
2204 return 0;
2205 }
2206
2207 if (object_wizard->wizard->callbacks.update(details->sorcery, object_wizard->data, details->obj)) {
2208 return 0;
2209 }
2210
2211 return CMP_MATCH;
2212}
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 308 of file sorcery.c.

309{
310 ast_string_field *field = (const char **)(obj + args[0]);
311 return !(*buf = ast_strdup(*field)) ? -1 : 0;
312}
const char * ast_string_field

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 296 of file sorcery.c.

297{
298 unsigned int *field = (unsigned int *)(obj + args[0]);
299 return (ast_asprintf(buf, "%u", *field) < 0) ? -1 : 0;
300}

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 320 of file sorcery.c.

321{
322 unsigned int *field = (unsigned int *)(obj + args[0]);
323 return !(*buf = ast_strdup(*field ? "yes" : "no")) ? -1 : 0;
324}

References args, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

Variable Documentation

◆ ast_sorcery_update_or_create_on_update_miss

int ast_sorcery_update_or_create_on_update_miss = 0

Global control for optional update->create fallback in backends.

When non-zero, writable Sorcery backends may attempt to call create() if update() indicates the object is missing (e.g., 0 rows affected or NOT_FOUND). This helps re-populate backends that temporarily missed an insert.

Default is 0 (off) to maintain legacy behavior.

Configured via sorcery.conf: [general] update_or_create_on_update_miss = yes|no

NOTE: Backends MUST gate their fallback logic on this variable.

Definition at line 288 of file sorcery.c.

Referenced by AST_TEST_DEFINE(), cli_show_settings(), parse_general_options(), sorcery_astdb_update(), sorcery_memory_update(), and sorcery_realtime_update().

◆ cli_commands

struct ast_cli_entry cli_commands[]
static
Initial value:
= {
{ .handler = cli_show_settings , .summary = "Show global configuration options" ,},
}
static char * cli_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Hashing and comparison functions for sorcery wizards.
Definition sorcery.c:376

Definition at line 397 of file sorcery.c.

397 {
398 AST_CLI_DEFINE(cli_show_settings, "Show global configuration options"),
399};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by ast_sorcery_init(), and sorcery_cleanup().

◆ instances

struct ao2_container* instances
static

Registered sorcery instances.

Definition at line 285 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

◆ taskpool

struct ast_taskpool* taskpool
static

Taskpool for observers.

Definition at line 87 of file sorcery.c.

Referenced by ast_serializer_taskpool_create(), ast_sorcery_init(), sorcery_cleanup(), and sorcery_object_type_alloc().

◆ wizards

struct ao2_container* wizards
static