LCOV - code coverage report
Current view: top level - media/mtransport/third_party/nrappkit/src/registry - registry.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 232 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 66 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.c,v $
       6             :  *    $Revision: 1.6 $
       7             :  *    $Date: 2007/11/21 00:09:12 $
       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 _MSC_VER
      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             : #include "c2ru.h"
      65             : 
      66             : /* vtbl used to switch hit between local and remote invocations */
      67             : static nr_registry_module *reg_vtbl = 0;
      68             : 
      69             : /* must be in the order the types are numbered */
      70             : static char *typenames[] = { "char", "UCHAR", "INT2", "UINT2", "INT4", "UINT4", "INT8", "UINT8", "double", "Data", "string", "registry" };
      71             : 
      72             : int NR_LOG_REGISTRY=0;
      73             : 
      74             : NR_registry NR_TOP_LEVEL_REGISTRY = "";
      75             : 
      76             : int
      77           0 : NR_reg_init(void *mode)
      78             : {
      79             :     int r, _status;
      80           0 :     nr_registry_module *module = (nr_registry_module*)mode;
      81             : #ifdef SANITY_CHECKS
      82             :     NR_registry registry;
      83             : #endif
      84             : 
      85           0 :     if (reg_vtbl) {
      86           0 :         if (reg_vtbl != module) {
      87           0 :           r_log(LOG_GENERIC,LOG_ERR,"Can't reinitialize registry in different mode");
      88           0 :           ABORT(R_INTERNAL);
      89             :         }
      90             : 
      91           0 :         return(0);
      92             :     }
      93             : 
      94           0 :     reg_vtbl = module;
      95             : 
      96           0 :     if ((r=reg_vtbl->vtbl->init(mode)))
      97           0 :         ABORT(r);
      98             : 
      99             : #ifdef SANITY_CHECKS
     100           0 :     if ((r=NR_reg_get_registry(NR_TOP_LEVEL_REGISTRY, registry)))
     101           0 :         ABORT(r);
     102           0 :     assert(strcmp(registry, NR_TOP_LEVEL_REGISTRY) == 0);
     103             : #endif
     104             : 
     105           0 :      r_log_init();
     106           0 :      r_log_register("registry",&NR_LOG_REGISTRY);
     107             : 
     108           0 :     _status=0;
     109             :   abort:
     110           0 :     r_log(NR_LOG_REGISTRY,
     111             :           (_status ? LOG_ERR                        :  LOG_INFO),
     112             :           (_status ? "Couldn't initialize registry" : "Initialized registry"));
     113           0 :     return(_status);
     114             : }
     115             : 
     116             : int
     117           0 : NR_reg_initted(void)
     118             : {
     119           0 :     return reg_vtbl!=0;
     120             : }
     121             : 
     122             : #define NRREGGET(func, method, type)                                \
     123             : int                                                                 \
     124             : func(NR_registry name, type *out)                                   \
     125             : {                                                                   \
     126             :     return reg_vtbl->vtbl->method(name, out);                             \
     127             : }
     128             : 
     129           0 : NRREGGET(NR_reg_get_char,     get_char,     char)
     130           0 : NRREGGET(NR_reg_get_uchar,    get_uchar,    UCHAR)
     131           0 : NRREGGET(NR_reg_get_int2,     get_int2,     INT2)
     132           0 : NRREGGET(NR_reg_get_uint2,    get_uint2,    UINT2)
     133           0 : NRREGGET(NR_reg_get_int4,     get_int4,     INT4)
     134           0 : NRREGGET(NR_reg_get_uint4,    get_uint4,    UINT4)
     135           0 : NRREGGET(NR_reg_get_int8,     get_int8,     INT8)
     136           0 : NRREGGET(NR_reg_get_uint8,    get_uint8,    UINT8)
     137           0 : NRREGGET(NR_reg_get_double,   get_double,   double)
     138             : 
     139             : int
     140           0 : NR_reg_get_registry(NR_registry name, NR_registry out)
     141             : {
     142           0 :     return reg_vtbl->vtbl->get_registry(name, out);
     143             : }
     144             : 
     145             : int
     146           0 : NR_reg_get_bytes(NR_registry name, UCHAR *out, size_t size, size_t *length)
     147             : {
     148           0 :     return reg_vtbl->vtbl->get_bytes(name, out, size, length);
     149             : }
     150             : 
     151             : int
     152           0 : NR_reg_get_string(NR_registry name, char *out, size_t size)
     153             : {
     154           0 :     return reg_vtbl->vtbl->get_string(name, out, size);
     155             : }
     156             : 
     157             : int
     158           0 : NR_reg_get_length(NR_registry name, size_t *length)
     159             : {
     160           0 :     return reg_vtbl->vtbl->get_length(name, length);
     161             : }
     162             : 
     163             : int
     164           0 : NR_reg_get_type(NR_registry name, NR_registry_type type)
     165             : {
     166           0 :     return reg_vtbl->vtbl->get_type(name, type);
     167             : }
     168             : 
     169             : #define NRREGSET(func, method, type)                            \
     170             : int                                                             \
     171             : func(NR_registry name, type data)                               \
     172             : {                                                               \
     173             :     return reg_vtbl->vtbl->method(name, data);                        \
     174             : }
     175             : 
     176           0 : NRREGSET(NR_reg_set_char,     set_char,     char)
     177           0 : NRREGSET(NR_reg_set_uchar,    set_uchar,    UCHAR)
     178           0 : NRREGSET(NR_reg_set_int2,     set_int2,     INT2)
     179           0 : NRREGSET(NR_reg_set_uint2,    set_uint2,    UINT2)
     180           0 : NRREGSET(NR_reg_set_int4,     set_int4,     INT4)
     181           0 : NRREGSET(NR_reg_set_uint4,    set_uint4,    UINT4)
     182           0 : NRREGSET(NR_reg_set_int8,     set_int8,     INT8)
     183           0 : NRREGSET(NR_reg_set_uint8,    set_uint8,    UINT8)
     184           0 : NRREGSET(NR_reg_set_double,   set_double,   double)
     185           0 : NRREGSET(NR_reg_set_string,   set_string,   char*)
     186             : 
     187             : int
     188           0 : NR_reg_set_registry(NR_registry name)
     189             : {
     190           0 :     return reg_vtbl->vtbl->set_registry(name);
     191             : }
     192             : 
     193             : int
     194           0 : NR_reg_set_bytes(NR_registry name, unsigned char *data, size_t length)
     195             : {
     196           0 :     return reg_vtbl->vtbl->set_bytes(name, data, length);
     197             : }
     198             : 
     199             : 
     200             : int
     201           0 : NR_reg_del(NR_registry name)
     202             : {
     203           0 :     return reg_vtbl->vtbl->del(name);
     204             : }
     205             : 
     206             : int
     207           0 : NR_reg_fin(NR_registry name)
     208             : {
     209           0 :     return reg_vtbl->vtbl->fin(name);
     210             : }
     211             : 
     212             : int
     213           0 : NR_reg_get_child_count(char *parent, unsigned int *count)
     214             : {
     215             :     assert(sizeof(count) == sizeof(size_t));
     216           0 :     return reg_vtbl->vtbl->get_child_count(parent, (size_t*)count);
     217             : }
     218             : 
     219             : int
     220           0 : NR_reg_get_child_registry(char *parent, unsigned int i, NR_registry child)
     221             : {
     222             :     int r, _status;
     223             :     size_t count;
     224           0 :     NR_registry *children=0;
     225             : 
     226           0 :     if ((r=reg_vtbl->vtbl->get_child_count(parent, &count)))
     227           0 :       ABORT(r);
     228             : 
     229           0 :     if (i >= count)
     230           0 :         ABORT(R_NOT_FOUND);
     231             :     else {
     232           0 :         count++;
     233           0 :         children = (NR_registry *)RCALLOC(count * sizeof(NR_registry));
     234           0 :         if (!children)
     235           0 :             ABORT(R_NO_MEMORY);
     236             : 
     237           0 :         if ((r=reg_vtbl->vtbl->get_children(parent, children, count, &count)))
     238           0 :             ABORT(r);
     239             : 
     240           0 :         if (i >= count)
     241           0 :             ABORT(R_NOT_FOUND);
     242             : 
     243           0 :         strncpy(child, children[i], sizeof(NR_registry));
     244             :     }
     245             : 
     246           0 :     _status=0;
     247             :   abort:
     248           0 :     RFREE(children);
     249           0 :     return(_status);
     250             : }
     251             : 
     252             : int
     253           0 : NR_reg_get_children(NR_registry parent, NR_registry *children, size_t size, size_t *length)
     254             : {
     255           0 :     return reg_vtbl->vtbl->get_children(parent, children, size, length);
     256             : }
     257             : 
     258             : int
     259           0 : NR_reg_dump()
     260             : {
     261             :     int r, _status;
     262             : 
     263           0 :     if ((r=reg_vtbl->vtbl->dump(0)))
     264           0 :       ABORT(r);
     265             : 
     266           0 :     _status=0;
     267             :   abort:
     268           0 :     return(_status);
     269             : }
     270             : 
     271             : // convenience methods, call RFREE on the returned data
     272             : int
     273           0 : NR_reg_alloc_data(NR_registry name, Data *data)
     274             : {
     275             :     int r, _status;
     276             :     size_t length;
     277           0 :     UCHAR  *tmp = 0;
     278             :     size_t sanity_check;
     279             : 
     280           0 :     if ((r=NR_reg_get_length(name, &length)))
     281           0 :       ABORT(r);
     282             : 
     283           0 :     if (!(tmp = (void*)RMALLOC(length)))
     284           0 :       ABORT(R_NO_MEMORY);
     285             : 
     286           0 :     if ((r=NR_reg_get_bytes(name, tmp, length, &sanity_check)))
     287           0 :       ABORT(r);
     288             : 
     289           0 :     assert(length == sanity_check);
     290             : 
     291           0 :     data->len = length;
     292           0 :     data->data = tmp;
     293             : 
     294           0 :     _status=0;
     295             :   abort:
     296           0 :     if (_status) {
     297           0 :       if (tmp) RFREE(tmp);
     298             :     }
     299           0 :     return(_status);
     300             : }
     301             : 
     302             : int
     303           0 : NR_reg_alloc_string(NR_registry name, char **data)
     304             : {
     305             :     int r, _status;
     306             :     size_t length;
     307           0 :     char  *tmp = 0;
     308             : 
     309           0 :     if ((r=NR_reg_get_length(name, &length)))
     310           0 :       ABORT(r);
     311             : 
     312           0 :     if (!(tmp = (void*)RMALLOC(length+1)))
     313           0 :       ABORT(R_NO_MEMORY);
     314             : 
     315           0 :     if ((r=NR_reg_get_string(name, tmp, length+1)))
     316           0 :       ABORT(r);
     317             : 
     318           0 :     assert(length == strlen(tmp));
     319             : 
     320           0 :     *data = tmp;
     321             : 
     322           0 :     _status=0;
     323             :   abort:
     324           0 :     if (_status) {
     325           0 :       if (tmp) RFREE(tmp);
     326             :     }
     327           0 :     return(_status);
     328             : }
     329             : 
     330             : 
     331             : char *
     332           0 : nr_reg_type_name(int type)
     333             : {
     334           0 :     if ((type < NR_REG_TYPE_CHAR) || (type > NR_REG_TYPE_REGISTRY))
     335           0 :        return(NULL);
     336             : 
     337           0 :     return(typenames[type]);
     338             : }
     339             : 
     340             : int
     341           0 : nr_reg_compute_type(char *typename, int *type)
     342             : {
     343             :     int _status;
     344             :     int i;
     345             : 
     346             : #ifdef SANITY_CHECKS
     347           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_CHAR],     "char"));
     348           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_UCHAR],    "UCHAR"));
     349           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_INT2],     "INT2"));
     350           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_UINT2],    "UINT2"));
     351           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_INT4],     "INT4"));
     352           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_UINT4],    "UINT4"));
     353           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_INT8],     "INT8"));
     354           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_UINT8],    "UINT8"));
     355           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_DOUBLE],   "double"));
     356           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_BYTES],    "Data"));
     357           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_STRING],   "string"));
     358           0 :     assert(!strcasecmp(typenames[NR_REG_TYPE_REGISTRY], "registry"));
     359             :     assert(sizeof(typenames)/sizeof(*typenames) == (NR_REG_TYPE_REGISTRY+1));
     360             : #endif
     361             : 
     362           0 :     for (i = 0; i < sizeof(typenames)/sizeof(*typenames); ++i) {
     363           0 :       if (!strcasecmp(typenames[i], typename)) {
     364           0 :         *type = i;
     365           0 :         return 0;
     366             :       }
     367             :     }
     368           0 :     ABORT(R_BAD_ARGS);
     369             : 
     370             :     _status=0;
     371             :   abort:
     372           0 :     return(_status);
     373             : }
     374             : 
     375             : /* More convenience functions: the same as their parents but they
     376             :    take a prefix and a suffix */
     377             : #define NRGET2(func, type, get) \
     378             : int                                                                  \
     379             : func(NR_registry parent, char *child, type *out)                     \
     380             : {                                                                    \
     381             :   int r, _status;                                                    \
     382             :   NR_registry registry;                                              \
     383             :                                                                      \
     384             :   if ((r = NR_reg_make_registry(parent, child, registry)))           \
     385             :     ABORT(r);                                                        \
     386             :                                                                      \
     387             :   if ((r = get(registry, out))) {                                    \
     388             :     ABORT(r);                                                        \
     389             :   }                                                                  \
     390             :                                                                      \
     391             :   _status = 0;                                                       \
     392             : abort:                                                               \
     393             :   return (_status);                                                  \
     394             : }
     395             : 
     396           0 : NRGET2(NR_reg_get2_char,     char,    NR_reg_get_char)
     397           0 : NRGET2(NR_reg_get2_uchar,    UCHAR,   NR_reg_get_uchar)
     398           0 : NRGET2(NR_reg_get2_int2,     INT2,    NR_reg_get_int2)
     399           0 : NRGET2(NR_reg_get2_uint2,    UINT2,   NR_reg_get_uint2)
     400           0 : NRGET2(NR_reg_get2_int4,     INT4,    NR_reg_get_int4)
     401           0 : NRGET2(NR_reg_get2_uint4,    UINT4,   NR_reg_get_uint4)
     402           0 : NRGET2(NR_reg_get2_int8,     INT8,    NR_reg_get_int8)
     403           0 : NRGET2(NR_reg_get2_uint8,    UINT8,   NR_reg_get_uint8)
     404           0 : NRGET2(NR_reg_get2_double,   double,  NR_reg_get_double)
     405           0 : NRGET2(NR_reg_alloc2_string,   char*,   NR_reg_alloc_string)
     406           0 : NRGET2(NR_reg_alloc2_data,     Data,    NR_reg_alloc_data)
     407             : 
     408             : int
     409           0 : NR_reg_get2_bytes(NR_registry parent, char *child, UCHAR *out, size_t size, size_t *length)
     410             : {
     411             :     int r, _status;
     412             :     NR_registry registry;
     413             : 
     414           0 :     if ((r=NR_reg_make_registry(parent, child, registry)))
     415           0 :       ABORT(r);
     416             : 
     417           0 :     if ((r=NR_reg_get_bytes(registry, out, size, length)))
     418           0 :       ABORT(r);
     419             : 
     420           0 :     _status = 0;
     421             : abort:
     422           0 :     return (_status);
     423             : }
     424             : 
     425             : int
     426           0 : NR_reg_get2_string(NR_registry parent, char *child, char *out, size_t size)
     427             : {
     428             :     int r, _status;
     429             :     NR_registry registry;
     430             : 
     431           0 :     if ((r=NR_reg_make_registry(parent, child, registry)))
     432           0 :       ABORT(r);
     433             : 
     434           0 :     if ((r=NR_reg_get_string(registry, out, size)))
     435           0 :       ABORT(r);
     436             : 
     437           0 :     _status = 0;
     438             : abort:
     439           0 :     return (_status);
     440             : }
     441             : 
     442             : /* More convenience functions: the same as their parents but they
     443             :    take a prefix and a suffix */
     444             : #define NRSET2(func, type, set) \
     445             : int                                                                  \
     446             : func(NR_registry parent, char *child, type in)                       \
     447             : {                                                                    \
     448             :   int r, _status;                                                    \
     449             :   NR_registry registry;                                              \
     450             :                                                                      \
     451             :   if ((r = NR_reg_make_registry(parent, child, registry)))           \
     452             :     ABORT(r);                                                        \
     453             :                                                                      \
     454             :   if ((r = set(registry, in))) {                                     \
     455             :     ABORT(r);                                                        \
     456             :   }                                                                  \
     457             :                                                                      \
     458             :   _status = 0;                                                       \
     459             : abort:                                                               \
     460             :   return (_status);                                                  \
     461             : }
     462             : 
     463           0 : NRSET2(NR_reg_set2_char,     char,    NR_reg_set_char)
     464           0 : NRSET2(NR_reg_set2_uchar,    UCHAR,   NR_reg_set_uchar)
     465           0 : NRSET2(NR_reg_set2_int2,     INT2,    NR_reg_set_int2)
     466           0 : NRSET2(NR_reg_set2_uint2,    UINT2,   NR_reg_set_uint2)
     467           0 : NRSET2(NR_reg_set2_int4,     INT4,    NR_reg_set_int4)
     468           0 : NRSET2(NR_reg_set2_uint4,    UINT4,   NR_reg_set_uint4)
     469           0 : NRSET2(NR_reg_set2_int8,     INT8,    NR_reg_set_int8)
     470           0 : NRSET2(NR_reg_set2_uint8,    UINT8,   NR_reg_set_uint8)
     471           0 : NRSET2(NR_reg_set2_double,   double,  NR_reg_set_double)
     472           0 : NRSET2(NR_reg_set2_string,   char*,   NR_reg_set_string)
     473             : 
     474             : int
     475           0 : NR_reg_set2_bytes(NR_registry prefix, char *name, UCHAR *data, size_t length)
     476             : {
     477             :     int r, _status;
     478             :     NR_registry registry;
     479             : 
     480           0 :     if ((r = NR_reg_make_registry(prefix, name, registry)))
     481           0 :       ABORT(r);
     482             : 
     483           0 :     if ((r = NR_reg_set_bytes(registry, data, length)))
     484           0 :       ABORT(r);
     485             : 
     486           0 :     _status = 0;
     487             : abort:
     488           0 :     return (_status);
     489             : }
     490             : 
     491             : 
     492             : int
     493           0 : NR_reg_make_child_registry(NR_registry parent, NR_registry descendant, unsigned int generation, NR_registry child)
     494             : {
     495             :     int _status;
     496             :     size_t length;
     497             : 
     498           0 :     length = strlen(parent);
     499             : 
     500           0 :     if (strncasecmp(parent, descendant, length))
     501           0 :         ABORT(R_BAD_ARGS);
     502             : 
     503           0 :     while (descendant[length] != '\0') {
     504           0 :         if (descendant[length] == '.') {
     505           0 :             if (generation == 0)
     506           0 :                 break;
     507             : 
     508           0 :             --generation;
     509             :         }
     510             : 
     511           0 :         ++length;
     512           0 :         if (length >= sizeof(NR_registry))
     513           0 :             ABORT(R_BAD_ARGS);
     514             :     }
     515             : 
     516           0 :     strncpy(child, descendant, length);
     517           0 :     child[length] = '\0';
     518             : 
     519           0 :     _status=0;
     520             :   abort:
     521           0 :     return(_status);
     522             : }
     523             : 
     524             : int
     525           0 : NR_reg_get2_child_count(NR_registry base, NR_registry name, unsigned int *count)
     526             :   {
     527             :     int r, _status;
     528             :     NR_registry registry;
     529             : 
     530           0 :     if ((r=nr_c2ru_make_registry(base, name, registry)))
     531           0 :       ABORT(r);
     532             : 
     533           0 :     if (r=NR_reg_get_child_count(registry,count))
     534           0 :       ABORT(r);
     535             : 
     536           0 :     _status=0;
     537             :   abort:
     538           0 :     return(_status);
     539             :   }
     540             : 
     541             : int
     542           0 : NR_reg_get2_child_registry(NR_registry base, NR_registry name, unsigned int i, NR_registry child)
     543             :   {
     544             :     int r, _status;
     545             :     NR_registry registry;
     546             : 
     547           0 :     if ((r=nr_c2ru_make_registry(base, name, registry)))
     548           0 :       ABORT(r);
     549             : 
     550           0 :     if (r=NR_reg_get_child_registry(registry, i, child))
     551           0 :       ABORT(r);
     552             : 
     553           0 :     _status=0;
     554             :   abort:
     555           0 :     return(_status);
     556             :   }
     557             : 
     558             : 
     559             : /* requires parent already in legal form */
     560             : int
     561           0 : NR_reg_make_registry(NR_registry parent, char *child, NR_registry out)
     562             : {
     563             :     int r, _status;
     564             :     int plen;
     565             :     int clen;
     566             :     char *c;
     567             :     int i;
     568             : 
     569           0 :     if ((r=nr_reg_is_valid(parent)))
     570           0 :         ABORT(r);
     571             : 
     572           0 :     if (*child == '.')
     573           0 :         ABORT(R_BAD_ARGS);
     574             : 
     575           0 :     clen = strlen(child);
     576           0 :     if (!clen)
     577           0 :         ABORT(R_BAD_ARGS);
     578           0 :     plen = strlen(parent);
     579           0 :     if ((plen + clen + 2) > sizeof(NR_registry))
     580           0 :         ABORT(R_BAD_ARGS);
     581             : 
     582           0 :     if (out != parent)
     583           0 :         strcpy(out, parent);
     584             : 
     585           0 :     c = &(out[plen]);
     586             : 
     587           0 :     if (parent[0] != '\0') {
     588           0 :         *c = '.';
     589           0 :         ++c;
     590             :     }
     591             : 
     592           0 :     for (i = 0; i < clen; ++i, ++c) {
     593           0 :         *c = child[i];
     594           0 :         if (isspace(*c) || *c == '.' || *c == '/' || ! isprint(*c))
     595           0 :             *c = '_';
     596             :     }
     597             : 
     598           0 :     *c = '\0';
     599             : 
     600           0 :     _status = 0;
     601             : abort:
     602           0 :     return _status;
     603             : }
     604             : 

Generated by: LCOV version 1.13