bucket.c File Reference

Bucket File API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/sorcery.h"
#include "asterisk/bucket.h"
#include "asterisk/config_options.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/json.h"
#include "asterisk/file.h"
#include "asterisk/module.h"

Include dependency graph for bucket.c:

Go to the source code of this file.

Data Structures

struct  ast_bucket_scheme
 Structure for available schemes. More...

Defines

#define METADATA_BUCKETS   53
 Number of buckets for the container of metadata in a file.
#define SCHEME_BUCKETS   53
 Number of buckets for the container of schemes.

Functions

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.
struct ast_bucketast_bucket_alloc (const char *uri)
 Allocate a new bucket.
int ast_bucket_create (struct ast_bucket *bucket)
 Create a new bucket in backend storage.
int ast_bucket_delete (struct ast_bucket *bucket)
 Delete a bucket from backend storage.
struct ast_bucket_fileast_bucket_file_alloc (const char *uri)
 Allocate a new bucket file.
struct ast_bucket_fileast_bucket_file_copy (struct ast_bucket_file *file, const char *uri)
 Copy a bucket file to a new URI.
int ast_bucket_file_create (struct ast_bucket_file *file)
 Create a new bucket file in backend storage.
int ast_bucket_file_delete (struct ast_bucket_file *file)
 Delete a bucket file from backend storage.
struct ast_jsonast_bucket_file_json (const struct ast_bucket_file *file)
 Get a JSON representation of a bucket file.
struct ast_bucket_metadataast_bucket_file_metadata_get (struct ast_bucket_file *file, const char *name)
 Retrieve a metadata attribute from a file.
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.
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_observer_add (const struct ast_sorcery_observer *callbacks)
 Add an observer for bucket file creation and deletion operations.
void ast_bucket_file_observer_remove (const struct ast_sorcery_observer *callbacks)
 Remove an observer from bucket file creation and deletion.
struct ast_bucket_fileast_bucket_file_retrieve (const char *uri)
 Retrieve a bucket file.
int ast_bucket_file_temporary_create (struct ast_bucket_file *file)
 Common file snapshot creation callback for creating a temporary file.
void ast_bucket_file_temporary_destroy (struct ast_bucket_file *file)
 Common file snapshot destruction callback for deleting a temporary file.
int ast_bucket_file_update (struct ast_bucket_file *file)
 Update an existing bucket file in backend storage.
int ast_bucket_init (void)
 Initialize bucket support.
struct ast_jsonast_bucket_json (const struct ast_bucket *bucket)
 Get a JSON representation of a bucket.
int ast_bucket_observer_add (const struct ast_sorcery_observer *callbacks)
 Add an observer for bucket creation and deletion operations.
void ast_bucket_observer_remove (const struct ast_sorcery_observer *callbacks)
 Remove an observer from bucket creation and deletion.
struct ast_bucketast_bucket_retrieve (const char *uri)
 Retrieve information about a bucket.
static void * bucket_alloc (const char *name)
 Allocator for buckets.
static void bucket_cleanup (void)
 Cleanup function for graceful shutdowns.
static int bucket_copy (const char *infile, const char *outfile)
 Copy a file, shamelessly taken from file.c.
static void bucket_destroy (void *obj)
 Destructor for buckets.
static void * bucket_file_alloc (const char *name)
 Allocator for bucket files.
static void bucket_file_destroy (void *obj)
 Destructor for bucket files.
static int bucket_file_metadata_cmp (void *obj, void *arg, int flags)
 Comparison function for file metadata.
static int bucket_file_metadata_hash (const void *obj, const int flags)
 Hashing function for file metadata.
static int bucket_file_wizard_create (const struct ast_sorcery *sorcery, void *data, void *object)
 Callback function for creating a bucket file.
static int bucket_file_wizard_delete (const struct ast_sorcery *sorcery, void *data, void *object)
 Callback function for deleting a bucket file.
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 bucket_file_wizard_update (const struct ast_sorcery *sorcery, void *data, void *object)
 Callback function for updating a bucket file.
static struct ast_bucket_metadatabucket_metadata_alloc (const char *name, const char *value)
 Allocator for metadata attributes.
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.
static int bucket_scheme_cmp (void *obj, void *arg, int flags)
 Comparison function for scheme container.
static int bucket_scheme_hash (const void *obj, const int flags)
 Hashing function for scheme container.
static int bucket_wizard_create (const struct ast_sorcery *sorcery, void *data, void *object)
 Callback function for creating a bucket.
static int bucket_wizard_delete (const struct ast_sorcery *sorcery, void *data, void *object)
 Callback function for deleting a bucket.
static void * bucket_wizard_retrieve (const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
 Callback function for retrieving a bucket.
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 int timeval_struct2str (const void *obj, const intptr_t *args, char **buf)
 Custom handler for translating from an actual structure timeval to string.

Variables

static struct ast_sorcery_wizard bucket_file_wizard
 Intermediary file wizard.
static struct ast_sorcerybucket_sorcery
 Sorcery instance for all bucket operations.
static struct ast_sorcery_wizard bucket_wizard
 Intermediary bucket wizard.
static struct ao2_containerschemes
 Container of registered schemes.


Detailed Description

Bucket File API.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file bucket.c.


Define Documentation

#define METADATA_BUCKETS   53

Number of buckets for the container of metadata in a file.

Definition at line 83 of file bucket.c.

Referenced by bucket_file_alloc().

#define SCHEME_BUCKETS   53

Number of buckets for the container of schemes.

Definition at line 80 of file bucket.c.

Referenced by ast_bucket_init().


Function Documentation

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.

Parameters:
name Name of the scheme, used to find based on scheme in URIs
bucket Sorcery wizard used for buckets
file Sorcery wizard used for files
create_cb Required file snapshot creation callback
destroy_cb Optional file snapshot destruction callback
module The module which implements this scheme
Return values:
0 success
-1 failure
Note:
Once a scheme has been registered it can not be unregistered

Definition at line 252 of file bucket.c.

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link_flags, ast_module_shutdown_ref, ast_strlen_zero, ast_verb, ast_sorcery_wizard::create, ast_sorcery_wizard::delete, lock, NULL, OBJ_KEY, OBJ_NOLOCK, RAII_VAR, ast_sorcery_wizard::retrieve_id, and SCOPED_AO2WRLOCK.

00255 {
00256    SCOPED_AO2WRLOCK(lock, schemes);
00257    RAII_VAR(struct ast_bucket_scheme *, scheme, NULL, ao2_cleanup);
00258 
00259    if (ast_strlen_zero(name) || !bucket || !file ||
00260        !bucket->create || !bucket->delete || !bucket->retrieve_id ||
00261        !create_cb) {
00262       return -1;
00263    }
00264 
00265    scheme = ao2_find(schemes, name, OBJ_KEY | OBJ_NOLOCK);
00266    if (scheme) {
00267       return -1;
00268    }
00269 
00270    scheme = ao2_alloc(sizeof(*scheme) + strlen(name) + 1, NULL);
00271    if (!scheme) {
00272       return -1;
00273    }
00274 
00275    strcpy(scheme->name, name);
00276    scheme->bucket = bucket;
00277    scheme->file = file;
00278    scheme->create = create_cb;
00279    scheme->destroy = destroy_cb;
00280 
00281    ao2_link_flags(schemes, scheme, OBJ_NOLOCK);
00282 
00283    ast_verb(2, "Registered bucket scheme '%s'\n", name);
00284 
00285    ast_module_shutdown_ref(module);
00286 
00287    return 0;
00288 }

struct ast_bucket* ast_bucket_alloc ( const char *  uri  )  [read]

Allocate a new bucket.

Parameters:
uri Complete URI for the bucket
non-NULL success
NULL failure
Note:
This only creates a local bucket object, to persist in backend storage you must call ast_bucket_create

Definition at line 400 of file bucket.c.

References ao2_cleanup, ao2_find, ao2_ref, ast_alloca, ast_copy_string(), ast_sorcery_alloc(), ast_strdupa, ast_string_field_set, ast_strlen_zero, len(), NULL, OBJ_KEY, RAII_VAR, ast_bucket::scheme, ast_bucket::scheme_impl, and tmp().

Referenced by AST_TEST_DEFINE(), and bucket_test_wizard_retrieve_id().

00401 {
00402 #ifdef HAVE_URIPARSER
00403    UriParserStateA state;
00404    UriUriA full_uri;
00405    size_t len;
00406 #else
00407    char *tmp = ast_strdupa(uri);
00408 #endif
00409    char *uri_scheme;
00410    RAII_VAR(struct ast_bucket_scheme *, scheme, NULL, ao2_cleanup);
00411    struct ast_bucket *bucket;
00412 
00413    if (ast_strlen_zero(uri)) {
00414       return NULL;
00415    }
00416 
00417 #ifdef HAVE_URIPARSER
00418    state.uri = &full_uri;
00419    if (uriParseUriA(&state, uri) != URI_SUCCESS ||
00420       !full_uri.scheme.first || !full_uri.scheme.afterLast ||
00421       !full_uri.pathTail) {
00422       uriFreeUriMembersA(&full_uri);
00423       return NULL;
00424    }
00425 
00426    len = (full_uri.scheme.afterLast - full_uri.scheme.first) + 1;
00427    uri_scheme = ast_alloca(len);
00428    ast_copy_string(uri_scheme, full_uri.scheme.first, len);
00429 
00430    uriFreeUriMembersA(&full_uri);
00431 #else
00432    uri_scheme = tmp;
00433    if (!(tmp = strchr(uri_scheme, ':'))) {
00434       return NULL;
00435    }
00436    *tmp = '\0';
00437 #endif
00438 
00439    scheme = ao2_find(schemes, uri_scheme, OBJ_KEY);
00440    if (!scheme) {
00441       return NULL;
00442    }
00443 
00444    bucket = ast_sorcery_alloc(bucket_sorcery, "bucket", uri);
00445    if (!bucket) {
00446       return NULL;
00447    }
00448 
00449    ao2_ref(scheme, +1);
00450    bucket->scheme_impl = scheme;
00451 
00452    ast_string_field_set(bucket, scheme, uri_scheme);
00453 
00454    return bucket;
00455 }

int ast_bucket_create ( struct ast_bucket bucket  ) 

Create a new bucket in backend storage.

Parameters:
bucket The bucket
Return values:
0 success
-1 failure

Definition at line 457 of file bucket.c.

References ast_sorcery_create().

Referenced by AST_TEST_DEFINE().

00458 {
00459    return ast_sorcery_create(bucket_sorcery, bucket);
00460 }

int ast_bucket_delete ( struct ast_bucket bucket  ) 

Delete a bucket from backend storage.

Parameters:
bucket The bucket
Return values:
0 success
-1 failure

Definition at line 481 of file bucket.c.

References ast_sorcery_delete().

Referenced by AST_TEST_DEFINE().

00482 {
00483    return ast_sorcery_delete(bucket_sorcery, bucket);
00484 }

struct ast_bucket_file* ast_bucket_file_alloc ( const char *  uri  )  [read]

Allocate a new bucket file.

Parameters:
uri Complete URI for the bucket file
non-NULL success
NULL failure
Note:
This only creates a local bucket file object, to persist in backend storage you must call ast_bucket_file_create

Definition at line 628 of file bucket.c.

References ao2_cleanup, ao2_find, ao2_ref, ast_alloca, ast_copy_string(), ast_sorcery_alloc(), ast_strdupa, ast_string_field_set, ast_strlen_zero, len(), NULL, OBJ_KEY, RAII_VAR, ast_bucket_file::scheme, ast_bucket_file::scheme_impl, and tmp().

Referenced by ast_bucket_file_copy(), AST_TEST_DEFINE(), and bucket_test_wizard_retrieve_id().

00629 {
00630 #ifdef HAVE_URIPARSER
00631    UriParserStateA state;
00632    UriUriA full_uri;
00633    size_t len;
00634 #else
00635    char *tmp = ast_strdupa(uri);
00636 #endif
00637    char *uri_scheme;
00638    RAII_VAR(struct ast_bucket_scheme *, scheme, NULL, ao2_cleanup);
00639    struct ast_bucket_file *file;
00640 
00641    if (ast_strlen_zero(uri)) {
00642       return NULL;
00643    }
00644 
00645 #ifdef HAVE_URIPARSER
00646    state.uri = &full_uri;
00647    if (uriParseUriA(&state, uri) != URI_SUCCESS ||
00648       !full_uri.scheme.first || !full_uri.scheme.afterLast ||
00649       !full_uri.pathTail) {
00650       uriFreeUriMembersA(&full_uri);
00651       return NULL;
00652    }
00653 
00654    len = (full_uri.scheme.afterLast - full_uri.scheme.first) + 1;
00655    uri_scheme = ast_alloca(len);
00656    ast_copy_string(uri_scheme, full_uri.scheme.first, len);
00657 
00658    uriFreeUriMembersA(&full_uri);
00659 #else
00660    uri_scheme = tmp;
00661    if (!(tmp = strchr(uri_scheme, ':'))) {
00662       return NULL;
00663    }
00664    *tmp = '\0';
00665 #endif
00666 
00667    scheme = ao2_find(schemes, uri_scheme, OBJ_KEY);
00668    if (!scheme) {
00669       return NULL;
00670    }
00671 
00672    file = ast_sorcery_alloc(bucket_sorcery, "file", uri);
00673    if (!file) {
00674       return NULL;
00675    }
00676 
00677    ao2_ref(scheme, +1);
00678    file->scheme_impl = scheme;
00679 
00680    ast_string_field_set(file, scheme, uri_scheme);
00681 
00682    if (scheme->create(file)) {
00683       ao2_ref(file, -1);
00684       return NULL;
00685    }
00686 
00687    return file;
00688 }

struct ast_bucket_file* ast_bucket_file_copy ( struct ast_bucket_file file,
const char *  uri 
) [read]

Copy a bucket file to a new URI.

Parameters:
file The source bucket file
uri The new URI
Return values:
non-NULL success
NULL failure
Note:
This operation stages things locally, you must call ast_bucket_file_create on the file that is returned to commit the copy to backend storage

Definition at line 733 of file bucket.c.

References ao2_cleanup, ao2_container_clone, ao2_ref, ast_bucket_file_alloc(), bucket_copy(), copy(), ast_bucket_file::metadata, NULL, ast_bucket_file::path, and RAII_VAR.

Referenced by AST_TEST_DEFINE().

00734 {
00735    RAII_VAR(struct ast_bucket_file *, copy, ast_bucket_file_alloc(uri), ao2_cleanup);
00736 
00737    if (!copy) {
00738       return NULL;
00739    }
00740 
00741    ao2_cleanup(copy->metadata);
00742    copy->metadata = ao2_container_clone(file->metadata, 0);
00743    if (!copy->metadata ||
00744       bucket_copy(file->path, copy->path)) {
00745       return NULL;
00746    }
00747 
00748    ao2_ref(copy, +1);
00749    return copy;
00750 }

int ast_bucket_file_create ( struct ast_bucket_file file  ) 

Create a new bucket file in backend storage.

Parameters:
file The bucket file
Return values:
0 success
-1 failure

Definition at line 690 of file bucket.c.

References ast_sorcery_create().

Referenced by AST_TEST_DEFINE().

00691 {
00692    return ast_sorcery_create(bucket_sorcery, file);
00693 }

int ast_bucket_file_delete ( struct ast_bucket_file file  ) 

Delete a bucket file from backend storage.

Parameters:
file The bucket file
Return values:
0 success
-1 failure

Definition at line 776 of file bucket.c.

References ast_sorcery_delete().

Referenced by AST_TEST_DEFINE().

00777 {
00778    return ast_sorcery_delete(bucket_sorcery, file);
00779 }

struct ast_json* ast_bucket_file_json ( const struct ast_bucket_file file  )  [read]

Get a JSON representation of a bucket file.

Parameters:
file The specific bucket file
Return values:
non-NULL success
NULL failure
Note:
The returned ast_json object must be unreferenced using ast_json_unref

Definition at line 781 of file bucket.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_json_object_create(), ast_json_object_set(), ast_json_ref(), ast_json_string_create(), ast_json_unref(), ast_sorcery_object_get_id(), ast_sorcery_objectset_json_create(), id, ast_bucket_file::metadata, ast_bucket_metadata::name, NULL, RAII_VAR, ast_bucket_metadata::value, and value.

Referenced by AST_TEST_DEFINE().

00782 {
00783    RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
00784    struct ast_json *id, *metadata;
00785    struct ao2_iterator i;
00786    struct ast_bucket_metadata *attribute;
00787    int res = 0;
00788 
00789    json = ast_sorcery_objectset_json_create(bucket_sorcery, file);
00790    if (!json) {
00791       return NULL;
00792    }
00793 
00794    id = ast_json_string_create(ast_sorcery_object_get_id(file));
00795    if (!id) {
00796       return NULL;
00797    }
00798 
00799    if (ast_json_object_set(json, "id", id)) {
00800       return NULL;
00801    }
00802 
00803    metadata = ast_json_object_create();
00804    if (!metadata) {
00805       return NULL;
00806    }
00807 
00808    if (ast_json_object_set(json, "metadata", metadata)) {
00809       return NULL;
00810    }
00811 
00812    i = ao2_iterator_init(file->metadata, 0);
00813    for (; (attribute = ao2_iterator_next(&i)); ao2_ref(attribute, -1)) {
00814       struct ast_json *value = ast_json_string_create(attribute->value);
00815 
00816       if (!value || ast_json_object_set(metadata, attribute->name, value)) {
00817          res = -1;
00818          break;
00819       }
00820    }
00821    ao2_iterator_destroy(&i);
00822 
00823    if (res) {
00824       return NULL;
00825    }
00826 
00827    ast_json_ref(json);
00828    return json;
00829 }

struct ast_bucket_metadata* ast_bucket_file_metadata_get ( struct ast_bucket_file file,
const char *  name 
) [read]

Retrieve a metadata attribute from a file.

Parameters:
file The bucket file
name Name of the attribute
Return values:
non-NULL if found
NULL if not found
Note:
The object is returned with reference count increased

Definition at line 334 of file bucket.c.

References ao2_find, ast_bucket_file::metadata, and OBJ_KEY.

Referenced by AST_TEST_DEFINE().

00335 {
00336    return ao2_find(file->metadata, name, OBJ_KEY);
00337 }

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.

Parameters:
file The bucket file
name Name of the attribute
value Value of the attribute
Return values:
0 success
-1 failure
Note:
This function will overwrite an existing attribute of the same name, unless an error occurs. If an error occurs the existing attribute is left alone.

Definition at line 309 of file bucket.c.

References ao2_cleanup, ao2_find, ao2_link, bucket_metadata_alloc(), ast_bucket_file::metadata, OBJ_KEY, OBJ_NODATA, OBJ_UNLINK, and RAII_VAR.

Referenced by AST_TEST_DEFINE().

00310 {
00311    RAII_VAR(struct ast_bucket_metadata *, metadata, bucket_metadata_alloc(name, value), ao2_cleanup);
00312 
00313    if (!metadata) {
00314       return -1;
00315    }
00316 
00317    ao2_find(file->metadata, name, OBJ_NODATA | OBJ_UNLINK | OBJ_KEY);
00318    ao2_link(file->metadata, metadata);
00319 
00320    return 0;
00321 }

int ast_bucket_file_metadata_unset ( struct ast_bucket_file file,
const char *  name 
)

Unset a specific metadata attribute on a file.

Parameters:
file The bucket file
name Name of the attribute
Return values:
0 success
-1 failure

Definition at line 323 of file bucket.c.

References ao2_cleanup, ao2_find, ast_bucket_file::metadata, OBJ_KEY, OBJ_UNLINK, and RAII_VAR.

Referenced by AST_TEST_DEFINE().

00324 {
00325    RAII_VAR(struct ast_bucket_metadata *, metadata, ao2_find(file->metadata, name, OBJ_UNLINK | OBJ_KEY), ao2_cleanup);
00326 
00327    if (!metadata) {
00328       return -1;
00329    }
00330 
00331    return 0;
00332 }

int ast_bucket_file_observer_add ( const struct ast_sorcery_observer callbacks  ) 

Add an observer for bucket file creation and deletion operations.

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

Definition at line 761 of file bucket.c.

References ast_sorcery_observer_add().

00762 {
00763    return ast_sorcery_observer_add(bucket_sorcery, "file", callbacks);
00764 }

void ast_bucket_file_observer_remove ( const struct ast_sorcery_observer callbacks  ) 

Remove an observer from bucket file creation and deletion.

Parameters:
callbacks Implementation of the sorcery observer interface

Definition at line 766 of file bucket.c.

References ast_sorcery_observer_remove().

00767 {
00768    ast_sorcery_observer_remove(bucket_sorcery, "file", callbacks);
00769 }

struct ast_bucket_file* ast_bucket_file_retrieve ( const char *  uri  )  [read]

Retrieve a bucket file.

Parameters:
uri Complete URI of the bucket file
Return values:
non-NULL if found
NULL if not found
Note:
The object is returned with reference count increased

Definition at line 752 of file bucket.c.

References ast_sorcery_retrieve_by_id(), ast_strlen_zero, and NULL.

Referenced by AST_TEST_DEFINE().

00753 {
00754    if (ast_strlen_zero(uri)) {
00755       return NULL;
00756    }
00757 
00758    return ast_sorcery_retrieve_by_id(bucket_sorcery, "file", uri);
00759 }

int ast_bucket_file_temporary_create ( struct ast_bucket_file file  ) 

Common file snapshot creation callback for creating a temporary file.

Parameters:
file Pointer to the file snapshot
Return values:
0 success
-1 failure

Definition at line 831 of file bucket.c.

References ast_copy_string(), and ast_bucket_file::path.

Referenced by load_module().

00832 {
00833    int fd;
00834 
00835    ast_copy_string(file->path, "/tmp/bucket-XXXXXX", sizeof(file->path));
00836 
00837    fd = mkstemp(file->path);
00838    if (fd < 0) {
00839       return -1;
00840    }
00841 
00842    close(fd);
00843    return 0;
00844 }

void ast_bucket_file_temporary_destroy ( struct ast_bucket_file file  ) 

Common file snapshot destruction callback for deleting a temporary file.

Parameters:
file Pointer to the file snapshot

Definition at line 846 of file bucket.c.

References ast_strlen_zero, and ast_bucket_file::path.

Referenced by load_module().

00847 {
00848    if (!ast_strlen_zero(file->path)) {
00849       unlink(file->path);
00850    }
00851 }

int ast_bucket_file_update ( struct ast_bucket_file file  ) 

Update an existing bucket file in backend storage.

Parameters:
file The bucket file
Return values:
0 success
-1 failure
Note:
This operation will update both the actual content of the file and the metadata associated with it

Definition at line 771 of file bucket.c.

References ast_sorcery_update().

Referenced by AST_TEST_DEFINE().

00772 {
00773    return ast_sorcery_update(bucket_sorcery, file);
00774 }

int ast_bucket_init ( void   ) 

Initialize bucket support.

Return values:
0 success
-1 failure

Definition at line 909 of file bucket.c.

References __ast_sorcery_wizard_register(), AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_options, ast_log, ast_register_cleanup(), ast_sorcery_apply_default, AST_SORCERY_APPLY_FAIL, ast_sorcery_object_field_register, ast_sorcery_object_field_register_custom, ast_sorcery_object_register, ast_sorcery_open, bucket_alloc(), bucket_cleanup(), bucket_file_alloc(), bucket_scheme_cmp(), bucket_scheme_hash(), FLDSET, LOG_ERROR, NULL, OPT_STRINGFIELD_T, SCHEME_BUCKETS, STRFLDSET, timeval_str2struct(), and timeval_struct2str().

Referenced by main().

00910 {
00911    ast_register_cleanup(&bucket_cleanup);
00912 
00913    schemes = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, SCHEME_BUCKETS, bucket_scheme_hash,
00914       bucket_scheme_cmp);
00915    if (!schemes) {
00916       ast_log(LOG_ERROR, "Failed to create container for Bucket schemes\n");
00917       return -1;
00918    }
00919 
00920    if (__ast_sorcery_wizard_register(&bucket_wizard, NULL)) {
00921       ast_log(LOG_ERROR, "Failed to register sorcery wizard for 'bucket' intermediary\n");
00922       return -1;
00923    }
00924 
00925    if (__ast_sorcery_wizard_register(&bucket_file_wizard, NULL)) {
00926       ast_log(LOG_ERROR, "Failed to register sorcery wizard for 'file' intermediary\n");
00927       return -1;
00928    }
00929 
00930    if (!(bucket_sorcery = ast_sorcery_open())) {
00931       ast_log(LOG_ERROR, "Failed to create sorcery instance for Bucket support\n");
00932       return -1;
00933    }
00934 
00935    if (ast_sorcery_apply_default(bucket_sorcery, "bucket", "bucket", NULL) == AST_SORCERY_APPLY_FAIL) {
00936       ast_log(LOG_ERROR, "Failed to apply intermediary for 'bucket' object type in Bucket sorcery\n");
00937       return -1;
00938    }
00939 
00940    if (ast_sorcery_object_register(bucket_sorcery, "bucket", bucket_alloc, NULL, NULL)) {
00941       ast_log(LOG_ERROR, "Failed to register 'bucket' object type in Bucket sorcery\n");
00942       return -1;
00943    }
00944 
00945    ast_sorcery_object_field_register(bucket_sorcery, "bucket", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket, scheme));
00946    ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, created));
00947    ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, modified));
00948 
00949    if (ast_sorcery_apply_default(bucket_sorcery, "file", "bucket_file", NULL) == AST_SORCERY_APPLY_FAIL) {
00950       ast_log(LOG_ERROR, "Failed to apply intermediary for 'file' object type in Bucket sorcery\n");
00951       return -1;
00952    }
00953 
00954    if (ast_sorcery_object_register(bucket_sorcery, "file", bucket_file_alloc, NULL, NULL)) {
00955       ast_log(LOG_ERROR, "Failed to register 'file' object type in Bucket sorcery\n");
00956       return -1;
00957    }
00958 
00959    ast_sorcery_object_field_register(bucket_sorcery, "file", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket_file, scheme));
00960    ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, created));
00961    ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, modified));
00962 
00963    return 0;
00964 }

struct ast_json* ast_bucket_json ( const struct ast_bucket bucket  )  [read]

Get a JSON representation of a bucket.

Parameters:
bucket The specific bucket
Return values:
non-NULL success
NULL failure
Note:
The returned ast_json object must be unreferenced using ast_json_unref

Definition at line 486 of file bucket.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_json_array_append(), ast_json_array_create(), ast_json_object_set(), ast_json_ref(), ast_json_string_create(), ast_json_unref(), ast_sorcery_object_get_id(), ast_sorcery_objectset_json_create(), ast_bucket::buckets, ast_bucket::files, id, NULL, and RAII_VAR.

Referenced by AST_TEST_DEFINE().

00487 {
00488    RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
00489    struct ast_json *id, *files, *buckets;
00490    struct ao2_iterator i;
00491    char *uri;
00492    int res = 0;
00493 
00494    json = ast_sorcery_objectset_json_create(bucket_sorcery, bucket);
00495    if (!json) {
00496       return NULL;
00497    }
00498 
00499    id = ast_json_string_create(ast_sorcery_object_get_id(bucket));
00500    if (!id) {
00501       return NULL;
00502    }
00503 
00504    if (ast_json_object_set(json, "id", id)) {
00505       return NULL;
00506    }
00507 
00508    buckets = ast_json_array_create();
00509    if (!buckets) {
00510       return NULL;
00511    }
00512 
00513    if (ast_json_object_set(json, "buckets", buckets)) {
00514       return NULL;
00515    }
00516 
00517    i = ao2_iterator_init(bucket->buckets, 0);
00518    for (; (uri = ao2_iterator_next(&i)); ao2_ref(uri, -1)) {
00519       struct ast_json *bucket_uri = ast_json_string_create(uri);
00520 
00521       if (!bucket_uri || ast_json_array_append(buckets, bucket_uri)) {
00522          res = -1;
00523          ao2_ref(uri, -1);
00524          break;
00525       }
00526    }
00527    ao2_iterator_destroy(&i);
00528 
00529    if (res) {
00530       return NULL;
00531    }
00532 
00533    files = ast_json_array_create();
00534    if (!files) {
00535       return NULL;
00536    }
00537 
00538    if (ast_json_object_set(json, "files", files)) {
00539       return NULL;
00540    }
00541 
00542    i = ao2_iterator_init(bucket->files, 0);
00543    for (; (uri = ao2_iterator_next(&i)); ao2_ref(uri, -1)) {
00544       struct ast_json *file_uri = ast_json_string_create(uri);
00545 
00546       if (!file_uri || ast_json_array_append(files, file_uri)) {
00547          res = -1;
00548          ao2_ref(uri, -1);
00549          break;
00550       }
00551    }
00552    ao2_iterator_destroy(&i);
00553 
00554    if (res) {
00555       return NULL;
00556    }
00557 
00558    ast_json_ref(json);
00559    return json;
00560 }

int ast_bucket_observer_add ( const struct ast_sorcery_observer callbacks  ) 

Add an observer for bucket creation and deletion operations.

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

Definition at line 471 of file bucket.c.

References ast_sorcery_observer_add().

00472 {
00473    return ast_sorcery_observer_add(bucket_sorcery, "bucket", callbacks);
00474 }

void ast_bucket_observer_remove ( const struct ast_sorcery_observer callbacks  ) 

Remove an observer from bucket creation and deletion.

Parameters:
callbacks Implementation of the sorcery observer interface

Definition at line 476 of file bucket.c.

References ast_sorcery_observer_remove().

00477 {
00478    ast_sorcery_observer_remove(bucket_sorcery, "bucket", callbacks);
00479 }

struct ast_bucket* ast_bucket_retrieve ( const char *  uri  )  [read]

Retrieve information about a bucket.

Parameters:
uri Complete URI of the bucket
Return values:
non-NULL if found
NULL if not found
Note:
The object is returned with reference count increased

Definition at line 462 of file bucket.c.

References ast_sorcery_retrieve_by_id(), ast_strlen_zero, and NULL.

Referenced by AST_TEST_DEFINE().

00463 {
00464    if (ast_strlen_zero(uri)) {
00465       return NULL;
00466    }
00467 
00468    return ast_sorcery_retrieve_by_id(bucket_sorcery, "bucket", uri);
00469 }

static void* bucket_alloc ( const char *  name  )  [static]

Allocator for buckets.

Definition at line 371 of file bucket.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_container_alloc_rbtree, ao2_ref, ast_sorcery_generic_alloc(), ast_string_field_init, bucket_destroy(), bucket_rbtree_str_sort_cmp(), NULL, and RAII_VAR.

Referenced by ast_bucket_init(), load_module(), and unload_module().

00372 {
00373    RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
00374 
00375    bucket = ast_sorcery_generic_alloc(sizeof(*bucket), bucket_destroy);
00376    if (!bucket) {
00377       return NULL;
00378    }
00379 
00380    if (ast_string_field_init(bucket, 128)) {
00381       return NULL;
00382    }
00383 
00384    bucket->buckets = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
00385       AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, bucket_rbtree_str_sort_cmp, NULL);
00386    if (!bucket->buckets) {
00387       return NULL;
00388    }
00389 
00390    bucket->files = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
00391       AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, bucket_rbtree_str_sort_cmp, NULL);
00392    if (!bucket->files) {
00393       return NULL;
00394    }
00395 
00396    ao2_ref(bucket, +1);
00397    return bucket;
00398 }

static void bucket_cleanup ( void   )  [static]

Cleanup function for graceful shutdowns.

Definition at line 883 of file bucket.c.

References ao2_cleanup, ast_sorcery_unref(), ast_sorcery_wizard_unregister(), and NULL.

Referenced by ast_bucket_init().

static int bucket_copy ( const char *  infile,
const char *  outfile 
) [static]

Copy a file, shamelessly taken from file.c.

Definition at line 696 of file bucket.c.

References AST_FILE_MODE, ast_log, buf, errno, len(), and LOG_WARNING.

Referenced by ast_bucket_file_copy().

00697 {
00698    int ifd, ofd, len;
00699    char buf[4096];   /* XXX make it lerger. */
00700 
00701    if ((ifd = open(infile, O_RDONLY)) < 0) {
00702       ast_log(LOG_WARNING, "Unable to open %s in read-only mode, error: %s\n", infile, strerror(errno));
00703       return -1;
00704    }
00705    if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
00706       ast_log(LOG_WARNING, "Unable to open %s in write-only mode, error: %s\n", outfile, strerror(errno));
00707       close(ifd);
00708       return -1;
00709    }
00710    while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
00711       int res;
00712       if (len < 0) {
00713          ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
00714          break;
00715       }
00716       /* XXX handle partial writes */
00717       res = write(ofd, buf, len);
00718       if (res != len) {
00719          ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
00720          len = -1; /* error marker */
00721          break;
00722       }
00723    }
00724    close(ifd);
00725    close(ofd);
00726    if (len < 0) {
00727       unlink(outfile);
00728       return -1; /* error */
00729    }
00730    return 0;   /* success */
00731 }

static void bucket_destroy ( void *  obj  )  [static]

Destructor for buckets.

Definition at line 340 of file bucket.c.

References ao2_cleanup, ast_string_field_free_memory, ast_bucket::buckets, ast_bucket::files, and ast_bucket::scheme_impl.

Referenced by bucket_alloc().

00341 {
00342    struct ast_bucket *bucket = obj;
00343 
00344    ao2_cleanup(bucket->scheme_impl);
00345    ast_string_field_free_memory(bucket);
00346    ao2_cleanup(bucket->buckets);
00347    ao2_cleanup(bucket->files);
00348 }

static void* bucket_file_alloc ( const char *  name  )  [static]

Allocator for bucket files.

Definition at line 605 of file bucket.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_options, ao2_ref, ast_sorcery_generic_alloc(), ast_string_field_init, bucket_file_destroy(), bucket_file_metadata_cmp(), bucket_file_metadata_hash(), METADATA_BUCKETS, NULL, and RAII_VAR.

Referenced by ast_bucket_init(), load_module(), and unload_module().

00606 {
00607    RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
00608 
00609    file = ast_sorcery_generic_alloc(sizeof(*file), bucket_file_destroy);
00610    if (!file) {
00611       return NULL;
00612    }
00613 
00614    if (ast_string_field_init(file, 128)) {
00615       return NULL;
00616    }
00617 
00618    file->metadata = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, METADATA_BUCKETS,
00619       bucket_file_metadata_hash, bucket_file_metadata_cmp);
00620    if (!file->metadata) {
00621       return NULL;
00622    }
00623 
00624    ao2_ref(file, +1);
00625    return file;
00626 }

static void bucket_file_destroy ( void *  obj  )  [static]

Destructor for bucket files.

Definition at line 592 of file bucket.c.

References ao2_cleanup, ast_bucket_scheme::destroy, ast_bucket_file::metadata, and ast_bucket_file::scheme_impl.

Referenced by bucket_file_alloc().

00593 {
00594    struct ast_bucket_file *file = obj;
00595 
00596    if (file->scheme_impl->destroy) {
00597       file->scheme_impl->destroy(file);
00598    }
00599 
00600    ao2_cleanup(file->scheme_impl);
00601    ao2_cleanup(file->metadata);
00602 }

static int bucket_file_metadata_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Comparison function for file metadata.

Definition at line 583 of file bucket.c.

References CMP_MATCH, CMP_STOP, ast_bucket_metadata::name, name, and OBJ_KEY.

Referenced by bucket_file_alloc().

00584 {
00585    struct ast_bucket_metadata *metadata1 = obj, *metadata2 = arg;
00586    const char *name = arg;
00587 
00588    return !strcmp(metadata1->name, flags & OBJ_KEY ? name : metadata2->name) ? CMP_MATCH | CMP_STOP : 0;
00589 }

static int bucket_file_metadata_hash ( const void *  obj,
const int  flags 
) [static]

Hashing function for file metadata.

Definition at line 563 of file bucket.c.

References ast_assert, ast_str_hash(), ast_bucket_metadata::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by bucket_file_alloc().

00564 {
00565    const struct ast_bucket_metadata *object;
00566    const char *key;
00567 
00568    switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
00569    case OBJ_KEY:
00570       key = obj;
00571       return ast_str_hash(key);
00572    case OBJ_POINTER:
00573       object = obj;
00574       return ast_str_hash(object->name);
00575    default:
00576       /* Hash can only work on something with a full key */
00577       ast_assert(0);
00578       return 0;
00579    }
00580 }

static int bucket_file_wizard_create ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
) [static]

Callback function for creating a bucket file.

Definition at line 175 of file bucket.c.

References ast_sorcery_wizard::create, ast_bucket_scheme::file, and ast_bucket_file::scheme_impl.

00176 {
00177    struct ast_bucket_file *file = object;
00178 
00179    return file->scheme_impl->file->create(sorcery, data, object);
00180 }

static int bucket_file_wizard_delete ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
) [static]

Callback function for deleting a bucket file.

Definition at line 236 of file bucket.c.

References ast_sorcery_wizard::delete, ast_bucket_scheme::file, and ast_bucket_file::scheme_impl.

00237 {
00238    struct ast_bucket_file *file = object;
00239 
00240    return file->scheme_impl->file->delete(sorcery, data, object);
00241 }

static void* bucket_file_wizard_retrieve ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const char *  id 
) [static]

Callback function for retrieving a bucket file.

Definition at line 183 of file bucket.c.

References ao2_cleanup, ao2_find, ast_alloca, ast_copy_string(), ast_strdupa, len(), lock, NULL, OBJ_KEY, OBJ_NOLOCK, RAII_VAR, ast_bucket_file::scheme, SCOPED_AO2RDLOCK, and tmp().

00185 {
00186 #ifdef HAVE_URIPARSER
00187    UriParserStateA state;
00188    UriUriA uri;
00189    size_t len;
00190 #else
00191    char *tmp = ast_strdupa(id);
00192 #endif
00193    char *uri_scheme;
00194    SCOPED_AO2RDLOCK(lock, schemes);
00195    RAII_VAR(struct ast_bucket_scheme *, scheme, NULL, ao2_cleanup);
00196 
00197 #ifdef HAVE_URIPARSER
00198    state.uri = &uri;
00199    if (uriParseUriA(&state, id) != URI_SUCCESS ||
00200       !uri.scheme.first || !uri.scheme.afterLast) {
00201       uriFreeUriMembersA(&uri);
00202       return NULL;
00203    }
00204 
00205    len = (uri.scheme.afterLast - uri.scheme.first) + 1;
00206    uri_scheme = ast_alloca(len);
00207    ast_copy_string(uri_scheme, uri.scheme.first, len);
00208 
00209    uriFreeUriMembersA(&uri);
00210 #else
00211    uri_scheme = tmp;
00212    if (!(tmp = strchr(uri_scheme, ':'))) {
00213       return NULL;
00214    }
00215    *tmp = '\0';
00216 #endif
00217 
00218    scheme = ao2_find(schemes, uri_scheme, OBJ_KEY | OBJ_NOLOCK);
00219 
00220    if (!scheme) {
00221       return NULL;
00222    }
00223 
00224    return scheme->file->retrieve_id(sorcery, data, type, id);
00225 }

static int bucket_file_wizard_update ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
) [static]

Callback function for updating a bucket file.

Definition at line 228 of file bucket.c.

References ast_bucket_scheme::file, ast_bucket_file::scheme_impl, and ast_sorcery_wizard::update.

00229 {
00230    struct ast_bucket_file *file = object;
00231 
00232    return file->scheme_impl->file->update(sorcery, data, object);
00233 }

static struct ast_bucket_metadata* bucket_metadata_alloc ( const char *  name,
const char *  value 
) [static, read]

Allocator for metadata attributes.

Definition at line 291 of file bucket.c.

References ao2_alloc, ast_bucket_metadata::data, ast_bucket_metadata::name, NULL, and ast_bucket_metadata::value.

Referenced by ast_bucket_file_metadata_set().

00292 {
00293    int name_len = strlen(name) + 1, value_len = strlen(value) + 1;
00294    struct ast_bucket_metadata *metadata = ao2_alloc(sizeof(*metadata) + name_len + value_len, NULL);
00295    char *dst;
00296 
00297    if (!metadata) {
00298       return NULL;
00299    }
00300 
00301    dst = metadata->data;
00302    metadata->name = strcpy(dst, name);
00303    dst += name_len;
00304    metadata->value = strcpy(dst, value);
00305 
00306    return metadata;
00307 }

static int bucket_rbtree_str_sort_cmp ( const void *  obj_left,
const void *  obj_right,
int  flags 
) [static]

Sorting function for red black tree string container.

Definition at line 351 of file bucket.c.

References OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by bucket_alloc().

00352 {
00353    const char *str_left = obj_left;
00354    const char *str_right = obj_right;
00355    int cmp = 0;
00356 
00357    switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
00358    default:
00359    case OBJ_POINTER:
00360    case OBJ_KEY:
00361       cmp = strcmp(str_left, str_right);
00362       break;
00363    case OBJ_PARTIAL_KEY:
00364       cmp = strncmp(str_left, str_right, strlen(str_right));
00365       break;
00366    }
00367    return cmp;
00368 }

static int bucket_scheme_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Comparison function for scheme container.

Definition at line 874 of file bucket.c.

References CMP_MATCH, CMP_STOP, ast_bucket_scheme::name, name, and OBJ_KEY.

Referenced by ast_bucket_init().

00875 {
00876    struct ast_bucket_scheme *scheme1 = obj, *scheme2 = arg;
00877    const char *name = arg;
00878 
00879    return !strcmp(scheme1->name, flags & OBJ_KEY ? name : scheme2->name) ? CMP_MATCH | CMP_STOP : 0;
00880 }

static int bucket_scheme_hash ( const void *  obj,
const int  flags 
) [static]

Hashing function for scheme container.

Definition at line 854 of file bucket.c.

References ast_assert, ast_str_hash(), ast_bucket_scheme::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by ast_bucket_init().

00855 {
00856    const struct ast_bucket_scheme *object;
00857    const char *key;
00858 
00859    switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
00860    case OBJ_KEY:
00861       key = obj;
00862       return ast_str_hash(key);
00863    case OBJ_POINTER:
00864       object = obj;
00865       return ast_str_hash(object->name);
00866    default:
00867       /* Hash can only work on something with a full key */
00868       ast_assert(0);
00869       return 0;
00870    }
00871 }

static int bucket_wizard_create ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
) [static]

Callback function for creating a bucket.

Definition at line 106 of file bucket.c.

References ast_bucket_scheme::bucket, ast_sorcery_wizard::create, and ast_bucket::scheme_impl.

00107 {
00108    struct ast_bucket *bucket = object;
00109 
00110    return bucket->scheme_impl->bucket->create(sorcery, data, object);
00111 }

static int bucket_wizard_delete ( const struct ast_sorcery sorcery,
void *  data,
void *  object 
) [static]

Callback function for deleting a bucket.

Definition at line 159 of file bucket.c.

References ast_bucket_scheme::bucket, ast_sorcery_wizard::delete, and ast_bucket::scheme_impl.

00160 {
00161    struct ast_bucket *bucket = object;
00162 
00163    return bucket->scheme_impl->bucket->delete(sorcery, data, object);
00164 }

static void* bucket_wizard_retrieve ( const struct ast_sorcery sorcery,
void *  data,
const char *  type,
const char *  id 
) [static]

Callback function for retrieving a bucket.

Definition at line 114 of file bucket.c.

References ao2_cleanup, ao2_find, ast_alloca, ast_copy_string(), ast_strdupa, len(), lock, NULL, OBJ_KEY, OBJ_NOLOCK, RAII_VAR, ast_bucket::scheme, SCOPED_AO2RDLOCK, and tmp().

00116 {
00117 #ifdef HAVE_URIPARSER
00118    UriParserStateA state;
00119    UriUriA uri;
00120    size_t len;
00121 #else
00122    char *tmp = ast_strdupa(id);
00123 #endif
00124    SCOPED_AO2RDLOCK(lock, schemes);
00125    char *uri_scheme;
00126    RAII_VAR(struct ast_bucket_scheme *, scheme, NULL, ao2_cleanup);
00127 
00128 #ifdef HAVE_URIPARSER
00129    state.uri = &uri;
00130    if (uriParseUriA(&state, id) != URI_SUCCESS ||
00131       !uri.scheme.first || !uri.scheme.afterLast) {
00132       uriFreeUriMembersA(&uri);
00133       return NULL;
00134    }
00135 
00136    len = (uri.scheme.afterLast - uri.scheme.first) + 1;
00137    uri_scheme = ast_alloca(len);
00138    ast_copy_string(uri_scheme, uri.scheme.first, len);
00139 
00140    uriFreeUriMembersA(&uri);
00141 #else
00142    uri_scheme = tmp;
00143    if (!(tmp = strchr(uri_scheme, ':'))) {
00144       return NULL;
00145    }
00146    *tmp = '\0';
00147 #endif
00148 
00149    scheme = ao2_find(schemes, uri_scheme, OBJ_KEY | OBJ_NOLOCK);
00150 
00151    if (!scheme) {
00152       return NULL;
00153    }
00154 
00155    return scheme->bucket->retrieve_id(sorcery, data, type, id);
00156 }

static int timeval_str2struct ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for translating from a string timeval to actual structure.

Definition at line 895 of file bucket.c.

References aco_option_get_argument(), ast_get_timeval(), ast_tv(), NULL, and ast_variable::value.

Referenced by ast_bucket_init().

00896 {
00897    struct timeval *field = (struct timeval *)(obj + aco_option_get_argument(opt, 0));
00898    return ast_get_timeval(var->value, field, ast_tv(0, 0), NULL);
00899 }

static int timeval_struct2str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Custom handler for translating from an actual structure timeval to string.

Definition at line 902 of file bucket.c.

References ast_asprintf.

Referenced by ast_bucket_init().

00903 {
00904    struct timeval *field = (struct timeval *)(obj + args[0]);
00905    return (ast_asprintf(buf, "%lu.%06lu", (unsigned long)field->tv_sec, (unsigned long)field->tv_usec) < 0) ? -1 : 0;
00906 }


Variable Documentation

Intermediary file wizard.

Definition at line 244 of file bucket.c.

struct ast_sorcery* bucket_sorcery [static]

Sorcery instance for all bucket operations.

Definition at line 86 of file bucket.c.

Intermediary bucket wizard.

Definition at line 167 of file bucket.c.

struct ao2_container* schemes [static]

Container of registered schemes.

Definition at line 89 of file bucket.c.


Generated on Thu Apr 16 06:29:16 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6