LCOV - code coverage report
Current view: top level - media/mtransport/third_party/nrappkit/src/registry - registry_local.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 454 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 50 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    registry.c
       4             :  *
       5             :  *    $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registry_local.c,v $
       6             :  *    $Revision: 1.4 $
       7             :  *    $Date: 2007/11/21 00:09:13 $
       8             :  *
       9             :  *    Datastore for tracking configuration and related info.
      10             :  *
      11             :  *
      12             :  *    Copyright (C) 2005, Network Resonance, Inc.
      13             :  *    Copyright (C) 2006, Network Resonance, Inc.
      14             :  *    All Rights Reserved
      15             :  *
      16             :  *    Redistribution and use in source and binary forms, with or without
      17             :  *    modification, are permitted provided that the following conditions
      18             :  *    are met:
      19             :  *
      20             :  *    1. Redistributions of source code must retain the above copyright
      21             :  *       notice, this list of conditions and the following disclaimer.
      22             :  *    2. Redistributions in binary form must reproduce the above copyright
      23             :  *       notice, this list of conditions and the following disclaimer in the
      24             :  *       documentation and/or other materials provided with the distribution.
      25             :  *    3. Neither the name of Network Resonance, Inc. nor the name of any
      26             :  *       contributors to this software may be used to endorse or promote
      27             :  *       products derived from this software without specific prior written
      28             :  *       permission.
      29             :  *
      30             :  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
      31             :  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      32             :  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      33             :  *    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      34             :  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      35             :  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      36             :  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      37             :  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      38             :  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      39             :  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      40             :  *    POSSIBILITY OF SUCH DAMAGE.
      41             :  *
      42             :  *
      43             :  */
      44             : 
      45             : #include <assert.h>
      46             : #include <string.h>
      47             : #ifndef WIN32
      48             : #include <strings.h>
      49             : #include <sys/param.h>
      50             : #include <netinet/in.h>
      51             : #endif
      52             : #ifdef OPENSSL
      53             : #include <openssl/ssl.h>
      54             : #endif
      55             : #include <ctype.h>
      56             : #include "registry.h"
      57             : #include "registry_int.h"
      58             : #include "registry_vtbl.h"
      59             : #include "r_assoc.h"
      60             : #include "nr_common.h"
      61             : #include "r_log.h"
      62             : #include "r_errors.h"
      63             : #include "r_macros.h"
      64             : 
      65             : /* if C were an object-oriented language, nr_scalar_registry_node and
      66             :  * nr_array_registry_node would subclass nr_registry_node, but it isn't
      67             :  * object-oriented language, so this is used in cases where the pointer
      68             :  * could be of either type */
      69             : typedef struct nr_registry_node_ {
      70             :     unsigned char  type;
      71             : } nr_registry_node;
      72             : 
      73             : typedef struct nr_scalar_registry_node_ {
      74             :     unsigned char  type;
      75             :     union {
      76             :         char          _char;
      77             :         UCHAR         _uchar;
      78             :         INT2       _nr_int2;
      79             :         UINT2      _nr_uint2;
      80             :         INT4       _nr_int4;
      81             :         UINT4      _nr_uint4;
      82             :         INT8       _nr_int8;
      83             :         UINT8      _nr_uint8;
      84             :         double        _double;
      85             :     } scalar;
      86             : } nr_scalar_registry_node;
      87             : 
      88             : /* string, bytes */
      89             : typedef struct nr_array_registry_node_ {
      90             :     unsigned char    type;
      91             :     struct {
      92             :         unsigned int     length;
      93             :         unsigned char    data[1];
      94             :     } array;
      95             : } nr_array_registry_node;
      96             : 
      97             : static int nr_reg_local_init(nr_registry_module *me);
      98             : static int nr_reg_local_get_char(NR_registry name, char *data);
      99             : static int nr_reg_local_get_uchar(NR_registry name, UCHAR *data);
     100             : static int nr_reg_local_get_int2(NR_registry name, INT2 *data);
     101             : static int nr_reg_local_get_uint2(NR_registry name, UINT2 *data);
     102             : static int nr_reg_local_get_int4(NR_registry name, INT4 *data);
     103             : static int nr_reg_local_get_uint4(NR_registry name, UINT4 *data);
     104             : static int nr_reg_local_get_int8(NR_registry name, INT8 *data);
     105             : static int nr_reg_local_get_uint8(NR_registry name, UINT8 *data);
     106             : static int nr_reg_local_get_double(NR_registry name, double *data);
     107             : static int nr_reg_local_get_registry(NR_registry name, NR_registry data);
     108             : static int nr_reg_local_get_bytes(NR_registry name, UCHAR *data, size_t size, size_t *length);
     109             : static int nr_reg_local_get_string(NR_registry name, char *data, size_t size);
     110             : static int nr_reg_local_get_length(NR_registry name, size_t *len);
     111             : static int nr_reg_local_get_type(NR_registry name, NR_registry_type type);
     112             : static int nr_reg_local_set_char(NR_registry name, char data);
     113             : static int nr_reg_local_set_uchar(NR_registry name, UCHAR data);
     114             : static int nr_reg_local_set_int2(NR_registry name, INT2 data);
     115             : static int nr_reg_local_set_uint2(NR_registry name, UINT2 data);
     116             : static int nr_reg_local_set_int4(NR_registry name, INT4 data);
     117             : static int nr_reg_local_set_uint4(NR_registry name, UINT4 data);
     118             : static int nr_reg_local_set_int8(NR_registry name, INT8 data);
     119             : static int nr_reg_local_set_uint8(NR_registry name, UINT8 data);
     120             : static int nr_reg_local_set_double(NR_registry name, double data);
     121             : static int nr_reg_local_set_registry(NR_registry name);
     122             : static int nr_reg_local_set_bytes(NR_registry name, UCHAR *data, size_t length);
     123             : static int nr_reg_local_set_string(NR_registry name, char *data);
     124             : static int nr_reg_local_del(NR_registry name);
     125             : static int nr_reg_local_get_child_count(NR_registry parent, size_t *count);
     126             : static int nr_reg_local_get_children(NR_registry parent, NR_registry *data, size_t size, size_t *length);
     127             : static int nr_reg_local_fin(NR_registry name);
     128             : static int nr_reg_local_dump(int sorted);
     129             : static int nr_reg_insert_node(char *name, void *node);
     130             : static int nr_reg_change_node(char *name, void *node, void *old);
     131             : static int nr_reg_get(char *name, int type, void *out);
     132             : static int nr_reg_get_data(NR_registry name, nr_scalar_registry_node *node, void *out);
     133             : static int nr_reg_get_array(char *name, unsigned char type, UCHAR *out, size_t size, size_t *length);
     134             : static int nr_reg_set(char *name, int type, void *data);
     135             : static int nr_reg_set_array(char *name, unsigned char type, UCHAR *data, size_t length);
     136             : static int nr_reg_set_parent_registries(char *name);
     137             : 
     138             : /* make these static OLD_REGISTRY */
     139             : #if 0
     140             : static int nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node);
     141             : static char *nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit);
     142             : #else
     143             : int nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node);
     144             : char *nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit);
     145             : #endif
     146             : static int nr_reg_rfree(void *ptr);
     147             : #if 0  /* Unused currently */
     148             : static int nr_reg_noop(void *ptr);
     149             : #endif
     150             : static int nr_reg_compute_length(char *name, nr_registry_node *node, size_t *length);
     151             : char *nr_reg_action_name(int action);
     152             : 
     153             : /* the registry, containing mappings like "foo.bar.baz" to registry
     154             :  * nodes, which are either of type nr_scalar_registry_node or
     155             :  * nr_array_registry_node */
     156             : static r_assoc     *nr_registry = 0;
     157             : 
     158             : #if 0  /* Unused currently */
     159             : static nr_array_registry_node nr_top_level_node;
     160             : #endif
     161             : 
     162             : typedef struct nr_reg_find_children_arg_ {
     163             :     size_t         size;
     164             :     NR_registry   *children;
     165             :     size_t         length;
     166             : } nr_reg_find_children_arg;
     167             : 
     168             : static int nr_reg_local_iter(char *prefix, int (*action)(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node), void *ptr);
     169             : static int nr_reg_local_iter_delete(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node);
     170             : static int nr_reg_local_find_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node);
     171             : static int nr_reg_local_count_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node);
     172             : static int nr_reg_local_dump_print(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node);
     173             : 
     174             : 
     175             : 
     176             : int
     177           0 : nr_reg_local_iter(NR_registry prefix, int (*action)(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node), void *ptr)
     178             : {
     179             :     int r, _status;
     180             :     r_assoc_iterator iter;
     181             :     char *name;
     182             :     int namel;
     183             :     nr_registry_node *node;
     184             :     int prefixl;
     185             : 
     186           0 :     if (prefix == 0)
     187           0 :         ABORT(R_INTERNAL);
     188             : 
     189           0 :     if ((r=r_assoc_init_iter(nr_registry, &iter)))
     190           0 :         ABORT(r);
     191             : 
     192           0 :     prefixl = strlen(prefix);
     193             : 
     194             :     for (;;) {
     195           0 :       if ((r=r_assoc_iter(&iter, (void*)&name, &namel, (void*)&node))) {
     196           0 :         if (r == R_EOD)
     197           0 :           break;
     198             :         else
     199           0 :           ABORT(r);
     200             :       }
     201             : 
     202             :       /* subtract to remove the '\0' character from the string length */
     203           0 :       --namel;
     204             : 
     205             :       /* sanity check that the name is null-terminated */
     206           0 :       assert(namel >= 0);
     207           0 :       assert(name[namel] == '\0');
     208             : 
     209           0 :       if (namel < 0 || name[namel] != '\0' || node == 0)
     210             :           break;
     211             : 
     212             :       /* 3 cases where action will be called:
     213             :        *   1) prefix == ""
     214             :        *   2) prefix == name
     215             :        *   3) name == prefix + '.'
     216             :        */
     217           0 :       if (prefixl == 0
     218           0 :        || ((namel == prefixl || (namel > prefixl && name[prefixl] == '.'))
     219           0 :          && !strncmp(prefix, name, prefixl))) {
     220           0 :         if ((r=action(ptr, &iter, prefix, name, node)))
     221           0 :           ABORT(r);
     222             :       }
     223             :     }
     224             : 
     225           0 :     _status=0;
     226             :   abort:
     227             : 
     228           0 :     return(_status);
     229             : }
     230             : 
     231             : int
     232           0 : nr_reg_local_iter_delete(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node)
     233             : {
     234             :     int r, _status;
     235             : 
     236           0 :     if ((r=r_assoc_iter_delete(iter)))
     237           0 :       ABORT(r);
     238             : 
     239           0 :     _status=0;
     240             :   abort:
     241           0 :     return(_status);
     242             : }
     243             : 
     244             : int
     245           0 : nr_reg_local_find_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node)
     246             : {
     247             :   int _status;
     248           0 :   int prefixl = strlen(prefix);
     249             :   char *dot;
     250           0 :   nr_reg_find_children_arg *arg = (void*)ptr;
     251             : 
     252             :   assert(sizeof(*(arg->children)) == sizeof(NR_registry));
     253             : 
     254             :   /* only grovel through immediate children */
     255           0 :   if (prefixl == 0 || name[prefixl] == '.') {
     256           0 :     if (name[prefixl] != '\0') {
     257           0 :       dot = strchr(&name[prefixl+1], '.');
     258           0 :       if (dot == 0) {
     259           0 :         strncpy(arg->children[arg->length], name, sizeof(NR_registry)-1);
     260           0 :         ++arg->length;
     261             : 
     262             :         /* only grab as many as there are room for */
     263           0 :         if (arg->length >= arg->size)
     264           0 :           ABORT(R_INTERRUPTED);
     265             :       }
     266             :     }
     267             :   }
     268             : 
     269           0 :   _status = 0;
     270             :  abort:
     271           0 :   return _status;
     272             : }
     273             : 
     274             : int
     275           0 : nr_reg_local_count_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node)
     276             : {
     277           0 :   int prefixl = strlen(prefix);
     278             :   char *dot;
     279             : 
     280             :   /* only count children */
     281           0 :   if (name[prefixl] == '.') {
     282           0 :     dot = strchr(&name[prefixl+1], '.');
     283           0 :     if (dot == 0)
     284           0 :       ++(*(unsigned int *)ptr);
     285             :   }
     286           0 :   else if (name[0] != '\0') {
     287           0 :     if (prefixl == 0)
     288           0 :       ++(*(unsigned int *)ptr);
     289             :   }
     290             : 
     291           0 :   return 0;
     292             : }
     293             : 
     294             : int
     295           0 : nr_reg_local_dump_print(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node)
     296             : {
     297             :     int _status;
     298           0 :     int freeit = 0;
     299             :     char *data;
     300             : 
     301             :     /* only print leaf nodes */
     302           0 :     if (node->type != NR_REG_TYPE_REGISTRY) {
     303           0 :       data = nr_reg_alloc_node_data(name, node, &freeit);
     304           0 :       if (ptr)
     305           0 :         fprintf((FILE*)ptr, "%s: %s\n", name, data);
     306             :       else
     307           0 :         r_log(NR_LOG_REGISTRY, LOG_INFO, "%s: %s", name, data);
     308           0 :       if (freeit)
     309           0 :         RFREE(data);
     310             :     }
     311             : 
     312           0 :     _status=0;
     313             :   //abort:
     314           0 :     return(_status);
     315             : }
     316             : 
     317             : 
     318             : #if 0  /* Unused currently */
     319             : int
     320             : nr_reg_noop(void *ptr)
     321             : {
     322             :     return 0;
     323             : }
     324             : #endif
     325             : 
     326             : int
     327           0 : nr_reg_rfree(void *ptr)
     328             : {
     329           0 :     RFREE(ptr);
     330           0 :     return 0;
     331             : }
     332             : 
     333             : int
     334           0 : nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node)
     335             : {
     336             :     int r, _status;
     337             : 
     338           0 :     *node = 0;
     339           0 :     *free_node = 0;
     340             : 
     341           0 :     if ((r=nr_reg_is_valid(name)))
     342           0 :       ABORT(r);
     343             : 
     344           0 :     if ((r=r_assoc_fetch(nr_registry, name, strlen(name)+1, (void*)node)))
     345           0 :       ABORT(r);
     346             : 
     347           0 :     if ((*node)->type != type)
     348           0 :       ABORT(R_FAILED);
     349             : 
     350           0 :     _status=0;
     351             :   abort:
     352           0 :     if (_status) {
     353           0 :         if (*node)
     354           0 :             r_log(NR_LOG_REGISTRY, LOG_DEBUG, "Couldn't fetch node '%s' ('%s'), found '%s' instead",
     355           0 :               name, nr_reg_type_name(type), nr_reg_type_name((*node)->type));
     356             :         else
     357           0 :             r_log(NR_LOG_REGISTRY, LOG_DEBUG, "Couldn't fetch node '%s' ('%s')",
     358             :               name, nr_reg_type_name(type));
     359             :     }
     360             :     else {
     361           0 :         r_log(NR_LOG_REGISTRY, LOG_DEBUG, "Fetched node '%s' ('%s')",
     362             :               name, nr_reg_type_name(type));
     363             :     }
     364           0 :     return(_status);
     365             : }
     366             : 
     367             : int
     368           0 : nr_reg_insert_node(char *name, void *node)
     369             : {
     370             :     int r, _status;
     371             : 
     372           0 :     if ((r=nr_reg_is_valid(name)))
     373           0 :       ABORT(r);
     374             : 
     375             :     /* since the registry application is not multi-threaded, a node being
     376             :      * inserted should always be a new node because the registry app must
     377             :      * have looked for a node with this key but not found it, so it is
     378             :      * being created/inserted now using R_ASSOC_NEW */
     379           0 :     if ((r=r_assoc_insert(nr_registry, name, strlen(name)+1, node, 0, nr_reg_rfree, R_ASSOC_NEW)))
     380           0 :       ABORT(r);
     381             : 
     382           0 :     if ((r=nr_reg_set_parent_registries(name)))
     383           0 :       ABORT(r);
     384             : 
     385           0 :     if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_ADD)))
     386           0 :       ABORT(r);
     387             : 
     388           0 :     _status=0;
     389             :   abort:
     390           0 :     if (r_logging(NR_LOG_REGISTRY, LOG_INFO)) {
     391             :       int freeit;
     392           0 :       char *data = nr_reg_alloc_node_data(name, (void*)node, &freeit);
     393           0 :       r_log(NR_LOG_REGISTRY, LOG_INFO,
     394             :              "insert '%s' (%s) %s: %s", name,
     395           0 :              nr_reg_type_name(((nr_registry_node*)node)->type),
     396             :              (_status ? "FAILED" : "succeeded"), data);
     397           0 :       if (freeit)
     398           0 :         RFREE(data);
     399             :     }
     400           0 :     return(_status);
     401             : }
     402             : 
     403             : int
     404           0 : nr_reg_change_node(char *name, void *node, void *old)
     405             : {
     406             :     int r, _status;
     407             : 
     408           0 :     if ((r=nr_reg_is_valid(name)))
     409           0 :       ABORT(r);
     410             : 
     411           0 :     if (old != node) {
     412           0 :         if ((r=r_assoc_insert(nr_registry, name, strlen(name)+1, node, 0, nr_reg_rfree, R_ASSOC_REPLACE)))
     413           0 :           ABORT(r);
     414             :     }
     415             : 
     416           0 :     if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_CHANGE)))
     417           0 :       ABORT(r);
     418             : 
     419           0 :     _status=0;
     420             :   abort:
     421           0 :     if (r_logging(NR_LOG_REGISTRY, LOG_INFO)) {
     422             :       int freeit;
     423           0 :       char *data = nr_reg_alloc_node_data(name, (void*)node, &freeit);
     424           0 :       r_log(NR_LOG_REGISTRY, LOG_INFO,
     425             :              "change '%s' (%s) %s: %s", name,
     426           0 :              nr_reg_type_name(((nr_registry_node*)node)->type),
     427             :              (_status ? "FAILED" : "succeeded"), data);
     428           0 :       if (freeit)
     429           0 :         RFREE(data);
     430             :     }
     431           0 :     return(_status);
     432             : }
     433             : 
     434             : char *
     435           0 : nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit)
     436             : {
     437           0 :     char *s = 0;
     438             :     int len;
     439           0 :     int alloc = 0;
     440             :     unsigned int i;
     441             : 
     442           0 :     *freeit = 0;
     443             : 
     444           0 :     switch (node->type) {
     445             :     default:
     446           0 :       alloc = 100;    /* plenty of room for any of the scalar types */
     447           0 :       break;
     448             :     case NR_REG_TYPE_REGISTRY:
     449           0 :       alloc = strlen(name) + 1;
     450           0 :       break;
     451             :     case NR_REG_TYPE_BYTES:
     452           0 :       alloc = (2 * ((nr_array_registry_node*)node)->array.length) + 1;
     453           0 :       break;
     454             :     case NR_REG_TYPE_STRING:
     455           0 :       alloc = 0;
     456           0 :       break;
     457             :     }
     458             : 
     459           0 :     if (alloc > 0) {
     460           0 :       s = (void*)RMALLOC(alloc);
     461           0 :       if (!s)
     462           0 :         return "";
     463             : 
     464           0 :       *freeit = 1;
     465             :     }
     466             : 
     467           0 :     len = alloc;
     468             : 
     469           0 :     switch (node->type) {
     470             :     case NR_REG_TYPE_CHAR:
     471           0 :       i = ((nr_scalar_registry_node*)node)->scalar._char;
     472           0 :       if (isprint(i) && ! isspace(i))
     473           0 :           snprintf(s, len, "%c", (char)i);
     474             :       else
     475           0 :           snprintf(s, len, "\\%03o", (char)i);
     476           0 :       break;
     477             :     case NR_REG_TYPE_UCHAR:
     478           0 :       snprintf(s, len, "0x%02x", ((nr_scalar_registry_node*)node)->scalar._uchar);
     479           0 :       break;
     480             :     case NR_REG_TYPE_INT2:
     481           0 :       snprintf(s, len, "%d", ((nr_scalar_registry_node*)node)->scalar._nr_int2);
     482           0 :       break;
     483             :     case NR_REG_TYPE_UINT2:
     484           0 :       snprintf(s, len, "%u", ((nr_scalar_registry_node*)node)->scalar._nr_uint2);
     485           0 :       break;
     486             :     case NR_REG_TYPE_INT4:
     487           0 :       snprintf(s, len, "%d", ((nr_scalar_registry_node*)node)->scalar._nr_int4);
     488           0 :       break;
     489             :     case NR_REG_TYPE_UINT4:
     490           0 :       snprintf(s, len, "%u", ((nr_scalar_registry_node*)node)->scalar._nr_uint4);
     491           0 :       break;
     492             :     case NR_REG_TYPE_INT8:
     493           0 :       snprintf(s, len, "%lld", ((nr_scalar_registry_node*)node)->scalar._nr_int8);
     494           0 :       break;
     495             :     case NR_REG_TYPE_UINT8:
     496           0 :       snprintf(s, len, "%llu", ((nr_scalar_registry_node*)node)->scalar._nr_uint8);
     497           0 :       break;
     498             :     case NR_REG_TYPE_DOUBLE:
     499           0 :       snprintf(s, len, "%#f", ((nr_scalar_registry_node*)node)->scalar._double);
     500           0 :       break;
     501             :     case NR_REG_TYPE_REGISTRY:
     502           0 :       snprintf(s, len, "%s", name);
     503           0 :       break;
     504             :     case NR_REG_TYPE_BYTES:
     505           0 :       for (i = 0; i < ((nr_array_registry_node*)node)->array.length; ++i) {
     506           0 :         sprintf(&s[2*i], "%02x", ((nr_array_registry_node*)node)->array.data[i]);
     507             :       }
     508           0 :       break;
     509             :     case NR_REG_TYPE_STRING:
     510           0 :       s = (char*)((nr_array_registry_node*)node)->array.data;
     511           0 :       break;
     512             :     default:
     513           0 :       assert(0); /* bad value */
     514             :       *freeit = 0;
     515             :       s = "";
     516             :       break;
     517             :     }
     518             : 
     519           0 :     return s;
     520             : }
     521             : 
     522             : int
     523           0 : nr_reg_get(char *name, int type, void *out)
     524             : {
     525             :     int r, _status;
     526           0 :     nr_scalar_registry_node *node = 0;
     527           0 :     int free_node = 0;
     528             : 
     529           0 :     if ((r=nr_reg_fetch_node(name, type, (void*)&node, &free_node)))
     530           0 :       ABORT(r);
     531             : 
     532           0 :     if ((r=nr_reg_get_data(name, node, out)))
     533           0 :       ABORT(r);
     534             : 
     535           0 :     _status=0;
     536             :   abort:
     537           0 :     if (free_node) RFREE(node);
     538           0 :     return(_status);
     539             : }
     540             : 
     541             : int
     542           0 : nr_reg_get_data(NR_registry name, nr_scalar_registry_node *node, void *out)
     543             : {
     544             :     int _status;
     545             : 
     546           0 :     switch (node->type) {
     547             :     case NR_REG_TYPE_CHAR:
     548           0 :       *(char*)out = node->scalar._char;
     549           0 :       break;
     550             :     case NR_REG_TYPE_UCHAR:
     551           0 :       *(UCHAR*)out = node->scalar._uchar;
     552           0 :       break;
     553             :     case NR_REG_TYPE_INT2:
     554           0 :       *(INT2*)out = node->scalar._nr_int2;
     555           0 :       break;
     556             :     case NR_REG_TYPE_UINT2:
     557           0 :       *(UINT2*)out = node->scalar._nr_uint2;
     558           0 :       break;
     559             :     case NR_REG_TYPE_INT4:
     560           0 :       *(INT4*)out = node->scalar._nr_int4;
     561           0 :       break;
     562             :     case NR_REG_TYPE_UINT4:
     563           0 :       *(UINT4*)out = node->scalar._nr_uint4;
     564           0 :       break;
     565             :     case NR_REG_TYPE_INT8:
     566           0 :       *(INT8*)out = node->scalar._nr_int8;
     567           0 :       break;
     568             :     case NR_REG_TYPE_UINT8:
     569           0 :       *(UINT8*)out = node->scalar._nr_uint8;
     570           0 :       break;
     571             :     case NR_REG_TYPE_DOUBLE:
     572           0 :       *(double*)out = node->scalar._double;
     573           0 :       break;
     574             :     default:
     575           0 :       ABORT(R_INTERNAL);
     576             :       break;
     577             :     }
     578             : 
     579           0 :     _status=0;
     580             :   abort:
     581           0 :     return(_status);
     582             : }
     583             : 
     584             : int
     585           0 : nr_reg_get_array(char *name, unsigned char type, unsigned char *out, size_t size, size_t *length)
     586             : {
     587             :     int r, _status;
     588           0 :     nr_array_registry_node *node = 0;
     589           0 :     int free_node = 0;
     590             : 
     591           0 :     if ((r=nr_reg_fetch_node(name, type, (void*)&node, &free_node)))
     592           0 :       ABORT(r);
     593             : 
     594           0 :     if (size < node->array.length)
     595           0 :       ABORT(R_BAD_ARGS);
     596             : 
     597           0 :     if (out != 0)
     598           0 :         memcpy(out, node->array.data, node->array.length);
     599           0 :     if (length != 0)
     600           0 :         *length = node->array.length;
     601             : 
     602           0 :     _status=0;
     603             :   abort:
     604           0 :     if (node && free_node) RFREE(node);
     605           0 :     return(_status);
     606             : }
     607             : 
     608             : int
     609           0 : nr_reg_set(char *name, int type, void *data)
     610             : {
     611             :     int r, _status;
     612           0 :     nr_scalar_registry_node *node = 0;
     613           0 :     int create_node = 0;
     614           0 :     int changed = 0;
     615           0 :     int free_node = 0;
     616             : 
     617           0 :     if ((r=nr_reg_fetch_node(name, type, (void*)&node, &free_node)))
     618           0 :       if (r == R_NOT_FOUND) {
     619           0 :         create_node = 1;
     620           0 :         free_node = 1;
     621             :       }
     622             :       else
     623           0 :         ABORT(r);
     624             : 
     625           0 :     if (create_node) {
     626           0 :       if (!(node=(void*)RCALLOC(sizeof(nr_scalar_registry_node))))
     627           0 :         ABORT(R_NO_MEMORY);
     628             : 
     629           0 :       node->type = type;
     630             :     }
     631             :     else {
     632           0 :       if (node->type != type)
     633           0 :         ABORT(R_BAD_ARGS);
     634             :     }
     635             : 
     636           0 :     switch (type) {
     637             : #define CASE(TYPE, _name, type)                   \
     638             :     case TYPE:                                    \
     639             :       if (node->scalar._name != *(type*)data) {   \
     640             :         node->scalar._name = *(type*)data;        \
     641             :         if (! create_node)                        \
     642             :           changed = 1;                            \
     643             :       }                                           \
     644             :       break;
     645           0 :     CASE(NR_REG_TYPE_CHAR,       _char,       char)
     646           0 :     CASE(NR_REG_TYPE_UCHAR,      _uchar,      UCHAR)
     647           0 :     CASE(NR_REG_TYPE_INT2,    _nr_int2,    INT2)
     648           0 :     CASE(NR_REG_TYPE_UINT2,   _nr_uint2,   UINT2)
     649           0 :     CASE(NR_REG_TYPE_INT4,    _nr_int4,    INT4)
     650           0 :     CASE(NR_REG_TYPE_UINT4,   _nr_uint4,   UINT4)
     651           0 :     CASE(NR_REG_TYPE_INT8,    _nr_int8,    INT8)
     652           0 :     CASE(NR_REG_TYPE_UINT8,   _nr_uint8,   UINT8)
     653           0 :     CASE(NR_REG_TYPE_DOUBLE,     _double,     double)
     654             : #undef CASE
     655             : 
     656             :     case NR_REG_TYPE_REGISTRY:
     657             :       /* do nothing */
     658           0 :       break;
     659             : 
     660             :     default:
     661           0 :       ABORT(R_INTERNAL);
     662             :       break;
     663             :     }
     664             : 
     665           0 :     if (create_node) {
     666           0 :       if ((r=nr_reg_insert_node(name, node)))
     667           0 :         ABORT(r);
     668           0 :       free_node = 0;
     669             :     }
     670             :     else {
     671           0 :       if (changed) {
     672           0 :         if ((r=nr_reg_change_node(name, node, node)))
     673           0 :           ABORT(r);
     674           0 :         free_node = 0;
     675             :       }
     676             :     }
     677             : 
     678           0 :     _status=0;
     679             :   abort:
     680           0 :     if (_status) {
     681           0 :       if (node && free_node) RFREE(node);
     682             :     }
     683           0 :     return(_status);
     684             : }
     685             : 
     686             : int
     687           0 : nr_reg_set_array(char *name, unsigned char type, UCHAR *data, size_t length)
     688             : {
     689             :     int r, _status;
     690           0 :     nr_array_registry_node *old = 0;
     691           0 :     nr_array_registry_node *node = 0;
     692           0 :     int free_node = 0;
     693           0 :     int added = 0;
     694           0 :     int changed = 0;
     695             : 
     696           0 :     if ((r=nr_reg_fetch_node(name, type, (void*)&old, &free_node))) {
     697           0 :         if (r != R_NOT_FOUND)
     698           0 :             ABORT(r);
     699             :     }
     700             :     else {
     701           0 :       assert(free_node == 0);
     702             :     }
     703             : 
     704           0 :     if (old) {
     705           0 :         if (old->type != type)
     706           0 :             ABORT(R_BAD_ARGS);
     707             : 
     708           0 :         if (old->array.length != length
     709           0 :          || memcmp(old->array.data, data, length)) {
     710           0 :             changed = 1;
     711             : 
     712           0 :             if (old->array.length < length) {
     713           0 :                 if (!(node=(void*)RCALLOC(sizeof(nr_array_registry_node)+length)))
     714           0 :                     ABORT(R_NO_MEMORY);
     715             :             }
     716             :             else {
     717           0 :                 node = old;
     718             :             }
     719             :         }
     720             :     }
     721             :     else {
     722           0 :         if (!(node=(void*)RCALLOC(sizeof(nr_array_registry_node)+length)))
     723           0 :             ABORT(R_NO_MEMORY);
     724             : 
     725           0 :         added = 1;
     726             :     }
     727             : 
     728           0 :     if (added || changed) {
     729           0 :         node->type = type;
     730           0 :         node->array.length = length;
     731           0 :         memcpy(node->array.data, data, length);
     732             :     }
     733             : 
     734           0 :     if (added) {
     735           0 :         if ((r=nr_reg_insert_node(name, node)))
     736           0 :             ABORT(r);
     737             :     }
     738           0 :     else if (changed) {
     739           0 :         if ((r=nr_reg_change_node(name, node, old)))
     740           0 :           ABORT(r);
     741             :     }
     742             : 
     743           0 :     _status=0;
     744             :   abort:
     745           0 :     return(_status);
     746             : }
     747             : 
     748             : int
     749           0 : nr_reg_set_parent_registries(char *name)
     750             : {
     751             :     int r, _status;
     752           0 :     char *parent = 0;
     753             :     char *dot;
     754             : 
     755           0 :     if ((parent = r_strdup(name)) == 0)
     756           0 :       ABORT(R_NO_MEMORY);
     757             : 
     758           0 :     if ((dot = strrchr(parent, '.')) != 0) {
     759           0 :       *dot = '\0';
     760           0 :       if ((r=NR_reg_set_registry(parent)))
     761           0 :         ABORT(r);
     762             :     }
     763             : 
     764           0 :     _status=0;
     765             :   abort:
     766           0 :     if (parent) RFREE(parent);
     767           0 :     return(_status);
     768             : }
     769             : 
     770             : 
     771             : 
     772             : 
     773             : 
     774             : /* NON-STATIC METHODS */
     775             : 
     776             : int
     777           0 : nr_reg_is_valid(NR_registry name)
     778             : {
     779             :     int _status;
     780             :     unsigned int length;
     781             :     unsigned int i;
     782             : 
     783           0 :     if (name == 0)
     784           0 :       ABORT(R_BAD_ARGS);
     785             : 
     786             :     /* make sure the key is null-terminated */
     787           0 :     if (memchr(name, '\0', sizeof(NR_registry)) == 0)
     788           0 :       ABORT(R_BAD_ARGS);
     789             : 
     790           0 :     length = strlen(name);
     791             : 
     792             :     /* cannot begin or end with a period */
     793           0 :     if (name[0] == '.')
     794           0 :       ABORT(R_BAD_ARGS);
     795           0 :     if (strlen(name) > 0 && name[length-1] == '.')
     796           0 :       ABORT(R_BAD_ARGS);
     797             : 
     798             :     /* all characters cannot be space, and must be printable and not / */
     799           0 :     for (i = 0; i < length; ++i) {
     800           0 :       if (isspace(name[i]) || ! (isprint(name[i]) || name[i] == '/'))
     801           0 :         ABORT(R_BAD_ARGS);
     802             :     }
     803             : 
     804           0 :     _status=0;
     805             :   abort:
     806           0 :     if (_status) {
     807           0 :       r_log(NR_LOG_REGISTRY, LOG_DEBUG, "invalid name '%s'", name);
     808             :     }
     809           0 :     return(_status);
     810             : }
     811             : 
     812             : 
     813             : int
     814           0 : nr_reg_compute_length(char *name, nr_registry_node *in, size_t *length)
     815             : {
     816             :     int _status;
     817           0 :     nr_array_registry_node *node = (nr_array_registry_node*)in;
     818             : 
     819           0 :     switch (node->type) {
     820             :     case NR_REG_TYPE_STRING:
     821           0 :       *length = node->array.length - 1;
     822           0 :       break;
     823             :     case NR_REG_TYPE_BYTES:
     824           0 :       *length = node->array.length;
     825           0 :       break;
     826             :     case NR_REG_TYPE_CHAR:
     827           0 :       *length = sizeof(char);
     828           0 :       break;
     829             :     case NR_REG_TYPE_UCHAR:
     830           0 :       *length = sizeof(UCHAR);
     831           0 :       break;
     832             :     case NR_REG_TYPE_INT2:
     833             :     case NR_REG_TYPE_UINT2:
     834           0 :       *length = 2;
     835           0 :       break;
     836             :     case NR_REG_TYPE_INT4:
     837             :     case NR_REG_TYPE_UINT4:
     838           0 :       *length = 4;
     839           0 :       break;
     840             :     case NR_REG_TYPE_INT8:
     841             :     case NR_REG_TYPE_UINT8:
     842           0 :       *length = 8;
     843           0 :       break;
     844             :     case NR_REG_TYPE_DOUBLE:
     845           0 :       *length = sizeof(double);
     846           0 :       break;
     847             :     case NR_REG_TYPE_REGISTRY:
     848           0 :       *length = strlen(name);
     849           0 :       break;
     850             :     default:
     851           0 :       ABORT(R_INTERNAL);
     852             :       break;
     853             :     }
     854             : 
     855           0 :     _status=0;
     856             :   abort:
     857           0 :     return(_status);
     858             : }
     859             : 
     860             : 
     861             : /* VTBL METHODS */
     862             : 
     863             : int
     864           0 : nr_reg_local_init(nr_registry_module *me)
     865             : {
     866             :     int r, _status;
     867             : 
     868           0 :     if (nr_registry == 0) {
     869           0 :       if ((r=r_assoc_create(&nr_registry, r_assoc_crc32_hash_compute, 12)))
     870           0 :         ABORT(r);
     871             : 
     872           0 :       if ((r=nr_reg_cb_init()))
     873           0 :             ABORT(r);
     874             : 
     875             :       /* make sure NR_TOP_LEVEL_REGISTRY always exists */
     876           0 :       if ((r=nr_reg_local_set_registry(NR_TOP_LEVEL_REGISTRY)))
     877           0 :           ABORT(r);
     878             :     }
     879             : 
     880           0 :     _status=0;
     881             :   abort:
     882           0 :     return(_status);
     883             : }
     884             : 
     885             : #define NRREGGET(func, TYPE, type)                                  \
     886             : int                                                                 \
     887             : func(NR_registry name, type *out)                                   \
     888             : {                                                                   \
     889             :     return nr_reg_get(name, TYPE, out);                             \
     890             : }
     891             : 
     892           0 : NRREGGET(nr_reg_local_get_char,     NR_REG_TYPE_CHAR,     char)
     893           0 : NRREGGET(nr_reg_local_get_uchar,    NR_REG_TYPE_UCHAR,    UCHAR)
     894           0 : NRREGGET(nr_reg_local_get_int2,     NR_REG_TYPE_INT2,     INT2)
     895           0 : NRREGGET(nr_reg_local_get_uint2,    NR_REG_TYPE_UINT2,    UINT2)
     896           0 : NRREGGET(nr_reg_local_get_int4,     NR_REG_TYPE_INT4,     INT4)
     897           0 : NRREGGET(nr_reg_local_get_uint4,    NR_REG_TYPE_UINT4,    UINT4)
     898           0 : NRREGGET(nr_reg_local_get_int8,     NR_REG_TYPE_INT8,     INT8)
     899           0 : NRREGGET(nr_reg_local_get_uint8,    NR_REG_TYPE_UINT8,    UINT8)
     900           0 : NRREGGET(nr_reg_local_get_double,   NR_REG_TYPE_DOUBLE,   double)
     901             : 
     902             : int
     903           0 : nr_reg_local_get_registry(NR_registry name, NR_registry out)
     904             : {
     905             :     int r, _status;
     906           0 :     nr_scalar_registry_node *node = 0;
     907           0 :     int free_node = 0;
     908             : 
     909           0 :     if ((r=nr_reg_fetch_node(name, NR_REG_TYPE_REGISTRY, (void*)&node, &free_node)))
     910           0 :       ABORT(r);
     911             : 
     912           0 :     strncpy(out, name, sizeof(NR_registry));
     913             : 
     914           0 :     _status=0;
     915             :   abort:
     916           0 :     if (free_node) RFREE(node);
     917           0 :     return(_status);
     918             : 
     919             : }
     920             : 
     921             : int
     922           0 : nr_reg_local_get_bytes(NR_registry name, UCHAR *out, size_t size, size_t *length)
     923             : {
     924           0 :     return nr_reg_get_array(name, NR_REG_TYPE_BYTES, out, size, length);
     925             : }
     926             : 
     927             : int
     928           0 : nr_reg_local_get_string(NR_registry name, char *out, size_t size)
     929             : {
     930           0 :     return nr_reg_get_array(name, NR_REG_TYPE_STRING, (UCHAR*)out, size, 0);
     931             : }
     932             : 
     933             : int
     934           0 : nr_reg_local_get_length(NR_registry name, size_t *length)
     935             : {
     936             :     int r, _status;
     937           0 :     nr_registry_node *node = 0;
     938             : 
     939           0 :     if ((r=nr_reg_is_valid(name)))
     940           0 :       ABORT(r);
     941             : 
     942           0 :     if ((r=r_assoc_fetch(nr_registry, name, strlen(name)+1, (void*)&node)))
     943           0 :       ABORT(r);
     944             : 
     945           0 :     if ((r=nr_reg_compute_length(name, node, length)))
     946           0 :       ABORT(r);
     947             : 
     948           0 :     _status=0;
     949             :   abort:
     950           0 :     return(_status);
     951             : }
     952             : 
     953             : int
     954           0 : nr_reg_local_get_type(NR_registry name, NR_registry_type type)
     955             : {
     956             :     int r, _status;
     957           0 :     nr_registry_node *node = 0;
     958             :     char *str;
     959             : 
     960           0 :     if ((r=nr_reg_is_valid(name)))
     961           0 :       ABORT(r);
     962             : 
     963           0 :     if ((r=r_assoc_fetch(nr_registry, name, strlen(name)+1, (void*)&node)))
     964           0 :       ABORT(r);
     965             : 
     966           0 :     str = nr_reg_type_name(node->type);
     967           0 :     if (! str)
     968           0 :         ABORT(R_BAD_ARGS);
     969             : 
     970           0 :     strncpy(type, str, sizeof(NR_registry_type));
     971             : 
     972           0 :     _status=0;
     973             :   abort:
     974           0 :     return(_status);
     975             : }
     976             : 
     977             : 
     978             : #define NRREGSET(func, TYPE, type)                              \
     979             : int                                                             \
     980             : func(NR_registry name, type data)                               \
     981             : {                                                               \
     982             :     return nr_reg_set(name, TYPE, &data);                       \
     983             : }
     984             : 
     985           0 : NRREGSET(nr_reg_local_set_char,     NR_REG_TYPE_CHAR,     char)
     986           0 : NRREGSET(nr_reg_local_set_uchar,    NR_REG_TYPE_UCHAR,    UCHAR)
     987           0 : NRREGSET(nr_reg_local_set_int2,     NR_REG_TYPE_INT2,     INT2)
     988           0 : NRREGSET(nr_reg_local_set_uint2,    NR_REG_TYPE_UINT2,    UINT2)
     989           0 : NRREGSET(nr_reg_local_set_int4,     NR_REG_TYPE_INT4,     INT4)
     990           0 : NRREGSET(nr_reg_local_set_uint4,    NR_REG_TYPE_UINT4,    UINT4)
     991           0 : NRREGSET(nr_reg_local_set_int8,     NR_REG_TYPE_INT8,     INT8)
     992           0 : NRREGSET(nr_reg_local_set_uint8,    NR_REG_TYPE_UINT8,    UINT8)
     993           0 : NRREGSET(nr_reg_local_set_double,   NR_REG_TYPE_DOUBLE,   double)
     994             : 
     995             : int
     996           0 : nr_reg_local_set_registry(NR_registry name)
     997             : {
     998           0 :     return nr_reg_set(name, NR_REG_TYPE_REGISTRY, 0);
     999             : }
    1000             : 
    1001             : int
    1002           0 : nr_reg_local_set_bytes(NR_registry name, unsigned char *data, size_t length)
    1003             : {
    1004           0 :     return nr_reg_set_array(name, NR_REG_TYPE_BYTES, data, length);
    1005             : }
    1006             : 
    1007             : int
    1008           0 : nr_reg_local_set_string(NR_registry name, char *data)
    1009             : {
    1010           0 :     return nr_reg_set_array(name, NR_REG_TYPE_STRING, (UCHAR*)data, strlen(data)+1);
    1011             : }
    1012             : 
    1013             : int
    1014           0 : nr_reg_local_del(NR_registry name)
    1015             : {
    1016             :     int r, _status;
    1017             : 
    1018           0 :     if ((r=nr_reg_is_valid(name)))
    1019           0 :       ABORT(r);
    1020             : 
    1021             :     /* delete from NR_registry */
    1022           0 :     if ((r=nr_reg_local_iter(name, nr_reg_local_iter_delete, 0)))
    1023           0 :       ABORT(r);
    1024             : 
    1025           0 :     if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_DELETE)))
    1026           0 :       ABORT(r);
    1027             : 
    1028             :     /* if deleting from the root, re-insert the root */
    1029           0 :     if (! strcasecmp(name, NR_TOP_LEVEL_REGISTRY)) {
    1030           0 :       if ((r=nr_reg_local_set_registry(NR_TOP_LEVEL_REGISTRY)))
    1031           0 :           ABORT(r);
    1032             :     }
    1033             : 
    1034           0 :     _status=0;
    1035             :   abort:
    1036           0 :     r_log(NR_LOG_REGISTRY,
    1037             :           (_status ? LOG_INFO               :  LOG_INFO),
    1038             :           "delete of '%s' %s", name,
    1039             :           (_status ? "FAILED"               : "succeeded"));
    1040           0 :     return(_status);
    1041             : }
    1042             : 
    1043             : int
    1044           0 : nr_reg_local_get_child_count(char *parent, size_t *count)
    1045             : {
    1046             :     int r, _status;
    1047             :     nr_registry_node *ignore1;
    1048             :     int ignore2;
    1049             : 
    1050             : 
    1051           0 :     if ((r=nr_reg_is_valid(parent)))
    1052           0 :       ABORT(r);
    1053             : 
    1054             :     /* test to see whether it is present */
    1055           0 :     if ((r=nr_reg_fetch_node(parent, NR_REG_TYPE_REGISTRY, &ignore1, &ignore2)))
    1056           0 :       ABORT(r);
    1057             : 
    1058             :     /* sanity check that there isn't any memory to free */
    1059           0 :     assert(ignore2 == 0);
    1060             : 
    1061           0 :     *count = 0;
    1062             : 
    1063           0 :     if ((r=nr_reg_local_iter(parent, nr_reg_local_count_children, count)))
    1064           0 :       ABORT(r);
    1065             : 
    1066           0 :     _status=0;
    1067             :   abort:
    1068           0 :     return(_status);
    1069             : }
    1070             : 
    1071             : int
    1072           0 : nr_reg_local_get_children(NR_registry parent, NR_registry *data, size_t size, size_t *length)
    1073             : {
    1074             :     int r, _status;
    1075             :     nr_reg_find_children_arg arg;
    1076             : 
    1077           0 :     if ((r=nr_reg_is_valid(parent)))
    1078           0 :       ABORT(r);
    1079             : 
    1080           0 :     arg.children = data;
    1081           0 :     arg.size = size;
    1082           0 :     arg.length = 0;
    1083             : 
    1084           0 :     if ((r=nr_reg_local_iter(parent, nr_reg_local_find_children, (void*)&arg))) {
    1085           0 :         if (r == R_INTERRUPTED)
    1086           0 :             ABORT(R_BAD_ARGS);
    1087             :         else
    1088           0 :             ABORT(r);
    1089             :     }
    1090             : 
    1091             :     assert(sizeof(*arg.children) == sizeof(NR_registry));
    1092           0 :     qsort(arg.children, arg.length, sizeof(*arg.children), (void*)strcasecmp);
    1093             : 
    1094           0 :     *length = arg.length;
    1095             : 
    1096           0 :     _status = 0;
    1097             :   abort:
    1098           0 :     return(_status);
    1099             : }
    1100             : 
    1101             : int
    1102           0 : nr_reg_local_fin(NR_registry name)
    1103             : {
    1104             :     int r, _status;
    1105             : 
    1106           0 :     if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_FINAL)))
    1107           0 :       ABORT(r);
    1108             : 
    1109           0 :     _status=0;
    1110             :   abort:
    1111           0 :     return(_status);
    1112             : }
    1113             : 
    1114             : int
    1115           0 : nr_reg_local_dump(int sorted)
    1116             : {
    1117             :     int r, _status;
    1118             : 
    1119           0 :     if ((r=nr_reg_local_iter(NR_TOP_LEVEL_REGISTRY, nr_reg_local_dump_print, 0)))
    1120           0 :       ABORT(r);
    1121             : 
    1122           0 :     _status=0;
    1123             :   abort:
    1124           0 :     return(_status);
    1125             : }
    1126             : 
    1127             : 
    1128             : 
    1129             : static nr_registry_module_vtbl nr_reg_local_vtbl = {
    1130             :     nr_reg_local_init,
    1131             :     nr_reg_local_get_char,
    1132             :     nr_reg_local_get_uchar,
    1133             :     nr_reg_local_get_int2,
    1134             :     nr_reg_local_get_uint2,
    1135             :     nr_reg_local_get_int4,
    1136             :     nr_reg_local_get_uint4,
    1137             :     nr_reg_local_get_int8,
    1138             :     nr_reg_local_get_uint8,
    1139             :     nr_reg_local_get_double,
    1140             :     nr_reg_local_get_registry,
    1141             :     nr_reg_local_get_bytes,
    1142             :     nr_reg_local_get_string,
    1143             :     nr_reg_local_get_length,
    1144             :     nr_reg_local_get_type,
    1145             :     nr_reg_local_set_char,
    1146             :     nr_reg_local_set_uchar,
    1147             :     nr_reg_local_set_int2,
    1148             :     nr_reg_local_set_uint2,
    1149             :     nr_reg_local_set_int4,
    1150             :     nr_reg_local_set_uint4,
    1151             :     nr_reg_local_set_int8,
    1152             :     nr_reg_local_set_uint8,
    1153             :     nr_reg_local_set_double,
    1154             :     nr_reg_local_set_registry,
    1155             :     nr_reg_local_set_bytes,
    1156             :     nr_reg_local_set_string,
    1157             :     nr_reg_local_del,
    1158             :     nr_reg_local_get_child_count,
    1159             :     nr_reg_local_get_children,
    1160             :     nr_reg_local_fin,
    1161             :     nr_reg_local_dump
    1162             : };
    1163             : 
    1164             : static nr_registry_module nr_reg_local_module = { 0, &nr_reg_local_vtbl };
    1165             : 
    1166             : void *NR_REG_MODE_LOCAL = &nr_reg_local_module;
    1167             : 
    1168             : 

Generated by: LCOV version 1.13