64 #include <uriparser/Uri.h> 79 #define SCHEME_BUCKETS 53 82 #define METADATA_BUCKETS 53 116 #ifdef HAVE_URIPARSER 117 UriParserStateA
state;
127 #ifdef HAVE_URIPARSER 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,
':'))) {
154 return scheme->bucket->retrieve_id(sorcery, data, type,
id);
198 #ifdef HAVE_URIPARSER 199 UriParserStateA
state;
209 #ifdef HAVE_URIPARSER 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,
':'))) {
236 return scheme->file->retrieve_id(sorcery, data, type,
id);
269 .
name =
"bucket_file",
286 (!bucket->
create && !create_cb)) {
295 scheme =
ao2_alloc(
sizeof(*scheme) + strlen(name) + 1,
NULL);
300 strcpy(scheme->name, name);
303 scheme->
create = create_cb;
304 scheme->destroy = destroy_cb;
308 ast_verb(2,
"Registered bucket scheme '%s'\n", name);
318 int name_len = strlen(name) + 1, value_len = strlen(value) + 1;
326 dst = metadata->
data;
327 metadata->
name = strcpy(dst, name);
329 metadata->
value = strcpy(dst, value);
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));
433 #ifdef HAVE_URIPARSER 434 UriParserStateA
state;
448 #ifdef HAVE_URIPARSER 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,
':'))) {
654 ast_bucket_metadata_hash_fn,
NULL, ast_bucket_metadata_cmp_fn);
665 #ifdef HAVE_URIPARSER 666 UriParserStateA
state;
680 #ifdef HAVE_URIPARSER 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);
931 bucket_sorcery =
NULL;
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");
enum sip_cc_notify_state state
void ast_bucket_file_temporary_destroy(struct ast_bucket_file *file)
Common file snapshot destruction callback for deleting a temporary file.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
int ast_bucket_file_temporary_create(struct ast_bucket_file *file)
Common file snapshot creation callback for creating a temporary file.
void(* bucket_file_destroy_cb)(struct ast_bucket_file *file)
A callback function invoked when destroying a file snapshot.
const char * ast_config_AST_CACHE_DIR
Asterisk main include file. File version handling, generic pbx functions.
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
struct ast_sorcery_wizard * bucket
Wizard for buckets.
int ast_bucket_init(void)
Initialize bucket support.
#define SCHEME_BUCKETS
Number of buckets for the container of schemes.
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_bucket_file_create(struct ast_bucket_file *file)
Create a new bucket file in backend storage.
String manipulation functions.
bucket_file_destroy_cb destroy
Pointer to the file snapshot destruction callback.
#define AO2_STRING_FIELD_HASH_FN(stype, field)
Creates a hash function for a structure string field.
struct ao2_container * files
Container of string URIs of files within this bucket.
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.
int __ast_sorcery_wizard_register(const struct ast_sorcery_wizard *interface, struct ast_module *module)
Register a sorcery wizard.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
#define METADATA_BUCKETS
Number of buckets for the container of metadata in a file.
#define ao2_container_clone(orig, flags)
static void * bucket_wizard_retrieve(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback function for retrieving a bucket.
Bucket structure, contains other buckets and files.
#define ao2_callback(c, flags, cb_fn, arg)
int(* bucket_file_create_cb)(struct ast_bucket_file *file)
A callback function invoked when creating a file snapshot.
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.
Structure for variables, used for configurations and for channel variables.
void ast_bucket_observer_remove(const struct ast_sorcery_observer *callbacks)
Remove an observer from bucket creation and deletion.
int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks)
Add an observer for bucket creation and deletion operations.
struct ast_bucket_scheme * scheme_impl
Scheme implementation in use.
Assume that the ao2_container is already locked.
Full structure for sorcery.
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.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static struct ast_sorcery_wizard bucket_wizard
Intermediary bucket wizard.
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define ao2_link_flags(container, obj, flags)
static int bucket_file_wizard_delete(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for deleting a bucket file.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
struct ast_module * module
Pointer to the Asterisk module this wizard is implemented by.
void ast_bucket_file_observer_remove(const struct ast_sorcery_observer *callbacks)
Remove an observer from bucket file creation and deletion.
const char * name
Name of the wizard.
int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed)
get values from config variables.
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(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
static int bucket_copy(const char *infile, const char *outfile)
Copy a file, shamelessly taken from file.c.
struct timeval modified
When this file was last modified.
struct ast_bucket_file * ast_bucket_file_retrieve(const char *uri)
Retrieve a bucket file.
static void bucket_cleanup(void)
Hashing function for scheme container.
static int bucket_file_copy_handler(const void *src, void *dst)
#define ast_verb(level,...)
int ast_bucket_file_metadata_unset(struct ast_bucket_file *file, const char *name)
Unset a specific metadata attribute on a file.
#define SCOPED_AO2WRLOCK(varname, obj)
scoped lock specialization for ao2 write locks.
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_strlen_zero(foo)
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
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.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
struct timeval created
When this bucket was created.
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
static struct ast_sorcery * bucket_sorcery
Sorcery instance for all bucket operations.
struct timeval created
When this file was created.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
#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.
struct ao2_container * buckets
Container of string URIs of buckets within this bucket.
static struct ast_bucket_metadata * bucket_metadata_alloc(const char *name, const char *value)
Allocator for metadata attributes.
static void * bucket_file_alloc(const char *name)
Allocator for bucket files.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
struct ast_sorcery_wizard * file
Wizard for files.
Asterisk JSON abstraction layer.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Asterisk file paths, configured in asterisk.conf.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
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.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
static void bucket_destroy(void *obj)
Destructor for buckets.
#define ao2_ref(o, delta)
#define SCOPED_AO2RDLOCK(varname, obj)
scoped lock specialization for ao2 read locks.
#define ast_strdupa(s)
duplicate a string in memory from the stack
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
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_metadata * ast_bucket_file_metadata_get(struct ast_bucket_file *file, const char *name)
Retrieve a metadata attribute from a file.
struct ast_bucket * ast_bucket_alloc(const char *uri)
Allocate a new bucket.
Bucket file structure, contains reference to file and information about it.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
int ast_bucket_create(struct ast_bucket *bucket)
Create a new bucket in backend storage.
int ast_bucket_file_delete(struct ast_bucket_file *file)
Delete a bucket file from backend storage.
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
struct ast_json * ast_bucket_json(const struct ast_bucket *bucket)
Get a JSON representation of a bucket.
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.
bucket_file_create_cb create
Pointer to the file snapshot creation callback.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Configuration option-handling.
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
struct ast_bucket * ast_bucket_retrieve(const char *uri)
Retrieve information about a bucket.
static struct ast_sorcery_wizard bucket_file_wizard
Intermediary file wizard.
int ast_bucket_is_stale(struct ast_bucket *bucket)
Retrieve whether or not the backing datastore views the bucket as stale.
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
struct ast_bucket_file * ast_bucket_file_clone(struct ast_bucket_file *file)
Clone a bucket file.
Interface for a sorcery object type observer.
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_bucket * ast_bucket_clone(struct ast_bucket *bucket)
Clone a bucket.
#define ast_sorcery_apply_default(sorcery, type, name, data)
static int timeval_struct2str(const void *obj, const intptr_t *args, char **buf)
Custom handler for translating from an actual structure timeval to string.
char name[0]
Name of the scheme.
#define ao2_iterator_next(iter)
#define ao2_alloc(data_size, destructor_fn)
const ast_string_field scheme
Name of scheme in use.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
struct ao2_container * metadata
Container of metadata attributes about file.
struct ast_bucket_scheme * scheme_impl
Scheme implementation in use.
static int bucket_file_wizard_update(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for updating a bucket file.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define ao2_find(container, arg, flags)
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.
static void bucket_file_destroy(void *obj)
Hashing function for file metadata.
Support for logging to various files, console and syslog Configuration in file logger.conf.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
int ast_bucket_file_observer_add(const struct ast_sorcery_observer *callbacks)
Add an observer for bucket file creation and deletion operations.
Interface for a sorcery wizard.
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
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.
#define AO2_STRING_FIELD_CMP_FN(stype, field)
Creates a compare function for a structure string field.
static struct ast_sorcery * sorcery
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
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 ast_bucket_delete(struct ast_bucket *bucket)
Delete a bucket from backend storage.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
void * ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object)
Create a copy of an object.
static void * bucket_alloc(const char *name)
Allocator for buckets.
static int bucket_copy_handler(const void *src, void *dst)
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.
#define ast_sorcery_open()
Structure for available schemes.
Abstract JSON element (object, array, string, int, ...).
Type for default option handler for stringfields.
static int bucket_wizard_is_stale(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for determining if a bucket is stale.
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.
const ast_string_field scheme
Name of scheme in use.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
int(* is_stale)(const struct ast_sorcery *sorcery, void *data, void *object)
Reject objects with duplicate keys in container.
struct timeval modified
When this bucket was last modified.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
static struct ao2_container * schemes
Container of registered schemes.
Asterisk module definitions.
int ast_bucket_file_update(struct ast_bucket_file *file)
Update an existing bucket file in backend storage.
static int bucket_wizard_create(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for creating a bucket.
struct ast_bucket_file * ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri)
Copy a bucket file to a new URI.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
char path[PATH_MAX]
Local path to this file.
Sorcery Data Access Layer API.
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
struct ast_bucket_file * ast_bucket_file_alloc(const char *uri)
Allocate a new bucket file.
static int bucket_wizard_delete(const struct ast_sorcery *sorcery, void *data, void *object)
Callback function for deleting a bucket.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
struct ast_json * ast_bucket_file_json(const struct ast_bucket_file *file)
Get a JSON representation of a bucket file.
int ast_bucket_file_is_stale(struct ast_bucket_file *file)
Retrieve whether or not the backing datastore views the bucket file as stale.
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.
#define ao2_link(container, obj)