tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

registry.c (13099B)


      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 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 <csi_platform.h>
     57 #include "registry.h"
     58 #include "registry_int.h"
     59 #include "r_assoc.h"
     60 #include "r_log.h"
     61 #include "r_errors.h"
     62 #include "r_macros.h"
     63 
     64 static int reg_initted = 0;
     65 
     66 /* must be in the order the types are numbered */
     67 static char *typenames[] = { "char", "UCHAR", "INT2", "UINT2", "INT4", "UINT4", "INT8", "UINT8", "double", "Data", "string", "registry" };
     68 
     69 int NR_LOG_REGISTRY=0;
     70 
     71 NR_registry NR_TOP_LEVEL_REGISTRY = "";
     72 
     73 int
     74 NR_reg_init()
     75 {
     76    int r, _status;
     77 #ifdef SANITY_CHECKS
     78    NR_registry registry;
     79 #endif
     80 
     81    if (reg_initted) {
     82        return(0);
     83    }
     84 
     85    reg_initted = 1;
     86 
     87    if ((r=nr_reg_local_init()))
     88        ABORT(r);
     89 
     90 #ifdef SANITY_CHECKS
     91    if ((r=NR_reg_get_registry(NR_TOP_LEVEL_REGISTRY, registry)))
     92        ABORT(r);
     93    assert(strcmp(registry, NR_TOP_LEVEL_REGISTRY) == 0);
     94 #endif
     95 
     96     r_log_init();
     97     r_log_register("registry",&NR_LOG_REGISTRY);
     98 
     99    _status=0;
    100  abort:
    101    r_log(NR_LOG_REGISTRY,
    102          (_status ? LOG_ERR                        :  LOG_INFO),
    103          (_status ? "Couldn't initialize registry" : "Initialized registry"));
    104    return(_status);
    105 }
    106 
    107 int
    108 NR_reg_initted(void)
    109 {
    110    return reg_initted!=0;
    111 }
    112 
    113 #define NRREGGET(func, TYPE, type)                                  \
    114 int                                                                 \
    115 func(NR_registry name, type *out)                                   \
    116 {                                                                   \
    117    return nr_reg_get(name, TYPE, out);                             \
    118 }
    119 
    120 NRREGGET(NR_reg_get_char,     NR_REG_TYPE_CHAR,     char)
    121 NRREGGET(NR_reg_get_uchar,    NR_REG_TYPE_UCHAR,    UCHAR)
    122 NRREGGET(NR_reg_get_uint2,    NR_REG_TYPE_UINT2,    UINT2)
    123 NRREGGET(NR_reg_get_int4,     NR_REG_TYPE_INT4,     INT4)
    124 NRREGGET(NR_reg_get_uint4,    NR_REG_TYPE_UINT4,    UINT4)
    125 NRREGGET(NR_reg_get_uint8,    NR_REG_TYPE_UINT8,    UINT8)
    126 NRREGGET(NR_reg_get_double,   NR_REG_TYPE_DOUBLE,   double)
    127 
    128 int
    129 NR_reg_get_registry(NR_registry name, NR_registry out)
    130 {
    131    int r, _status;
    132    nr_scalar_registry_node *node = 0;
    133    int free_node = 0;
    134 
    135    if ((r=nr_reg_fetch_node(name, NR_REG_TYPE_REGISTRY, (void*)&node, &free_node)))
    136      ABORT(r);
    137 
    138    strncpy(out, name, sizeof(NR_registry));
    139 
    140    _status=0;
    141  abort:
    142    if (free_node) RFREE(node);
    143    return(_status);
    144 
    145 }
    146 
    147 int
    148 NR_reg_get_bytes(NR_registry name, UCHAR *out, size_t size, size_t *length)
    149 {
    150    return nr_reg_get_array(name, NR_REG_TYPE_BYTES, out, size, length);
    151 }
    152 
    153 int
    154 NR_reg_get_string(NR_registry name, char *out, size_t size)
    155 {
    156    return nr_reg_get_array(name, NR_REG_TYPE_STRING, (UCHAR*)out, size, 0);
    157 }
    158 
    159 int
    160 NR_reg_get_length(NR_registry name, size_t *length)
    161 {
    162    return nr_reg_local_get_length(name, length);
    163 }
    164 
    165 #define NRREGSET(func, TYPE, type)                         \
    166 int                                                             \
    167 func(NR_registry name, type data)                               \
    168 {                                                               \
    169    return nr_reg_set(name, TYPE, &data);                       \
    170 }
    171 
    172 NRREGSET(NR_reg_set_char,     NR_REG_TYPE_CHAR,     char)
    173 NRREGSET(NR_reg_set_uchar,    NR_REG_TYPE_UCHAR,    UCHAR)
    174 NRREGSET(NR_reg_set_int4,     NR_REG_TYPE_INT4,     INT4)
    175 NRREGSET(NR_reg_set_uint4,    NR_REG_TYPE_UINT4,    UINT4)
    176 
    177 int
    178 NR_reg_set_string(NR_registry name, char *data)
    179 {
    180    return nr_reg_set_array(name, NR_REG_TYPE_STRING, (UCHAR*)data, strlen(data)+1);
    181 }
    182 
    183 int
    184 NR_reg_set_registry(NR_registry name)
    185 {
    186    return nr_reg_set(name, NR_REG_TYPE_REGISTRY, 0);
    187 }
    188 
    189 int
    190 NR_reg_set_bytes(NR_registry name, unsigned char *data, size_t length)
    191 {
    192    return nr_reg_set_array(name, NR_REG_TYPE_BYTES, data, length);
    193 }
    194 
    195 
    196 int
    197 NR_reg_del(NR_registry name)
    198 {
    199    return nr_reg_local_del(name);
    200 }
    201 
    202 int
    203 NR_reg_get_child_count(NR_registry parent, unsigned int *count)
    204 {
    205    assert(sizeof(count) == sizeof(size_t));
    206    return nr_reg_local_get_child_count(parent, (size_t*)count);
    207 }
    208 
    209 int
    210 NR_reg_get_child_registry(NR_registry parent, unsigned int i, NR_registry child)
    211 {
    212    int r, _status;
    213    size_t count;
    214    NR_registry *children=0;
    215 
    216    if ((r=nr_reg_local_get_child_count(parent, &count)))
    217      ABORT(r);
    218 
    219    if (i >= count)
    220        ABORT(R_NOT_FOUND);
    221    else {
    222        count++;
    223        children = (NR_registry *)RCALLOC(count * sizeof(NR_registry));
    224        if (!children)
    225            ABORT(R_NO_MEMORY);
    226 
    227        if ((r=nr_reg_local_get_children(parent, children, count, &count)))
    228            ABORT(r);
    229 
    230        if (i >= count)
    231            ABORT(R_NOT_FOUND);
    232 
    233        strncpy(child, children[i], sizeof(NR_registry));
    234    }
    235 
    236    _status=0;
    237  abort:
    238    RFREE(children);
    239    return(_status);
    240 }
    241 
    242 // convenience methods, call RFREE on the returned data
    243 int
    244 NR_reg_alloc_data(NR_registry name, Data *data)
    245 {
    246    int r, _status;
    247    size_t length;
    248    UCHAR  *tmp = 0;
    249    size_t sanity_check;
    250 
    251    if ((r=NR_reg_get_length(name, &length)))
    252      ABORT(r);
    253 
    254    if (!(tmp = (void*)RMALLOC(length)))
    255      ABORT(R_NO_MEMORY);
    256 
    257    if ((r=NR_reg_get_bytes(name, tmp, length, &sanity_check)))
    258      ABORT(r);
    259 
    260    assert(length == sanity_check);
    261 
    262    data->len = length;
    263    data->data = tmp;
    264 
    265    _status=0;
    266  abort:
    267    if (_status) {
    268      if (tmp) RFREE(tmp);
    269    }
    270    return(_status);
    271 }
    272 
    273 int
    274 NR_reg_alloc_string(NR_registry name, char **data)
    275 {
    276    int r, _status;
    277    size_t length;
    278    char  *tmp = 0;
    279 
    280    if ((r=NR_reg_get_length(name, &length)))
    281      ABORT(r);
    282 
    283    if (!(tmp = (void*)RMALLOC(length+1)))
    284      ABORT(R_NO_MEMORY);
    285 
    286    if ((r=NR_reg_get_string(name, tmp, length+1)))
    287      ABORT(r);
    288 
    289    assert(length == strlen(tmp));
    290 
    291    *data = tmp;
    292 
    293    _status=0;
    294  abort:
    295    if (_status) {
    296      if (tmp) RFREE(tmp);
    297    }
    298    return(_status);
    299 }
    300 
    301 
    302 char *
    303 nr_reg_type_name(int type)
    304 {
    305    if ((type < NR_REG_TYPE_CHAR) || (type > NR_REG_TYPE_REGISTRY))
    306       return(NULL);
    307 
    308    return(typenames[type]);
    309 }
    310 
    311 int
    312 nr_reg_compute_type(char *typename, int *type)
    313 {
    314    int _status;
    315    size_t i;
    316 
    317 #ifdef SANITY_CHECKS
    318    assert(!strcasecmp(typenames[NR_REG_TYPE_CHAR],     "char"));
    319    assert(!strcasecmp(typenames[NR_REG_TYPE_UCHAR],    "UCHAR"));
    320    assert(!strcasecmp(typenames[NR_REG_TYPE_INT2],     "INT2"));
    321    assert(!strcasecmp(typenames[NR_REG_TYPE_UINT2],    "UINT2"));
    322    assert(!strcasecmp(typenames[NR_REG_TYPE_INT4],     "INT4"));
    323    assert(!strcasecmp(typenames[NR_REG_TYPE_UINT4],    "UINT4"));
    324    assert(!strcasecmp(typenames[NR_REG_TYPE_INT8],     "INT8"));
    325    assert(!strcasecmp(typenames[NR_REG_TYPE_UINT8],    "UINT8"));
    326    assert(!strcasecmp(typenames[NR_REG_TYPE_DOUBLE],   "double"));
    327    assert(!strcasecmp(typenames[NR_REG_TYPE_BYTES],    "Data"));
    328    assert(!strcasecmp(typenames[NR_REG_TYPE_STRING],   "string"));
    329    assert(!strcasecmp(typenames[NR_REG_TYPE_REGISTRY], "registry"));
    330    assert(sizeof(typenames)/sizeof(*typenames) == (NR_REG_TYPE_REGISTRY+1));
    331 #endif
    332 
    333    for (i = 0; i < sizeof(typenames)/sizeof(*typenames); ++i) {
    334      if (!strcasecmp(typenames[i], typename)) {
    335        *type = i;
    336        return 0;
    337      }
    338    }
    339    ABORT(R_BAD_ARGS);
    340 
    341    _status=0;
    342  abort:
    343    return(_status);
    344 }
    345 
    346 /* More convenience functions: the same as their parents but they
    347   take a prefix and a suffix */
    348 #define NRGET2(func, type, get) \
    349 int                                                                  \
    350 func(NR_registry parent, char *child, type *out)                     \
    351 {                                                                    \
    352  int r, _status;                                                    \
    353  NR_registry registry;                                              \
    354                                                                     \
    355  if ((r = NR_reg_make_registry(parent, child, registry)))           \
    356    ABORT(r);                                                        \
    357                                                                     \
    358  if ((r = get(registry, out))) {                                    \
    359    ABORT(r);                                                        \
    360  }                                                                  \
    361                                                                     \
    362  _status = 0;                                                       \
    363 abort:                                                               \
    364  return (_status);                                                  \
    365 }
    366 
    367 NRGET2(NR_reg_get2_char,     char,    NR_reg_get_char)
    368 NRGET2(NR_reg_get2_uchar,    UCHAR,   NR_reg_get_uchar)
    369 NRGET2(NR_reg_get2_uint2,    UINT2,   NR_reg_get_uint2)
    370 NRGET2(NR_reg_alloc2_string,   char*,   NR_reg_alloc_string)
    371 NRGET2(NR_reg_alloc2_data,     Data,    NR_reg_alloc_data)
    372 
    373 /* More convenience functions: the same as their parents but they
    374   take a prefix and a suffix */
    375 #define NRSET2(func, type, set) \
    376 int                                                                  \
    377 func(NR_registry parent, char *child, type in)                       \
    378 {                                                                    \
    379  int r, _status;                                                    \
    380  NR_registry registry;                                              \
    381                                                                     \
    382  if ((r = NR_reg_make_registry(parent, child, registry)))           \
    383    ABORT(r);                                                        \
    384                                                                     \
    385  if ((r = set(registry, in))) {                                     \
    386    ABORT(r);                                                        \
    387  }                                                                  \
    388                                                                     \
    389  _status = 0;                                                       \
    390 abort:                                                               \
    391  return (_status);                                                  \
    392 }
    393 
    394 NRSET2(NR_reg_set2_uchar,    UCHAR,   NR_reg_set_uchar)
    395 NRSET2(NR_reg_set2_string,   char*,   NR_reg_set_string)
    396 
    397 /* requires parent already in legal form */
    398 int
    399 NR_reg_make_registry(NR_registry parent, char *child, NR_registry out)
    400 {
    401    int r, _status;
    402    size_t plen;
    403    size_t clen;
    404    char *c = 0;
    405    size_t i;
    406 
    407    if ((r=nr_reg_is_valid(parent)))
    408        ABORT(r);
    409 
    410    if (*child == '.')
    411        ABORT(R_BAD_ARGS);
    412 
    413    clen = strlen(child);
    414    if (!clen)
    415        ABORT(R_BAD_ARGS);
    416    plen = strlen(parent);
    417    if ((plen + clen + 2) > sizeof(NR_registry))
    418        ABORT(R_BAD_ARGS);
    419 
    420    if (out != parent)
    421        strcpy(out, parent);
    422 
    423    c = &(out[plen]);
    424 
    425    if (parent[0] != '\0') {
    426        *c = '.';
    427        ++c;
    428    }
    429 
    430    for (i = 0; i < clen; ++i, ++c) {
    431        *c = child[i];
    432        if (isspace(*c) || *c == '.' || *c == '/' || ! isprint(*c))
    433            *c = '_';
    434    }
    435 
    436    *c = '\0';
    437 
    438    _status = 0;
    439 abort:
    440    return _status;
    441 }