Sat Apr 26 2014 22:02:45

Asterisk developer's documentation


data.c File Reference

Data retrieval API. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include <regex.h>
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/data.h"
#include "asterisk/astobj2.h"
#include "asterisk/xml.h"
#include "asterisk/cli.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/test.h"
#include "asterisk/frame.h"
Include dependency graph for data.c:

Go to the source code of this file.

Data Structures

struct  ast_data
 The data tree to be returned by the callbacks and managed by functions local to this file. More...
struct  ast_data_iterator
 This structure is used by the iterator. More...
struct  ast_data_search
 The list of nodes with their search requirement. More...
struct  data_filter
 The filter node. More...
struct  data_provider
 A data container node pointing to the registered handler. More...
struct  data_filter::glob_list_t
 glob list More...

Defines

#define data_read_lock()   ast_rwlock_rdlock(&root_data.lock)
#define data_unlock()   ast_rwlock_unlock(&root_data.lock)
#define data_write_lock()   ast_rwlock_wrlock(&root_data.lock)
#define NUM_DATA_FILTER_BUCKETS   59
#define NUM_DATA_NODE_BUCKETS   59
#define NUM_DATA_RESULT_BUCKETS   59
#define NUM_DATA_SEARCH_BUCKETS   59

Enumerations

enum  data_search_comparison {
  DATA_CMP_UNKNOWN, DATA_CMP_EQ, DATA_CMP_NEQ, DATA_CMP_GT,
  DATA_CMP_GE, DATA_CMP_LT, DATA_CMP_LE
}
 Type of comparisons allow in the search string. More...

Functions

static struct ast_data__ast_data_add (struct ast_data *root, const char *name, enum ast_data_type type, void *ptr)
int __ast_data_add_structure (struct ast_data *root, const struct ast_data_mapping_structure *mapping, size_t mapping_len, void *structure)
 Add a complete structure to a node.
int __ast_data_register (const char *path, const struct ast_data_handler *handler, const char *registrar, struct ast_module *mod)
 Register a data provider.
int __ast_data_register_multiple (const struct ast_data_entry *data_entries, size_t entries, const char *registrar, struct ast_module *mod)
 Register multiple data providers at once.
int __ast_data_search_cmp_structure (const struct ast_data_search *search, const struct ast_data_mapping_structure *mapping, size_t mapping_len, void *structure, const char *structure_name)
 Based on a search tree, evaluate every member of a structure against it.
int __ast_data_unregister (const char *path, const char *registrar)
 Unregister a data provider.
static void __data_result_print_cli (int fd, const struct ast_data *root, uint32_t depth)
struct ast_dataast_data_add_bool (struct ast_data *root, const char *childname, unsigned int boolean)
 Add a boolean node type.
struct ast_dataast_data_add_char (struct ast_data *root, const char *name, char value)
 Add a char node type.
int ast_data_add_codec (struct ast_data *root, const char *node_name, struct ast_format *format)
 Add the codec in the root node based on the format parameter.
int ast_data_add_codecs (struct ast_data *root, const char *node_name, struct ast_format_cap *cap)
 Add the list of codecs in the root node based on the capability parameter.
struct ast_dataast_data_add_dbl (struct ast_data *root, const char *childname, double dbl)
 Add a floating point node type.
struct ast_dataast_data_add_int (struct ast_data *root, const char *name, int value)
 Add an integer node type.
struct ast_dataast_data_add_ipaddr (struct ast_data *root, const char *childname, struct in_addr addr)
 Add a ipv4 address type.
struct ast_dataast_data_add_milliseconds (struct ast_data *root, const char *childname, unsigned int milliseconds)
 Add a milliseconds node type.
struct ast_dataast_data_add_node (struct ast_data *root, const char *name)
 Add a container child.
struct ast_dataast_data_add_password (struct ast_data *root, const char *childname, const char *value)
 Add a password node type.
struct ast_dataast_data_add_ptr (struct ast_data *root, const char *childname, void *ptr)
 Add a ptr node type.
struct ast_dataast_data_add_seconds (struct ast_data *root, const char *childname, unsigned int seconds)
 Add a seconds node type.
struct ast_dataast_data_add_str (struct ast_data *root, const char *childname, const char *value)
 Add a string node type.
struct ast_dataast_data_add_timestamp (struct ast_data *root, const char *childname, unsigned int timestamp)
 Add a timestamp node type.
struct ast_dataast_data_add_uint (struct ast_data *root, const char *name, unsigned int value)
 Add an unsigned integer node type.
void ast_data_free (struct ast_data *root)
 Release the allocated memory of a tree.
struct ast_dataast_data_get (const struct ast_data_query *query)
 Retrieve a subtree from the asterisk data API.
struct ast_xml_doc * ast_data_get_xml (const struct ast_data_query *query)
 Retrieve a subtree from the asterisk data API in XML format..
int ast_data_init (void)
void ast_data_iterator_end (struct ast_data_iterator *iterator)
 Release (stop using) an iterator.
struct ast_data_iteratorast_data_iterator_init (struct ast_data *tree, const char *elements)
 Initialize an iterator.
struct ast_dataast_data_iterator_next (struct ast_data_iterator *iterator)
 Get the next node of the tree.
void ast_data_remove_node (struct ast_data *root, struct ast_data *child)
 Remove a node that was added using ast_data_add_.
int ast_data_retrieve (struct ast_data *tree, const char *path, struct ast_data_retrieve *content)
 Retrieve a value from a node in the tree.
char * ast_data_retrieve_name (struct ast_data *node)
 Get the node name.
enum ast_data_type ast_data_retrieve_type (struct ast_data *node, const char *path)
 Get a node type.
int ast_data_search_match (const struct ast_data_search *search, struct ast_data *data)
 Check the current generated node to know if it matches the search condition.
static struct data_filterdata_filter_add_child (struct ao2_container *root, char *name)
static int data_filter_add_nodes (struct ao2_container *root, char *path)
static struct data_filterdata_filter_alloc (const char *name)
static int data_filter_cmp (void *obj, void *arg, int flags)
static void data_filter_destructor (void *obj)
static struct data_filterdata_filter_find (struct ao2_container *parent, const char *name)
static struct data_filterdata_filter_generate (const char *constfilter)
static int data_filter_hash (const void *obj, const int flags)
static void data_filter_release (struct data_filter *filter)
static void data_get_xml_add_child (struct ast_data *parent_data, struct ast_xml_node *parent_xml)
static struct data_providerdata_provider_add_child (struct ao2_container *parent, const char *name, const struct ast_data_handler *handler, const char *registrar)
static int data_provider_cmp (void *obj1, void *obj2, int flags)
static struct data_providerdata_provider_create (struct ao2_container *parent, const char *path, const char *registrar)
static void data_provider_destructor (void *obj)
static struct data_providerdata_provider_find (struct ao2_container *parent, const char *name, const char *registrar)
static int data_provider_hash (const void *obj, const int flags)
static struct data_providerdata_provider_new (const char *name, const struct ast_data_handler *handler, const char *registrar)
static void data_provider_print_cli (int fd, const char *name, struct ao2_container *container, struct ast_str *path)
static int data_provider_release (struct ao2_container *parent, const char *path, const char *registrar)
static void data_provider_release_all (struct ao2_container *parent, const char *registrar)
static void data_result_add_child (struct ast_data *root, struct ast_data *child)
static int data_result_cmp (void *obj, void *arg, int flags)
static struct ast_datadata_result_create (const char *name)
static void data_result_destructor (void *obj)
static struct ast_datadata_result_find_child (struct ast_data *root, const char *name)
static struct ast_datadata_result_generate (const struct ast_data_query *query, const char *search_path)
static struct ast_datadata_result_generate_node (const struct ast_data_query *query, const struct data_provider *root_provider, const char *parent_node_name, const struct ast_data_search *search, const struct data_filter *filter)
static int data_result_get_color (enum ast_data_type type)
static struct ast_datadata_result_get_node (struct ast_data *node, const char *path)
static int data_result_hash (const void *obj, const int flags)
static void data_result_manager_output (struct mansession *s, const char *name, struct ao2_container *container, struct ast_str *path, int id)
static void data_result_print_cli (int fd, const struct ast_data *root)
static void data_result_print_cli_node (int fd, const struct ast_data *node, uint32_t depth)
static struct ast_data_searchdata_search_add_child (struct ao2_container *parent, const char *name)
static struct ast_data_searchdata_search_alloc (const char *name)
static int data_search_cmp (void *obj, void *arg, int flags)
static int data_search_cmp_bool (const struct ast_data_search *root, const char *name, unsigned int value)
static int data_search_cmp_char (const struct ast_data_search *root, const char *name, char value)
static int data_search_cmp_dbl (const struct ast_data_search *root, const char *name, double value)
static int data_search_cmp_int (const struct ast_data_search *root, const char *name, int value)
static int data_search_cmp_ipaddr (const struct ast_data_search *root, const char *name, struct in_addr addr)
static int data_search_cmp_ptr (const struct ast_data_search *root, const char *name, void *ptr)
static int data_search_cmp_string (const struct ast_data_search *root, const char *name, char *value)
static int data_search_cmp_uint (const struct ast_data_search *root, const char *name, unsigned int value)
static int data_search_comparison_char (char a)
static int data_search_comparison_result (int cmpval, enum data_search_comparison comparison_type)
static enum data_search_comparison data_search_comparison_type (const char *comparison)
static struct ast_data_searchdata_search_create (struct ao2_container *parent, const char *path)
static void data_search_destructor (void *obj)
static struct ast_data_searchdata_search_find (struct ao2_container *parent, const char *name)
static struct ast_data_searchdata_search_generate (const char *search_string)
static struct ast_data_searchdata_search_get_node (const struct ast_data_search *node, const char *path)
static int data_search_hash (const void *obj, const int flags)
static int data_search_mapping_find (const struct ast_data_mapping_structure *map, size_t mapping_len, const char *member_name)
static void data_search_release (struct ast_data_search *search)
static void data_shutdown (void)
static int data_structure_compatible (int structure_version, uint32_t latest_compatible, uint32_t current)
static char * handle_cli_data_get (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_data_show_providers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int manager_data_get (struct mansession *s, const struct message *m)
static char * next_node_name (char **path)

Variables

static struct ast_cli_entry cli_data []
static const uint32_t current_handler_version = AST_DATA_HANDLER_VERSION
 Current handler structure version.
static const uint32_t current_query_version = AST_DATA_QUERY_VERSION
 Current query structure version.
struct {
   int   color
   enum ast_data_type   type
data_result_color []
static const uint32_t latest_handler_compatible_version = 0
 The last compatible version.
static const uint32_t latest_query_compatible_version = 0
 The last compatible version.
struct {
   struct ao2_container *   container
 The asterisk data main content structure.
   ast_rwlock_t   lock
 asterisk data locking mechanism.
root_data

Detailed Description

Data retrieval API.

Author:
Brett Bryant <brettbryant@gmail.com>
Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>

Definition in file data.c.


Define Documentation

Definition at line 238 of file data.c.

Referenced by ast_data_get(), and handle_cli_data_show_providers().

Definition at line 231 of file data.c.

Referenced by __ast_data_register(), and __ast_data_unregister().

#define NUM_DATA_FILTER_BUCKETS   59

Definition at line 69 of file data.c.

Referenced by data_filter_alloc().

#define NUM_DATA_NODE_BUCKETS   59

Definition at line 66 of file data.c.

Referenced by ast_data_init(), and data_provider_new().

#define NUM_DATA_RESULT_BUCKETS   59

Definition at line 67 of file data.c.

Referenced by data_result_create().

#define NUM_DATA_SEARCH_BUCKETS   59

Definition at line 68 of file data.c.

Referenced by data_search_alloc().


Enumeration Type Documentation

Type of comparisons allow in the search string.

Enumerator:
DATA_CMP_UNKNOWN 
DATA_CMP_EQ 
DATA_CMP_NEQ 
DATA_CMP_GT 
DATA_CMP_GE 
DATA_CMP_LT 
DATA_CMP_LE 

Definition at line 111 of file data.c.

                            {
   DATA_CMP_UNKNOWN,
   DATA_CMP_EQ,   /* =  */
   DATA_CMP_NEQ,  /* != */
   DATA_CMP_GT,   /* >  */
   DATA_CMP_GE,   /* >= */
   DATA_CMP_LT,   /* <  */
   DATA_CMP_LE /* <= */
};

Function Documentation

static struct ast_data* __ast_data_add ( struct ast_data root,
const char *  name,
enum ast_data_type  type,
void *  ptr 
) [static, read]

Definition at line 2240 of file data.c.

References ao2_ref, AST_DATA_BOOLEAN, AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, AST_DATA_INTEGER, AST_DATA_IPADDR, AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, AST_DATA_POINTER, AST_DATA_SECONDS, AST_DATA_STRING, AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, ast_data::boolean, ast_data::character, ast_data::children, data_filter::children, data_filter_find(), data_result_add_child(), data_result_create(), ast_data::dbl, ast_data::filter, filter(), ast_data::ipaddr, ast_data::payload, ast_data::ptr, ast_data::sint, ast_data::str, type, ast_data::type, and ast_data::uint.

Referenced by ast_data_add_bool(), ast_data_add_char(), ast_data_add_dbl(), ast_data_add_int(), ast_data_add_ipaddr(), ast_data_add_milliseconds(), ast_data_add_node(), ast_data_add_password(), ast_data_add_ptr(), ast_data_add_seconds(), ast_data_add_str(), ast_data_add_timestamp(), and ast_data_add_uint().

{
   struct ast_data *node;
   struct data_filter *filter, *filter_child = NULL;

   if (!root || !root->children) {
      /* invalid data result node. */
      return NULL;
   }

   /* check if we need to add this node, based on the filter. */
   if (root->filter) {
      filter = data_filter_find(root->filter->children, name);
      if (!filter) {
         return NULL;
      }
      ao2_ref(filter, -1);
   }

   node = data_result_create(name);
   if (!node) {
      return NULL;
   }

   node->type = type;

   switch (type) {
   case AST_DATA_BOOLEAN:
      node->payload.boolean = *(unsigned int *) ptr;
      break;
   case AST_DATA_INTEGER:
      node->payload.sint = *(int *) ptr;
      break;
   case AST_DATA_TIMESTAMP:
   case AST_DATA_SECONDS:
   case AST_DATA_MILLISECONDS:
   case AST_DATA_UNSIGNED_INTEGER:
      node->payload.uint = *(unsigned int *) ptr;
      break;
   case AST_DATA_DOUBLE:
      node->payload.dbl = *(double *) ptr;
      break;
   case AST_DATA_PASSWORD:
   case AST_DATA_STRING:
      node->payload.str = (char *) ptr;
      break;
   case AST_DATA_CHARACTER:
      node->payload.character = *(char *) ptr;
      break;
   case AST_DATA_POINTER:
      node->payload.ptr = ptr;
      break;
   case AST_DATA_IPADDR:
      node->payload.ipaddr = *(struct in_addr *) ptr;
      break;
   case AST_DATA_CONTAINER:
      if (root->filter) {
         filter_child = data_filter_find(root->filter->children, name);
         if (filter_child) {
            /* do not increment the refcount because it is not neccesary. */
            ao2_ref(filter_child, -1);
         }
      }
      node->filter = filter_child;
      break;
   default:
      break;
   }

   data_result_add_child(root, node);

   ao2_ref(node, -1);

   return node;
}
int __ast_data_add_structure ( struct ast_data root,
const struct ast_data_mapping_structure mapping,
size_t  mapping_len,
void *  structure 
)

Add a complete structure to a node.

Parameters:
[in]rootWhere to add the structure.
[in]mappingThe structure mapping array.
[in]mapping_lenThe lenght of the mapping array.
[in]structureThe structure pointer.
Return values:
0on success.
1on error.

Definition at line 2422 of file data.c.

References ast_data_add_bool(), ast_data_add_char(), ast_data_add_dbl(), ast_data_add_int(), ast_data_add_ipaddr(), ast_data_add_milliseconds(), ast_data_add_password(), ast_data_add_ptr(), ast_data_add_seconds(), ast_data_add_str(), ast_data_add_timestamp(), ast_data_add_uint(), AST_DATA_BOOLEAN, AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, AST_DATA_INTEGER, AST_DATA_IPADDR, AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, AST_DATA_POINTER, AST_DATA_SECONDS, AST_DATA_STRING, AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, data_filter::name, and type.

{
   int i;

   for (i = 0; i < mapping_len; i++) {
      switch (mapping[i].type) {
      case AST_DATA_INTEGER:
         ast_data_add_int(root, mapping[i].name,
            mapping[i].get.AST_DATA_INTEGER(structure));
         break;
      case AST_DATA_UNSIGNED_INTEGER:
         ast_data_add_uint(root, mapping[i].name,
            mapping[i].get.AST_DATA_UNSIGNED_INTEGER(structure));
         break;
      case AST_DATA_DOUBLE:
         ast_data_add_dbl(root, mapping[i].name,
            mapping[i].get.AST_DATA_DOUBLE(structure));
         break;
      case AST_DATA_BOOLEAN:
         ast_data_add_bool(root, mapping[i].name,
            mapping[i].get.AST_DATA_BOOLEAN(structure));
         break;
      case AST_DATA_PASSWORD:
         ast_data_add_password(root, mapping[i].name,
            mapping[i].get.AST_DATA_PASSWORD(structure));
         break;
      case AST_DATA_TIMESTAMP:
         ast_data_add_timestamp(root, mapping[i].name,
            mapping[i].get.AST_DATA_TIMESTAMP(structure));
         break;
      case AST_DATA_SECONDS:
         ast_data_add_seconds(root, mapping[i].name,
            mapping[i].get.AST_DATA_SECONDS(structure));
         break;
      case AST_DATA_MILLISECONDS:
         ast_data_add_milliseconds(root, mapping[i].name,
            mapping[i].get.AST_DATA_MILLISECONDS(structure));
         break;
      case AST_DATA_STRING:
         ast_data_add_str(root, mapping[i].name,
            mapping[i].get.AST_DATA_STRING(structure));
         break;
      case AST_DATA_CHARACTER:
         ast_data_add_char(root, mapping[i].name,
            mapping[i].get.AST_DATA_CHARACTER(structure));
         break;
      case AST_DATA_CONTAINER:
         break;
      case AST_DATA_IPADDR:
         ast_data_add_ipaddr(root, mapping[i].name,
            mapping[i].get.AST_DATA_IPADDR(structure));
         break;
      case AST_DATA_POINTER:
         ast_data_add_ptr(root, mapping[i].name,
            mapping[i].get.AST_DATA_POINTER(structure));
         break;
      }
   }

   return 0;
}
int __ast_data_register ( const char *  path,
const struct ast_data_handler handler,
const char *  registrar,
struct ast_module mod 
)

Register a data provider.

Parameters:
[in]pathThe path of the node to register.
[in]handlerThe structure defining this node handler.
[in]registrarWho is registering this node.
[in]modThe module registering this handler.
See also:
ast_data_unregister
Return values:
<0on error.
0on success.
See also:
__ast_data_unregister, __ast_data_register_multiple

Definition at line 518 of file data.c.

References ao2_container_count(), ao2_ref, ast_log(), data_provider::children, data_provider_create(), data_structure_compatible(), data_unlock, data_write_lock, data_provider::handler, LOG_ERROR, data_provider::module, data_provider::name, root_data, and ast_data_handler::version.

Referenced by __ast_data_register_multiple().

{
   struct data_provider *node;

   if (!path) {
      return -1;
   }

   /* check if the handler structure is compatible. */
   if (!data_structure_compatible(handler->version,
      latest_handler_compatible_version,
      current_handler_version)) {
      return -1;
   }

   /* create the node structure for the registered handler. */
   data_write_lock();

   node = data_provider_create(root_data.container, path, registrar);
   if (!node) {
      ast_log(LOG_ERROR, "Unable to create the specified path (%s) "
         "for '%s'.\n", path, registrar);
      data_unlock();
      return -1;
   }

   if (ao2_container_count(node->children) || node->handler) {
      ast_log(LOG_ERROR, "The node '%s' was already registered. "
         "We were unable to register '%s' for registrar '%s'.\n",
         node->name, path, registrar);
      ao2_ref(node, -1);
      data_unlock();
      return -1;
   }

   /* add handler to that node. */
   node->handler = handler;
   node->module = mod;

   ao2_ref(node, -1);

   data_unlock();

   return 0;
}
int __ast_data_register_multiple ( const struct ast_data_entry data_entries,
size_t  entries,
const char *  registrar,
struct ast_module mod 
)

Register multiple data providers at once.

Parameters:
[in]data_entriesAn array of data_entries structures.
[in]entriesThe number of entries in the data_entries array.
[in]registrarWho is registering this nodes.
[in]modThe module registering this handlers.
Return values:
<0on error (none of the nodes are being registered on error).
0on success.
See also:
__ast_data_register, __ast_data_unregister

Definition at line 565 of file data.c.

References __ast_data_register(), __ast_data_unregister(), and data_provider::handler.

{
   int i, res;

   for (i = 0; i < entries; i++) {
      res = __ast_data_register(data_entries[i].path, data_entries[i].handler,
            registrar, mod);
      if (res) {
         /* unregister all the already registered nodes, and make
          * this an atomic action. */
         while ((--i) >= 0) {
            __ast_data_unregister(data_entries[i].path, registrar);
         }
         return -1;
      }
   }

   return 0;
}
int __ast_data_search_cmp_structure ( const struct ast_data_search search,
const struct ast_data_mapping_structure mapping,
size_t  mapping_len,
void *  structure,
const char *  structure_name 
)

Based on a search tree, evaluate every member of a structure against it.

Parameters:
[in]searchThe search tree.
[in]mappingThe structure mapping.
[in]mapping_lenThe lenght of the structure mapping.
[in]structureThe structure pointer.
[in]structure_nameThe name of the structure to compare.
Return values:
0If the structure matches.
1If the structure doesn't match.

Definition at line 1272 of file data.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_DATA_BOOLEAN, ast_data_mapping_structure::AST_DATA_BOOLEAN, AST_DATA_CHARACTER, ast_data_mapping_structure::AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, ast_data_mapping_structure::AST_DATA_DOUBLE, AST_DATA_INTEGER, ast_data_mapping_structure::AST_DATA_INTEGER, AST_DATA_IPADDR, ast_data_mapping_structure::AST_DATA_IPADDR, AST_DATA_MILLISECONDS, ast_data_mapping_structure::AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, ast_data_mapping_structure::AST_DATA_PASSWORD, AST_DATA_POINTER, ast_data_mapping_structure::AST_DATA_POINTER, AST_DATA_SECONDS, ast_data_mapping_structure::AST_DATA_SECONDS, AST_DATA_STRING, ast_data_mapping_structure::AST_DATA_STRING, AST_DATA_TIMESTAMP, ast_data_mapping_structure::AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, ast_data_mapping_structure::AST_DATA_UNSIGNED_INTEGER, ast_data_search::children, data_search_cmp_bool(), data_search_cmp_char(), data_search_cmp_dbl(), data_search_cmp_int(), data_search_cmp_ipaddr(), data_search_cmp_ptr(), data_search_cmp_string(), data_search_cmp_uint(), data_search_get_node(), data_search_mapping_find(), ast_data_mapping_structure::get, ast_data_search::name, and type.

{
   struct ao2_iterator i;
   struct ast_data_search *node, *struct_children;
   int member, notmatch = 0;

   if (!search) {
      return 0;
   }

   struct_children = data_search_get_node(search, structure_name);
   if (!struct_children) {
      return 0;
   }

   i = ao2_iterator_init(struct_children->children, 0);
   while ((node = ao2_iterator_next(&i))) {
      member = data_search_mapping_find(mapping, mapping_len, node->name);
      if (member < 0) {
         /* the structure member name doesn't match! */
         ao2_ref(node, -1);
         ao2_ref(struct_children, -1);
         ao2_iterator_destroy(&i);
         return 0;
      }

      notmatch = 0;
      switch (mapping[member].type) {
      case AST_DATA_PASSWORD:
         notmatch = data_search_cmp_string(struct_children,
            node->name,
            mapping[member].get.AST_DATA_PASSWORD(structure));
         break;
      case AST_DATA_TIMESTAMP:
         notmatch = data_search_cmp_uint(struct_children,
            node->name,
            mapping[member].get.AST_DATA_TIMESTAMP(structure));
         break;
      case AST_DATA_SECONDS:
         notmatch = data_search_cmp_uint(struct_children,
            node->name,
            mapping[member].get.AST_DATA_SECONDS(structure));
         break;
      case AST_DATA_MILLISECONDS:
         notmatch = data_search_cmp_uint(struct_children,
            node->name,
            mapping[member].get.AST_DATA_MILLISECONDS(structure));
         break;
      case AST_DATA_STRING:
         notmatch = data_search_cmp_string(struct_children,
            node->name,
            mapping[member].get.AST_DATA_STRING(structure));
         break;
      case AST_DATA_CHARACTER:
         notmatch = data_search_cmp_char(struct_children,
            node->name,
            mapping[member].get.AST_DATA_CHARACTER(structure));
         break;
      case AST_DATA_INTEGER:
         notmatch = data_search_cmp_int(struct_children,
            node->name,
            mapping[member].get.AST_DATA_INTEGER(structure));
         break;
      case AST_DATA_BOOLEAN:
         notmatch = data_search_cmp_bool(struct_children,
            node->name,
            mapping[member].get.AST_DATA_BOOLEAN(structure));
         break;
      case AST_DATA_UNSIGNED_INTEGER:
         notmatch = data_search_cmp_uint(struct_children,
            node->name,
            mapping[member].get.AST_DATA_UNSIGNED_INTEGER(structure));
         break;
      case AST_DATA_DOUBLE:
         notmatch = data_search_cmp_dbl(struct_children,
            node->name,
            mapping[member].get.AST_DATA_DOUBLE(structure));
         break;
      case AST_DATA_IPADDR:
         notmatch = data_search_cmp_ipaddr(struct_children,
            node->name,
            mapping[member].get.AST_DATA_IPADDR(structure));
         break;
      case AST_DATA_POINTER:
         notmatch = data_search_cmp_ptr(struct_children,
            node->name,
            mapping[member].get.AST_DATA_POINTER(structure));
         break;
      case AST_DATA_CONTAINER:
         break;
      }

      ao2_ref(node, -1);
   }
   ao2_iterator_destroy(&i);

   ao2_ref(struct_children, -1);

   return notmatch;
}
int __ast_data_unregister ( const char *  path,
const char *  registrar 
)

Unregister a data provider.

Parameters:
[in]pathWhich node to unregister, if path is NULL unregister every node registered by the passed 'registrar'.
[in]registrarWho is trying to unregister this node, only the owner (the one who registered the node) will be able to unregister it.
See also:
ast_data_register
Return values:
<0on error.
0on success.
See also:
__ast_data_register, __ast_data_register_multiple

Definition at line 586 of file data.c.

References ast_log(), data_provider_release(), data_provider_release_all(), data_unlock, data_write_lock, LOG_ERROR, and root_data.

Referenced by __ast_data_register_multiple().

{
   int ret = 0;

   data_write_lock();
   if (path) {
      ret = data_provider_release(root_data.container, path, registrar);
   } else {
      data_provider_release_all(root_data.container, registrar);
   }
   data_unlock();

   if (path && ret) {
      ast_log(LOG_ERROR, "Unable to unregister '%s' for '%s'\n",
         path, registrar);
   }

   return ret;
}
static void __data_result_print_cli ( int  fd,
const struct ast_data root,
uint32_t  depth 
) [static]

Definition at line 2818 of file data.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_DATA_CONTAINER, ast_data::children, data_result_print_cli_node(), and ast_data::type.

Referenced by data_result_print_cli(), and data_result_print_cli_node().

{
   struct ao2_iterator iter;
   struct ast_data *node;

   if (root->type == AST_DATA_CONTAINER) {
      iter = ao2_iterator_init(root->children, 0);
      while ((node = ao2_iterator_next(&iter))) {
         data_result_print_cli_node(fd, node, depth + 1);
         ao2_ref(node, -1);
      }
      ao2_iterator_destroy(&iter);
   } else {
      data_result_print_cli_node(fd, root, depth);
   }
}
struct ast_data* ast_data_add_bool ( struct ast_data root,
const char *  childname,
unsigned int  boolean 
) [read]

Add a boolean node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]booleanThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2344 of file data.c.

References __ast_data_add(), and AST_DATA_BOOLEAN.

Referenced by __ast_data_add_structure(), agents_data_provider_get(), ast_channel_data_add_structure(), channel_data_add_flags(), dahdi_status_data_provider_get(), data_channeltypes_provider_handler(), data_odbc_provider_handler(), peers_data_provider_get(), and users_data_provider_get().

{
   return __ast_data_add(root, childname, AST_DATA_BOOLEAN, &boolean);
}
struct ast_data* ast_data_add_char ( struct ast_data root,
const char *  childname,
char  value 
) [read]

Add a char node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]valueThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2327 of file data.c.

References __ast_data_add(), and AST_DATA_CHARACTER.

Referenced by __ast_data_add_structure().

int ast_data_add_codec ( struct ast_data root,
const char *  node_name,
struct ast_format format 
)

Add the codec in the root node based on the format parameter.

Parameters:
[in]rootThe astdata root node where to add the codec node.
[in]node_nameThe name of the node where we are going to add the codec.
[in]formatThe codec allowed.
Returns:
< 0 on error.
0 on success.

Definition at line 3111 of file data.c.

References ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_list_destroy(), ast_format_list_get(), desc, ast_format_list::fr_len, data_filter::name, and ast_format_list::samplespersecond.

Referenced by ast_channel_data_add_structure().

{
   struct ast_data *codecs, *codec;
   size_t fmlist_size;
   const struct ast_format_list *fmlist;
   int x;

   codecs = ast_data_add_node(root, node_name);
   if (!codecs) {
      return -1;
   }
   fmlist = ast_format_list_get(&fmlist_size);
   for (x = 0; x < fmlist_size; x++) {
      if (ast_format_cmp(&fmlist[x].format, format) == AST_FORMAT_CMP_EQUAL) {
         codec = ast_data_add_node(codecs, "codec");
         if (!codec) {
            ast_format_list_destroy(fmlist);
            return -1;
         }
         ast_data_add_str(codec, "name", fmlist[x].name);
         ast_data_add_int(codec, "samplespersecond", fmlist[x].samplespersecond);
         ast_data_add_str(codec, "description", fmlist[x].desc);
         ast_data_add_int(codec, "frame_length", fmlist[x].fr_len);
      }
   }
   ast_format_list_destroy(fmlist);

   return 0;
}
int ast_data_add_codecs ( struct ast_data root,
const char *  node_name,
struct ast_format_cap capability 
)

Add the list of codecs in the root node based on the capability parameter.

Parameters:
[in]rootThe astdata root node where to add the codecs node.
[in]node_nameThe name of the node where we are going to add the list of codecs.
[in]capabilityThe codecs allowed.
Returns:
< 0 on error.
0 on success.

Definition at line 3141 of file data.c.

References ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_format_cap_iscompatible(), ast_format_list_destroy(), ast_format_list_get(), desc, format, ast_format_list::fr_len, data_filter::name, and ast_format_list::samplespersecond.

Referenced by ast_channel_data_add_structure(), data_channeltypes_provider_handler(), iax2_data_add_codecs(), and peers_data_provider_get().

{
   struct ast_data *codecs, *codec;
   size_t fmlist_size;
   const struct ast_format_list *fmlist;
   int x;

   codecs = ast_data_add_node(root, node_name);
   if (!codecs) {
      return -1;
   }
   fmlist = ast_format_list_get(&fmlist_size);
   for (x = 0; x < fmlist_size; x++) {
      if (ast_format_cap_iscompatible(cap, &fmlist[x].format)) {
         codec = ast_data_add_node(codecs, "codec");
         if (!codec) {
            ast_format_list_destroy(fmlist);
            return -1;
         }
         ast_data_add_str(codec, "name", fmlist[x].name);
         ast_data_add_int(codec, "samplespersecond", fmlist[x].samplespersecond);
         ast_data_add_str(codec, "description", fmlist[x].desc);
         ast_data_add_int(codec, "frame_length", fmlist[x].fr_len);
      }
   }
   ast_format_list_destroy(fmlist);

   return 0;
}
struct ast_data* ast_data_add_dbl ( struct ast_data root,
const char *  childname,
double  dbl 
) [read]

Add a floating point node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]dblThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2338 of file data.c.

References __ast_data_add(), and AST_DATA_DOUBLE.

Referenced by __ast_data_add_structure().

{
   return __ast_data_add(root, childname, AST_DATA_DOUBLE, &dbl);
}
struct ast_data* ast_data_add_int ( struct ast_data root,
const char *  childname,
int  value 
) [read]

Add an integer node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]valueThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2322 of file data.c.

References __ast_data_add(), and AST_DATA_INTEGER.

Referenced by __ast_data_add_structure(), ast_cdr_data_add_structure(), ast_channel_data_add_structure(), ast_data_add_codec(), ast_data_add_codecs(), dahdi_status_data_provider_get(), data_odbc_provider_handler(), hints_data_provider_get(), peers_data_provider_get(), queues_data_provider_get_helper(), user_add_provider_cb(), users_data_provider_get(), and vm_users_data_provider_get_helper().

{
   return __ast_data_add(root, name, AST_DATA_INTEGER, &value);
}
struct ast_data* ast_data_add_ipaddr ( struct ast_data root,
const char *  childname,
struct in_addr  addr 
) [read]

Add a ipv4 address type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]addrThe ipv4 address value.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2350 of file data.c.

References __ast_data_add(), and AST_DATA_IPADDR.

Referenced by __ast_data_add_structure().

{
   return __ast_data_add(root, childname, AST_DATA_IPADDR, &addr);
}
struct ast_data* ast_data_add_milliseconds ( struct ast_data root,
const char *  childname,
unsigned int  milliseconds 
) [read]

Add a milliseconds node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]millisecondsThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2374 of file data.c.

References __ast_data_add(), and AST_DATA_MILLISECONDS.

Referenced by __ast_data_add_structure().

{
   return __ast_data_add(root, childname, AST_DATA_MILLISECONDS, &milliseconds);
}
struct ast_data* ast_data_add_password ( struct ast_data root,
const char *  childname,
const char *  string 
) [read]

Add a password node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]stringThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2380 of file data.c.

References __ast_data_add(), AST_DATA_PASSWORD, ast_free, ast_malloc, ast_strlen_zero(), and data_filter::name.

Referenced by __ast_data_add_structure(), and users_data_provider_get().

{
   char *name;
   size_t namelen = 1 + (ast_strlen_zero(value) ? 0 : strlen(value));
   struct ast_data *res;

   if (!(name = ast_malloc(namelen))) {
      return NULL;
   }

   strcpy(name, (ast_strlen_zero(value) ? "" : value));

   res = __ast_data_add(root, childname, AST_DATA_PASSWORD, name);
   if (!res) {
      ast_free(name);
   }

   return res;
}
struct ast_data* ast_data_add_ptr ( struct ast_data root,
const char *  childname,
void *  ptr 
) [read]

Add a ptr node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]ptrThe pointer value to add.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2356 of file data.c.

References __ast_data_add(), and AST_DATA_POINTER.

Referenced by __ast_data_add_structure().

{
   return __ast_data_add(root, childname, AST_DATA_POINTER, ptr);
}
struct ast_data* ast_data_add_seconds ( struct ast_data root,
const char *  childname,
unsigned int  seconds 
) [read]

Add a seconds node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]secondsThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2368 of file data.c.

References __ast_data_add(), and AST_DATA_SECONDS.

Referenced by __ast_data_add_structure().

{
   return __ast_data_add(root, childname, AST_DATA_SECONDS, &seconds);
}
struct ast_data* ast_data_add_str ( struct ast_data root,
const char *  childname,
const char *  string 
) [read]

Add a string node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]stringThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2401 of file data.c.

References __ast_data_add(), AST_DATA_STRING, ast_free, ast_malloc, ast_strlen_zero(), and data_filter::name.

Referenced by __ast_data_add_structure(), agents_data_provider_get(), ast_cdr_data_add_structure(), ast_channel_data_add_structure(), ast_data_add_codec(), ast_data_add_codecs(), dahdi_status_data_provider_get(), dahdi_version_data_provider_get(), data_channeltypes_provider_handler(), data_odbc_provider_handler(), hints_data_provider_get(), peers_data_provider_get(), queues_data_provider_get_helper(), and users_data_provider_get().

{
   char *name;
   size_t namelen = 1 + (ast_strlen_zero(value) ? 0 : strlen(value));
   struct ast_data *res;

   if (!(name = ast_malloc(namelen))) {
      return NULL;
   }

   strcpy(name, (ast_strlen_zero(value) ? "" : value));

   res = __ast_data_add(root, childname, AST_DATA_STRING, name);
   if (!res) {
      ast_free(name);
   }

   return res;
}
struct ast_data* ast_data_add_timestamp ( struct ast_data root,
const char *  childname,
unsigned int  timestamp 
) [read]

Add a timestamp node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]timestampThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2362 of file data.c.

References __ast_data_add(), and AST_DATA_TIMESTAMP.

Referenced by __ast_data_add_structure().

{
   return __ast_data_add(root, childname, AST_DATA_TIMESTAMP, &timestamp);
}
struct ast_data* ast_data_add_uint ( struct ast_data root,
const char *  childname,
unsigned int  value 
) [read]

Add an unsigned integer node type.

Parameters:
[in]rootThe root of the ast_data to insert into.
[in]childnameThe name of the child element to be added.
[in]valueThe value for the new node.
Return values:
NULLon error (memory exhaustion only).
non-NULLa newly allocated node.

Definition at line 2332 of file data.c.

References __ast_data_add(), and AST_DATA_UNSIGNED_INTEGER.

Referenced by __ast_data_add_structure(), and ast_channel_data_add_structure().

void ast_data_free ( struct ast_data root)

Release the allocated memory of a tree.

Parameters:
[in]rootThe sub-tree pointer returned by a call to ast_data_get.
See also:
ast_data_get

Definition at line 2491 of file data.c.

References ao2_ref.

Referenced by ast_data_get_xml(), handle_cli_data_get(), and manager_data_get().

{
   /* destroy it, this will destroy all the internal nodes. */
   ao2_ref(root, -1);
}
struct ast_data* ast_data_get ( const struct ast_data_query query) [read]

Retrieve a subtree from the asterisk data API.

Parameters:
[in]queryThe query structure specifying what nodes to retrieve.
Return values:
NULLon error.
non-NULLThe dynamically allocated requested sub-tree (it needs to be released using ast_data_free.
See also:
ast_data_free, ast_data_get_xml

Definition at line 2065 of file data.c.

References ast_log(), data_read_lock, data_result_generate(), data_structure_compatible(), data_unlock, LOG_ERROR, ast_data_query::path, and ast_data_query::version.

Referenced by ast_data_get_xml(), handle_cli_data_get(), and manager_data_get().

{
   struct ast_data *res;

   /* check compatibility */
   if (!data_structure_compatible(query->version, latest_query_compatible_version,
      current_query_version)) {
      return NULL;
   }

   data_read_lock();
   res = data_result_generate(query, query->path);
   data_unlock();

   if (!res) {
      ast_log(LOG_ERROR, "Unable to get data from %s\n", query->path);
      return NULL;
   }

   return res;
}
struct ast_xml_doc* ast_data_get_xml ( const struct ast_data_query query) [read]

Retrieve a subtree from the asterisk data API in XML format..

Parameters:
[in]queryThe query structure specifying what nodes to retrieve.
Return values:
NULLon error.
non-NULLThe dynamically allocated requested sub-tree (it needs to be released using ast_data_free.
See also:
ast_data_free, ast_data_get

Definition at line 2181 of file data.c.

References ast_data_free(), ast_data_get(), ast_xml_close(), ast_xml_new(), ast_xml_new_node(), ast_xml_set_root(), data_get_xml_add_child(), and ast_data::name.

{
   struct ast_xml_doc *doc;
   struct ast_xml_node *root;
   struct ast_data *res;

   res = ast_data_get(query);
   if (!res) {
      return NULL;
   }

   doc = ast_xml_new();
   if (!doc) {
      ast_data_free(res);
      return NULL;
   }

   root = ast_xml_new_node(res->name);
   if (!root) {
      ast_xml_close(doc);
   }

   ast_xml_set_root(doc, root);

   data_get_xml_add_child(res, root);

   ast_data_free(res);

   return doc;
}
void ast_data_iterator_end ( struct ast_data_iterator iterator)

Release (stop using) an iterator.

Parameters:
[in]iteratorThe iterator created by ast_data_iterator_start.
See also:
ast_data_iterator_start

Definition at line 2542 of file data.c.

References ao2_iterator_destroy(), ao2_ref, ast_free, ast_data_iterator::internal_iterator, ast_data_iterator::is_pattern, ast_data_iterator::last, and ast_data_iterator::regex_pattern.

{
   /* decrement the reference counter. */
   if (iterator->last) {
      ao2_ref(iterator->last, -1);
   }

   /* release the generated pattern. */
   if (iterator->is_pattern) {
      regfree(&(iterator->regex_pattern));
   }

   ao2_iterator_destroy(&(iterator->internal_iterator));

   ast_free(iterator);
   iterator = NULL;
}
struct ast_data_iterator* ast_data_iterator_init ( struct ast_data tree,
const char *  elements 
) [read]

Initialize an iterator.

Parameters:
[in]treeThe returned tree by a call to ast_data_get.
[in]elementsWhich elements to iterate through.
Return values:
NULLon error.
non-NULLA dinamically allocated iterator structure.

Definition at line 2497 of file data.c.

References ao2_iterator_init(), ast_calloc, data_result_get_node(), ast_data_iterator::internal_iterator, ast_data_iterator::is_pattern, ast_data_iterator::pattern, ast_data::ptr, and ast_data_iterator::regex_pattern.

{
   struct ast_data_iterator *iterator;
   struct ao2_iterator i;
   struct ast_data *internal = tree;
   char *path, *ptr = NULL;

   if (!elements) {
      return NULL;
   }

   /* tree is the node we want to use to iterate? or we are going
    * to iterate thow an internal node? */
   path = ast_strdupa(elements);

   ptr = strrchr(path, '/');
   if (ptr) {
      *ptr = '\0';
      internal = data_result_get_node(tree, path);
      if (!internal) {
         return NULL;
      }
   }

   iterator = ast_calloc(1, sizeof(*iterator));
   if (!iterator) {
      return NULL;
   }

   i = ao2_iterator_init(internal->children, 0);

   iterator->pattern = (ptr ? strrchr(elements, '/') + 1 : elements);

   /* is the last node a regular expression?, compile it! */
   if (!regcomp(&(iterator->regex_pattern), iterator->pattern,
         REG_EXTENDED | REG_NOSUB | REG_ICASE)) {
      iterator->is_pattern = 1;
   }

   iterator->internal_iterator = i;

   return iterator;
}
struct ast_data* ast_data_iterator_next ( struct ast_data_iterator iterator) [read]

Get the next node of the tree.

Parameters:
[in]iteratorThe iterator structure returned by ast_data_iterator_start.
Return values:
NULLwhen no more nodes to return.
non-NULLA node of the ast_data tree.
See also:
ast_data_iterator_start, ast_data_iterator_stop

Definition at line 2560 of file data.c.

References ao2_iterator_next, ao2_ref, ast_data_iterator::internal_iterator, ast_data_iterator::is_pattern, ast_data_iterator::last, ast_data::name, ast_data_iterator::pattern, and ast_data_iterator::regex_pattern.

{
   struct ast_data *res;

   if (iterator->last) {
      /* release the last retrieved node reference. */
      ao2_ref(iterator->last, -1);
   }

   while ((res = ao2_iterator_next(&iterator->internal_iterator))) {
      /* if there is no node name pattern specified, return
       * the next node. */
      if (!iterator->pattern) {
         break;
      }

      /* if the pattern is a regular expression, check if this node
       * matches. */
      if (iterator->is_pattern && !regexec(&(iterator->regex_pattern),
         res->name, 0, NULL, 0)) {
         break;
      }

      /* if there is a pattern specified, check if this node matches
       * the wanted node names. */
      if (!iterator->is_pattern && (iterator->pattern &&
            !strcasecmp(res->name, iterator->pattern))) {
         break;
      }

      ao2_ref(res, -1);
   }

   iterator->last = res;

   return res;
}
void ast_data_remove_node ( struct ast_data root,
struct ast_data child 
)
int ast_data_retrieve ( struct ast_data tree,
const char *  path,
struct ast_data_retrieve content 
)

Retrieve a value from a node in the tree.

Parameters:
[in]treeThe structure returned by a call to ast_data_get.
[in]pathThe path to the node.
[out]contentThe node content.
Return values:
0on success.
<0on error.

Definition at line 2598 of file data.c.

References AST_DATA_BOOLEAN, ast_data_retrieve::AST_DATA_BOOLEAN, AST_DATA_CHARACTER, ast_data_retrieve::AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, ast_data_retrieve::AST_DATA_DOUBLE, AST_DATA_INTEGER, ast_data_retrieve::AST_DATA_INTEGER, AST_DATA_IPADDR, ast_data_retrieve::AST_DATA_IPADDR, AST_DATA_MILLISECONDS, ast_data_retrieve::AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, ast_data_retrieve::AST_DATA_PASSWORD, AST_DATA_POINTER, ast_data_retrieve::AST_DATA_POINTER, AST_DATA_SECONDS, ast_data_retrieve::AST_DATA_SECONDS, AST_DATA_STRING, ast_data_retrieve::AST_DATA_STRING, AST_DATA_TIMESTAMP, ast_data_retrieve::AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, ast_data_retrieve::AST_DATA_UNSIGNED_INTEGER, ast_log(), ast_data::boolean, ast_data::character, data_result_get_node(), ast_data::dbl, ast_data::ipaddr, LOG_ERROR, ast_data::payload, ast_data::ptr, ast_data::sint, ast_data::str, ast_data::type, ast_data_retrieve::type, ast_data::uint, and ast_data_retrieve::value.

Referenced by ast_data_retrieve_bool(), ast_data_retrieve_char(), ast_data_retrieve_dbl(), ast_data_retrieve_int(), ast_data_retrieve_ipaddr(), ast_data_retrieve_password(), ast_data_retrieve_ptr(), ast_data_retrieve_string(), and ast_data_retrieve_uint().

{
   struct ast_data *node;

   if (!content) {
      return -1;
   }

   node = data_result_get_node(tree, path);
   if (!node) {
      ast_log(LOG_ERROR, "Invalid internal node %s\n", path);
      return -1;
   }

   content->type = node->type;
   switch (node->type) {
   case AST_DATA_STRING:
      content->value.AST_DATA_STRING = node->payload.str;
      break;
   case AST_DATA_PASSWORD:
      content->value.AST_DATA_PASSWORD = node->payload.str;
      break;
   case AST_DATA_TIMESTAMP:
      content->value.AST_DATA_TIMESTAMP = node->payload.uint;
      break;
   case AST_DATA_SECONDS:
      content->value.AST_DATA_SECONDS = node->payload.uint;
      break;
   case AST_DATA_MILLISECONDS:
      content->value.AST_DATA_MILLISECONDS = node->payload.uint;
      break;
   case AST_DATA_CHARACTER:
      content->value.AST_DATA_CHARACTER = node->payload.character;
      break;
   case AST_DATA_INTEGER:
      content->value.AST_DATA_INTEGER = node->payload.sint;
      break;
   case AST_DATA_UNSIGNED_INTEGER:
      content->value.AST_DATA_UNSIGNED_INTEGER = node->payload.uint;
      break;
   case AST_DATA_BOOLEAN:
      content->value.AST_DATA_BOOLEAN = node->payload.boolean;
      break;
   case AST_DATA_IPADDR:
      content->value.AST_DATA_IPADDR = node->payload.ipaddr;
      break;
   case AST_DATA_DOUBLE:
      content->value.AST_DATA_DOUBLE = node->payload.dbl;
      break;
   case AST_DATA_CONTAINER:
      break;
   case AST_DATA_POINTER:
      content->value.AST_DATA_POINTER = node->payload.ptr;
      break;
   }

   return 0;
}
char* ast_data_retrieve_name ( struct ast_data node)

Get the node name.

Parameters:
[in]nodeThe node pointer.
Returns:
The node name.

Definition at line 2225 of file data.c.

References ast_data::name.

{
   return node->name;
}
enum ast_data_type ast_data_retrieve_type ( struct ast_data res,
const char *  path 
)

Get a node type.

Parameters:
[in]resA pointer to the ast_data result set.
[in]pathA path to the node to get the type.
Returns:
The type of the requested node type.

Definition at line 2213 of file data.c.

References data_result_get_node().

{
   struct ast_data *internal;

   internal = data_result_get_node(node, path);
   if (!internal) {
      return -1;
   }

   return internal->type;
}
int ast_data_search_match ( const struct ast_data_search search,
struct ast_data data 
)

Check the current generated node to know if it matches the search condition.

Parameters:
[in]searchThe search condition.
[in]dataThe AstData node generated.
Returns:
1 If the "data" node matches the search condition.
0 If the "data" node does not matches the search condition.
See also:
ast_data_remove_node

Definition at line 1458 of file data.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_DATA_BOOLEAN, AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, AST_DATA_INTEGER, AST_DATA_IPADDR, AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, AST_DATA_POINTER, ast_data_search_match(), AST_DATA_SECONDS, AST_DATA_STRING, AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, ast_data::boolean, ast_data::character, ast_data::children, ast_data_search::children, data_result_find_child(), data_search_cmp_bool(), data_search_cmp_char(), data_search_cmp_int(), data_search_cmp_ipaddr(), data_search_cmp_ptr(), data_search_cmp_string(), data_search_cmp_uint(), data_search_find(), ast_data::dbl, ast_data::ipaddr, ast_data::name, ast_data_search::name, ast_data::payload, ast_data::ptr, ast_data::sint, ast_data::str, ast_data::type, and ast_data::uint.

Referenced by agents_data_provider_get(), ast_data_search_match(), dahdi_channels_data_provider_get(), dahdi_status_data_provider_get(), data_channels_provider_handler(), data_channeltypes_provider_handler(), data_odbc_provider_handler(), hints_data_provider_get(), meetme_data_provider_get(), peers_data_provider_get(), queues_data_provider_get_helper(), users_data_provider_get(), and vm_users_data_provider_get_helper().

{
   struct ao2_iterator i, ii;
   struct ast_data_search *s, *s_child;
   struct ast_data *d_child;
   int notmatch = 1;

   if (!search) {
      return 1;
   }

   s_child = data_search_find(search->children, data->name);
   if (!s_child) {
      /* nothing to compare */
      ao2_ref(s_child, -1);
      return 1;
   }

   i = ao2_iterator_init(s_child->children, 0);
   while ((s = ao2_iterator_next(&i))) {
      if (!ao2_container_count(s->children)) {
         /* compare this search node with every data node */
         d_child = data_result_find_child(data, s->name);
         if (!d_child) {
            ao2_ref(s, -1);
            notmatch = 1;
            continue;
         }

         switch (d_child->type) {
         case AST_DATA_PASSWORD:
         case AST_DATA_STRING:
            notmatch = data_search_cmp_string(s_child, d_child->name,
               d_child->payload.str);
            break;
         case AST_DATA_CHARACTER:
            notmatch = data_search_cmp_char(s_child, d_child->name,
               d_child->payload.character);
            break;
         case AST_DATA_INTEGER:
            notmatch = data_search_cmp_int(s_child, d_child->name,
               d_child->payload.sint);
            break;
         case AST_DATA_BOOLEAN:
            notmatch = data_search_cmp_bool(s_child, d_child->name,
               d_child->payload.boolean);
            break;
         case AST_DATA_UNSIGNED_INTEGER:
            notmatch = data_search_cmp_uint(s_child, d_child->name,
               d_child->payload.uint);
            break;
         case AST_DATA_TIMESTAMP:
         case AST_DATA_SECONDS:
         case AST_DATA_MILLISECONDS:
         case AST_DATA_DOUBLE:
            notmatch = data_search_cmp_uint(s_child, d_child->name,
               d_child->payload.dbl);
            break;
         case AST_DATA_IPADDR:
            notmatch = data_search_cmp_ipaddr(s_child, d_child->name,
               d_child->payload.ipaddr);
            break;
         case AST_DATA_POINTER:
            notmatch = data_search_cmp_ptr(s_child, d_child->name,
               d_child->payload.ptr);
            break;
         case AST_DATA_CONTAINER:
            break;
         }
         ao2_ref(d_child, -1);
      } else {
         ii = ao2_iterator_init(data->children, 0);
         while ((d_child = ao2_iterator_next(&ii))) {
            if (strcmp(d_child->name, s->name)) {
               ao2_ref(d_child, -1);
               continue;
            }
            if (!(notmatch = !ast_data_search_match(s_child, d_child))) {
               /* do not continue if we have a match. */
               ao2_ref(d_child, -1);
               break;
            }
            ao2_ref(d_child, -1);
         }
         ao2_iterator_destroy(&ii);
      }
      ao2_ref(s, -1);
      if (notmatch) {
         /* do not continue if we don't have a match. */
         break;
      }
   }
   ao2_iterator_destroy(&i);

   ao2_ref(s_child, -1);

   return !notmatch;
}
static struct data_filter* data_filter_add_child ( struct ao2_container root,
char *  name 
) [static, read]

Definition at line 1780 of file data.c.

References ao2_link, data_filter_alloc(), and data_filter_find().

Referenced by data_filter_add_nodes().

{
   struct data_filter *node;

   node = data_filter_find(root, name);
   if (node) {
      return node;
   }

   node = data_filter_alloc(name);
   if (!node) {
      return NULL;
   }

   ao2_link(root, node);

   return node;
}
static int data_filter_add_nodes ( struct ao2_container root,
char *  path 
) [static]

Definition at line 1808 of file data.c.

References ao2_ref, data_filter::children, data_filter_add_child(), and next_node_name().

Referenced by data_filter_generate().

{
   struct data_filter *node;
   char *savepath, *saveptr, *token, *node_name;
   int ret = 0;

   if (!path) {
      return 0;
   }

   savepath = ast_strdupa(path);

   node_name = next_node_name(&savepath);

   if (!node_name) {
      return 0;
   }

   for (token = strtok_r(node_name, "|", &saveptr);
         token; token = strtok_r(NULL, "|", &saveptr)) {
      node = data_filter_add_child(root, token);
      if (!node) {
         continue;
      }
      data_filter_add_nodes(node->children, savepath);
      ret = 1;
      ao2_ref(node, -1);
   }

   return ret;
}
static struct data_filter* data_filter_alloc ( const char *  name) [static, read]

Definition at line 1647 of file data.c.

References ao2_alloc, ao2_container_alloc, ao2_ref, AST_LIST_INSERT_TAIL, data_filter::children, data_filter_cmp(), data_filter_destructor(), data_filter_hash(), data_filter::glob_list, data_filter::list, data_filter::name, and NUM_DATA_FILTER_BUCKETS.

Referenced by data_filter_add_child(), data_filter_find(), and data_filter_generate().

{
   char *globname, *token;
   struct data_filter *res, *globfilter;
   size_t name_len = strlen(name) + 1;

   res = ao2_alloc(sizeof(*res) + name_len, data_filter_destructor);
   if (!res) {
      return NULL;
   }

   res->children = ao2_container_alloc(NUM_DATA_FILTER_BUCKETS, data_filter_hash,
      data_filter_cmp);

   if (!res->children) {
      ao2_ref(res, -1);
      return NULL;
   }

   strcpy(res->name, name);

   if (strchr(res->name, '*')) {
      globname = ast_strdupa(res->name);

      while ((token = strsep(&globname, "*"))) {
         globfilter = data_filter_alloc(token);
         AST_LIST_INSERT_TAIL(&(res->glob_list), globfilter, list);
      }
   }

   return res;
}
static int data_filter_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1619 of file data.c.

References CMP_MATCH, and data_filter::name.

Referenced by data_filter_alloc().

{
   struct data_filter *node1 = obj, *node2 = arg;
   return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
}
static void data_filter_destructor ( void *  obj) [static]

Definition at line 1630 of file data.c.

References ao2_ref, AST_LIST_REMOVE_HEAD, data_filter::children, filter(), data_filter::glob_list, and data_filter::list.

Referenced by data_filter_alloc().

{
   struct data_filter *filter = obj, *globres;

   while ((globres = AST_LIST_REMOVE_HEAD(&(filter->glob_list), list))) {
      ao2_ref(globres, -1);
   }

   ao2_ref(filter->children, -1);
}
static struct data_filter* data_filter_find ( struct ao2_container parent,
const char *  name 
) [static, read]

Definition at line 1699 of file data.c.

References ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_strlen_zero(), data_filter_alloc(), data_filter::glob_list, data_filter::list, data_filter::name, and OBJ_POINTER.

Referenced by __ast_data_add(), data_filter_add_child(), data_result_generate(), and data_result_generate_node().

{
   int i, olend, orend, globfound;
   size_t name_len = strlen(name), glob_len;
   struct ao2_iterator iter;
   struct data_filter *find_node, *found, *globres;

   find_node = data_filter_alloc(name);
   if (!find_node) {
      return NULL;
   }

   found = ao2_find(parent, find_node, OBJ_POINTER);

   /* free the created node used for searching. */
   ao2_ref(find_node, -1);

   if (found) {
      return found;
   }

   iter = ao2_iterator_init(parent, 0);
   while ((found = ao2_iterator_next(&iter))) {
      if (!AST_LIST_EMPTY(&(found->glob_list))) {
         i = 0;
         globfound = 1;

         olend = ast_strlen_zero(AST_LIST_FIRST(&(found->glob_list))->name);
         orend = ast_strlen_zero(AST_LIST_LAST(&(found->glob_list))->name);

         AST_LIST_TRAVERSE(&(found->glob_list), globres, list) {
            if (!*globres->name) {
               continue;
            }

            glob_len = strlen(globres->name);

            if (!i && !olend) {
               if (strncasecmp(name, globres->name, glob_len)) {
                  globfound = 0;
                  break;
               }

               i += glob_len;
               continue;
            }

            for (globfound = 0; name_len - i >= glob_len; ++i) {
               if (!strncasecmp(name + i, globres->name, glob_len)) {
                  globfound = 1;
                  i += glob_len;
                  break;
               }
            }

            if (!globfound) {
               break;
            }
         }

         if (globfound && (i == name_len || orend)) {
            ao2_iterator_destroy(&iter);
            return found;
         }
      }

      ao2_ref(found, -1);
   }
   ao2_iterator_destroy(&iter);

   return NULL;
}
static struct data_filter* data_filter_generate ( const char *  constfilter) [static, read]

Definition at line 1845 of file data.c.

References ao2_ref, data_filter::children, data_filter_add_nodes(), data_filter_alloc(), and filter().

Referenced by data_result_generate().

{
   struct data_filter *filter = NULL;
   char *strfilter, *token, *saveptr;
   int node_added = 0;

   if (!constfilter) {
      return NULL;
   }

   strfilter = ast_strdupa(constfilter);

   filter = data_filter_alloc("/");
   if (!filter) {
      return NULL;
   }

   for (token = strtok_r(strfilter, ",", &saveptr); token;
         token = strtok_r(NULL, ",", &saveptr)) {
      node_added = data_filter_add_nodes(filter->children, token);
   }

   if (!node_added) {
      ao2_ref(filter, -1);
      return NULL;
   }

   return filter;
}
static int data_filter_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 1609 of file data.c.

References ast_str_hash(), and data_filter::name.

Referenced by data_filter_alloc().

{
   const struct data_filter *node = obj;
   return ast_str_hash(node->name);
}
static void data_filter_release ( struct data_filter filter) [static]

Definition at line 1685 of file data.c.

References ao2_ref.

Referenced by data_result_generate().

{
   ao2_ref(filter, -1);
}
static void data_get_xml_add_child ( struct ast_data parent_data,
struct ast_xml_node *  parent_xml 
) [static]

Definition at line 2094 of file data.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_DATA_BOOLEAN, AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, AST_DATA_INTEGER, AST_DATA_IPADDR, AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, AST_DATA_POINTER, AST_DATA_SECONDS, AST_DATA_STRING, AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, ast_inet_ntoa(), ast_xml_add_child(), ast_xml_new_node(), ast_xml_set_text(), ast_data::boolean, ast_data::character, ast_data::children, ast_data::dbl, ast_data::ipaddr, ast_data::name, ast_data::payload, ast_data::ptr, ast_data::sint, ast_data::str, ast_data::type, and ast_data::uint.

Referenced by ast_data_get_xml().

{
   struct ao2_iterator i;
   struct ast_data *node;
   struct ast_xml_node *child_xml;
   char node_content[256];

   i = ao2_iterator_init(parent_data->children, 0);
   while ((node = ao2_iterator_next(&i))) {
      child_xml = ast_xml_new_node(node->name);
      if (!child_xml) {
         ao2_ref(node, -1);
         continue;
      }

      switch (node->type) {
      case AST_DATA_CONTAINER:
         data_get_xml_add_child(node, child_xml);
         break;
      case AST_DATA_PASSWORD:
         ast_xml_set_text(child_xml, node->payload.str);
         break;
      case AST_DATA_TIMESTAMP:
         snprintf(node_content, sizeof(node_content), "%d",
            node->payload.uint);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_SECONDS:
         snprintf(node_content, sizeof(node_content), "%d",
            node->payload.uint);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_MILLISECONDS:
         snprintf(node_content, sizeof(node_content), "%d",
            node->payload.uint);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_STRING:
         ast_xml_set_text(child_xml, node->payload.str);
         break;
      case AST_DATA_CHARACTER:
         snprintf(node_content, sizeof(node_content), "%c",
            node->payload.character);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_INTEGER:
         snprintf(node_content, sizeof(node_content), "%d",
            node->payload.sint);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_UNSIGNED_INTEGER:
         snprintf(node_content, sizeof(node_content), "%u",
            node->payload.uint);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_DOUBLE:
         snprintf(node_content, sizeof(node_content), "%f",
            node->payload.dbl);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_BOOLEAN:
         if (node->payload.boolean) {
            ast_xml_set_text(child_xml, "true");
         } else {
            ast_xml_set_text(child_xml, "false");
         }
         break;
      case AST_DATA_POINTER:
         snprintf(node_content, sizeof(node_content), "%p",
            node->payload.ptr);
         ast_xml_set_text(child_xml, node_content);
         break;
      case AST_DATA_IPADDR:
         snprintf(node_content, sizeof(node_content), "%s",
            ast_inet_ntoa(node->payload.ipaddr));
         ast_xml_set_text(child_xml, node_content);
         break;
      }
      ast_xml_add_child(parent_xml, child_xml);

      ao2_ref(node, -1);
   }
   ao2_iterator_destroy(&i);

}
static struct data_provider* data_provider_add_child ( struct ao2_container parent,
const char *  name,
const struct ast_data_handler handler,
const char *  registrar 
) [static, read]

Definition at line 344 of file data.c.

References ao2_link, and data_provider_new().

Referenced by data_provider_create().

{
   struct data_provider *child;

   child = data_provider_new(name, handler, registrar);
   if (!child) {
      return NULL;
   }

   ao2_link(parent, child);

   return child;
}
static int data_provider_cmp ( void *  obj1,
void *  obj2,
int  flags 
) [static]

Definition at line 200 of file data.c.

References CMP_MATCH, and data_provider::name.

Referenced by ast_data_init(), and data_provider_new().

{
   struct data_provider *node1 = obj1, *node2 = obj2;
   return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
}
static struct data_provider* data_provider_create ( struct ao2_container parent,
const char *  path,
const char *  registrar 
) [static, read]

Definition at line 487 of file data.c.

References ao2_ref, data_provider::children, data_provider_add_child(), data_provider_find(), and next_node_name().

Referenced by __ast_data_register().

{
   char *rpath, *node_name;
   struct data_provider *child, *ret = NULL;

   rpath = ast_strdupa(path);

   node_name = next_node_name(&rpath);
   if (!node_name) {
      /* no more nodes to create. */
      return NULL;
   }

   child = data_provider_find(parent, node_name, NULL);

   if (!child) {
      /* nodes without handler are non-terminal nodes. */
      child = data_provider_add_child(parent, node_name, NULL, registrar);
   }

   if (rpath) {
      ret = data_provider_create(child->children, rpath, registrar);
      if (ret) {
         ao2_ref(child, -1);
      }
   }

   return ret ? ret : child;
}
static void data_provider_destructor ( void *  obj) [static]

Definition at line 291 of file data.c.

References ao2_ref, and data_provider::children.

Referenced by data_provider_new().

{
   struct data_provider *provider = obj;

   ao2_ref(provider->children, -1);
}
static struct data_provider* data_provider_find ( struct ao2_container parent,
const char *  name,
const char *  registrar 
) [static, read]

Definition at line 369 of file data.c.

References ao2_find, ao2_ref, ast_debug, data_provider_new(), OBJ_POINTER, and data_provider::registrar.

Referenced by data_provider_create(), data_provider_release(), and data_result_generate().

{
   struct data_provider *find_node, *found;

   /* XXX avoid allocating a new data node for searching... */
   find_node = data_provider_new(name, NULL, NULL);
   if (!find_node) {
      return NULL;
   }

   found = ao2_find(parent, find_node, OBJ_POINTER);

   /* free the created node used for searching. */
   ao2_ref(find_node, -1);

   if (found && found->registrar && registrar) {
      if (strcmp(found->registrar, registrar)) {
         /* if the name doesn't match, do not return this node. */
         ast_debug(1, "Registrar doesn't match, node was registered"
            " by '%s' and we are searching for '%s'\n",
            found->registrar, registrar);
         ao2_ref(found, -1);
         return NULL;
      }
   }

   return found;
}
static int data_provider_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 189 of file data.c.

References ast_str_case_hash(), and data_provider::name.

Referenced by ast_data_init(), and data_provider_new().

{
   const struct data_provider *node = obj;
   return ast_str_case_hash(node->name);
}
static struct data_provider* data_provider_new ( const char *  name,
const struct ast_data_handler handler,
const char *  registrar 
) [static, read]

Definition at line 307 of file data.c.

References ao2_alloc, ao2_container_alloc, ao2_ref, data_provider::children, data_provider_cmp(), data_provider_destructor(), data_provider_hash(), data_provider::handler, data_provider::name, NUM_DATA_NODE_BUCKETS, data_provider::registrar, and registrar.

Referenced by data_provider_add_child(), and data_provider_find().

{
   struct data_provider *node;
   size_t namelen;

   namelen = strlen(name) + 1;

   node = ao2_alloc(sizeof(*node) + namelen, data_provider_destructor);
   if (!node) {
      return NULL;
   }

   node->handler = handler;
   node->registrar = registrar;
   strcpy(node->name, name);

   /* initialize the childrens container. */
   if (!(node->children = ao2_container_alloc(NUM_DATA_NODE_BUCKETS,
         data_provider_hash, data_provider_cmp))) {
      ao2_ref(node, -1);
      return NULL;
   }

   return node;
}
static void data_provider_print_cli ( int  fd,
const char *  name,
struct ao2_container container,
struct ast_str path 
) [static]

Definition at line 2919 of file data.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), ast_free, ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_set(), data_provider::children, ast_data_handler::get, data_provider::handler, data_provider::name, and data_provider::registrar.

Referenced by handle_cli_data_show_providers().

{
   struct ao2_iterator i;
   struct ast_str *current_path;
   struct data_provider *provider;

   current_path = ast_str_create(60);
   if (!current_path) {
      return;
   }

   ast_str_reset(current_path);
   if (path) {
      ast_str_set(&current_path, 0, "%s/%s", ast_str_buffer(path), name);
   } else {
      ast_str_set(&current_path, 0, "%s", name);
   }

   i = ao2_iterator_init(container, 0);
   while ((provider = ao2_iterator_next(&i))) {
      if (provider->handler) {
         /* terminal node, print it. */
         ast_cli(fd, "%s/%s (", ast_str_buffer(current_path),
            provider->name);
         if (provider->handler->get) {
            ast_cli(fd, "get");
         }
         ast_cli(fd, ") [%s]\n", provider->registrar);
      }
      data_provider_print_cli(fd, provider->name, provider->children,
         current_path);
      ao2_ref(provider, -1);
   }
   ao2_iterator_destroy(&i);

   ast_free(current_path);
}
static int data_provider_release ( struct ao2_container parent,
const char *  path,
const char *  registrar 
) [static]

Definition at line 409 of file data.c.

References ao2_container_count(), ao2_ref, ao2_unlink, data_provider::children, data_provider_find(), data_provider::handler, and next_node_name().

Referenced by __ast_data_unregister().

{
   char *node_name, *rpath;
   struct data_provider *child;
   int ret = 0;

   rpath = ast_strdupa(path);

   node_name = next_node_name(&rpath);
   if (!node_name) {
      return -1;
   }

   child = data_provider_find(parent, node_name, registrar);
   if (!child) {
      return -1;
   }

   /* if this is not a terminal node. */
   if (!child->handler && rpath) {
      ret = data_provider_release(child->children, rpath, registrar);
   }

   /* if this node is empty, unlink it. */
   if (!ret && !ao2_container_count(child->children)) {
      ao2_unlink(parent, child);
   }

   ao2_ref(child, -1);

   return ret;
}
static void data_provider_release_all ( struct ao2_container parent,
const char *  registrar 
) [static]

Definition at line 450 of file data.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ao2_unlink, data_provider::children, data_provider::handler, and data_provider::registrar.

Referenced by __ast_data_unregister().

{
   struct ao2_iterator i;
   struct data_provider *node;

   i = ao2_iterator_init(parent, 0);
   while ((node = ao2_iterator_next(&i))) {
      if (!node->handler) {
         /* this is a non-terminal node, go inside it. */
         data_provider_release_all(node->children, registrar);
         if (!ao2_container_count(node->children)) {
            /* if this node was left empty, unlink it. */
            ao2_unlink(parent, node);
         }
      } else {
         if (!strcmp(node->registrar, registrar)) {
            /* if the registrars match, release it! */
            ao2_unlink(parent, node);
         }
      }
      ao2_ref(node, -1);
   }
   ao2_iterator_destroy(&i);

}
static void data_result_add_child ( struct ast_data root,
struct ast_data child 
) [static]

Definition at line 1600 of file data.c.

References ao2_link, and ast_data::children.

Referenced by __ast_data_add(), and data_result_generate_node().

{
   ao2_link(root->children, child);
}
static int data_result_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 220 of file data.c.

References CMP_MATCH, and ast_data::name.

Referenced by data_result_create().

{
   struct ast_data *node1 = obj, *node2 = arg;
   return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
}
static struct ast_data* data_result_create ( const char *  name) [static, read]

Definition at line 1405 of file data.c.

References ao2_alloc, ao2_container_alloc, ao2_ref, AST_DATA_CONTAINER, ast_strlen_zero(), ast_data::children, data_result_cmp(), data_result_destructor(), data_result_hash(), ast_data::name, NUM_DATA_RESULT_BUCKETS, and ast_data::type.

Referenced by __ast_data_add(), data_result_find_child(), and data_result_generate_node().

{
   struct ast_data *res;
   size_t namelen;

   namelen = ast_strlen_zero(name) ? 1 : strlen(name) + 1;

   res = ao2_alloc(sizeof(*res) + namelen, data_result_destructor);
   if (!res) {
      return NULL;
   }

   strcpy(res->name, namelen ? name : "");

   /* initialize the children container */
   res->children = ao2_container_alloc(NUM_DATA_RESULT_BUCKETS, data_result_hash,
      data_result_cmp);
   if (!res->children) {
      ao2_ref(res, -1);
      return NULL;
   }

   /* set this node as a container. */
   res->type = AST_DATA_CONTAINER;

   return res;
}
static struct ast_data* data_result_find_child ( struct ast_data root,
const char *  name 
) [static, read]

Definition at line 1441 of file data.c.

References ao2_find, ao2_ref, ast_data::children, data_result_create(), and OBJ_POINTER.

Referenced by ast_data_search_match(), and data_result_get_node().

{
   struct ast_data *found, *find_node;

   find_node = data_result_create(name);
   if (!find_node) {
      return NULL;
   }

   found = ao2_find(root->children, find_node, OBJ_POINTER);

   /* release the temporary created node used for searching. */
   ao2_ref(find_node, -1);

   return found;
}
static struct ast_data* data_result_generate ( const struct ast_data_query query,
const char *  search_path 
) [static, read]

Definition at line 1973 of file data.c.

References ao2_ref, ast_log(), ast_data_search::children, data_filter::children, data_provider::children, data_filter_find(), data_filter_generate(), data_filter_release(), data_provider_find(), data_result_generate_node(), data_search_find(), data_search_generate(), data_search_release(), ast_data_query::filter, filter(), LOG_ERROR, data_provider::name, next_node_name(), root_data, and ast_data_query::search.

Referenced by ast_data_get().

{
   char *node_name, *tmp_path;
   struct data_provider *provider_child, *tmp_provider_child;
   struct ast_data *result, *result_filtered;
   struct ast_data_search *search = NULL, *search_child = NULL;
   struct data_filter *filter = NULL, *filter_child = NULL;

   if (!search_path) {
      /* generate all the trees?. */
      return NULL;
   }

   tmp_path = ast_strdupa(search_path);

   /* start searching the root node name */
   node_name = next_node_name(&tmp_path);
   if (!node_name) {
      return NULL;
   }
   provider_child = data_provider_find(root_data.container, node_name, NULL);

   /* continue with the rest of the path. */
   while (provider_child) {
      node_name = next_node_name(&tmp_path);
      if (!node_name) {
         break;
      }

      tmp_provider_child = data_provider_find(provider_child->children,
            node_name, NULL);

      /* release the reference from this child */
      ao2_ref(provider_child, -1);

      provider_child = tmp_provider_child;
   }

   if (!provider_child) {
      ast_log(LOG_ERROR, "Invalid path '%s', '%s' not found.\n",
            tmp_path, node_name);
      return NULL;
   }

   /* generate the search tree. */
   if (query->search) {
      search = data_search_generate(query->search);
      if (search) {
         search_child = data_search_find(search->children,
            provider_child->name);
      }
   }

   /* generate the filter tree. */
   if (query->filter) {
      filter = data_filter_generate(query->filter);
      if (filter) {
         filter_child = data_filter_find(filter->children,
            provider_child->name);
      }
   }

   result = data_result_generate_node(query, provider_child, provider_child->name,
         search_child, filter_child);

   /* release the requested provider. */
   ao2_ref(provider_child, -1);

   /* release the generated search tree. */
   if (search_child) {
      ao2_ref(search_child, -1);
   }

   if (filter_child) {
      ao2_ref(filter_child, -1);
   }

   if (search) {
      data_search_release(search);
   }

   result_filtered = result;

   /* release the generated filter tree. */
   if (filter) {
      data_filter_release(filter);
   }

   return result_filtered;
}
static struct ast_data* data_result_generate_node ( const struct ast_data_query query,
const struct data_provider root_provider,
const char *  parent_node_name,
const struct ast_data_search search,
const struct data_filter filter 
) [static, read]

Definition at line 1884 of file data.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_log(), ast_module_ref(), ast_module_unref(), ast_data_search::children, data_filter::children, data_provider::children, data_filter_find(), data_result_add_child(), data_result_create(), data_search_find(), ast_data::filter, filter(), ast_data_handler::get, data_provider::handler, LOG_ERROR, data_provider::module, and data_provider::name.

Referenced by data_result_generate().

{
   struct ast_data *generated, *node;
   struct ao2_iterator i;
   struct data_provider *provider;
   struct ast_data_search *search_child = NULL;
   struct data_filter *filter_child;

   node = data_result_create(parent_node_name);
   if (!node) {
      ast_log(LOG_ERROR, "Unable to allocate '%s' node\n", parent_node_name);
      return NULL;
   }

   if (root_provider->module) {
      ast_module_ref(root_provider->module);
   }

   /* if this is a terminal node, just run the callback function. */
   if (root_provider->handler && root_provider->handler->get) {
      node->filter = filter;
      root_provider->handler->get(search, node);
      if (root_provider->module) {
         ast_module_unref(root_provider->module);
      }
      return node;
   }

   if (root_provider->module) {
      ast_module_unref(root_provider->module);
   }

   /* if this is not a terminal node, generate every child node. */
   i = ao2_iterator_init(root_provider->children, 0);
   while ((provider = ao2_iterator_next(&i))) {
      filter_child = NULL;
      generated = NULL;

      /* get the internal search node. */
      if (search) {
         search_child = data_search_find(search->children, provider->name);
      }
      /* get the internal filter node. */
      if (filter) {
         filter_child = data_filter_find(filter->children, provider->name);
      }

      if (!filter || filter_child) {
         /* only generate the internal node, if we have something to
          * generate based on the filtering string. */
         generated = data_result_generate_node(query, provider,
            provider->name,
            search_child, filter_child);
      }

      /* decrement the refcount of the internal search node. */
      if (search_child) {
         ao2_ref(search_child, -1);
      }

      /* decrement the refcount of the internal filter node. */
      if (filter_child) {
         ao2_ref(filter_child, -1);
      }

      if (generated) {
         data_result_add_child(node, generated);
         ao2_ref(generated, -1);
      }

      ao2_ref(provider, -1);
   }
   ao2_iterator_destroy(&i);

   return node;
}
static int data_result_get_color ( enum ast_data_type  type) [static]

Definition at line 2687 of file data.c.

References ARRAY_LEN, COLOR_BLUE, and data_result_color.

Referenced by data_result_print_cli(), and data_result_print_cli_node().

{
   int i;
   for (i = 0; i < ARRAY_LEN(data_result_color); i++) {
      if (data_result_color[i].type == type) {
         return data_result_color[i].color;
      }
   }

   return COLOR_BLUE;
}
static struct ast_data* data_result_get_node ( struct ast_data node,
const char *  path 
) [static, read]

Definition at line 1565 of file data.c.

References ao2_ref, data_result_find_child(), and next_node_name().

Referenced by ast_data_iterator_init(), ast_data_retrieve(), and ast_data_retrieve_type().

{
   char *savepath, *node_name;
   struct ast_data *child, *current = node;

   savepath = ast_strdupa(path);
   node_name = next_node_name(&savepath);

   while (node_name) {
      child = data_result_find_child(current, node_name);
      if (current != node) {
         ao2_ref(current, -1);
      }
      if (!child) {
         return NULL;
      }
      current = child;
      node_name = next_node_name(&savepath);
   }

   /* do not increment the refcount of the returned object. */
   if (current != node) {
      ao2_ref(current, -1);
   }

   return current;
}
static int data_result_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 210 of file data.c.

References ast_str_hash(), and ast_data::name.

Referenced by data_result_create().

{
   const struct ast_data *node = obj;
   return ast_str_hash(node->name);
}
static void data_result_manager_output ( struct mansession s,
const char *  name,
struct ao2_container container,
struct ast_str path,
int  id 
) [static]

Definition at line 3000 of file data.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_DATA_BOOLEAN, AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, AST_DATA_INTEGER, AST_DATA_IPADDR, AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, AST_DATA_POINTER, AST_DATA_SECONDS, AST_DATA_STRING, AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, ast_free, ast_inet_ntoa(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_str_set(), astman_append(), ast_data::boolean, ast_data::character, ast_data::children, ast_data::dbl, id, ast_data::ipaddr, ast_data::name, ast_data::payload, ast_data::sint, ast_data::str, ast_data::type, and ast_data::uint.

Referenced by manager_data_get().

{
   struct ao2_iterator i;
   struct ast_str *current_path;
   struct ast_data *node;
   int current_id = id;

   current_path = ast_str_create(60);
   if (!current_path) {
      return;
   }

   ast_str_reset(current_path);
   if (path) {
      ast_str_set(&current_path, 0, "%s.%s", ast_str_buffer(path), name);
   } else {
      ast_str_set(&current_path, 0, "%s", name);
   }

   i = ao2_iterator_init(container, 0);
   while ((node = ao2_iterator_next(&i))) {
      /* terminal node, print it. */
      if (node->type != AST_DATA_CONTAINER) {
         astman_append(s, "%d-%s.%s", id, ast_str_buffer(current_path),
               node->name);
      }
      switch (node->type) {
      case AST_DATA_CONTAINER:
         data_result_manager_output(s, node->name, node->children, current_path, ++current_id);
         break;
      case AST_DATA_INTEGER:
         astman_append(s, ": %d\r\n", node->payload.sint);
         break;
      case AST_DATA_TIMESTAMP:
      case AST_DATA_SECONDS:
      case AST_DATA_MILLISECONDS:
      case AST_DATA_UNSIGNED_INTEGER:
         astman_append(s, ": %u\r\n", node->payload.uint);
         break;
      case AST_DATA_PASSWORD:
         astman_append(s, ": %s\r\n", node->payload.str);
         break;
      case AST_DATA_STRING:
         astman_append(s, ": %s\r\n", node->payload.str);
         break;
      case AST_DATA_CHARACTER:
         astman_append(s, ": %c\r\n", node->payload.character);
         break;
      case AST_DATA_IPADDR:
         astman_append(s, ": %s\r\n", ast_inet_ntoa(node->payload.ipaddr));
         break;
      case AST_DATA_POINTER:
         break;
      case AST_DATA_DOUBLE:
         astman_append(s, ": %f\r\n", node->payload.dbl);
         break;
      case AST_DATA_BOOLEAN:
         astman_append(s, ": %s\r\n",
            (node->payload.boolean ? "True" : "False"));
         break;
      }

      ao2_ref(node, -1);
   }
   ao2_iterator_destroy(&i);

   ast_free(current_path);
}
static void data_result_print_cli ( int  fd,
const struct ast_data root 
) [static]

Definition at line 2841 of file data.c.

References __data_result_print_cli(), ast_cli(), ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_term_color_code(), COLOR_WHITE, data_result_get_color(), ast_data::name, and ast_data::type.

Referenced by handle_cli_data_get().

{
   struct ast_str *output;

   /* print the initial node. */
   output = ast_str_create(30);
   if (!output) {
      return;
   }

   ast_term_color_code(&output, data_result_get_color(root->type), 0);
   ast_str_append(&output, 0, "%s\n", root->name);
   ast_term_color_code(&output, COLOR_WHITE, 0);
   ast_cli(fd, "%s", ast_str_buffer(output));
   ast_free(output);

   __data_result_print_cli(fd, root, 0);

   ast_cli(fd, "\n");
}
static void data_result_print_cli_node ( int  fd,
const struct ast_data node,
uint32_t  depth 
) [static]

Definition at line 2706 of file data.c.

References __data_result_print_cli(), ast_cli(), AST_DATA_BOOLEAN, AST_DATA_CHARACTER, AST_DATA_CONTAINER, AST_DATA_DOUBLE, AST_DATA_INTEGER, AST_DATA_IPADDR, AST_DATA_MILLISECONDS, AST_DATA_PASSWORD, AST_DATA_POINTER, AST_DATA_SECONDS, AST_DATA_STRING, AST_DATA_TIMESTAMP, AST_DATA_UNSIGNED_INTEGER, ast_free, ast_inet_ntoa(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_term_color_code(), ast_data::boolean, ast_data::character, COLOR_WHITE, data_result_get_color(), ast_data::dbl, ast_data::ipaddr, ast_data::name, ast_data::payload, ast_data::ptr, ast_data::sint, ast_data::str, ast_data::type, and ast_data::uint.

Referenced by __data_result_print_cli().

{
   int i;
   struct ast_str *tabs, *output;

   tabs = ast_str_create(depth * 10 + 1);
   if (!tabs) {
      return;
   }
   ast_str_reset(tabs);
   for (i = 0; i < depth; i++) {
      ast_str_append(&tabs, 0, "  ");
   }

   output = ast_str_create(20);
   if (!output) {
      ast_free(tabs);
      return;
   }

   ast_str_reset(output);
   ast_term_color_code(&output, data_result_get_color(node->type), 0);

   switch (node->type) {
   case AST_DATA_POINTER:
      ast_str_append(&output, 0, "%s%s: %p\n", ast_str_buffer(tabs),
            node->name, node->payload.ptr);
      break;
   case AST_DATA_PASSWORD:
      ast_str_append(&output, 0, "%s%s: \"%s\"\n",
            ast_str_buffer(tabs),
            node->name,
            node->payload.str);
      break;
   case AST_DATA_STRING:
      ast_str_append(&output, 0, "%s%s: \"%s\"\n",
            ast_str_buffer(tabs),
            node->name,
            node->payload.str);
      break;
   case AST_DATA_CHARACTER:
      ast_str_append(&output, 0, "%s%s: \'%c\'\n",
            ast_str_buffer(tabs),
            node->name,
            node->payload.character);
      break;
   case AST_DATA_CONTAINER:
      ast_str_append(&output, 0, "%s%s\n", ast_str_buffer(tabs),
            node->name);
      break;
   case AST_DATA_TIMESTAMP:
      ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
            node->name,
            node->payload.uint);
      break;
   case AST_DATA_SECONDS:
      ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
            node->name,
            node->payload.uint);
      break;
   case AST_DATA_MILLISECONDS:
      ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
            node->name,
            node->payload.uint);
      break;
   case AST_DATA_INTEGER:
      ast_str_append(&output, 0, "%s%s: %d\n", ast_str_buffer(tabs),
            node->name,
            node->payload.sint);
      break;
   case AST_DATA_UNSIGNED_INTEGER:
      ast_str_append(&output, 0, "%s%s: %u\n", ast_str_buffer(tabs),
            node->name,
            node->payload.uint);
      break;
   case AST_DATA_DOUBLE:
      ast_str_append(&output, 0, "%s%s: %lf\n", ast_str_buffer(tabs),
            node->name,
            node->payload.dbl);
      break;
   case AST_DATA_BOOLEAN:
      ast_str_append(&output, 0, "%s%s: %s\n", ast_str_buffer(tabs),
            node->name,
            ((node->payload.boolean) ? "True" : "False"));
      break;
   case AST_DATA_IPADDR:
      ast_str_append(&output, 0, "%s%s: %s\n", ast_str_buffer(tabs),
            node->name,
            ast_inet_ntoa(node->payload.ipaddr));
      break;
   }

   ast_free(tabs);

   ast_term_color_code(&output, COLOR_WHITE, 0);

   ast_cli(fd, "%s", ast_str_buffer(output));

   ast_free(output);

   if (node->type == AST_DATA_CONTAINER) {
      __data_result_print_cli(fd, node, depth + 1);
   }
}
static struct ast_data_search* data_search_add_child ( struct ao2_container parent,
const char *  name 
) [static, read]

Definition at line 748 of file data.c.

References ao2_link, and data_search_alloc().

Referenced by data_search_create().

{
   struct ast_data_search *child;

   child = data_search_alloc(name);
   if (!child) {
      return NULL;
   }

   ao2_link(parent, child);

   return child;
}
static struct ast_data_search* data_search_alloc ( const char *  name) [static, read]

Definition at line 690 of file data.c.

References ao2_alloc, ao2_container_alloc, ao2_ref, ast_data_search::children, data_search_cmp(), data_search_destructor(), data_search_hash(), ast_data_search::name, and NUM_DATA_SEARCH_BUCKETS.

Referenced by data_search_add_child(), data_search_find(), and data_search_generate().

{
   struct ast_data_search *res;
   size_t name_len = strlen(name) + 1;

   res = ao2_alloc(sizeof(*res) + name_len, data_search_destructor);
   if (!res) {
      return NULL;
   }

   res->children = ao2_container_alloc(NUM_DATA_SEARCH_BUCKETS, data_search_hash,
      data_search_cmp);

   if (!res->children) {
      ao2_ref(res, -1);
      return NULL;
   }

   strcpy(res->name, name);

   return res;
}
static int data_search_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 663 of file data.c.

References CMP_MATCH, and ast_data_search::name.

Referenced by data_search_alloc().

{
   struct ast_data_search *node1 = obj, *node2 = arg;
   return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
}
static int data_search_cmp_bool ( const struct ast_data_search root,
const char *  name,
unsigned int  value 
) [static]

Definition at line 1102 of file data.c.

References ao2_ref, ast_true(), ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and ast_data_search::value.

Referenced by __ast_data_search_cmp_structure(), and ast_data_search_match().

{
   struct ast_data_search *child;
   unsigned int node_value;
   enum data_search_comparison cmp_type;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }

   node_value = abs(ast_true(child->value));
   cmp_type = child->cmp_type;

   ao2_ref(child, -1);

   return data_search_comparison_result(value - node_value, cmp_type);
}
static int data_search_cmp_char ( const struct ast_data_search root,
const char *  name,
char  value 
) [static]

Definition at line 1230 of file data.c.

References ao2_ref, ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and ast_data_search::value.

Referenced by __ast_data_search_cmp_structure(), and ast_data_search_match().

{
   struct ast_data_search *child;
   char node_value;
   enum data_search_comparison cmp_type;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }

   node_value = *(child->value);
   cmp_type = child->cmp_type;

   ao2_ref(child, -1);

   return data_search_comparison_result(value - node_value, cmp_type);
}
static int data_search_cmp_dbl ( const struct ast_data_search root,
const char *  name,
double  value 
) [static]

Definition at line 1134 of file data.c.

References ao2_ref, ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and ast_data_search::value.

Referenced by __ast_data_search_cmp_structure().

{
   struct ast_data_search *child;
   double node_value;
   enum data_search_comparison cmp_type;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }

   node_value = strtod(child->value, NULL);
   cmp_type = child->cmp_type;

   ao2_ref(child, -1);

   return data_search_comparison_result(value - node_value, cmp_type);
}
static int data_search_cmp_int ( const struct ast_data_search root,
const char *  name,
int  value 
) [static]

Definition at line 1198 of file data.c.

References ao2_ref, ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and ast_data_search::value.

Referenced by __ast_data_search_cmp_structure(), and ast_data_search_match().

{
   struct ast_data_search *child;
   int node_value;
   enum data_search_comparison cmp_type;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }

   node_value = atoi(child->value);
   cmp_type = child->cmp_type;

   ao2_ref(child, -1);

   return data_search_comparison_result(value - node_value, cmp_type);
}
static int data_search_cmp_ipaddr ( const struct ast_data_search root,
const char *  name,
struct in_addr  addr 
) [static]

Definition at line 1070 of file data.c.

References ao2_ref, ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and inet_aton().

Referenced by __ast_data_search_cmp_structure(), and ast_data_search_match().

{
   struct ast_data_search *child;
   enum data_search_comparison cmp_type;
   struct in_addr node_addr;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }
   cmp_type = child->cmp_type;

   inet_aton(child->value, &node_addr);

   ao2_ref(child, -1);

   return data_search_comparison_result((node_addr.s_addr - addr.s_addr), cmp_type);
}
static int data_search_cmp_ptr ( const struct ast_data_search root,
const char *  name,
void *  ptr 
) [static]

Definition at line 1034 of file data.c.

References ao2_ref, ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and ast_data_search::value.

Referenced by __ast_data_search_cmp_structure(), and ast_data_search_match().

{
   struct ast_data_search *child;
   enum data_search_comparison cmp_type;
   void *node_ptr;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }

   cmp_type = child->cmp_type;

   if (sscanf(child->value, "%p", &node_ptr) <= 0) {
      ao2_ref(child, -1);
      return 1;
   }

   ao2_ref(child, -1);

   return data_search_comparison_result((node_ptr - ptr), cmp_type);
}
static int data_search_cmp_string ( const struct ast_data_search root,
const char *  name,
char *  value 
) [static]

Definition at line 1002 of file data.c.

References ao2_ref, ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and ast_data_search::value.

Referenced by __ast_data_search_cmp_structure(), and ast_data_search_match().

{
   struct ast_data_search *child;
   enum data_search_comparison cmp_type;
   int ret;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }

   ret = strcmp(value, child->value);
   cmp_type = child->cmp_type;

   ao2_ref(child, -1);

   return data_search_comparison_result(ret, cmp_type);
}
static int data_search_cmp_uint ( const struct ast_data_search root,
const char *  name,
unsigned int  value 
) [static]

Definition at line 1166 of file data.c.

References ao2_ref, ast_data_search::cmp_type, data_search_comparison_result(), data_search_get_node(), and ast_data_search::value.

Referenced by __ast_data_search_cmp_structure(), and ast_data_search_match().

{
   struct ast_data_search *child;
   unsigned int node_value;
   enum data_search_comparison cmp_type;

   child = data_search_get_node(root, name);
   if (!child) {
      return 0;
   }

   node_value = atoi(child->value);
   cmp_type = child->cmp_type;

   ao2_ref(child, -1);

   return data_search_comparison_result(value - node_value, cmp_type);
}
static int data_search_comparison_char ( char  a) [static]

Definition at line 613 of file data.c.

Referenced by data_search_generate().

{
   switch (a) {
   case '!':
   case '=':
   case '<':
   case '>':
      return 1;
   }

   return 0;
}
static int data_search_comparison_result ( int  cmpval,
enum data_search_comparison  comparison_type 
) [inline, static]

Definition at line 914 of file data.c.

References DATA_CMP_EQ, DATA_CMP_GE, DATA_CMP_GT, DATA_CMP_LE, DATA_CMP_LT, DATA_CMP_NEQ, and DATA_CMP_UNKNOWN.

Referenced by data_search_cmp_bool(), data_search_cmp_char(), data_search_cmp_dbl(), data_search_cmp_int(), data_search_cmp_ipaddr(), data_search_cmp_ptr(), data_search_cmp_string(), and data_search_cmp_uint().

{
   switch (comparison_type) {
   case DATA_CMP_GE:
      if (cmpval >= 0) {
         return 0;
      }
      break;
   case DATA_CMP_LE:
      if (cmpval <= 0) {
         return 0;
      }
      break;
   case DATA_CMP_EQ:
      if (cmpval == 0) {
         return 0;
      }
      break;
   case DATA_CMP_NEQ:
      if (cmpval != 0) {
         return 0;
      }
      break;
   case DATA_CMP_LT:
      if (cmpval < 0) {
         return 0;
      }
      break;
   case DATA_CMP_GT:
      if (cmpval > 0) {
         return 0;
      }
      break;
   case DATA_CMP_UNKNOWN:
      break;
   }
   return 1;
}
static enum data_search_comparison data_search_comparison_type ( const char *  comparison) [static]

Definition at line 630 of file data.c.

References DATA_CMP_EQ, DATA_CMP_GE, DATA_CMP_GT, DATA_CMP_LE, DATA_CMP_LT, DATA_CMP_NEQ, and DATA_CMP_UNKNOWN.

Referenced by data_search_generate().

{
   if (!strcmp(comparison, "=")) {
      return DATA_CMP_EQ;
   } else if (!strcmp(comparison, "!=")) {
      return DATA_CMP_NEQ;
   } else if (!strcmp(comparison, "<")) {
      return DATA_CMP_LT;
   } else if (!strcmp(comparison, ">")) {
      return DATA_CMP_GT;
   } else if (!strcmp(comparison, "<=")) {
      return DATA_CMP_LE;
   } else if (!strcmp(comparison, ">=")) {
      return DATA_CMP_GE;
   }

   return DATA_CMP_UNKNOWN;
}
static struct ast_data_search* data_search_create ( struct ao2_container parent,
const char *  path 
) [static, read]

Definition at line 771 of file data.c.

References ao2_ref, ast_data_search::children, data_search_add_child(), data_search_find(), and next_node_name().

Referenced by data_search_generate().

{
   char *rpath, *node_name;
   struct ast_data_search *child = NULL;
   struct ao2_container *current = parent;

   rpath = ast_strdupa(path);

   node_name = next_node_name(&rpath);
   while (node_name) {
      child = data_search_find(current, node_name);
      if (!child) {
         child = data_search_add_child(current, node_name);
      }
      ao2_ref(child, -1);
      current = child->children;
      node_name = next_node_name(&rpath);
   }

   return child;
}
static void data_search_destructor ( void *  obj) [static]

Definition at line 673 of file data.c.

References ao2_ref, ast_free, ast_data_search::children, and ast_data_search::value.

Referenced by data_search_alloc().

{
   struct ast_data_search *node = obj;

   if (node->value) {
      ast_free(node->value);
   }

   ao2_ref(node->children, -1);
}
static struct ast_data_search* data_search_find ( struct ao2_container parent,
const char *  name 
) [static, read]

Definition at line 722 of file data.c.

References ao2_find, ao2_ref, data_search_alloc(), and OBJ_POINTER.

Referenced by ast_data_search_match(), data_result_generate(), data_result_generate_node(), data_search_create(), and data_search_get_node().

{
   struct ast_data_search *find_node, *found;

   find_node = data_search_alloc(name);
   if (!find_node) {
      return NULL;
   }

   found = ao2_find(parent, find_node, OBJ_POINTER);

   /* free the created node used for searching. */
   ao2_ref(find_node, -1);

   return found;
}
static struct ast_data_search* data_search_generate ( const char *  search_string) [static, read]

Definition at line 801 of file data.c.

References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_strdup, ast_data_search::children, ast_data_search::cmp_type, DATA_CMP_UNKNOWN, data_search_alloc(), data_search_comparison_char(), data_search_comparison_type(), data_search_create(), LOG_ERROR, data_filter::name, value, and ast_data_search::value.

Referenced by data_result_generate().

{
   struct ast_str *name, *value, *comparison;
   char *elements, *search_string_dup, *saveptr;
   int i;
   struct ast_data_search *root, *child;
   enum data_search_comparison cmp_type;
   size_t search_string_len;

   if (!search_string) {
      ast_log(LOG_ERROR, "You must pass a valid search string.\n");
      return NULL;
   }

   search_string_len = strlen(search_string);

   name = ast_str_create(search_string_len);
   if (!name) {
      return NULL;
   }
   value = ast_str_create(search_string_len);
   if (!value) {
      ast_free(name);
      return NULL;
   }
   comparison = ast_str_create(search_string_len);
   if (!comparison) {
      ast_free(name);
      ast_free(value);
      return NULL;
   }

   search_string_dup = ast_strdupa(search_string);

   /* Create the root node (just used as a container) */
   root = data_search_alloc("/");
   if (!root) {
      ast_free(name);
      ast_free(value);
      ast_free(comparison);
      return NULL;
   }

   for (elements = strtok_r(search_string_dup, ",", &saveptr); elements;
      elements = strtok_r(NULL, ",", &saveptr)) {
      /* Parse the name */
      ast_str_reset(name);
      for (i = 0; !data_search_comparison_char(elements[i]) &&
         elements[i]; i++) {
         ast_str_append(&name, 0, "%c", elements[i]);
      }

      /* check if the syntax is ok. */
      if (!data_search_comparison_char(elements[i])) {
         /* if this is the end of the string, then this is
          * an error! */
         ast_log(LOG_ERROR, "Invalid search string!\n");
         continue;
      }

      /* parse the comparison string. */
      ast_str_reset(comparison);
      for (; data_search_comparison_char(elements[i]) && elements[i]; i++) {
         ast_str_append(&comparison, 0, "%c", elements[i]);
      }

      /* parse the value string. */
      ast_str_reset(value);
      for (; elements[i]; i++) {
         ast_str_append(&value, 0, "%c", elements[i]);
      }

      cmp_type = data_search_comparison_type(ast_str_buffer(comparison));
      if (cmp_type == DATA_CMP_UNKNOWN) {
         ast_log(LOG_ERROR, "Invalid comparison '%s'\n",
            ast_str_buffer(comparison));
         continue;
      }

      /* add this node to the tree. */
      child = data_search_create(root->children, ast_str_buffer(name));
      if (child) {
         child->cmp_type = cmp_type;
         child->value = ast_strdup(ast_str_buffer(value));
      }
   }

   ast_free(name);
   ast_free(value);
   ast_free(comparison);

   return root;
}
static struct ast_data_search* data_search_get_node ( const struct ast_data_search node,
const char *  path 
) [static, read]

Definition at line 962 of file data.c.

References ao2_ref, ast_data_search::children, data_search_find(), and next_node_name().

Referenced by __ast_data_search_cmp_structure(), data_search_cmp_bool(), data_search_cmp_char(), data_search_cmp_dbl(), data_search_cmp_int(), data_search_cmp_ipaddr(), data_search_cmp_ptr(), data_search_cmp_string(), and data_search_cmp_uint().

{
   char *savepath, *node_name;
   struct ast_data_search *child, *current = (struct ast_data_search *) node;

   if (!node) {
      return NULL;
   }

   savepath = ast_strdupa(path);
   node_name = next_node_name(&savepath);

   while (node_name) {
      child = data_search_find(current->children, node_name);
      if (current != node) {
         ao2_ref(current, -1);
      }
      if (!child) {
         return NULL;
      };
      current = child;
      node_name = next_node_name(&savepath);
   }

   return current;
}
static int data_search_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 653 of file data.c.

References ast_str_hash(), and ast_data_search::name.

Referenced by data_search_alloc().

{
   const struct ast_data_search *node = obj;
   return ast_str_hash(node->name);
}
static int data_search_mapping_find ( const struct ast_data_mapping_structure map,
size_t  mapping_len,
const char *  member_name 
) [inline, static]

Definition at line 1257 of file data.c.

References data_filter::name.

Referenced by __ast_data_search_cmp_structure().

{
   int i;

   for (i = 0; i < mapping_len; i++) {
      if (!strcmp(map[i].name, member_name)) {
         return i;
      }
   }

   return -1;
}
static void data_search_release ( struct ast_data_search search) [static]

Definition at line 900 of file data.c.

References ao2_ref.

Referenced by data_result_generate().

{
   ao2_ref(search, -1);
}
static void data_shutdown ( void  ) [static]

Definition at line 3318 of file data.c.

References ao2_t_ref, ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), ast_rwlock_destroy, AST_TEST_UNREGISTER, cli_data, and root_data.

Referenced by ast_data_init().

{
   ast_manager_unregister("DataGet");
   ast_cli_unregister_multiple(cli_data, ARRAY_LEN(cli_data));
   ao2_t_ref(root_data.container, -1, "Unref root_data.container in data_shutdown");
   root_data.container = NULL;
   ast_rwlock_destroy(&root_data.lock);
   AST_TEST_UNREGISTER(test_data_get);
}
static int data_structure_compatible ( int  structure_version,
uint32_t  latest_compatible,
uint32_t  current 
) [static]

Definition at line 255 of file data.c.

References ast_log(), and LOG_ERROR.

Referenced by __ast_data_register(), and ast_data_get().

{
   if (structure_version >= latest_compatible && structure_version <= current) {
      return 1;
   }

   ast_log(LOG_ERROR, "A module is not compatible with the"
      "current data api version\n");

   return 0;
}
static char* handle_cli_data_get ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2866 of file data.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_data_free(), ast_data_get(), AST_DATA_QUERY_VERSION, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, data_result_print_cli(), ast_cli_args::fd, ast_data_query::filter, ast_data_query::path, ast_data_query::search, ast_cli_entry::usage, and ast_data_query::version.

{
   struct ast_data_query query = {
      .version = AST_DATA_QUERY_VERSION
   };
   struct ast_data *tree;

   switch (cmd) {
   case CLI_INIT:
      e->command = "data get";
      e->usage = ""
         "Usage: data get <path> [<search> [<filter>]]\n"
         "       Get the tree based on a path.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc < e->args + 1) {
      return CLI_SHOWUSAGE;
   }

   query.path = (char *) a->argv[e->args];

   if (a->argc > e->args + 1) {
      query.search = (char *) a->argv[e->args + 1];
   }

   if (a->argc > e->args + 2) {
      query.filter = (char *) a->argv[e->args + 2];
   }

   tree = ast_data_get(&query);
   if (!tree) {
      return CLI_FAILURE;
   }

   data_result_print_cli(a->fd, tree);

   ast_data_free(tree);

   return CLI_SUCCESS;
}
static char* handle_cli_data_show_providers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 2962 of file data.c.

References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, data_provider_print_cli(), data_read_lock, data_unlock, ast_cli_args::fd, root_data, and ast_cli_entry::usage.

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "data show providers";
      e->usage = ""
         "Usage: data show providers\n"
         "       Show the list of registered providers\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   data_read_lock();
   data_provider_print_cli(a->fd, "", root_data.container, NULL);
   data_unlock();

   return CLI_SUCCESS;
}
static int manager_data_get ( struct mansession s,
const struct message m 
) [static]

Definition at line 3074 of file data.c.

References ast_data_free(), ast_data_get(), AST_DATA_QUERY_VERSION, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), ast_data::children, data_result_manager_output(), filter(), ast_data::name, RESULT_SUCCESS, ast_data_query::search, and ast_data_query::version.

Referenced by ast_data_init().

{
   const char *path = astman_get_header(m, "Path");
   const char *search = astman_get_header(m, "Search");
   const char *filter = astman_get_header(m, "Filter");
   const char *id = astman_get_header(m, "ActionID");
   struct ast_data *res;
   struct ast_data_query query = {
      .version = AST_DATA_QUERY_VERSION,
      .path = (char *) path,
      .search = (char *) search,
      .filter = (char *) filter,
   };

   if (ast_strlen_zero(path)) {
      astman_send_error(s, m, "'Path' parameter not specified");
      return 0;
   }

   res = ast_data_get(&query);
   if (!res) {
      astman_send_error(s, m, "No data returned");
      return 0;
   }

   astman_append(s, "Event: DataGet Tree\r\n");
   if (!ast_strlen_zero(id)) {
      astman_append(s, "ActionID: %s\r\n", id);
   }
   data_result_manager_output(s, res->name, res->children, NULL, 0);
   astman_append(s, "\r\n");

   ast_data_free(res);

   return RESULT_SUCCESS;
}
static char* next_node_name ( char **  path) [static]

Definition at line 276 of file data.c.

References ast_strlen_zero().

Referenced by data_filter_add_nodes(), data_provider_create(), data_provider_release(), data_result_generate(), data_result_get_node(), data_search_create(), and data_search_get_node().

{
   char *res;

   do {
      res = strsep(path, "/");
   } while (res && ast_strlen_zero(res));

   return res;
}

Variable Documentation

struct ast_cli_entry cli_data[] [static]
Initial value:

Definition at line 2987 of file data.c.

Referenced by ast_data_init(), and data_shutdown().

int color

Definition at line 2664 of file data.c.

Current handler structure version.

Definition at line 78 of file data.c.

const uint32_t current_query_version = AST_DATA_QUERY_VERSION [static]

Current query structure version.

Definition at line 81 of file data.c.

struct { ... } data_result_color[] [static]

Referenced by data_result_get_color().

const uint32_t latest_handler_compatible_version = 0 [static]

The last compatible version.

Definition at line 72 of file data.c.

const uint32_t latest_query_compatible_version = 0 [static]

The last compatible version.

Definition at line 75 of file data.c.

asterisk data locking mechanism.

Definition at line 179 of file data.c.

Definition at line 2663 of file data.c.