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

Sorcery Data Access Layer API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/sorcery.h"
#include "asterisk/astobj2.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/strings.h"
#include "asterisk/config_options.h"
#include "asterisk/netsock2.h"
#include "asterisk/module.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/threadpool.h"
#include "asterisk/json.h"
#include "asterisk/vector.h"
#include "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) More...
 
#define MAX_REGEX_ERROR_LEN   128
 
#define NOTIFY_GENERIC_OBSERVERS(container, type, callback, ...)
 
#define NOTIFY_GLOBAL_OBSERVERS(container, callback, ...)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_global_observer, callback, __VA_ARGS__)
 
#define NOTIFY_INSTANCE_OBSERVERS(container, callback, ...)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_instance_observer, callback, __VA_ARGS__)
 
#define NOTIFY_WIZARD_OBSERVERS(container, callback, ...)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_wizard_observer, callback, __VA_ARGS__)
 
#define OBJECT_FIELD_BUCKETS   29
 Number of buckets for object fields (should be prime for performance reasons) More...
 
#define TYPE_BUCKETS   53
 Number of buckets for types (should be prime for performance reasons) More...
 
#define WIZARD_BUCKETS   7
 Number of buckets for wizards (should be prime for performance reasons) More...
 
#define WIZARD_COMPARE(a, b)   ((a)->wizard == (b))
 
#define WIZARD_NAME_COMPARE(a, b)   (strcmp((a)->wizard->callbacks.name, (b)) == 0)
 

Functions

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

Variables

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

Detailed Description

Sorcery Data Access Layer API.

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

Definition in file sorcery.c.

Macro Definition Documentation

◆ INITIAL_WIZARD_VECTOR_SIZE

#define INITIAL_WIZARD_VECTOR_SIZE   5

◆ INSTANCE_BUCKETS

#define INSTANCE_BUCKETS   17

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

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

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

1049{
1050 struct ast_flags flags = { 0 };
1051 struct ast_config *config = ast_config_load2("sorcery.conf", "sorcery", flags);
1052 struct ast_variable *mapping;
1053 int res = AST_SORCERY_APPLY_SUCCESS;
1054
1055 if (!config) {
1057 }
1058
1061 }
1062
1063 for (mapping = ast_variable_browse(config, name); mapping; mapping = mapping->next) {
1064 RAII_VAR(char *, mapping_name, ast_strdup(mapping->name), ast_free);
1065 RAII_VAR(char *, mapping_value, ast_strdup(mapping->value), ast_free);
1066 char *options = mapping_name;
1067 char *type = strsep(&options, "/");
1068 char *data = mapping_value;
1069 char *wizard = strsep(&data, ",");
1070 unsigned int caching = 0;
1071
1072 /* If no object type or wizard exists just skip, nothing we can do */
1073 if (ast_strlen_zero(type) || ast_strlen_zero(wizard)) {
1074 continue;
1075 }
1076
1077 /* If the wizard is configured as a cache treat it as such */
1078 if (!ast_strlen_zero(options) && strstr(options, "cache")) {
1079 caching = 1;
1080 }
1081
1082 /* Any error immediately causes us to stop */
1083 if (__ast_sorcery_apply_wizard_mapping(sorcery, type, module, wizard, data, caching) == AST_SORCERY_APPLY_FAIL) {
1085 break;
1086 }
1087 }
1088
1090
1091 return res;
1092}
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 type[]
Definition: chan_ooh323.c:109
static const char config[]
Definition: chan_ooh323.c:111
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.
Definition: main/config.c:3541
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
static struct ast_sorcery * sorcery
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching)
Internal function which creates an object type and adds a wizard mapping.
Definition: sorcery.c:1040
@ 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:217
unsigned int flags
Definition: utils.h:218
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:978

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

1095{
1097
1098 /* Defaults can not be added if any existing mapping exists */
1099 if (object_type) {
1101 }
1102
1103 return __ast_sorcery_apply_wizard_mapping(sorcery, type, module, name, data, 0);
1104}
#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 1040 of file sorcery.c.

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

1033{
1036 position, NULL, NULL);
1037}
#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:932
@ 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 1255 of file sorcery.c.

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

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

1144{
1146
1147 if (!object_type || object_type->type.item_alloc) {
1148 return -1;
1149 }
1150
1151 object_type->type.name = object_type->name;
1152 object_type->type.type = ACO_ITEM;
1153 object_type->type.category = ".?";
1154 object_type->type.item_alloc = alloc;
1155 object_type->type.hidden = hidden;
1156
1157 object_type->reloadable = reloadable;
1158 object_type->transform = transform;
1159 object_type->apply = apply;
1160 object_type->file->types[0] = &object_type->type;
1161 object_type->file->types[1] = NULL;
1162
1163 if (aco_info_init(object_type->info)) {
1164 return -1;
1165 }
1166
1168 return -1;
1169 }
1170
1171 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, object_type_registered,
1173
1174 return 0;
1175}
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:1223
static int sorcery_extended_fields_handler(const void *obj, struct ast_variable **fields)
Definition: sorcery.c:1111
#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:1106
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 932 of file sorcery.c.

936{
937 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, object_type_name, OBJ_KEY), ao2_cleanup);
938 RAII_VAR(struct ast_sorcery_internal_wizard *, internal_wizard, ao2_find(wizards, wizard_type_name, OBJ_KEY), ao2_cleanup);
939 RAII_VAR(struct ast_sorcery_object_wizard *, object_wizard, NULL, ao2_cleanup);
940 int created = 0;
941
942 object_wizard = ao2_alloc(sizeof(*object_wizard)
943 + (ast_strlen_zero(wizard_args) ? 0 : strlen(wizard_args) + 1),
945
946 if (!object_wizard) {
948 }
949
950 if (!internal_wizard
951 || internal_wizard->callbacks.module != ast_module_running_ref(internal_wizard->callbacks.module)) {
953 "Wizard '%s' could not be applied to object type '%s' as it was not found\n",
954 wizard_type_name, object_type_name);
956 }
957
958 if (!object_type) {
959 if (!(object_type = sorcery_object_type_alloc(object_type_name, module))) {
960 ast_module_unref(internal_wizard->callbacks.module);
962 }
963 created = 1;
964 }
965
966 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
967 if (!created) {
968 struct ast_sorcery_object_wizard *found;
969
970#define WIZARD_COMPARE(a, b) ((a)->wizard == (b))
971 found = AST_VECTOR_GET_CMP(&object_type->wizards, internal_wizard, WIZARD_COMPARE);
972#undef WIZARD_COMPARE
973 if (found
975 ast_debug(1, "Wizard %s already applied to object type %s\n",
976 internal_wizard->callbacks.name, object_type->name);
977 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
978 ast_module_unref(internal_wizard->callbacks.module);
980 }
981 }
982
983 ast_debug(5, "Calling wizard %s open callback on object type %s\n",
984 wizard_type_name, object_type->name);
985 if (internal_wizard->callbacks.open && !(object_wizard->data = internal_wizard->callbacks.open(wizard_args))) {
986 ast_log(LOG_WARNING, "Wizard '%s' failed to open mapping for object type '%s' with data: %s\n",
987 wizard_type_name, object_type->name, S_OR(wizard_args, ""));
988 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
989 ast_module_unref(internal_wizard->callbacks.module);
991 }
992
993 object_wizard->wizard = ao2_bump(internal_wizard);
994 object_wizard->caching = !!(flags & AST_SORCERY_WIZARD_APPLY_CACHING);
995 object_wizard->read_only = !!(flags & AST_SORCERY_WIZARD_APPLY_READONLY);
996 if (wizard_args) {
997 strcpy(object_wizard->wizard_args, wizard_args); /* Safe */
998 }
999
1000 if (position == AST_SORCERY_WIZARD_POSITION_LAST) {
1001 position = AST_VECTOR_SIZE(&object_type->wizards);
1002 }
1003
1004 if (AST_VECTOR_INSERT_AT(&object_type->wizards, position, object_wizard) != 0) {
1005 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1007 }
1008 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1009 ao2_bump(object_wizard);
1010
1011 if (created) {
1012 ao2_link(sorcery->types, object_type);
1013 }
1014
1016 sorcery->module_name, sorcery, object_type_name, &internal_wizard->callbacks, wizard_args,
1017 object_wizard->data);
1018
1019 if (wizard) {
1020 *wizard = &internal_wizard->callbacks;
1021 }
1022 if (wizard_data) {
1023 *wizard_data = object_wizard->data;
1024 }
1025
1027}
#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:763
static void sorcery_object_wizard_destructor(void *obj)
Object wizard destructor.
Definition: sorcery.c:825
@ 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 883 of file sorcery.c.

886{
887 RAII_VAR(struct ast_sorcery_object_type *, object_type,
888 ao2_find(sorcery->types, object_type_name, OBJ_SEARCH_KEY), ao2_cleanup);
889 int res = -1;
890 int i;
891
892 if (!object_type) {
893 return res;
894 }
895
896 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
897 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
898 struct ast_sorcery_object_wizard *wizard = AST_VECTOR_GET(&object_type->wizards, i);
899
900 if (strcmp(wizard->wizard->callbacks.name, wizard_type_name) == 0
901 && strcmp(S_OR(wizard->wizard_args, ""), S_OR(wizard_args, "")) == 0) {
902 ao2_cleanup(AST_VECTOR_REMOVE_ORDERED(&object_type->wizards, i));
903 res = 0;
904 break;
905 }
906 }
907 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
908
909 return res;
910}
@ 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 664 of file sorcery.c.

665{
666 struct sorcery_proxy *proxy;
667 struct ast_sorcery *sorcery;
668
670
673 __PRETTY_FUNCTION__, file, line, func);
674 if (sorcery) {
676
677 return sorcery;
678 }
679
680 proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + strlen(module_name) + 1, NULL, module_name);
681 if (!proxy) {
682 goto failure_cleanup;
683 }
684 strcpy(proxy->module_name, module_name); /* Safe */
685
687 if (!sorcery) {
688 goto failure_cleanup;
689 }
690
692
693 /* We have exclusive access to proxy and sorcery, no need for locking here. */
694 if (ao2_t_weakproxy_set_object(proxy, sorcery, OBJ_NOLOCK, "weakproxy link")) {
695 goto failure_cleanup;
696 }
697
699 goto failure_cleanup;
700 }
701
703 ast_sorcery_object_type_hash_fn, NULL, ast_sorcery_object_type_cmp_fn);
704 if (!sorcery->types) {
705 goto failure_cleanup;
706 }
707
709 goto failure_cleanup;
710 }
711
713 ast_log(LOG_ERROR, "Error attempting to apply configuration %s to sorcery.\n", module_name);
714 goto failure_cleanup;
715 }
716
718 ao2_ref(proxy, -1);
719
721
723 return sorcery;
724
725failure_cleanup:
726 /* cleanup of sorcery may result in locking instances, so make sure we unlock first. */
729 ao2_cleanup(proxy);
730
731 return NULL;
732}
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:644
static void sorcery_proxy_cb(void *weakproxy, void *data)
Hashing function for sorcery types.
Definition: sorcery.c:659
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:1048
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, make_ari_stubs::file, instances, LOG_ERROR, sorcery_proxy::module_name, ast_sorcery::module_name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_NOLOCK, OBJ_SEARCH_KEY, ast_sorcery::observers, observers, sorcery, sorcery_destructor(), sorcery_proxy_cb(), TYPE_BUCKETS, and ast_sorcery::types.

◆ __ast_sorcery_remove_wizard_mapping()

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

Internal function removes a wizard mapping.

Remove an object wizard mapping.

Definition at line 913 of file sorcery.c.

915{
917 int res;
918
919 if (!object_type) {
920 return -1;
921 }
922
923 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
924#define WIZARD_NAME_COMPARE(a, b) (strcmp((a)->wizard->callbacks.name, (b)) == 0)
926#undef WIZARD_NAME_COMPARE
927 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
928
929 return res;
930}
#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 495 of file sorcery.c.

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

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

Referenced by ast_bucket_init().

◆ ast_sorcery_alloc()

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

Allocate an object.

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

Definition at line 1807 of file sorcery.c.

1808{
1810 struct ast_sorcery_object_details *details;
1811
1812 if (!object_type || !object_type->type.item_alloc ||
1813 !(details = object_type->type.item_alloc(id))) {
1814 return NULL;
1815 }
1816
1817 if (ast_strlen_zero(id)) {
1818 char uuid[AST_UUID_STR_LEN];
1819
1821 details->object->id = ast_strdup(uuid);
1822 } else {
1823 details->object->id = ast_strdup(id);
1824 }
1825 if (!details->object->id) {
1826 ao2_ref(details, -1);
1827 return NULL;
1828 }
1829
1830 details->object->created = ast_tvnow();
1831 ast_copy_string(details->object->type, type, sizeof(details->object->type));
1832
1833 if (aco_set_defaults(&object_type->type, id, details)) {
1834 ao2_ref(details, -1);
1835 return NULL;
1836 }
1837
1838 return details;
1839}
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(), create_artificial_endpoint(), create_effective_profile(), create_object(), default_profile_create(), global_loaded_observer(), load_module(), mock_retrieve_id(), permanent_uri_handler(), sip_cli_print_global(), sip_cli_print_system(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_internal_load(), sorcery_memory_cache_thrash_update(), sorcery_realtime_retrieve_fields(), sorcery_realtime_retrieve_multiple(), sorcery_test_retrieve_id(), and subscription_persistence_create().

◆ ast_sorcery_changeset_create()

int ast_sorcery_changeset_create ( const struct ast_variable original,
const struct ast_variable modified,
struct ast_variable **  changes 
)

Create a changeset given two object sets.

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

Definition at line 1726 of file sorcery.c.

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

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

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

◆ ast_sorcery_copy()

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

Create a copy of an object.

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

Definition at line 1841 of file sorcery.c.

1842{
1843 const struct ast_sorcery_object_details *details = object;
1844 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1846 RAII_VAR(struct ast_variable *, objectset, NULL, ast_variables_destroy);
1847 int res = 0;
1848
1849 if (!copy) {
1850 return NULL;
1851 } else if (object_type->copy) {
1852 res = object_type->copy(object, copy);
1853 } else if ((objectset = ast_sorcery_objectset_create(sorcery, object))) {
1854 res = ast_sorcery_objectset_apply(sorcery, copy, objectset);
1855 } else {
1856 /* No native copy available and could not create an objectset, this copy has failed */
1857 res = -1;
1858 }
1859
1860 if (res) {
1862 copy = NULL;
1863 }
1864
1865 return copy;
1866}
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:1807
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:1695
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1137

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

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

◆ ast_sorcery_create()

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

Create and potentially persist an object using an available wizard.

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

Definition at line 2125 of file sorcery.c.

2126{
2127 const struct ast_sorcery_object_details *details = object;
2128 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2129 struct ast_sorcery_object_wizard *object_wizard = NULL;
2130 struct ast_sorcery_object_wizard *found_wizard;
2131 int i;
2132 struct sorcery_details sdetails = {
2133 .sorcery = sorcery,
2134 .obj = object,
2135 };
2136
2137 if (!object_type) {
2138 return -1;
2139 }
2140
2141 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2142 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2143 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2144 if (!found_wizard->caching
2145 && sorcery_wizard_create(found_wizard, &sdetails) == CMP_MATCH) {
2146 object_wizard = found_wizard;
2147 }
2148 }
2149
2150 if (object_wizard) {
2151 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2152 found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2153 if (found_wizard->caching) {
2154 sorcery_wizard_create(found_wizard, &sdetails);
2155 }
2156 }
2157
2158 if (ao2_container_count(object_type->observers)) {
2159 struct sorcery_observer_invocation *invocation;
2160
2161 invocation = sorcery_observer_invocation_alloc(object_type, object);
2162 if (invocation
2164 invocation)) {
2165 ao2_cleanup(invocation);
2166 }
2167 }
2168 }
2169
2171
2172 return object_wizard ? 0 : -1;
2173}
@ 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:2115
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:2088
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:1355
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:1894
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition: sorcery.c:1896
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(), 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 2301 of file sorcery.c.

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

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

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

◆ ast_sorcery_diff()

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

Create a changeset of two objects.

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

Definition at line 1868 of file sorcery.c.

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

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

1489{
1490 struct sorcery_load_details details = {
1491 .sorcery = sorcery,
1492 .reload = 1,
1493 .force = 1,
1494 };
1495
1496 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1498
1500
1503}
#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:1399
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 1520 of file sorcery.c.

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

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

Referenced by acl_change_stasis_cb(), as_config_reload(), 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 1791 of file sorcery.c.

1792{
1793 void *object = ao2_alloc_options(size + sizeof(struct ast_sorcery_object),
1795 struct ast_sorcery_object_details *details = object;
1796
1797 if (!object) {
1798 return NULL;
1799 }
1800
1801 details->object = object + size;
1802 details->object->destructor = destructor;
1803
1804 return object;
1805}
@ 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:1763
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(), 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 2599 of file sorcery.c.

2600{
2601 return sorcery->module_name;
2602}

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

2559{
2561}

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

855{
857 struct ast_sorcery_object_wizard *owizard;
858
859 if (!object_type) {
860 return -1;
861 }
862
863 if (index < 0 || index >= AST_VECTOR_SIZE(&object_type->wizards)) {
864 return -1;
865 }
866
867 owizard = AST_VECTOR_GET(&object_type->wizards, index);
868
869 if (wizard != NULL) {
870 *wizard = &(owizard->wizard->callbacks);
871 ao2_bump(owizard->wizard);
872 } else {
873 return -1;
874 }
875
876 if (data != NULL) {
877 *data = owizard->data;
878 }
879
880 return 0;
881}
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 841 of file sorcery.c.

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

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

Referenced by AST_TEST_DEFINE().

◆ ast_sorcery_global_observer_add()

int ast_sorcery_global_observer_add ( const struct ast_sorcery_global_observer callbacks)

Add a global observer to sorcery.

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

Definition at line 561 of file sorcery.c.

562{
563 struct sorcery_global_observer *cb;
564
565 cb = ao2_alloc(sizeof(*cb), NULL);
566 if (!cb) {
567 return -1;
568 }
569
570 cb->callbacks = callbacks;
571 ao2_link(observers, cb);
572 ao2_ref(cb, -1);
573
574 return 0;
575}
struct @474 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 577 of file sorcery.c.

579{
581}
@ 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:554

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 = 0,
452 };
454
456
458 if (!threadpool) {
459 return -1;
460 }
461
463 ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn);
464 if (!wizards) {
465 return -1;
466 }
467
469 if (!observers) {
470 return -1;
471 }
472
474 sorcery_proxy_hash_fn, NULL, sorcery_proxy_cmp_fn);
475 if (!instances) {
476 return -1;
477 }
478
480 return -1;
481 }
482
484
485 return 0;
486}
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_threadpool * threadpool
Thread pool for observers.
Definition: sorcery.c:87
static void sorcery_cleanup(void)
Cleanup function for graceful shutdowns.
Definition: sorcery.c:402
struct ast_threadpool * ast_threadpool_create(const char *name, struct ast_threadpool_listener *listener, const struct ast_threadpool_options *options)
Create a new threadpool.
Definition: threadpool.c:916
#define AST_THREADPOOL_OPTIONS_VERSION
Definition: threadpool.h:71
#define ARRAY_LEN(a)
Definition: utils.h:703

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_threadpool_create(), AST_THREADPOOL_OPTIONS_VERSION, cli_commands, INSTANCE_BUCKETS, instances, NULL, observers, options, parse_general_options(), sorcery_cleanup(), threadpool, WIZARD_BUCKETS, and wizards.

Referenced by asterisk_daemon().

◆ ast_sorcery_instance_observer_add()

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

Add an observer to a sorcery instance.

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

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

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

Definition at line 583 of file sorcery.c.

585{
586 struct sorcery_instance_observer *cb;
587
588 cb = ao2_alloc(sizeof(*cb), NULL);
589 if (!cb) {
590 return -1;
591 }
592
593 cb->callbacks = callbacks;
595 ao2_ref(cb, -1);
596
597 return 0;
598}
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(), 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 600 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 2577 of file sorcery.c.

2579{
2580 struct ast_sorcery_object_field *object_field;
2581 int res = 1;
2582
2583 ast_assert(object_type != NULL);
2584
2585 object_field = ao2_find(object_type->fields, field_name, OBJ_SEARCH_KEY);
2586
2587 if (!object_field) {
2588 object_field = ao2_callback(object_type->fields, 0, is_registered_cb, (char *)field_name);
2589 }
2590
2591 if (!object_field) {
2592 res = 0;
2593 }
2594
2595 ao2_cleanup(object_field);
2596 return res;
2597}
static int is_registered_cb(void *obj, void *arg, int flags)
Definition: sorcery.c:2563
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 2351 of file sorcery.c.

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

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

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

◆ ast_sorcery_load()

void ast_sorcery_load ( const struct ast_sorcery sorcery)

Inform any wizards to load persistent objects.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1440 of file sorcery.c.

1441{
1442 struct sorcery_load_details details = {
1443 .sorcery = sorcery,
1444 .reload = 0,
1445 };
1446
1447 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1449
1451
1454}

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

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

◆ ast_sorcery_load_object()

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

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

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

Definition at line 1456 of file sorcery.c.

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

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

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

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

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

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

◆ ast_sorcery_object_get_created()

const struct timeval ast_sorcery_object_get_created ( const void *  object)

Get when the sorcery object was created.

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

Definition at line 2386 of file sorcery.c.

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

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

2399{
2400 const struct ast_sorcery_object_details *details = object;
2401 struct ast_variable *field;
2402
2403 for (field = details->object->extended; field; field = field->next) {
2404 if (!strcmp(field->name + 1, name)) {
2405 return field->value;
2406 }
2407 }
2408
2409 return NULL;
2410}
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 2380 of file sorcery.c.

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

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_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(), 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_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_outgoing_request(), handle_slash(), has_mwi_subscription(), header_identify_match_check(), ident_handler(), internal_state_alloc(), ip_identify_apply(), ip_identify_match_check(), ip_identify_match_handler(), line_identify(), load_engine(), load_module(), log_caps(), mark_object_as_stale_in_cache(), matches_engine(), media_cache_handle_show_item(), media_cache_item_del_from_astdb(), media_cache_item_sync_to_astdb(), media_cache_prnt_summary(), memory_cache_stale_update_object(), msg_send(), mwi_contact_changed(), mwi_observe_delete(), mwi_post_event(), mwi_subscription_alloc(), mwi_validate_for_aor(), new_subscribe(), 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(), 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 2392 of file sorcery.c.

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

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

2441{
2442 const struct ast_sorcery_object_details *details = object;
2443
2444 return details->object->has_dynamic_contents;
2445}
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 2527 of file sorcery.c.

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

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(), handle_registrations(), sip_options_aor_alloc(), and sorcery_config_internal_load().

◆ ast_sorcery_object_id_hash()

int ast_sorcery_object_id_hash ( const void *  obj,
int  flags 
)

ao2 object hasher based on sorcery id.

Definition at line 2538 of file sorcery.c.

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

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

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

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

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

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

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

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

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

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

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

1696{
1697 const struct ast_sorcery_object_details *details = object;
1698 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1699 RAII_VAR(struct ast_variable *, transformed, NULL, ast_variables_destroy);
1700 struct ast_variable *field;
1701 int res = 0;
1702
1703 if (!object_type) {
1704 return -1;
1705 }
1706
1707 if (object_type->transform && (transformed = object_type->transform(objectset))) {
1708 field = transformed;
1709 } else {
1710 field = objectset;
1711 }
1712
1713 for (; field; field = field->next) {
1714 if ((res = aco_process_var(&object_type->type, details->object->id, field, object))) {
1715 break;
1716 }
1717 }
1718
1719 if (!res && object_type->apply) {
1720 res = object_type->apply(sorcery, object);
1721 }
1722
1723 return res;
1724}
int aco_process_var(struct aco_type *type, const char *cat, struct ast_variable *var, void *obj)
Parse a single ast_variable and apply it to an object.

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

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

◆ ast_sorcery_objectset_create2()

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

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

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

Definition at line 1574 of file sorcery.c.

1576{
1577 const struct ast_sorcery_object_details *details = object;
1578 RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1579 struct ao2_iterator i;
1580 struct ast_sorcery_object_field *object_field;
1581 struct ast_variable *head = NULL;
1582 struct ast_variable *tail = NULL;
1583
1584 if (!object_type) {
1585 return NULL;
1586 }
1587
1588 i = ao2_iterator_init(object_type->fields, 0);
1589
1590 for (; (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1591 struct ast_variable *tmp;
1592
1593 switch (flags) {
1595 if ((tmp = get_multiple_fields_as_var_list(object, object_field)) ||
1596 (tmp = get_single_field_as_var_list(object, object_field))) {
1597 break;
1598 }
1599 continue;
1601 if ((tmp = get_single_field_as_var_list(object, object_field)) ||
1602 (tmp = get_multiple_fields_as_var_list(object, object_field))) {
1603 break;
1604 }
1605 continue;
1607 if ((tmp = get_multiple_fields_as_var_list(object, object_field))) {
1608 break;
1609 }
1610 continue;
1612 if ((tmp = get_single_field_as_var_list(object, object_field))) {
1613 break;
1614 }
1615 continue;
1616 default:
1617 continue;
1618 }
1619
1620 tail = ast_variable_list_append_hint(&head, tail, tmp);
1621 }
1622
1624
1625 return head;
1626}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ast_variable * ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *new_var)
Appends a variable list to the end of another list.
Definition: main/config.c:732
static struct ast_variable * get_single_field_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition: sorcery.c:1541
static struct ast_variable * get_multiple_fields_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition: sorcery.c:1558
@ AST_HANDLER_PREFER_STRING
Try both handlers, string first.
Definition: sorcery.h:131
@ AST_HANDLER_PREFER_LIST
Try both handlers, list first.
Definition: sorcery.h:134
@ AST_HANDLER_ONLY_LIST
Use list handler only.
Definition: sorcery.h:140
@ AST_HANDLER_ONLY_STRING
Use string handler only.
Definition: sorcery.h:137
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

References ao2_cleanup, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_HANDLER_ONLY_LIST, AST_HANDLER_ONLY_STRING, AST_HANDLER_PREFER_LIST, AST_HANDLER_PREFER_STRING, ast_variable_list_append_hint(), get_multiple_fields_as_var_list(), get_single_field_as_var_list(), NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, sorcery, 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 1628 of file sorcery.c.

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

2455{
2458 int res;
2459
2460 if (!object_type || !callbacks) {
2461 return -1;
2462 }
2463
2464 if (!(observer = ao2_alloc(sizeof(*observer), NULL))) {
2465 return -1;
2466 }
2467
2468 observer->callbacks = callbacks;
2469 res = 0;
2470 if (!ao2_link(object_type->observers, observer)) {
2471 res = -1;
2472 }
2473 ao2_ref(observer, -1);
2474
2475 return res;
2476}
struct ast_sorcery_instance_observer observer
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(), 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 2486 of file sorcery.c.

2487{
2488 RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
2489 struct ast_sorcery_observer *cbs = (struct ast_sorcery_observer *) callbacks;/* Remove const for traversal. */
2490
2491 if (!sorcery) {
2492 return;
2493 }
2494 object_type = ao2_find(sorcery->types, type, OBJ_KEY);
2495 if (!object_type) {
2496 return;
2497 }
2498
2499 ao2_callback(object_type->observers, OBJ_NODATA | OBJ_UNLINK,
2501}
static int sorcery_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing an observer.
Definition: sorcery.c:2479
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(), 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 1536 of file sorcery.c.

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

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

1472{
1473 struct sorcery_load_details details = {
1474 .sorcery = sorcery,
1475 .reload = 1,
1476 };
1477
1478 NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1480
1482
1485
1486}

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_websocket_client_reload(), geoloc_config_reload(), load_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 1505 of file sorcery.c.

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

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(), load_module(), load_users(), and reload_module().

◆ ast_sorcery_retrieve_by_fields()

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

Retrieve an object or multiple objects using specific fields.

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

Example:

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

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

if (!var) { return; }

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

Definition at line 1960 of file sorcery.c.

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

1917{
1918 struct ast_sorcery_object_type *object_type;
1919 void *object = NULL;
1920 int i;
1921 unsigned int cached = 0;
1922
1923 if (ast_strlen_zero(id)) {
1924 return NULL;
1925 }
1926
1927 object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1928 if (!object_type) {
1929 return NULL;
1930 }
1931
1932 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1933 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1935 AST_VECTOR_GET(&object_type->wizards, i);
1936
1937 if (wizard->wizard->callbacks.retrieve_id &&
1938 !(object = wizard->wizard->callbacks.retrieve_id(sorcery, wizard->data, object_type->name, id))) {
1939 continue;
1940 }
1941
1942 cached = wizard->caching;
1943 break;
1944 }
1945
1946 if (!cached && object) {
1947 struct sorcery_details sdetails = {
1948 .sorcery = sorcery,
1949 .obj = object,
1950 };
1951
1952 AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, &sdetails, 0);
1953 }
1954 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1955
1956 ao2_ref(object_type, -1);
1957 return object;
1958}
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_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_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 735 of file sorcery.c.

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

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

2018{
2020 struct ao2_container *objects;
2021 int i;
2022
2023 if (!object_type) {
2024 return NULL;
2025 }
2026
2028 if (!objects) {
2029 return NULL;
2030 }
2031
2032 AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2033 for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2035 AST_VECTOR_GET(&object_type->wizards, i);
2036
2037 if (!wizard->wizard->callbacks.retrieve_regex) {
2038 continue;
2039 }
2040
2041 wizard->wizard->callbacks.retrieve_regex(sorcery, wizard->data, object_type->name, objects, regex);
2042
2043 if (wizard->caching && ao2_container_count(objects)) {
2044 break;
2045 }
2046 }
2047 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2048
2049 return objects;
2050}
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(), cli_aor_get_container(), cli_contact_get_container(), cli_endpoint_get_container(), cli_get_container(), geoloc_config_list_locations(), geoloc_config_list_profiles(), and geoloc_config_show_profiles().

◆ ast_sorcery_update()

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

Update an object.

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

Definition at line 2213 of file sorcery.c.

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

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

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

◆ ast_sorcery_wizard_observer_add()

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

Add an observer to a sorcery wizard.

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

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

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

Definition at line 606 of file sorcery.c.

608{
609 RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
610 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
612
613 if (wizard) {
614 struct sorcery_wizard_observer *cb;
615
616 cb = ao2_alloc(sizeof(*cb), NULL);
617 if (!cb) {
618 return -1;
619 }
620
621 cb->callbacks = callbacks;
622 ao2_link(wizard->observers, cb);
623 ao2_ref(cb, -1);
624
625 return 0;
626 }
627
628 return -1;
629}
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 631 of file sorcery.c.

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

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

538{
539 struct ast_sorcery_internal_wizard *wizard =
540 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL;
541
542 if (wizard) {
543 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_unregistering, wizard->callbacks.name, &wizard->callbacks);
544 ao2_unlink(wizards, wizard);
545 ao2_ref(wizard, -1);
546 ast_verb(5, "Sorcery unregistered wizard '%s'\n", interface->name);
547 return 0;
548 } else {
549 return -1;
550 }
551}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578

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

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

◆ AST_VECTOR_RW()

AST_VECTOR_RW ( ast_sorcery_object_wizards  ,
struct ast_sorcery_object_wizard  
)

Interface for a sorcery object type wizards.

◆ bool_handler_fn()

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

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

1559{
1560 struct ast_variable *tmp = NULL;
1561
1562 if (!object_field->multiple_handler) {
1563 return NULL;
1564 }
1565
1566 if (object_field->multiple_handler(object, &tmp)) {
1568 tmp = NULL;
1569 }
1570
1571 return tmp;
1572}
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 1541 of file sorcery.c.

1542{
1543 struct ast_variable *tmp = NULL;
1544 char *buf = NULL;
1545
1546 if (!object_field->handler) {
1547 return NULL;
1548 }
1549
1550 if (!(object_field->handler(object, object_field->args, &buf))) {
1551 tmp = ast_variable_new(object_field->name, S_OR(buf, ""), "");
1552 }
1553 ast_free(buf);
1554
1555 return tmp;
1556}
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 2563 of file sorcery.c.

2564{
2565 struct ast_sorcery_object_field *object_field = obj;
2566 char *name = arg;
2567 int rc = 0;
2568
2569 if (object_field->name_regex
2570 && !regexec(object_field->name_regex, name, 0, NULL, 0)) {
2571 rc = CMP_MATCH;
2572 }
2573
2574 return rc;
2575}
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, 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 1902 of file sorcery.c.

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

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{
408 wizards = NULL;
410 observers = NULL;
412 instances = NULL;
413}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void ast_threadpool_shutdown(struct ast_threadpool *pool)
Shut down a threadpool and destroy it.
Definition: threadpool.c:966

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

Referenced by ast_sorcery_init().

◆ sorcery_destructor()

static void sorcery_destructor ( void *  obj)
static

Destructor called when sorcery structure is destroyed.

Definition at line 644 of file sorcery.c.

645{
646 struct ast_sorcery *sorcery = obj;
647
648 if (sorcery->observers) {
650 }
653}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

764{
765#define INITIAL_WIZARD_VECTOR_SIZE 5
766 struct ast_sorcery_object_type *object_type;
767 char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
768
769 if (!(object_type = ao2_alloc(sizeof(*object_type), sorcery_object_type_destructor))) {
770 return NULL;
771 }
772
773 /* Order matters for object wizards */
774 if (AST_VECTOR_RW_INIT(&object_type->wizards, INITIAL_WIZARD_VECTOR_SIZE) != 0) {
775 ao2_ref(object_type, -1);
776 return NULL;
777 }
778
780 OBJECT_FIELD_BUCKETS, ast_sorcery_object_field_hash_fn, NULL, ast_sorcery_object_field_cmp_fn);
781 if (!object_type->fields) {
782 ao2_ref(object_type, -1);
783 return NULL;
784 }
785
787 NULL, NULL);
788 if (!object_type->observers) {
789 ao2_ref(object_type, -1);
790 return NULL;
791 }
792
793 object_type->info = ast_calloc(1,
794 sizeof(*object_type->info) + 2 * sizeof(object_type->info->files[0]));
795 if (!object_type->info) {
796 ao2_ref(object_type, -1);
797 return NULL;
798 }
799
800 object_type->file = ast_calloc(1,
801 sizeof(*object_type->file) + 2 * sizeof(object_type->file->types[0]));
802 if (!object_type->file) {
803 ao2_ref(object_type, -1);
804 return NULL;
805 }
806
807 /* Create name with seq number appended. */
808 ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "sorcery/%s", type);
809
810 if (!(object_type->serializer = ast_threadpool_serializer(tps_name, threadpool))) {
811 ao2_ref(object_type, -1);
812 return NULL;
813 }
814
815 object_type->info->files[0] = object_type->file;
816 object_type->info->files[1] = NULL;
817 object_type->info->module = module;
818
819 ast_copy_string(object_type->name, type, sizeof(object_type->name));
820
821 return object_type;
822}
#define INITIAL_WIZARD_VECTOR_SIZE
static void sorcery_object_type_destructor(void *obj)
Destructor function for object types.
Definition: sorcery.c:741
#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[]
const char * module
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
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:61
struct ast_taskprocessor * ast_threadpool_serializer(const char *name, struct ast_threadpool *pool)
Serialized execution of tasks within a ast_threadpool.
Definition: threadpool.c:1428
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Definition: vector.h: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_taskprocessor_build_name(), AST_TASKPROCESSOR_MAX_NAME, ast_threadpool_serializer(), AST_VECTOR_RW_INIT, ast_sorcery_object_type::fields, ast_sorcery_object_type::file, aco_info::files, ast_sorcery_object_type::info, INITIAL_WIZARD_VECTOR_SIZE, aco_info::module, ast_sorcery_object_type::name, NULL, OBJECT_FIELD_BUCKETS, ast_sorcery_object_type::observers, ast_sorcery_object_type::serializer, sorcery_object_type_destructor(), threadpool, type, aco_file::types, and ast_sorcery_object_type::wizards.

Referenced by __ast_sorcery_object_type_insert_wizard().

◆ sorcery_object_type_destructor()

static void sorcery_object_type_destructor ( void *  obj)
static

Destructor function for object types.

Definition at line 741 of file sorcery.c.

742{
743 struct ast_sorcery_object_type *object_type = obj;
744
745 AST_VECTOR_RW_WRLOCK(&object_type->wizards);
747 AST_VECTOR_RW_UNLOCK(&object_type->wizards);
748 AST_VECTOR_RW_FREE(&object_type->wizards);
749 ao2_cleanup(object_type->fields);
750 ao2_cleanup(object_type->observers);
751
752 if (object_type->info) {
753 aco_info_destroy(object_type->info);
754 ast_free(object_type->info);
755 }
756
757 ast_free(object_type->file);
758
760}
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 825 of file sorcery.c.

826{
827 struct ast_sorcery_object_wizard *object_wizard = obj;
828
829 if (object_wizard->data && object_wizard->wizard->callbacks.close) {
830 object_wizard->wizard->callbacks.close(object_wizard->data);
831 }
832
833 if (object_wizard->wizard) {
834 ast_module_unref(object_wizard->wizard->callbacks.module);
835 }
836
837 ao2_cleanup(object_wizard->wizard);
838}
void(* close)(void *data)
Callback for closing a wizard.
Definition: sorcery.h:322

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

Referenced by __ast_sorcery_object_type_insert_wizard().

◆ sorcery_observer_invocation_alloc()

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

Allocator function for observer invocation.

Definition at line 1355 of file sorcery.c.

1356{
1357 struct sorcery_observer_invocation *invocation;
1358
1359 invocation = ao2_alloc_options(sizeof(*invocation),
1361 if (!invocation) {
1362 return NULL;
1363 }
1364
1365 ao2_ref(object_type, +1);
1366 invocation->object_type = object_type;
1367
1368 if (object) {
1369 ao2_ref(object, +1);
1370 invocation->object = object;
1371 }
1372
1373 return invocation;
1374}
static void sorcery_observer_invocation_destroy(void *obj)
Destructor for observer invocation.
Definition: sorcery.c:1346
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 1346 of file sorcery.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2089{
2090 if (!object_wizard->wizard->callbacks.create || object_wizard->read_only) {
2091 ast_debug(5, "Sorcery wizard '%s' does not support creation\n", object_wizard->wizard->callbacks.name);
2092 return 0;
2093 }
2094
2095 if (object_wizard->wizard->callbacks.create(details->sorcery, object_wizard->data, details->obj)) {
2096 return 0;
2097 }
2098
2099 return CMP_MATCH;
2100}
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 2287 of file sorcery.c.

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

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

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

References args, ast_strdup, and buf.

Referenced by sorcery_field_default_handler().

◆ uint_handler_fn()

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

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

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

◆ threadpool

struct ast_threadpool* threadpool
static

◆ wizards

struct ao2_container* wizards
static