64#include <uriparser/Uri.h>
79#define SCHEME_BUCKETS 53
82#define METADATA_BUCKETS 53
117 UriParserStateA
state;
129 if (uriParseUriA(&
state,
id) != URI_SUCCESS ||
130 !uri.scheme.first || !uri.scheme.afterLast) {
131 uriFreeUriMembersA(&uri);
135 len = (uri.scheme.afterLast - uri.scheme.first) + 1;
139 uriFreeUriMembersA(&uri);
142 if (!(
tmp = strchr(uri_scheme,
':'))) {
191 return file->scheme_impl->file->create(
sorcery, data,
object);
199 UriParserStateA
state;
211 if (uriParseUriA(&
state,
id) != URI_SUCCESS ||
212 !uri.scheme.first || !uri.scheme.afterLast) {
213 uriFreeUriMembersA(&uri);
217 len = (uri.scheme.afterLast - uri.scheme.first) + 1;
221 uriFreeUriMembersA(&uri);
224 if (!(
tmp = strchr(uri_scheme,
':'))) {
244 return file->scheme_impl->file->update(
sorcery, data,
object);
252 return file->scheme_impl->file->delete(
sorcery, data,
object);
260 if (!
file->scheme_impl->file->is_stale) {
264 return file->scheme_impl->file->is_stale(
sorcery, data,
object);
269 .
name =
"bucket_file",
286 (!bucket->
create && !create_cb)) {
300 strcpy(scheme->name,
name);
301 scheme->bucket = bucket;
303 scheme->create = create_cb;
304 scheme->destroy = destroy_cb;
318 int name_len = strlen(
name) + 1, value_len = strlen(
value) + 1;
326 dst = metadata->
data;
384 const char *str_left = obj_left;
385 const char *str_right = obj_right;
392 cmp = strcmp(str_left, str_right);
395 cmp = strncmp(str_left, str_right, strlen(str_right));
417 if (!bucket->buckets) {
423 if (!bucket->files) {
434 UriParserStateA
state;
449 state.uri = &full_uri;
450 if (uriParseUriA(&
state, uri) != URI_SUCCESS ||
451 !full_uri.scheme.first || !full_uri.scheme.afterLast ||
452 !full_uri.pathTail) {
453 uriFreeUriMembersA(&full_uri);
457 len = (full_uri.scheme.afterLast - full_uri.scheme.first) + 1;
461 uriFreeUriMembersA(&full_uri);
464 if (!(
tmp = strchr(uri_scheme,
':'))) {
631 if (
file->scheme_impl->destroy) {
654 ast_bucket_metadata_hash_fn,
NULL, ast_bucket_metadata_cmp_fn);
655 if (!
file->metadata) {
666 UriParserStateA
state;
681 state.uri = &full_uri;
682 if (uriParseUriA(&
state, uri) != URI_SUCCESS ||
683 !full_uri.scheme.first || !full_uri.scheme.afterLast ||
684 !full_uri.pathTail) {
685 uriFreeUriMembersA(&full_uri);
689 len = (full_uri.scheme.afterLast - full_uri.scheme.first) + 1;
693 uriFreeUriMembersA(&full_uri);
696 if (!(
tmp = strchr(uri_scheme,
':'))) {
736 if ((ifd = open(infile, O_RDONLY)) < 0) {
740 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT,
AST_FILE_MODE)) < 0) {
745 while ( (
len = read(ifd,
buf,
sizeof(
buf)) ) ) {
752 res = write(ofd,
buf,
len);
781 strcpy(dst_file->
path, src_file->
path);
801 if (!
copy->metadata ||
905 fd = mkstemp(
file->path);
949 struct timeval *field = (
struct timeval *)(obj +
args[0]);
950 return (
ast_asprintf(
buf,
"%lu.%06lu", (
unsigned long)field->tv_sec, (
unsigned long)field->tv_usec) < 0) ? -1 : 0;
959 ast_bucket_scheme_hash_fn,
NULL, ast_bucket_scheme_cmp_fn);
966 ast_log(
LOG_ERROR,
"Failed to register sorcery wizard for 'bucket' intermediary\n");
971 ast_log(
LOG_ERROR,
"Failed to register sorcery wizard for 'file' intermediary\n");
976 ast_log(
LOG_ERROR,
"Failed to create sorcery instance for Bucket support\n");
981 ast_log(
LOG_ERROR,
"Failed to apply intermediary for 'bucket' object type in Bucket sorcery\n");
986 ast_log(
LOG_ERROR,
"Failed to register 'bucket' object type in Bucket sorcery\n");
996 ast_log(
LOG_ERROR,
"Failed to apply intermediary for 'file' object type in Bucket sorcery\n");
1001 ast_log(
LOG_ERROR,
"Failed to register 'file' object type in Bucket sorcery\n");
static int copy(char *infile, char *outfile)
Utility function to copy a file.
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_RWLOCK
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
#define AO2_STRING_FIELD_CMP_FN(stype, field)
Creates a compare function for a structure string field.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
#define AO2_STRING_FIELD_HASH_FN(stype, field)
Creates a hash function for a structure string field.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
#define ao2_alloc(data_size, destructor_fn)
#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.
#define ao2_container_clone(orig, flags)
Create a clone/copy of the given container.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
static void * bucket_wizard_retrieve(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback function for retrieving a bucket.
struct ast_bucket * ast_bucket_alloc(const char *uri)
Allocate a new bucket.
static int bucket_file_wizard_create(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for creating a bucket file.
struct ast_bucket_file * ast_bucket_file_clone(struct ast_bucket_file *file)
Clone a bucket file.
#define METADATA_BUCKETS
Number of buckets for the container of metadata in a file.
static void bucket_file_destroy(void *obj)
Hashing function for file metadata.
int ast_bucket_file_metadata_set(struct ast_bucket_file *file, const char *name, const char *value)
Set a metadata attribute on a file to a specific value.
struct ast_bucket_file * ast_bucket_file_alloc(const char *uri)
Allocate a new bucket file.
static void bucket_cleanup(void)
Hashing function for scheme container.
static int bucket_wizard_is_stale(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for determining if a bucket is stale.
void ast_bucket_file_observer_remove(const struct ast_sorcery_observer *callbacks)
Remove an observer from bucket file creation and deletion.
static int bucket_file_wizard_is_stale(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for determining if a bucket is stale.
static int bucket_wizard_delete(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for deleting a bucket.
static void * bucket_file_alloc(const char *name)
Allocator for bucket files.
static struct ast_sorcery_wizard bucket_file_wizard
Intermediary file wizard.
static struct ast_sorcery * bucket_sorcery
Sorcery instance for all bucket operations.
int ast_bucket_file_temporary_create(struct ast_bucket_file *file)
Common file snapshot creation callback for creating a temporary file.
static struct ast_sorcery_wizard bucket_wizard
Intermediary bucket wizard.
void ast_bucket_file_metadata_callback(struct ast_bucket_file *file, ao2_callback_fn cb, void *arg)
Execute a callback function on the metadata associated with a file.
int ast_bucket_create(struct ast_bucket *bucket)
Create a new bucket in backend storage.
static int bucket_file_wizard_update(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for updating a bucket file.
int ast_bucket_file_create(struct ast_bucket_file *file)
Create a new bucket file in backend storage.
static int timeval_str2struct(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for translating from a string timeval to actual structure.
static void * bucket_file_wizard_retrieve(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback function for retrieving a bucket file.
static int timeval_struct2str(const void *obj, const intptr_t *args, char **buf)
Custom handler for translating from an actual structure timeval to string.
static int bucket_copy_handler(const void *src, void *dst)
static struct ao2_container * schemes
Container of registered schemes.
int ast_bucket_file_metadata_unset(struct ast_bucket_file *file, const char *name)
Unset a specific metadata attribute on a file.
int ast_bucket_file_update(struct ast_bucket_file *file)
Update an existing bucket file in backend storage.
struct ast_bucket_metadata * ast_bucket_file_metadata_get(struct ast_bucket_file *file, const char *name)
Retrieve a metadata attribute from a file.
int ast_bucket_file_observer_add(const struct ast_sorcery_observer *callbacks)
Add an observer for bucket file creation and deletion operations.
struct ast_bucket_file * ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri)
Copy a bucket file to a new URI.
int ast_bucket_is_stale(struct ast_bucket *bucket)
Retrieve whether or not the backing datastore views the bucket as stale.
static void * bucket_alloc(const char *name)
Allocator for buckets.
struct ast_bucket_file * ast_bucket_file_retrieve(const char *uri)
Retrieve a bucket file.
void ast_bucket_observer_remove(const struct ast_sorcery_observer *callbacks)
Remove an observer from bucket creation and deletion.
static int bucket_file_copy_handler(const void *src, void *dst)
int __ast_bucket_scheme_register(const char *name, struct ast_sorcery_wizard *bucket, struct ast_sorcery_wizard *file, bucket_file_create_cb create_cb, bucket_file_destroy_cb destroy_cb, struct ast_module *module)
Register support for a specific scheme.
#define SCHEME_BUCKETS
Number of buckets for the container of schemes.
static void bucket_destroy(void *obj)
Destructor for buckets.
struct ast_bucket * ast_bucket_retrieve(const char *uri)
Retrieve information about a bucket.
int ast_bucket_file_delete(struct ast_bucket_file *file)
Delete a bucket file from backend storage.
struct ast_json * ast_bucket_json(const struct ast_bucket *bucket)
Get a JSON representation of a bucket.
static struct ast_bucket_metadata * bucket_metadata_alloc(const char *name, const char *value)
Allocator for metadata attributes.
struct ast_json * ast_bucket_file_json(const struct ast_bucket_file *file)
Get a JSON representation of a bucket file.
struct ast_bucket * ast_bucket_clone(struct ast_bucket *bucket)
Clone a bucket.
void ast_bucket_file_temporary_destroy(struct ast_bucket_file *file)
Common file snapshot destruction callback for deleting a temporary file.
int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks)
Add an observer for bucket creation and deletion operations.
static int bucket_file_wizard_delete(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for deleting a bucket file.
static int bucket_copy(const char *infile, const char *outfile)
Copy a file, shamelessly taken from file.c.
static int bucket_wizard_create(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for creating a bucket.
int ast_bucket_init(void)
Initialize bucket support.
static int bucket_rbtree_str_sort_cmp(const void *obj_left, const void *obj_right, int flags)
Sorting function for red black tree string container.
int ast_bucket_file_is_stale(struct ast_bucket_file *file)
Retrieve whether or not the backing datastore views the bucket file as stale.
int ast_bucket_delete(struct ast_bucket *bucket)
Delete a bucket from backend storage.
void(* bucket_file_destroy_cb)(struct ast_bucket_file *file)
A callback function invoked when destroying a file snapshot.
int(* bucket_file_create_cb)(struct ast_bucket_file *file)
A callback function invoked when creating a file snapshot.
Configuration option-handling.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
intptr_t aco_option_get_argument(const struct aco_option *option, unsigned int position)
Get the offset position for an argument within a config option.
Generic File Format Support. Should be included by clients of the file handling routines....
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_verb(level,...)
Asterisk JSON abstraction layer.
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
#define SCOPED_AO2WRLOCK(varname, obj)
scoped lock specialization for ao2 write locks.
#define SCOPED_AO2RDLOCK(varname, obj)
scoped lock specialization for ao2 read locks.
Asterisk module definitions.
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_CACHE_DIR
static struct ast_sorcery * sorcery
Sorcery Data Access Layer API.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
void ast_sorcery_object_set_copy_handler(struct ast_sorcery *sorcery, const char *type, sorcery_copy_handler copy)
Set the copy handler for an object type.
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
int __ast_sorcery_wizard_register(const struct ast_sorcery_wizard *interface, struct ast_module *module)
Register a sorcery wizard.
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.
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
#define ast_sorcery_apply_default(sorcery, type, name, data)
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.
#define ast_sorcery_open()
Open a new sorcery structure.
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.
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
void * ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object)
Create a copy of an object.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
String manipulation functions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed)
Parse a time (float) string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Bucket file structure, contains reference to file and information about it.
struct timeval modified
When this file was last modified.
struct timeval created
When this file was created.
const ast_string_field scheme
struct ao2_container * metadata
Container of metadata attributes about file.
char path[PATH_MAX]
Local path to this file.
struct ast_bucket_scheme * scheme_impl
Scheme implementation in use.
Structure for available schemes.
struct ast_sorcery_wizard * file
Wizard for files.
bucket_file_create_cb create
Pointer to the file snapshot creation callback.
bucket_file_destroy_cb destroy
Pointer to the file snapshot destruction callback.
struct ast_sorcery_wizard * bucket
Wizard for buckets.
char name[0]
Name of the scheme.
Bucket structure, contains other buckets and files.
struct ao2_container * buckets
Container of string URIs of buckets within this bucket.
struct timeval modified
When this bucket was last modified.
struct timeval created
When this bucket was created.
struct ao2_container * files
Container of string URIs of files within this bucket.
const ast_string_field scheme
struct ast_bucket_scheme * scheme_impl
Scheme implementation in use.
Abstract JSON element (object, array, string, int, ...).
Interface for a sorcery object type observer.
Interface for a sorcery wizard.
struct ast_module * module
Pointer to the Asterisk module this wizard is implemented by.
const char * name
Name of the wizard.
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
int(* is_stale)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for whether or not the wizard believes the object is stale.
Full structure for sorcery.
Structure for variables, used for configurations and for channel variables.
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.