diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /media/mtransport/third_party/nrappkit/src/registry | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'media/mtransport/third_party/nrappkit/src/registry')
8 files changed, 2975 insertions, 0 deletions
diff --git a/media/mtransport/third_party/nrappkit/src/registry/c2ru.c b/media/mtransport/third_party/nrappkit/src/registry/c2ru.c new file mode 100644 index 000000000..f2c19cb80 --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/c2ru.c @@ -0,0 +1,320 @@ +/* + * + * c2ru.c + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/c2ru.c,v $ + * $Revision: 1.3 $ + * $Date: 2007/06/26 22:37:50 $ + * + * c2r utility methods + * + * + * Copyright (C) 2005, Network Resonance, Inc. + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <sys/queue.h> +#include <string.h> +#include <registry.h> +#include "nr_common.h" +#include <r_errors.h> +#include <r_macros.h> +#include <ctype.h> +#include "c2ru.h" + + +#define NRGET(func, type, get) \ +int \ +func(NR_registry parent, char *child, type **out) \ +{ \ + int r, _status; \ + NR_registry registry; \ + type tmp; \ + \ + if ((r = nr_c2ru_make_registry(parent, child, registry))) \ + ABORT(r); \ + \ + if ((r = get(registry, &tmp))) { \ + if (r != R_NOT_FOUND) \ + ABORT(r); \ + *out = 0; \ + } \ + else { \ + *out = RCALLOC(sizeof(tmp)); \ + if (*out == 0) \ + ABORT(R_NO_MEMORY); \ + **out = tmp; \ + } \ + \ + _status = 0; \ +abort: \ + return (_status); \ +} + +int +nr_c2ru_get_char(NR_registry parent, char *child, char **out) +{ + int r, _status; + NR_registry registry; + char tmp; + + if ((r = nr_c2ru_make_registry(parent, child, registry))) + ABORT(r); + + if ((r = NR_reg_get_char(registry, &tmp))) { + if (r != R_NOT_FOUND) + ABORT(r); + *out = 0; + } + else { + *out = RCALLOC(sizeof(tmp)); + if (*out == 0) + ABORT(R_NO_MEMORY); + **out = tmp; + } + + _status = 0; +abort: + return (_status); +} +NRGET(nr_c2ru_get_uchar, UCHAR, NR_reg_get_uchar) +NRGET(nr_c2ru_get_int2, INT2, NR_reg_get_int2) +NRGET(nr_c2ru_get_uint2, UINT2, NR_reg_get_uint2) +NRGET(nr_c2ru_get_int4, INT4, NR_reg_get_int4) +NRGET(nr_c2ru_get_uint4, UINT4, NR_reg_get_uint4) +NRGET(nr_c2ru_get_int8, INT8, NR_reg_get_int8) +NRGET(nr_c2ru_get_uint8, UINT8, NR_reg_get_uint8) +NRGET(nr_c2ru_get_double, double, NR_reg_get_double) +NRGET(nr_c2ru_get_string, char*, NR_reg_alloc_string) +NRGET(nr_c2ru_get_data, Data, NR_reg_alloc_data) + + +#define NRSET(func, type, set) \ +int \ +func(NR_registry parent, char *child, type *in) \ +{ \ + int r, _status; \ + NR_registry registry; \ + \ + if (in == 0) \ + return 0; \ + \ + if ((r = nr_c2ru_make_registry(parent, child, registry))) \ + ABORT(r); \ + \ + if ((r = set(registry, *in))) \ + ABORT(r); \ + \ + _status = 0; \ +abort: \ + return (_status); \ +} + +NRSET(nr_c2ru_set_char, char, NR_reg_set_char) +NRSET(nr_c2ru_set_uchar, UCHAR, NR_reg_set_uchar) +NRSET(nr_c2ru_set_int2, INT2, NR_reg_set_int2) +NRSET(nr_c2ru_set_uint2, UINT2, NR_reg_set_uint2) +NRSET(nr_c2ru_set_int4, INT4, NR_reg_set_int4) +NRSET(nr_c2ru_set_uint4, UINT4, NR_reg_set_uint4) +NRSET(nr_c2ru_set_int8, INT8, NR_reg_set_int8) +NRSET(nr_c2ru_set_uint8, UINT8, NR_reg_set_uint8) +NRSET(nr_c2ru_set_double, double, NR_reg_set_double) +NRSET(nr_c2ru_set_string, char*, NR_reg_set_string) + +int +nr_c2ru_set_data(NR_registry parent, char *child, Data *in) +{ + int r, _status; + NR_registry registry; + + if (in == 0) + return 0; + + if ((r = nr_c2ru_make_registry(parent, child, registry))) + ABORT(r); + + if ((r = NR_reg_set_bytes(registry, in->data, in->len))) + ABORT(r); + + _status = 0; +abort: + return (_status); +} + +#define NRFREE(func, type) \ +int \ +func(type *in) \ +{ \ + if (in) \ + RFREE(in); \ + return 0; \ +} + +NRFREE(nr_c2ru_free_char, char) +NRFREE(nr_c2ru_free_uchar, UCHAR) +NRFREE(nr_c2ru_free_int2, INT2) +NRFREE(nr_c2ru_free_uint2, UINT2) +NRFREE(nr_c2ru_free_int4, INT4) +NRFREE(nr_c2ru_free_uint4, UINT4) +NRFREE(nr_c2ru_free_int8, INT8) +NRFREE(nr_c2ru_free_uint8, UINT8) +NRFREE(nr_c2ru_free_double, double) + + +int +nr_c2ru_free_string(char **in) +{ + if (*in) + RFREE(*in); + if (in) + RFREE(in); + return 0; +} + +int +nr_c2ru_free_data(Data *in) +{ + int r, _status; + + if (in) { + if ((r=r_data_destroy(&in))) + ABORT(r); + } + + _status = 0; +abort: + return (_status); +} + +int +nr_c2ru_get_children(NR_registry parent, char *child, void *ptr, size_t size, int (*get)(NR_registry, void*)) +{ + int r, _status; + NR_registry registry; + unsigned int count; + int i; + NR_registry name; + struct entry { TAILQ_ENTRY(entry) entries; } *entry; + TAILQ_HEAD(, entry) *tailq = (void*)ptr; + + TAILQ_INIT(tailq); + + if ((r=nr_c2ru_make_registry(parent, child, registry))) + ABORT(r); + + if ((r=NR_reg_get_child_count(registry, &count))) { + if (r != R_NOT_FOUND) + ABORT(r); + } + else { + for (i = 0; i < count; ++i) { + if ((r=NR_reg_get_child_registry(registry, i, name))) { + /* ignore R_NOT_FOUND errors */ + if (r == R_NOT_FOUND) + continue; + else + ABORT(r); + } + + if ((r=get(name, &entry))) { + /* ignore R_NOT_FOUND errors */ + if (r == R_NOT_FOUND) + continue; + else + ABORT(r); + } + + TAILQ_INSERT_TAIL(tailq, entry, entries); + } + } + + _status = 0; +abort: + return (_status); +} + +int +nr_c2ru_set_children(NR_registry parent, char *child, void *ptr, int (*set)(NR_registry, void*), int (*label)(NR_registry, void*, char[NR_REG_MAX_NR_REGISTRY_LEN])) +{ + int r, _status; + NR_registry registry; + int i; + NR_registry name; + char buffer[NR_REG_MAX_NR_REGISTRY_LEN]; + struct entry { TAILQ_ENTRY(entry) entries; } *entry; + TAILQ_HEAD(, entry) *tailq = (void*)ptr; + + if ((r=nr_c2ru_make_registry(parent, child, registry))) + ABORT(r); + + (void)NR_reg_del(registry); + + i = 0; + TAILQ_FOREACH(entry, tailq, entries) { + if (label == 0 || (r=label(registry, entry, buffer))) { + snprintf(buffer, sizeof(buffer), "%d", i); + } + if ((r=nr_c2ru_make_registry(registry, buffer, name))) + ABORT(r); + + if ((r=set(name, entry))) + ABORT(r); + + ++i; + } + + _status = 0; +abort: + return (_status); +} + +int +nr_c2ru_free_children(void *ptr, int (*free)(void*)) +{ + struct entry { TAILQ_ENTRY(entry) entries; } *entry; + TAILQ_HEAD(, entry) *tailq = (void*)ptr; + + while (! TAILQ_EMPTY(tailq)) { + entry = TAILQ_FIRST(tailq); + TAILQ_REMOVE(tailq, entry, entries); + (void)free(entry); + } + + return 0; +} + +/* requires parent already in legal form */ +int +nr_c2ru_make_registry(NR_registry parent, char *child, NR_registry out) +{ + return NR_reg_make_registry(parent, child, out); +} diff --git a/media/mtransport/third_party/nrappkit/src/registry/c2ru.h b/media/mtransport/third_party/nrappkit/src/registry/c2ru.h new file mode 100644 index 000000000..0f8c38ecc --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/c2ru.h @@ -0,0 +1,96 @@ +/* + * + * c2ru.h + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/c2ru.h,v $ + * $Revision: 1.2 $ + * $Date: 2006/08/16 19:39:13 $ + * + * c2r utility methods + * + * + * Copyright (C) 2005, Network Resonance, Inc. + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#ifndef __C2RU_H__ +#define __C2RU_H__ + +#include <sys/types.h> +#include <r_types.h> +#include <r_data.h> +#include "registry_int.h" + +int nr_c2ru_get_char(NR_registry parent, char *child, char **out); +int nr_c2ru_get_uchar(NR_registry parent, char *child, UCHAR **out); +int nr_c2ru_get_int2(NR_registry parent, char *child, INT2 **out); +int nr_c2ru_get_uint2(NR_registry parent, char *child, UINT2 **out); +int nr_c2ru_get_int4(NR_registry parent, char *child, INT4 **out); +int nr_c2ru_get_uint4(NR_registry parent, char *child, UINT4 **out); +int nr_c2ru_get_int8(NR_registry parent, char *child, INT8 **out); +int nr_c2ru_get_uint8(NR_registry parent, char *child, UINT8 **out); +int nr_c2ru_get_double(NR_registry parent, char *child, double **out); +int nr_c2ru_get_data(NR_registry parent, char *child, Data **out); +int nr_c2ru_get_string(NR_registry parent, char *child, char ***out); + +int nr_c2ru_set_char(NR_registry parent, char *child, char *data); +int nr_c2ru_set_uchar(NR_registry parent, char *child, UCHAR *data); +int nr_c2ru_set_int2(NR_registry parent, char *child, INT2 *data); +int nr_c2ru_set_uint2(NR_registry parent, char *child, UINT2 *data); +int nr_c2ru_set_int4(NR_registry parent, char *child, INT4 *data); +int nr_c2ru_set_uint4(NR_registry parent, char *child, UINT4 *data); +int nr_c2ru_set_int8(NR_registry parent, char *child, INT8 *data); +int nr_c2ru_set_uint8(NR_registry parent, char *child, UINT8 *data); +int nr_c2ru_set_double(NR_registry parent, char *child, double *data); +int nr_c2ru_set_registry(NR_registry parent, char *child); +int nr_c2ru_set_data(NR_registry parent, char *child, Data *data); +int nr_c2ru_set_string(NR_registry parent, char *child, char **data); + +int nr_c2ru_free_char(char *data); +int nr_c2ru_free_uchar(UCHAR *data); +int nr_c2ru_free_int2(INT2 *data); +int nr_c2ru_free_uint2(UINT2 *data); +int nr_c2ru_free_int4(INT4 *data); +int nr_c2ru_free_uint4(UINT4 *data); +int nr_c2ru_free_int8(INT8 *data); +int nr_c2ru_free_uint8(UINT8 *data); +int nr_c2ru_free_double(double *data); +int nr_c2ru_free_data(Data *data); +int nr_c2ru_free_string(char **data); + +int nr_c2ru_get_children(NR_registry parent, char *child, void *ptr, size_t size, int (*get)(NR_registry, void*)); +int nr_c2ru_set_children(NR_registry parent, char *child, void *ptr, int (*set)(NR_registry, void*), int (*label)(NR_registry, void*, char[NR_REG_MAX_NR_REGISTRY_LEN])); +int nr_c2ru_free_children(void *ptr, int (*free)(void*)); + +int nr_c2ru_make_registry(NR_registry parent, char *child, NR_registry out); + +#endif diff --git a/media/mtransport/third_party/nrappkit/src/registry/registry.c b/media/mtransport/third_party/nrappkit/src/registry/registry.c new file mode 100644 index 000000000..d7ba472e5 --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/registry.c @@ -0,0 +1,604 @@ +/* + * + * registry.c + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registry.c,v $ + * $Revision: 1.6 $ + * $Date: 2007/11/21 00:09:12 $ + * + * Datastore for tracking configuration and related info. + * + * + * Copyright (C) 2005, Network Resonance, Inc. + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <assert.h> +#include <string.h> +#ifndef _MSC_VER +#include <strings.h> +#include <sys/param.h> +#include <netinet/in.h> +#endif +#ifdef OPENSSL +#include <openssl/ssl.h> +#endif +#include <ctype.h> +#include "registry.h" +#include "registry_int.h" +#include "registry_vtbl.h" +#include "r_assoc.h" +#include "nr_common.h" +#include "r_log.h" +#include "r_errors.h" +#include "r_macros.h" +#include "c2ru.h" + +/* vtbl used to switch hit between local and remote invocations */ +static nr_registry_module *reg_vtbl = 0; + +/* must be in the order the types are numbered */ +static char *typenames[] = { "char", "UCHAR", "INT2", "UINT2", "INT4", "UINT4", "INT8", "UINT8", "double", "Data", "string", "registry" }; + +int NR_LOG_REGISTRY=0; + +NR_registry NR_TOP_LEVEL_REGISTRY = ""; + +int +NR_reg_init(void *mode) +{ + int r, _status; + nr_registry_module *module = (nr_registry_module*)mode; +#ifdef SANITY_CHECKS + NR_registry registry; +#endif + + if (reg_vtbl) { + if (reg_vtbl != module) { + r_log(LOG_GENERIC,LOG_ERR,"Can't reinitialize registry in different mode"); + ABORT(R_INTERNAL); + } + + return(0); + } + + reg_vtbl = module; + + if ((r=reg_vtbl->vtbl->init(mode))) + ABORT(r); + +#ifdef SANITY_CHECKS + if ((r=NR_reg_get_registry(NR_TOP_LEVEL_REGISTRY, registry))) + ABORT(r); + assert(strcmp(registry, NR_TOP_LEVEL_REGISTRY) == 0); +#endif + + r_log_init(); + r_log_register("registry",&NR_LOG_REGISTRY); + + _status=0; + abort: + r_log(NR_LOG_REGISTRY, + (_status ? LOG_ERR : LOG_INFO), + (_status ? "Couldn't initialize registry" : "Initialized registry")); + return(_status); +} + +int +NR_reg_initted(void) +{ + return reg_vtbl!=0; +} + +#define NRREGGET(func, method, type) \ +int \ +func(NR_registry name, type *out) \ +{ \ + return reg_vtbl->vtbl->method(name, out); \ +} + +NRREGGET(NR_reg_get_char, get_char, char) +NRREGGET(NR_reg_get_uchar, get_uchar, UCHAR) +NRREGGET(NR_reg_get_int2, get_int2, INT2) +NRREGGET(NR_reg_get_uint2, get_uint2, UINT2) +NRREGGET(NR_reg_get_int4, get_int4, INT4) +NRREGGET(NR_reg_get_uint4, get_uint4, UINT4) +NRREGGET(NR_reg_get_int8, get_int8, INT8) +NRREGGET(NR_reg_get_uint8, get_uint8, UINT8) +NRREGGET(NR_reg_get_double, get_double, double) + +int +NR_reg_get_registry(NR_registry name, NR_registry out) +{ + return reg_vtbl->vtbl->get_registry(name, out); +} + +int +NR_reg_get_bytes(NR_registry name, UCHAR *out, size_t size, size_t *length) +{ + return reg_vtbl->vtbl->get_bytes(name, out, size, length); +} + +int +NR_reg_get_string(NR_registry name, char *out, size_t size) +{ + return reg_vtbl->vtbl->get_string(name, out, size); +} + +int +NR_reg_get_length(NR_registry name, size_t *length) +{ + return reg_vtbl->vtbl->get_length(name, length); +} + +int +NR_reg_get_type(NR_registry name, NR_registry_type type) +{ + return reg_vtbl->vtbl->get_type(name, type); +} + +#define NRREGSET(func, method, type) \ +int \ +func(NR_registry name, type data) \ +{ \ + return reg_vtbl->vtbl->method(name, data); \ +} + +NRREGSET(NR_reg_set_char, set_char, char) +NRREGSET(NR_reg_set_uchar, set_uchar, UCHAR) +NRREGSET(NR_reg_set_int2, set_int2, INT2) +NRREGSET(NR_reg_set_uint2, set_uint2, UINT2) +NRREGSET(NR_reg_set_int4, set_int4, INT4) +NRREGSET(NR_reg_set_uint4, set_uint4, UINT4) +NRREGSET(NR_reg_set_int8, set_int8, INT8) +NRREGSET(NR_reg_set_uint8, set_uint8, UINT8) +NRREGSET(NR_reg_set_double, set_double, double) +NRREGSET(NR_reg_set_string, set_string, char*) + +int +NR_reg_set_registry(NR_registry name) +{ + return reg_vtbl->vtbl->set_registry(name); +} + +int +NR_reg_set_bytes(NR_registry name, unsigned char *data, size_t length) +{ + return reg_vtbl->vtbl->set_bytes(name, data, length); +} + + +int +NR_reg_del(NR_registry name) +{ + return reg_vtbl->vtbl->del(name); +} + +int +NR_reg_fin(NR_registry name) +{ + return reg_vtbl->vtbl->fin(name); +} + +int +NR_reg_get_child_count(char *parent, unsigned int *count) +{ + assert(sizeof(count) == sizeof(size_t)); + return reg_vtbl->vtbl->get_child_count(parent, (size_t*)count); +} + +int +NR_reg_get_child_registry(char *parent, unsigned int i, NR_registry child) +{ + int r, _status; + size_t count; + NR_registry *children=0; + + if ((r=reg_vtbl->vtbl->get_child_count(parent, &count))) + ABORT(r); + + if (i >= count) + ABORT(R_NOT_FOUND); + else { + count++; + children = (NR_registry *)RCALLOC(count * sizeof(NR_registry)); + if (!children) + ABORT(R_NO_MEMORY); + + if ((r=reg_vtbl->vtbl->get_children(parent, children, count, &count))) + ABORT(r); + + if (i >= count) + ABORT(R_NOT_FOUND); + + strncpy(child, children[i], sizeof(NR_registry)); + } + + _status=0; + abort: + RFREE(children); + return(_status); +} + +int +NR_reg_get_children(NR_registry parent, NR_registry *children, size_t size, size_t *length) +{ + return reg_vtbl->vtbl->get_children(parent, children, size, length); +} + +int +NR_reg_dump() +{ + int r, _status; + + if ((r=reg_vtbl->vtbl->dump(0))) + ABORT(r); + + _status=0; + abort: + return(_status); +} + +// convenience methods, call RFREE on the returned data +int +NR_reg_alloc_data(NR_registry name, Data *data) +{ + int r, _status; + size_t length; + UCHAR *tmp = 0; + size_t sanity_check; + + if ((r=NR_reg_get_length(name, &length))) + ABORT(r); + + if (!(tmp = (void*)RMALLOC(length))) + ABORT(R_NO_MEMORY); + + if ((r=NR_reg_get_bytes(name, tmp, length, &sanity_check))) + ABORT(r); + + assert(length == sanity_check); + + data->len = length; + data->data = tmp; + + _status=0; + abort: + if (_status) { + if (tmp) RFREE(tmp); + } + return(_status); +} + +int +NR_reg_alloc_string(NR_registry name, char **data) +{ + int r, _status; + size_t length; + char *tmp = 0; + + if ((r=NR_reg_get_length(name, &length))) + ABORT(r); + + if (!(tmp = (void*)RMALLOC(length+1))) + ABORT(R_NO_MEMORY); + + if ((r=NR_reg_get_string(name, tmp, length+1))) + ABORT(r); + + assert(length == strlen(tmp)); + + *data = tmp; + + _status=0; + abort: + if (_status) { + if (tmp) RFREE(tmp); + } + return(_status); +} + + +char * +nr_reg_type_name(int type) +{ + if ((type < NR_REG_TYPE_CHAR) || (type > NR_REG_TYPE_REGISTRY)) + return(NULL); + + return(typenames[type]); +} + +int +nr_reg_compute_type(char *typename, int *type) +{ + int _status; + int i; + +#ifdef SANITY_CHECKS + assert(!strcasecmp(typenames[NR_REG_TYPE_CHAR], "char")); + assert(!strcasecmp(typenames[NR_REG_TYPE_UCHAR], "UCHAR")); + assert(!strcasecmp(typenames[NR_REG_TYPE_INT2], "INT2")); + assert(!strcasecmp(typenames[NR_REG_TYPE_UINT2], "UINT2")); + assert(!strcasecmp(typenames[NR_REG_TYPE_INT4], "INT4")); + assert(!strcasecmp(typenames[NR_REG_TYPE_UINT4], "UINT4")); + assert(!strcasecmp(typenames[NR_REG_TYPE_INT8], "INT8")); + assert(!strcasecmp(typenames[NR_REG_TYPE_UINT8], "UINT8")); + assert(!strcasecmp(typenames[NR_REG_TYPE_DOUBLE], "double")); + assert(!strcasecmp(typenames[NR_REG_TYPE_BYTES], "Data")); + assert(!strcasecmp(typenames[NR_REG_TYPE_STRING], "string")); + assert(!strcasecmp(typenames[NR_REG_TYPE_REGISTRY], "registry")); + assert(sizeof(typenames)/sizeof(*typenames) == (NR_REG_TYPE_REGISTRY+1)); +#endif + + for (i = 0; i < sizeof(typenames)/sizeof(*typenames); ++i) { + if (!strcasecmp(typenames[i], typename)) { + *type = i; + return 0; + } + } + ABORT(R_BAD_ARGS); + + _status=0; + abort: + return(_status); +} + +/* More convenience functions: the same as their parents but they + take a prefix and a suffix */ +#define NRGET2(func, type, get) \ +int \ +func(NR_registry parent, char *child, type *out) \ +{ \ + int r, _status; \ + NR_registry registry; \ + \ + if ((r = NR_reg_make_registry(parent, child, registry))) \ + ABORT(r); \ + \ + if ((r = get(registry, out))) { \ + ABORT(r); \ + } \ + \ + _status = 0; \ +abort: \ + return (_status); \ +} + +NRGET2(NR_reg_get2_char, char, NR_reg_get_char) +NRGET2(NR_reg_get2_uchar, UCHAR, NR_reg_get_uchar) +NRGET2(NR_reg_get2_int2, INT2, NR_reg_get_int2) +NRGET2(NR_reg_get2_uint2, UINT2, NR_reg_get_uint2) +NRGET2(NR_reg_get2_int4, INT4, NR_reg_get_int4) +NRGET2(NR_reg_get2_uint4, UINT4, NR_reg_get_uint4) +NRGET2(NR_reg_get2_int8, INT8, NR_reg_get_int8) +NRGET2(NR_reg_get2_uint8, UINT8, NR_reg_get_uint8) +NRGET2(NR_reg_get2_double, double, NR_reg_get_double) +NRGET2(NR_reg_alloc2_string, char*, NR_reg_alloc_string) +NRGET2(NR_reg_alloc2_data, Data, NR_reg_alloc_data) + +int +NR_reg_get2_bytes(NR_registry parent, char *child, UCHAR *out, size_t size, size_t *length) +{ + int r, _status; + NR_registry registry; + + if ((r=NR_reg_make_registry(parent, child, registry))) + ABORT(r); + + if ((r=NR_reg_get_bytes(registry, out, size, length))) + ABORT(r); + + _status = 0; +abort: + return (_status); +} + +int +NR_reg_get2_string(NR_registry parent, char *child, char *out, size_t size) +{ + int r, _status; + NR_registry registry; + + if ((r=NR_reg_make_registry(parent, child, registry))) + ABORT(r); + + if ((r=NR_reg_get_string(registry, out, size))) + ABORT(r); + + _status = 0; +abort: + return (_status); +} + +/* More convenience functions: the same as their parents but they + take a prefix and a suffix */ +#define NRSET2(func, type, set) \ +int \ +func(NR_registry parent, char *child, type in) \ +{ \ + int r, _status; \ + NR_registry registry; \ + \ + if ((r = NR_reg_make_registry(parent, child, registry))) \ + ABORT(r); \ + \ + if ((r = set(registry, in))) { \ + ABORT(r); \ + } \ + \ + _status = 0; \ +abort: \ + return (_status); \ +} + +NRSET2(NR_reg_set2_char, char, NR_reg_set_char) +NRSET2(NR_reg_set2_uchar, UCHAR, NR_reg_set_uchar) +NRSET2(NR_reg_set2_int2, INT2, NR_reg_set_int2) +NRSET2(NR_reg_set2_uint2, UINT2, NR_reg_set_uint2) +NRSET2(NR_reg_set2_int4, INT4, NR_reg_set_int4) +NRSET2(NR_reg_set2_uint4, UINT4, NR_reg_set_uint4) +NRSET2(NR_reg_set2_int8, INT8, NR_reg_set_int8) +NRSET2(NR_reg_set2_uint8, UINT8, NR_reg_set_uint8) +NRSET2(NR_reg_set2_double, double, NR_reg_set_double) +NRSET2(NR_reg_set2_string, char*, NR_reg_set_string) + +int +NR_reg_set2_bytes(NR_registry prefix, char *name, UCHAR *data, size_t length) +{ + int r, _status; + NR_registry registry; + + if ((r = NR_reg_make_registry(prefix, name, registry))) + ABORT(r); + + if ((r = NR_reg_set_bytes(registry, data, length))) + ABORT(r); + + _status = 0; +abort: + return (_status); +} + + +int +NR_reg_make_child_registry(NR_registry parent, NR_registry descendant, unsigned int generation, NR_registry child) +{ + int _status; + size_t length; + + length = strlen(parent); + + if (strncasecmp(parent, descendant, length)) + ABORT(R_BAD_ARGS); + + while (descendant[length] != '\0') { + if (descendant[length] == '.') { + if (generation == 0) + break; + + --generation; + } + + ++length; + if (length >= sizeof(NR_registry)) + ABORT(R_BAD_ARGS); + } + + strncpy(child, descendant, length); + child[length] = '\0'; + + _status=0; + abort: + return(_status); +} + +int +NR_reg_get2_child_count(NR_registry base, NR_registry name, unsigned int *count) + { + int r, _status; + NR_registry registry; + + if ((r=nr_c2ru_make_registry(base, name, registry))) + ABORT(r); + + if (r=NR_reg_get_child_count(registry,count)) + ABORT(r); + + _status=0; + abort: + return(_status); + } + +int +NR_reg_get2_child_registry(NR_registry base, NR_registry name, unsigned int i, NR_registry child) + { + int r, _status; + NR_registry registry; + + if ((r=nr_c2ru_make_registry(base, name, registry))) + ABORT(r); + + if (r=NR_reg_get_child_registry(registry, i, child)) + ABORT(r); + + _status=0; + abort: + return(_status); + } + + +/* requires parent already in legal form */ +int +NR_reg_make_registry(NR_registry parent, char *child, NR_registry out) +{ + int r, _status; + int plen; + int clen; + char *c; + int i; + + if ((r=nr_reg_is_valid(parent))) + ABORT(r); + + if (*child == '.') + ABORT(R_BAD_ARGS); + + clen = strlen(child); + if (!clen) + ABORT(R_BAD_ARGS); + plen = strlen(parent); + if ((plen + clen + 2) > sizeof(NR_registry)) + ABORT(R_BAD_ARGS); + + if (out != parent) + strcpy(out, parent); + + c = &(out[plen]); + + if (parent[0] != '\0') { + *c = '.'; + ++c; + } + + for (i = 0; i < clen; ++i, ++c) { + *c = child[i]; + if (isspace(*c) || *c == '.' || *c == '/' || ! isprint(*c)) + *c = '_'; + } + + *c = '\0'; + + _status = 0; +abort: + return _status; +} + diff --git a/media/mtransport/third_party/nrappkit/src/registry/registry.h b/media/mtransport/third_party/nrappkit/src/registry/registry.h new file mode 100644 index 000000000..b48893ba7 --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/registry.h @@ -0,0 +1,154 @@ +/* + * + * registry.h + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registry.h,v $ + * $Revision: 1.3 $ + * $Date: 2007/07/17 17:58:16 $ + * + * Datastore for tracking configuration and related info. + * + * + * Copyright (C) 2005, Network Resonance, Inc. + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#ifndef __REGISTRY_H__ +#define __REGISTRY_H__ + +#include <stdio.h> +#include <sys/types.h> +#include <r_types.h> +#include <r_data.h> + +#define NR_REG_MAX_NR_REGISTRY_LEN 128 +#define NR_REG_MAX_TYPE_LEN 32 + +typedef char NR_registry[NR_REG_MAX_NR_REGISTRY_LEN]; +typedef char NR_registry_type[NR_REG_MAX_TYPE_LEN]; + +extern NR_registry NR_TOP_LEVEL_REGISTRY; + +extern void *NR_REG_MODE_LOCAL; +extern void *NR_REG_MODE_REMOTE; + +int NR_reg_init(void *mode); + +int NR_reg_initted(void); + +int NR_reg_get_char(NR_registry name, char *out); +int NR_reg_get_uchar(NR_registry name, UCHAR *out); +int NR_reg_get_int2(NR_registry name, INT2 *out); +int NR_reg_get_uint2(NR_registry name, UINT2 *out); +int NR_reg_get_int4(NR_registry name, INT4 *out); +int NR_reg_get_uint4(NR_registry name, UINT4 *out); +int NR_reg_get_int8(NR_registry name, INT8 *out); +int NR_reg_get_uint8(NR_registry name, UINT8 *out); +int NR_reg_get_double(NR_registry name, double *out); +int NR_reg_get_registry(NR_registry name, NR_registry out); + +int NR_reg_get_bytes(NR_registry name, UCHAR *out, size_t size, size_t *length); +int NR_reg_get_string(NR_registry name, char *out, size_t size); +int NR_reg_get_length(NR_registry name, size_t *length); +int NR_reg_get_type(NR_registry name, NR_registry_type type); + + +int NR_reg_get2_char(NR_registry prefix, char *name, char *); +int NR_reg_get2_uchar(NR_registry prefix, char *name, UCHAR *); +int NR_reg_get2_int2(NR_registry prefix, char *name, INT2 *); +int NR_reg_get2_uint2(NR_registry prefix, char *name, UINT2 *); +int NR_reg_get2_int4(NR_registry prefix, char *name, INT4 *); +int NR_reg_get2_uint4(NR_registry prefix, char *name, UINT4 *); +int NR_reg_get2_int8(NR_registry prefix, char *name, INT8 *); +int NR_reg_get2_uint8(NR_registry prefix, char *name, UINT8 *); +int NR_reg_get2_double(NR_registry prefix, char *name, double *); +int NR_reg_get2_bytes(NR_registry prefix, char *name, UCHAR *out, size_t size, size_t *length); +int NR_reg_get2_string(NR_registry prefix, char *name, char *out, size_t size); + +int NR_reg_alloc2_string(NR_registry prefix, char *name, char **); +int NR_reg_alloc2_data(NR_registry prefix, char *name, Data *); + +int NR_reg_set_char(NR_registry name, char data); +int NR_reg_set_uchar(NR_registry name, UCHAR data); +int NR_reg_set_int2(NR_registry name, INT2 data); +int NR_reg_set_uint2(NR_registry name, UINT2 data); +int NR_reg_set_int4(NR_registry name, INT4 data); +int NR_reg_set_uint4(NR_registry name, UINT4 data); +int NR_reg_set_int8(NR_registry name, INT8 data); +int NR_reg_set_uint8(NR_registry name, UINT8 data); +int NR_reg_set_double(NR_registry name, double data); + +int NR_reg_set_registry(NR_registry name); + +int NR_reg_set_bytes(NR_registry name, UCHAR *data, size_t length); +int NR_reg_set_string(NR_registry name, char *data); + +int NR_reg_set2_char(NR_registry prefix, char *name, char data); +int NR_reg_set2_uchar(NR_registry prefix, char *name, UCHAR data); +int NR_reg_set2_int2(NR_registry prefix, char *name, INT2 data); +int NR_reg_set2_uint2(NR_registry prefix, char *name, UINT2 data); +int NR_reg_set2_int4(NR_registry prefix, char *name, INT4 data); +int NR_reg_set2_uint4(NR_registry prefix, char *name, UINT4 data); +int NR_reg_set2_int8(NR_registry prefix, char *name, INT8 data); +int NR_reg_set2_uint8(NR_registry prefix, char *name, UINT8 data); +int NR_reg_set2_double(NR_registry prefix, char *name, double data); + +int NR_reg_set2_bytes(NR_registry prefix, char *name, UCHAR *data, size_t length); +int NR_reg_set2_string(NR_registry prefix, char *name, char *data); + +int NR_reg_del(NR_registry name); + +int NR_reg_fin(NR_registry name); + +int NR_reg_get_child_count(NR_registry parent, unsigned int *count); +int NR_reg_get_child_registry(NR_registry parent, unsigned int i, NR_registry child); +int NR_reg_get2_child_count(NR_registry base, NR_registry name, unsigned int *count); +int NR_reg_get2_child_registry(NR_registry base, NR_registry name, unsigned int i, NR_registry child); +int NR_reg_get_children(NR_registry parent, NR_registry children[], size_t size, size_t *length); + +int NR_reg_dump(void); + +/* convenience methods, call RFREE on the returned data */ +int NR_reg_alloc_data(NR_registry name, Data *data); +int NR_reg_alloc_string(NR_registry name, char **data); + +#define NR_REG_CB_ACTION_ADD (1<<0) +#define NR_REG_CB_ACTION_CHANGE (1<<1) +#define NR_REG_CB_ACTION_DELETE (1<<2) +#define NR_REG_CB_ACTION_FINAL (1<<6) +int NR_reg_register_callback(NR_registry name, char action, void (*cb)(void *cb_arg, char action, NR_registry name), void *cb_arg); +int NR_reg_unregister_callback(NR_registry name, char action, void (*cb)(void *cb_arg, char action, NR_registry name)); + +int NR_reg_make_registry(NR_registry parent, char *child, NR_registry out); +int NR_reg_make_child_registry(NR_registry parent, NR_registry descendant, unsigned int generation, NR_registry child); + +#endif diff --git a/media/mtransport/third_party/nrappkit/src/registry/registry_int.h b/media/mtransport/third_party/nrappkit/src/registry/registry_int.h new file mode 100644 index 000000000..d6d412c54 --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/registry_int.h @@ -0,0 +1,97 @@ +#if 0 +#define NR_LOG_REGISTRY BLAHBLAH() +#define LOG_REGISTRY BLAHBLAH() +static int BLAHBLAH() { +int blahblah; +r_log_register("registry",&blahblah); +return blahblah; +} +#endif + +/* + * + * registry_int.h + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registry_int.h,v $ + * $Revision: 1.3 $ + * $Date: 2007/06/26 22:37:51 $ + * + * Callback-related functions + * + * + * Copyright (C) 2005, Network Resonance, Inc. + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#ifndef __REGISTRY_INT_H__ +#define __REGISTRY_INT_H__ + +#include <sys/types.h> +#include <r_types.h> +#ifndef NO_REG_RPC +#include <rpc/rpc.h> +#endif + +extern int NR_LOG_REGISTRY; + +int nr_reg_is_valid(NR_registry name); + +#define NR_REG_TYPE_CHAR 0 +#define NR_REG_TYPE_UCHAR 1 +#define NR_REG_TYPE_INT2 2 +#define NR_REG_TYPE_UINT2 3 +#define NR_REG_TYPE_INT4 4 +#define NR_REG_TYPE_UINT4 5 +#define NR_REG_TYPE_INT8 6 +#define NR_REG_TYPE_UINT8 7 +#define NR_REG_TYPE_DOUBLE 8 +#define NR_REG_TYPE_BYTES 9 +#define NR_REG_TYPE_STRING 10 +#define NR_REG_TYPE_REGISTRY 11 +char *nr_reg_type_name(int type); +int nr_reg_compute_type(char *type_name, int *type); + +char *nr_reg_action_name(int action); + +int nr_reg_cb_init(void); +int nr_reg_client_cb_init(void); +int nr_reg_register_for_callbacks(int fd, int connect_to_port); +int nr_reg_raise_event(NR_registry name, int action); +#ifndef NO_REG_RPC +int nr_reg_get_client(CLIENT **client); +#endif + +#define CALLBACK_SERVER_ADDR "127.0.0.1" +#define CALLBACK_SERVER_PORT 8082 +#define CALLBACK_SERVER_BACKLOG 32 + +#endif diff --git a/media/mtransport/third_party/nrappkit/src/registry/registry_local.c b/media/mtransport/third_party/nrappkit/src/registry/registry_local.c new file mode 100644 index 000000000..c52e22351 --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/registry_local.c @@ -0,0 +1,1168 @@ +/* + * + * registry.c + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registry_local.c,v $ + * $Revision: 1.4 $ + * $Date: 2007/11/21 00:09:13 $ + * + * Datastore for tracking configuration and related info. + * + * + * Copyright (C) 2005, Network Resonance, Inc. + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <assert.h> +#include <string.h> +#ifndef WIN32 +#include <strings.h> +#include <sys/param.h> +#include <netinet/in.h> +#endif +#ifdef OPENSSL +#include <openssl/ssl.h> +#endif +#include <ctype.h> +#include "registry.h" +#include "registry_int.h" +#include "registry_vtbl.h" +#include "r_assoc.h" +#include "nr_common.h" +#include "r_log.h" +#include "r_errors.h" +#include "r_macros.h" + +/* if C were an object-oriented language, nr_scalar_registry_node and + * nr_array_registry_node would subclass nr_registry_node, but it isn't + * object-oriented language, so this is used in cases where the pointer + * could be of either type */ +typedef struct nr_registry_node_ { + unsigned char type; +} nr_registry_node; + +typedef struct nr_scalar_registry_node_ { + unsigned char type; + union { + char _char; + UCHAR _uchar; + INT2 _nr_int2; + UINT2 _nr_uint2; + INT4 _nr_int4; + UINT4 _nr_uint4; + INT8 _nr_int8; + UINT8 _nr_uint8; + double _double; + } scalar; +} nr_scalar_registry_node; + +/* string, bytes */ +typedef struct nr_array_registry_node_ { + unsigned char type; + struct { + unsigned int length; + unsigned char data[1]; + } array; +} nr_array_registry_node; + +static int nr_reg_local_init(nr_registry_module *me); +static int nr_reg_local_get_char(NR_registry name, char *data); +static int nr_reg_local_get_uchar(NR_registry name, UCHAR *data); +static int nr_reg_local_get_int2(NR_registry name, INT2 *data); +static int nr_reg_local_get_uint2(NR_registry name, UINT2 *data); +static int nr_reg_local_get_int4(NR_registry name, INT4 *data); +static int nr_reg_local_get_uint4(NR_registry name, UINT4 *data); +static int nr_reg_local_get_int8(NR_registry name, INT8 *data); +static int nr_reg_local_get_uint8(NR_registry name, UINT8 *data); +static int nr_reg_local_get_double(NR_registry name, double *data); +static int nr_reg_local_get_registry(NR_registry name, NR_registry data); +static int nr_reg_local_get_bytes(NR_registry name, UCHAR *data, size_t size, size_t *length); +static int nr_reg_local_get_string(NR_registry name, char *data, size_t size); +static int nr_reg_local_get_length(NR_registry name, size_t *len); +static int nr_reg_local_get_type(NR_registry name, NR_registry_type type); +static int nr_reg_local_set_char(NR_registry name, char data); +static int nr_reg_local_set_uchar(NR_registry name, UCHAR data); +static int nr_reg_local_set_int2(NR_registry name, INT2 data); +static int nr_reg_local_set_uint2(NR_registry name, UINT2 data); +static int nr_reg_local_set_int4(NR_registry name, INT4 data); +static int nr_reg_local_set_uint4(NR_registry name, UINT4 data); +static int nr_reg_local_set_int8(NR_registry name, INT8 data); +static int nr_reg_local_set_uint8(NR_registry name, UINT8 data); +static int nr_reg_local_set_double(NR_registry name, double data); +static int nr_reg_local_set_registry(NR_registry name); +static int nr_reg_local_set_bytes(NR_registry name, UCHAR *data, size_t length); +static int nr_reg_local_set_string(NR_registry name, char *data); +static int nr_reg_local_del(NR_registry name); +static int nr_reg_local_get_child_count(NR_registry parent, size_t *count); +static int nr_reg_local_get_children(NR_registry parent, NR_registry *data, size_t size, size_t *length); +static int nr_reg_local_fin(NR_registry name); +static int nr_reg_local_dump(int sorted); +static int nr_reg_insert_node(char *name, void *node); +static int nr_reg_change_node(char *name, void *node, void *old); +static int nr_reg_get(char *name, int type, void *out); +static int nr_reg_get_data(NR_registry name, nr_scalar_registry_node *node, void *out); +static int nr_reg_get_array(char *name, unsigned char type, UCHAR *out, size_t size, size_t *length); +static int nr_reg_set(char *name, int type, void *data); +static int nr_reg_set_array(char *name, unsigned char type, UCHAR *data, size_t length); +static int nr_reg_set_parent_registries(char *name); + +/* make these static OLD_REGISTRY */ +#if 0 +static int nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node); +static char *nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit); +#else +int nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node); +char *nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit); +#endif +static int nr_reg_rfree(void *ptr); +#if 0 /* Unused currently */ +static int nr_reg_noop(void *ptr); +#endif +static int nr_reg_compute_length(char *name, nr_registry_node *node, size_t *length); +char *nr_reg_action_name(int action); + +/* the registry, containing mappings like "foo.bar.baz" to registry + * nodes, which are either of type nr_scalar_registry_node or + * nr_array_registry_node */ +static r_assoc *nr_registry = 0; + +#if 0 /* Unused currently */ +static nr_array_registry_node nr_top_level_node; +#endif + +typedef struct nr_reg_find_children_arg_ { + size_t size; + NR_registry *children; + size_t length; +} nr_reg_find_children_arg; + +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); +static int nr_reg_local_iter_delete(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node); +static int nr_reg_local_find_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node); +static int nr_reg_local_count_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node); +static int nr_reg_local_dump_print(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node); + + + +int +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) +{ + int r, _status; + r_assoc_iterator iter; + char *name; + int namel; + nr_registry_node *node; + int prefixl; + + if (prefix == 0) + ABORT(R_INTERNAL); + + if ((r=r_assoc_init_iter(nr_registry, &iter))) + ABORT(r); + + prefixl = strlen(prefix); + + for (;;) { + if ((r=r_assoc_iter(&iter, (void*)&name, &namel, (void*)&node))) { + if (r == R_EOD) + break; + else + ABORT(r); + } + + /* subtract to remove the '\0' character from the string length */ + --namel; + + /* sanity check that the name is null-terminated */ + assert(namel >= 0); + assert(name[namel] == '\0'); + + if (namel < 0 || name[namel] != '\0' || node == 0) + break; + + /* 3 cases where action will be called: + * 1) prefix == "" + * 2) prefix == name + * 3) name == prefix + '.' + */ + if (prefixl == 0 + || ((namel == prefixl || (namel > prefixl && name[prefixl] == '.')) + && !strncmp(prefix, name, prefixl))) { + if ((r=action(ptr, &iter, prefix, name, node))) + ABORT(r); + } + } + + _status=0; + abort: + + return(_status); +} + +int +nr_reg_local_iter_delete(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node) +{ + int r, _status; + + if ((r=r_assoc_iter_delete(iter))) + ABORT(r); + + _status=0; + abort: + return(_status); +} + +int +nr_reg_local_find_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node) +{ + int _status; + int prefixl = strlen(prefix); + char *dot; + nr_reg_find_children_arg *arg = (void*)ptr; + + assert(sizeof(*(arg->children)) == sizeof(NR_registry)); + + /* only grovel through immediate children */ + if (prefixl == 0 || name[prefixl] == '.') { + if (name[prefixl] != '\0') { + dot = strchr(&name[prefixl+1], '.'); + if (dot == 0) { + strncpy(arg->children[arg->length], name, sizeof(NR_registry)-1); + ++arg->length; + + /* only grab as many as there are room for */ + if (arg->length >= arg->size) + ABORT(R_INTERRUPTED); + } + } + } + + _status = 0; + abort: + return _status; +} + +int +nr_reg_local_count_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node) +{ + int prefixl = strlen(prefix); + char *dot; + + /* only count children */ + if (name[prefixl] == '.') { + dot = strchr(&name[prefixl+1], '.'); + if (dot == 0) + ++(*(unsigned int *)ptr); + } + else if (name[0] != '\0') { + if (prefixl == 0) + ++(*(unsigned int *)ptr); + } + + return 0; +} + +int +nr_reg_local_dump_print(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node) +{ + int _status; + int freeit = 0; + char *data; + + /* only print leaf nodes */ + if (node->type != NR_REG_TYPE_REGISTRY) { + data = nr_reg_alloc_node_data(name, node, &freeit); + if (ptr) + fprintf((FILE*)ptr, "%s: %s\n", name, data); + else + r_log(NR_LOG_REGISTRY, LOG_INFO, "%s: %s", name, data); + if (freeit) + RFREE(data); + } + + _status=0; + //abort: + return(_status); +} + + +#if 0 /* Unused currently */ +int +nr_reg_noop(void *ptr) +{ + return 0; +} +#endif + +int +nr_reg_rfree(void *ptr) +{ + RFREE(ptr); + return 0; +} + +int +nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node) +{ + int r, _status; + + *node = 0; + *free_node = 0; + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + if ((r=r_assoc_fetch(nr_registry, name, strlen(name)+1, (void*)node))) + ABORT(r); + + if ((*node)->type != type) + ABORT(R_FAILED); + + _status=0; + abort: + if (_status) { + if (*node) + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "Couldn't fetch node '%s' ('%s'), found '%s' instead", + name, nr_reg_type_name(type), nr_reg_type_name((*node)->type)); + else + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "Couldn't fetch node '%s' ('%s')", + name, nr_reg_type_name(type)); + } + else { + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "Fetched node '%s' ('%s')", + name, nr_reg_type_name(type)); + } + return(_status); +} + +int +nr_reg_insert_node(char *name, void *node) +{ + int r, _status; + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + /* since the registry application is not multi-threaded, a node being + * inserted should always be a new node because the registry app must + * have looked for a node with this key but not found it, so it is + * being created/inserted now using R_ASSOC_NEW */ + if ((r=r_assoc_insert(nr_registry, name, strlen(name)+1, node, 0, nr_reg_rfree, R_ASSOC_NEW))) + ABORT(r); + + if ((r=nr_reg_set_parent_registries(name))) + ABORT(r); + + if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_ADD))) + ABORT(r); + + _status=0; + abort: + if (r_logging(NR_LOG_REGISTRY, LOG_INFO)) { + int freeit; + char *data = nr_reg_alloc_node_data(name, (void*)node, &freeit); + r_log(NR_LOG_REGISTRY, LOG_INFO, + "insert '%s' (%s) %s: %s", name, + nr_reg_type_name(((nr_registry_node*)node)->type), + (_status ? "FAILED" : "succeeded"), data); + if (freeit) + RFREE(data); + } + return(_status); +} + +int +nr_reg_change_node(char *name, void *node, void *old) +{ + int r, _status; + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + if (old != node) { + if ((r=r_assoc_insert(nr_registry, name, strlen(name)+1, node, 0, nr_reg_rfree, R_ASSOC_REPLACE))) + ABORT(r); + } + + if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_CHANGE))) + ABORT(r); + + _status=0; + abort: + if (r_logging(NR_LOG_REGISTRY, LOG_INFO)) { + int freeit; + char *data = nr_reg_alloc_node_data(name, (void*)node, &freeit); + r_log(NR_LOG_REGISTRY, LOG_INFO, + "change '%s' (%s) %s: %s", name, + nr_reg_type_name(((nr_registry_node*)node)->type), + (_status ? "FAILED" : "succeeded"), data); + if (freeit) + RFREE(data); + } + return(_status); +} + +char * +nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit) +{ + char *s = 0; + int len; + int alloc = 0; + unsigned int i; + + *freeit = 0; + + switch (node->type) { + default: + alloc = 100; /* plenty of room for any of the scalar types */ + break; + case NR_REG_TYPE_REGISTRY: + alloc = strlen(name) + 1; + break; + case NR_REG_TYPE_BYTES: + alloc = (2 * ((nr_array_registry_node*)node)->array.length) + 1; + break; + case NR_REG_TYPE_STRING: + alloc = 0; + break; + } + + if (alloc > 0) { + s = (void*)RMALLOC(alloc); + if (!s) + return ""; + + *freeit = 1; + } + + len = alloc; + + switch (node->type) { + case NR_REG_TYPE_CHAR: + i = ((nr_scalar_registry_node*)node)->scalar._char; + if (isprint(i) && ! isspace(i)) + snprintf(s, len, "%c", (char)i); + else + snprintf(s, len, "\\%03o", (char)i); + break; + case NR_REG_TYPE_UCHAR: + snprintf(s, len, "0x%02x", ((nr_scalar_registry_node*)node)->scalar._uchar); + break; + case NR_REG_TYPE_INT2: + snprintf(s, len, "%d", ((nr_scalar_registry_node*)node)->scalar._nr_int2); + break; + case NR_REG_TYPE_UINT2: + snprintf(s, len, "%u", ((nr_scalar_registry_node*)node)->scalar._nr_uint2); + break; + case NR_REG_TYPE_INT4: + snprintf(s, len, "%d", ((nr_scalar_registry_node*)node)->scalar._nr_int4); + break; + case NR_REG_TYPE_UINT4: + snprintf(s, len, "%u", ((nr_scalar_registry_node*)node)->scalar._nr_uint4); + break; + case NR_REG_TYPE_INT8: + snprintf(s, len, "%lld", ((nr_scalar_registry_node*)node)->scalar._nr_int8); + break; + case NR_REG_TYPE_UINT8: + snprintf(s, len, "%llu", ((nr_scalar_registry_node*)node)->scalar._nr_uint8); + break; + case NR_REG_TYPE_DOUBLE: + snprintf(s, len, "%#f", ((nr_scalar_registry_node*)node)->scalar._double); + break; + case NR_REG_TYPE_REGISTRY: + snprintf(s, len, "%s", name); + break; + case NR_REG_TYPE_BYTES: + for (i = 0; i < ((nr_array_registry_node*)node)->array.length; ++i) { + sprintf(&s[2*i], "%02x", ((nr_array_registry_node*)node)->array.data[i]); + } + break; + case NR_REG_TYPE_STRING: + s = (char*)((nr_array_registry_node*)node)->array.data; + break; + default: + assert(0); /* bad value */ + *freeit = 0; + s = ""; + break; + } + + return s; +} + +int +nr_reg_get(char *name, int type, void *out) +{ + int r, _status; + nr_scalar_registry_node *node = 0; + int free_node = 0; + + if ((r=nr_reg_fetch_node(name, type, (void*)&node, &free_node))) + ABORT(r); + + if ((r=nr_reg_get_data(name, node, out))) + ABORT(r); + + _status=0; + abort: + if (free_node) RFREE(node); + return(_status); +} + +int +nr_reg_get_data(NR_registry name, nr_scalar_registry_node *node, void *out) +{ + int _status; + + switch (node->type) { + case NR_REG_TYPE_CHAR: + *(char*)out = node->scalar._char; + break; + case NR_REG_TYPE_UCHAR: + *(UCHAR*)out = node->scalar._uchar; + break; + case NR_REG_TYPE_INT2: + *(INT2*)out = node->scalar._nr_int2; + break; + case NR_REG_TYPE_UINT2: + *(UINT2*)out = node->scalar._nr_uint2; + break; + case NR_REG_TYPE_INT4: + *(INT4*)out = node->scalar._nr_int4; + break; + case NR_REG_TYPE_UINT4: + *(UINT4*)out = node->scalar._nr_uint4; + break; + case NR_REG_TYPE_INT8: + *(INT8*)out = node->scalar._nr_int8; + break; + case NR_REG_TYPE_UINT8: + *(UINT8*)out = node->scalar._nr_uint8; + break; + case NR_REG_TYPE_DOUBLE: + *(double*)out = node->scalar._double; + break; + default: + ABORT(R_INTERNAL); + break; + } + + _status=0; + abort: + return(_status); +} + +int +nr_reg_get_array(char *name, unsigned char type, unsigned char *out, size_t size, size_t *length) +{ + int r, _status; + nr_array_registry_node *node = 0; + int free_node = 0; + + if ((r=nr_reg_fetch_node(name, type, (void*)&node, &free_node))) + ABORT(r); + + if (size < node->array.length) + ABORT(R_BAD_ARGS); + + if (out != 0) + memcpy(out, node->array.data, node->array.length); + if (length != 0) + *length = node->array.length; + + _status=0; + abort: + if (node && free_node) RFREE(node); + return(_status); +} + +int +nr_reg_set(char *name, int type, void *data) +{ + int r, _status; + nr_scalar_registry_node *node = 0; + int create_node = 0; + int changed = 0; + int free_node = 0; + + if ((r=nr_reg_fetch_node(name, type, (void*)&node, &free_node))) + if (r == R_NOT_FOUND) { + create_node = 1; + free_node = 1; + } + else + ABORT(r); + + if (create_node) { + if (!(node=(void*)RCALLOC(sizeof(nr_scalar_registry_node)))) + ABORT(R_NO_MEMORY); + + node->type = type; + } + else { + if (node->type != type) + ABORT(R_BAD_ARGS); + } + + switch (type) { +#define CASE(TYPE, _name, type) \ + case TYPE: \ + if (node->scalar._name != *(type*)data) { \ + node->scalar._name = *(type*)data; \ + if (! create_node) \ + changed = 1; \ + } \ + break; + CASE(NR_REG_TYPE_CHAR, _char, char) + CASE(NR_REG_TYPE_UCHAR, _uchar, UCHAR) + CASE(NR_REG_TYPE_INT2, _nr_int2, INT2) + CASE(NR_REG_TYPE_UINT2, _nr_uint2, UINT2) + CASE(NR_REG_TYPE_INT4, _nr_int4, INT4) + CASE(NR_REG_TYPE_UINT4, _nr_uint4, UINT4) + CASE(NR_REG_TYPE_INT8, _nr_int8, INT8) + CASE(NR_REG_TYPE_UINT8, _nr_uint8, UINT8) + CASE(NR_REG_TYPE_DOUBLE, _double, double) +#undef CASE + + case NR_REG_TYPE_REGISTRY: + /* do nothing */ + break; + + default: + ABORT(R_INTERNAL); + break; + } + + if (create_node) { + if ((r=nr_reg_insert_node(name, node))) + ABORT(r); + free_node = 0; + } + else { + if (changed) { + if ((r=nr_reg_change_node(name, node, node))) + ABORT(r); + free_node = 0; + } + } + + _status=0; + abort: + if (_status) { + if (node && free_node) RFREE(node); + } + return(_status); +} + +int +nr_reg_set_array(char *name, unsigned char type, UCHAR *data, size_t length) +{ + int r, _status; + nr_array_registry_node *old = 0; + nr_array_registry_node *node = 0; + int free_node = 0; + int added = 0; + int changed = 0; + + if ((r=nr_reg_fetch_node(name, type, (void*)&old, &free_node))) { + if (r != R_NOT_FOUND) + ABORT(r); + } + else { + assert(free_node == 0); + } + + if (old) { + if (old->type != type) + ABORT(R_BAD_ARGS); + + if (old->array.length != length + || memcmp(old->array.data, data, length)) { + changed = 1; + + if (old->array.length < length) { + if (!(node=(void*)RCALLOC(sizeof(nr_array_registry_node)+length))) + ABORT(R_NO_MEMORY); + } + else { + node = old; + } + } + } + else { + if (!(node=(void*)RCALLOC(sizeof(nr_array_registry_node)+length))) + ABORT(R_NO_MEMORY); + + added = 1; + } + + if (added || changed) { + node->type = type; + node->array.length = length; + memcpy(node->array.data, data, length); + } + + if (added) { + if ((r=nr_reg_insert_node(name, node))) + ABORT(r); + } + else if (changed) { + if ((r=nr_reg_change_node(name, node, old))) + ABORT(r); + } + + _status=0; + abort: + return(_status); +} + +int +nr_reg_set_parent_registries(char *name) +{ + int r, _status; + char *parent = 0; + char *dot; + + if ((parent = r_strdup(name)) == 0) + ABORT(R_NO_MEMORY); + + if ((dot = strrchr(parent, '.')) != 0) { + *dot = '\0'; + if ((r=NR_reg_set_registry(parent))) + ABORT(r); + } + + _status=0; + abort: + if (parent) RFREE(parent); + return(_status); +} + + + + + +/* NON-STATIC METHODS */ + +int +nr_reg_is_valid(NR_registry name) +{ + int _status; + unsigned int length; + unsigned int i; + + if (name == 0) + ABORT(R_BAD_ARGS); + + /* make sure the key is null-terminated */ + if (memchr(name, '\0', sizeof(NR_registry)) == 0) + ABORT(R_BAD_ARGS); + + length = strlen(name); + + /* cannot begin or end with a period */ + if (name[0] == '.') + ABORT(R_BAD_ARGS); + if (strlen(name) > 0 && name[length-1] == '.') + ABORT(R_BAD_ARGS); + + /* all characters cannot be space, and must be printable and not / */ + for (i = 0; i < length; ++i) { + if (isspace(name[i]) || ! (isprint(name[i]) || name[i] == '/')) + ABORT(R_BAD_ARGS); + } + + _status=0; + abort: + if (_status) { + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "invalid name '%s'", name); + } + return(_status); +} + + +int +nr_reg_compute_length(char *name, nr_registry_node *in, size_t *length) +{ + int _status; + nr_array_registry_node *node = (nr_array_registry_node*)in; + + switch (node->type) { + case NR_REG_TYPE_STRING: + *length = node->array.length - 1; + break; + case NR_REG_TYPE_BYTES: + *length = node->array.length; + break; + case NR_REG_TYPE_CHAR: + *length = sizeof(char); + break; + case NR_REG_TYPE_UCHAR: + *length = sizeof(UCHAR); + break; + case NR_REG_TYPE_INT2: + case NR_REG_TYPE_UINT2: + *length = 2; + break; + case NR_REG_TYPE_INT4: + case NR_REG_TYPE_UINT4: + *length = 4; + break; + case NR_REG_TYPE_INT8: + case NR_REG_TYPE_UINT8: + *length = 8; + break; + case NR_REG_TYPE_DOUBLE: + *length = sizeof(double); + break; + case NR_REG_TYPE_REGISTRY: + *length = strlen(name); + break; + default: + ABORT(R_INTERNAL); + break; + } + + _status=0; + abort: + return(_status); +} + + +/* VTBL METHODS */ + +int +nr_reg_local_init(nr_registry_module *me) +{ + int r, _status; + + if (nr_registry == 0) { + if ((r=r_assoc_create(&nr_registry, r_assoc_crc32_hash_compute, 12))) + ABORT(r); + + if ((r=nr_reg_cb_init())) + ABORT(r); + + /* make sure NR_TOP_LEVEL_REGISTRY always exists */ + if ((r=nr_reg_local_set_registry(NR_TOP_LEVEL_REGISTRY))) + ABORT(r); + } + + _status=0; + abort: + return(_status); +} + +#define NRREGGET(func, TYPE, type) \ +int \ +func(NR_registry name, type *out) \ +{ \ + return nr_reg_get(name, TYPE, out); \ +} + +NRREGGET(nr_reg_local_get_char, NR_REG_TYPE_CHAR, char) +NRREGGET(nr_reg_local_get_uchar, NR_REG_TYPE_UCHAR, UCHAR) +NRREGGET(nr_reg_local_get_int2, NR_REG_TYPE_INT2, INT2) +NRREGGET(nr_reg_local_get_uint2, NR_REG_TYPE_UINT2, UINT2) +NRREGGET(nr_reg_local_get_int4, NR_REG_TYPE_INT4, INT4) +NRREGGET(nr_reg_local_get_uint4, NR_REG_TYPE_UINT4, UINT4) +NRREGGET(nr_reg_local_get_int8, NR_REG_TYPE_INT8, INT8) +NRREGGET(nr_reg_local_get_uint8, NR_REG_TYPE_UINT8, UINT8) +NRREGGET(nr_reg_local_get_double, NR_REG_TYPE_DOUBLE, double) + +int +nr_reg_local_get_registry(NR_registry name, NR_registry out) +{ + int r, _status; + nr_scalar_registry_node *node = 0; + int free_node = 0; + + if ((r=nr_reg_fetch_node(name, NR_REG_TYPE_REGISTRY, (void*)&node, &free_node))) + ABORT(r); + + strncpy(out, name, sizeof(NR_registry)); + + _status=0; + abort: + if (free_node) RFREE(node); + return(_status); + +} + +int +nr_reg_local_get_bytes(NR_registry name, UCHAR *out, size_t size, size_t *length) +{ + return nr_reg_get_array(name, NR_REG_TYPE_BYTES, out, size, length); +} + +int +nr_reg_local_get_string(NR_registry name, char *out, size_t size) +{ + return nr_reg_get_array(name, NR_REG_TYPE_STRING, (UCHAR*)out, size, 0); +} + +int +nr_reg_local_get_length(NR_registry name, size_t *length) +{ + int r, _status; + nr_registry_node *node = 0; + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + if ((r=r_assoc_fetch(nr_registry, name, strlen(name)+1, (void*)&node))) + ABORT(r); + + if ((r=nr_reg_compute_length(name, node, length))) + ABORT(r); + + _status=0; + abort: + return(_status); +} + +int +nr_reg_local_get_type(NR_registry name, NR_registry_type type) +{ + int r, _status; + nr_registry_node *node = 0; + char *str; + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + if ((r=r_assoc_fetch(nr_registry, name, strlen(name)+1, (void*)&node))) + ABORT(r); + + str = nr_reg_type_name(node->type); + if (! str) + ABORT(R_BAD_ARGS); + + strncpy(type, str, sizeof(NR_registry_type)); + + _status=0; + abort: + return(_status); +} + + +#define NRREGSET(func, TYPE, type) \ +int \ +func(NR_registry name, type data) \ +{ \ + return nr_reg_set(name, TYPE, &data); \ +} + +NRREGSET(nr_reg_local_set_char, NR_REG_TYPE_CHAR, char) +NRREGSET(nr_reg_local_set_uchar, NR_REG_TYPE_UCHAR, UCHAR) +NRREGSET(nr_reg_local_set_int2, NR_REG_TYPE_INT2, INT2) +NRREGSET(nr_reg_local_set_uint2, NR_REG_TYPE_UINT2, UINT2) +NRREGSET(nr_reg_local_set_int4, NR_REG_TYPE_INT4, INT4) +NRREGSET(nr_reg_local_set_uint4, NR_REG_TYPE_UINT4, UINT4) +NRREGSET(nr_reg_local_set_int8, NR_REG_TYPE_INT8, INT8) +NRREGSET(nr_reg_local_set_uint8, NR_REG_TYPE_UINT8, UINT8) +NRREGSET(nr_reg_local_set_double, NR_REG_TYPE_DOUBLE, double) + +int +nr_reg_local_set_registry(NR_registry name) +{ + return nr_reg_set(name, NR_REG_TYPE_REGISTRY, 0); +} + +int +nr_reg_local_set_bytes(NR_registry name, unsigned char *data, size_t length) +{ + return nr_reg_set_array(name, NR_REG_TYPE_BYTES, data, length); +} + +int +nr_reg_local_set_string(NR_registry name, char *data) +{ + return nr_reg_set_array(name, NR_REG_TYPE_STRING, (UCHAR*)data, strlen(data)+1); +} + +int +nr_reg_local_del(NR_registry name) +{ + int r, _status; + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + /* delete from NR_registry */ + if ((r=nr_reg_local_iter(name, nr_reg_local_iter_delete, 0))) + ABORT(r); + + if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_DELETE))) + ABORT(r); + + /* if deleting from the root, re-insert the root */ + if (! strcasecmp(name, NR_TOP_LEVEL_REGISTRY)) { + if ((r=nr_reg_local_set_registry(NR_TOP_LEVEL_REGISTRY))) + ABORT(r); + } + + _status=0; + abort: + r_log(NR_LOG_REGISTRY, + (_status ? LOG_INFO : LOG_INFO), + "delete of '%s' %s", name, + (_status ? "FAILED" : "succeeded")); + return(_status); +} + +int +nr_reg_local_get_child_count(char *parent, size_t *count) +{ + int r, _status; + nr_registry_node *ignore1; + int ignore2; + + + if ((r=nr_reg_is_valid(parent))) + ABORT(r); + + /* test to see whether it is present */ + if ((r=nr_reg_fetch_node(parent, NR_REG_TYPE_REGISTRY, &ignore1, &ignore2))) + ABORT(r); + + /* sanity check that there isn't any memory to free */ + assert(ignore2 == 0); + + *count = 0; + + if ((r=nr_reg_local_iter(parent, nr_reg_local_count_children, count))) + ABORT(r); + + _status=0; + abort: + return(_status); +} + +int +nr_reg_local_get_children(NR_registry parent, NR_registry *data, size_t size, size_t *length) +{ + int r, _status; + nr_reg_find_children_arg arg; + + if ((r=nr_reg_is_valid(parent))) + ABORT(r); + + arg.children = data; + arg.size = size; + arg.length = 0; + + if ((r=nr_reg_local_iter(parent, nr_reg_local_find_children, (void*)&arg))) { + if (r == R_INTERRUPTED) + ABORT(R_BAD_ARGS); + else + ABORT(r); + } + + assert(sizeof(*arg.children) == sizeof(NR_registry)); + qsort(arg.children, arg.length, sizeof(*arg.children), (void*)strcasecmp); + + *length = arg.length; + + _status = 0; + abort: + return(_status); +} + +int +nr_reg_local_fin(NR_registry name) +{ + int r, _status; + + if ((r=nr_reg_raise_event(name, NR_REG_CB_ACTION_FINAL))) + ABORT(r); + + _status=0; + abort: + return(_status); +} + +int +nr_reg_local_dump(int sorted) +{ + int r, _status; + + if ((r=nr_reg_local_iter(NR_TOP_LEVEL_REGISTRY, nr_reg_local_dump_print, 0))) + ABORT(r); + + _status=0; + abort: + return(_status); +} + + + +static nr_registry_module_vtbl nr_reg_local_vtbl = { + nr_reg_local_init, + nr_reg_local_get_char, + nr_reg_local_get_uchar, + nr_reg_local_get_int2, + nr_reg_local_get_uint2, + nr_reg_local_get_int4, + nr_reg_local_get_uint4, + nr_reg_local_get_int8, + nr_reg_local_get_uint8, + nr_reg_local_get_double, + nr_reg_local_get_registry, + nr_reg_local_get_bytes, + nr_reg_local_get_string, + nr_reg_local_get_length, + nr_reg_local_get_type, + nr_reg_local_set_char, + nr_reg_local_set_uchar, + nr_reg_local_set_int2, + nr_reg_local_set_uint2, + nr_reg_local_set_int4, + nr_reg_local_set_uint4, + nr_reg_local_set_int8, + nr_reg_local_set_uint8, + nr_reg_local_set_double, + nr_reg_local_set_registry, + nr_reg_local_set_bytes, + nr_reg_local_set_string, + nr_reg_local_del, + nr_reg_local_get_child_count, + nr_reg_local_get_children, + nr_reg_local_fin, + nr_reg_local_dump +}; + +static nr_registry_module nr_reg_local_module = { 0, &nr_reg_local_vtbl }; + +void *NR_REG_MODE_LOCAL = &nr_reg_local_module; + + diff --git a/media/mtransport/third_party/nrappkit/src/registry/registry_vtbl.h b/media/mtransport/third_party/nrappkit/src/registry/registry_vtbl.h new file mode 100644 index 000000000..0f75a03b9 --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/registry_vtbl.h @@ -0,0 +1,96 @@ +/* + * + * registry_vtbl.h + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registry_vtbl.h,v $ + * $Revision: 1.2 $ + * $Date: 2006/08/16 19:39:14 $ + * + * + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#ifndef __REGISTRY_VTBL_H__ +#define __REGISTRY_VTBL_H__ + +typedef struct nr_registry_module_ nr_registry_module; + +typedef struct nr_registry_module_vtbl_ { + int (*init)(nr_registry_module*); + + int (*get_char)(NR_registry name, char *out); + int (*get_uchar)(NR_registry name, UCHAR *out); + int (*get_int2)(NR_registry name, INT2 *out); + int (*get_uint2)(NR_registry name, UINT2 *out); + int (*get_int4)(NR_registry name, INT4 *out); + int (*get_uint4)(NR_registry name, UINT4 *out); + int (*get_int8)(NR_registry name, INT8 *out); + int (*get_uint8)(NR_registry name, UINT8 *out); + int (*get_double)(NR_registry name, double *out); + int (*get_registry)(NR_registry name, NR_registry out); + + int (*get_bytes)(NR_registry name, UCHAR *out, size_t size, size_t *length); + int (*get_string)(NR_registry name, char *out, size_t size); + int (*get_length)(NR_registry name, size_t *length); + int (*get_type)(NR_registry name, NR_registry_type type); + + int (*set_char)(NR_registry name, char data); + int (*set_uchar)(NR_registry name, UCHAR data); + int (*set_int2)(NR_registry name, INT2 data); + int (*set_uint2)(NR_registry name, UINT2 data); + int (*set_int4)(NR_registry name, INT4 data); + int (*set_uint4)(NR_registry name, UINT4 data); + int (*set_int8)(NR_registry name, INT8 data); + int (*set_uint8)(NR_registry name, UINT8 data); + int (*set_double)(NR_registry name, double data); + int (*set_registry)(NR_registry name); + + int (*set_bytes)(NR_registry name, UCHAR *data, size_t length); + int (*set_string)(NR_registry name, char *data); + + int (*del)(NR_registry name); + + int (*get_child_count)(NR_registry parent, size_t *count); + int (*get_children)(NR_registry parent, NR_registry *data, size_t size, size_t *length); + + int (*fin)(NR_registry name); + + int (*dump)(int sorted); +} nr_registry_module_vtbl; + +struct nr_registry_module_ { + void *handle; + nr_registry_module_vtbl *vtbl; +}; + +#endif + diff --git a/media/mtransport/third_party/nrappkit/src/registry/registrycb.c b/media/mtransport/third_party/nrappkit/src/registry/registrycb.c new file mode 100644 index 000000000..d5aaf915d --- /dev/null +++ b/media/mtransport/third_party/nrappkit/src/registry/registrycb.c @@ -0,0 +1,440 @@ +/* + * + * registrycb.c + * + * $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registrycb.c,v $ + * $Revision: 1.3 $ + * $Date: 2007/06/26 22:37:51 $ + * + * Callback-related functions + * + * + * Copyright (C) 2005, Network Resonance, Inc. + * Copyright (C) 2006, Network Resonance, Inc. + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Network Resonance, Inc. nor the name of any + * contributors to this software may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + */ + +#include <assert.h> +#include <string.h> +#include "registry.h" +#include "registry_int.h" +#include "r_assoc.h" +#include "r_errors.h" +#include "nr_common.h" +#include "r_log.h" +#include "r_macros.h" + +static char CB_ACTIONS[] = { NR_REG_CB_ACTION_ADD, + NR_REG_CB_ACTION_DELETE, + NR_REG_CB_ACTION_CHANGE, + NR_REG_CB_ACTION_FINAL }; + +typedef struct nr_reg_cb_info_ { + char action; + void (*cb)(void *cb_arg, char action, NR_registry name); + void *cb_arg; + NR_registry name; +} nr_reg_cb_info; + +/* callbacks that are registered, a mapping from names like "foo.bar.baz" + * to an r_assoc which contains possibly several nr_reg_cb_info*'s */ +static r_assoc *nr_registry_callbacks = 0; + +//static size_t SIZEOF_CB_ID = (sizeof(void (*)()) + 1); +#define SIZEOF_CB_ID (sizeof(void (*)()) + 1) + +static int nr_reg_validate_action(char action); +static int nr_reg_assoc_destroy(void *ptr); +static int compute_cb_id(void *cb, char action, unsigned char cb_id[SIZEOF_CB_ID]); +static int nr_reg_info_free(void *ptr); +static int nr_reg_raise_event_recurse(char *name, char *tmp, int action); +static int nr_reg_register_callback(NR_registry name, char action, void (*cb)(void *cb_arg, char action, NR_registry name), void *cb_arg); +static int nr_reg_unregister_callback(char *name, char action, void (*cb)(void *cb_arg, char action, NR_registry name)); + +int +nr_reg_cb_init() +{ + int r, _status; + + if (nr_registry_callbacks == 0) { + if ((r=r_assoc_create(&nr_registry_callbacks, r_assoc_crc32_hash_compute, 12))) + ABORT(r); + } + + _status=0; + abort: + if (_status) { + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "Couldn't init notifications: %s", nr_strerror(_status)); + } + return(_status); +} + +int +nr_reg_validate_action(char action) +{ + int _status; + int i; + + for (i = 0; i < sizeof(CB_ACTIONS); ++i) { + if (action == CB_ACTIONS[i]) + return 0; + } + ABORT(R_BAD_ARGS); + + _status=0; + abort: + return(_status); +} + +int +nr_reg_register_callback(NR_registry name, char action, void (*cb)(void *cb_arg, char action, NR_registry name), void *cb_arg) +{ + int r, _status; + r_assoc *assoc; + int create_assoc = 0; + nr_reg_cb_info *info; + int create_info = 0; + unsigned char cb_id[SIZEOF_CB_ID]; + + if (name == 0 || cb == 0) + ABORT(R_BAD_ARGS); + + if (nr_registry_callbacks == 0) + ABORT(R_FAILED); + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + if ((r=nr_reg_validate_action(action))) + ABORT(r); + + if ((r=r_assoc_fetch(nr_registry_callbacks, name, strlen(name)+1, (void*)&assoc))) { + if (r == R_NOT_FOUND) + create_assoc = 1; + else + ABORT(r); + } + + if (create_assoc) { + if ((r=r_assoc_create(&assoc, r_assoc_crc32_hash_compute, 5))) + ABORT(r); + + if ((r=r_assoc_insert(nr_registry_callbacks, name, strlen(name)+1, assoc, 0, nr_reg_assoc_destroy, R_ASSOC_NEW))) + ABORT(r); + } + + if ((r=compute_cb_id(cb, action, cb_id))) + ABORT(r); + + if ((r=r_assoc_fetch(assoc, (char*)cb_id, SIZEOF_CB_ID, (void*)&info))) { + if (r == R_NOT_FOUND) + create_info = 1; + else + ABORT(r); + } + + if (create_info) { + if (!(info=(void*)RCALLOC(sizeof(*info)))) + ABORT(R_NO_MEMORY); + } + + strncpy(info->name, name, sizeof(info->name)); + info->action = action; + info->cb = cb; + info->cb_arg = cb_arg; + + if (create_info) { + if ((r=r_assoc_insert(assoc, (char*)cb_id, SIZEOF_CB_ID, info, 0, nr_reg_info_free, R_ASSOC_NEW))) + ABORT(r); + } + + _status=0; + abort: + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "register callback %p on '%s' for '%s' %s", cb, name, nr_reg_action_name(action), (_status ? "FAILED" : "succeeded")); + + if (_status) { + if (create_info && info) RFREE(info); + if (create_assoc && assoc) nr_reg_assoc_destroy(&assoc); + } + return(_status); +} + +int +nr_reg_unregister_callback(char *name, char action, void (*cb)(void *cb_arg, char action, NR_registry name)) +{ + int r, _status; + r_assoc *assoc; + int size; + unsigned char cb_id[SIZEOF_CB_ID]; + + if (name == 0 || cb == 0) + ABORT(R_BAD_ARGS); + + if (nr_registry_callbacks == 0) + ABORT(R_FAILED); + + if ((r=nr_reg_is_valid(name))) + ABORT(r); + + if ((r=nr_reg_validate_action(action))) + ABORT(r); + + if ((r=r_assoc_fetch(nr_registry_callbacks, name, strlen(name)+1, (void*)&assoc))) { + if (r != R_NOT_FOUND) + ABORT(r); + } + else { + if ((r=compute_cb_id(cb, action, cb_id))) + ABORT(r); + + if ((r=r_assoc_delete(assoc, (char*)cb_id, SIZEOF_CB_ID))) { + if (r != R_NOT_FOUND) + ABORT(r); + } + + if ((r=r_assoc_num_elements(assoc, &size))) + ABORT(r); + + if (size == 0) { + if ((r=r_assoc_delete(nr_registry_callbacks, name, strlen(name)+1))) + ABORT(r); + } + } + + _status=0; + abort: + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "unregister callback %p on '%s' for '%s' %s", cb, name, nr_reg_action_name(action), (_status ? "FAILED" : "succeeded")); + + return(_status); +} + +int +compute_cb_id(void *cb, char action, unsigned char cb_id[SIZEOF_CB_ID]) +{ + /* callbacks are identified by the pointer to the cb function plus + * the action being watched */ + assert(sizeof(cb) == sizeof(void (*)())); + assert(sizeof(cb) == (SIZEOF_CB_ID - 1)); + + memcpy(cb_id, &(cb), sizeof(cb)); + cb_id[SIZEOF_CB_ID-1] = action; + + return 0; +} + +char * +nr_reg_action_name(int action) +{ + char *name = "*Unknown*"; + + switch (action) { + case NR_REG_CB_ACTION_ADD: name = "add"; break; + case NR_REG_CB_ACTION_DELETE: name = "delete"; break; + case NR_REG_CB_ACTION_CHANGE: name = "change"; break; + case NR_REG_CB_ACTION_FINAL: name = "final"; break; + } + + return name; +} + +int +nr_reg_assoc_destroy(void *ptr) +{ + return r_assoc_destroy((r_assoc**)&ptr); +} + +int +nr_reg_info_free(void *ptr) +{ + RFREE(ptr); + return 0; +} + +/* call with tmp=0 */ +int +nr_reg_raise_event_recurse(char *name, char *tmp, int action) +{ + int r, _status; + r_assoc *assoc; + nr_reg_cb_info *info; + r_assoc_iterator iter; + char *key; + int keyl; + char *c; + int free_tmp = 0; + int count; + + if (tmp == 0) { + if (!(tmp = (char*)r_strdup(name))) + ABORT(R_NO_MEMORY); + free_tmp = 1; + } + + if ((r=r_assoc_fetch(nr_registry_callbacks, tmp, strlen(tmp)+1, (void*)&assoc))) { + if (r != R_NOT_FOUND) + ABORT(r); + + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "No callbacks found on '%s'", tmp); + } + else { + if (!r_assoc_num_elements(assoc, &count)) { + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "%d callback%s found on '%s'", + count, ((count == 1) ? "" : "s"), tmp); + } + + if ((r=r_assoc_init_iter(assoc, &iter))) + ABORT(r); + + for (;;) { + if ((r=r_assoc_iter(&iter, (void*)&key, &keyl, (void*)&info))) { + if (r == R_EOD) + break; + else + ABORT(r); + } + + if (info->action == action) { + r_log(NR_LOG_REGISTRY, LOG_DEBUG, + "Invoking callback %p for '%s'", + info->cb, + nr_reg_action_name(info->action)); + + (void)info->cb(info->cb_arg, action, name); + } + else { + r_log(NR_LOG_REGISTRY, LOG_DEBUG, + "Skipping callback %p for '%s'", + info->cb, + nr_reg_action_name(info->action)); + } + } + } + + if (strlen(tmp) > 0) { + c = strrchr(tmp, '.'); + if (c != 0) + *c = '\0'; + else + tmp[0] = '\0'; + + if ((r=nr_reg_raise_event_recurse(name, tmp, action))) + ABORT(r); + } + + _status=0; + abort: + if (free_tmp && tmp != 0) RFREE(tmp); + return(_status); +} + + +/* NON-STATIC METHODS */ + +int +nr_reg_raise_event(char *name, int action) +{ + int r, _status; + int count; + char *event = nr_reg_action_name(action); + + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "raising event '%s' on '%s'", event, name); + + if (name == 0) + ABORT(R_BAD_ARGS); + + if ((r=nr_reg_validate_action(action))) + ABORT(r); + + if ((r=r_assoc_num_elements(nr_registry_callbacks, &count))) + ABORT(r); + + if (count > 0) { + if ((r=nr_reg_raise_event_recurse(name, 0, action))) + ABORT(r); + } + else { + r_log(NR_LOG_REGISTRY, LOG_DEBUG, "No callbacks found"); + return 0; + } + + _status=0; + abort: + return(_status); +} + + +/* PUBLIC METHODS */ + +int +NR_reg_register_callback(NR_registry name, char action, void (*cb)(void *cb_arg, char action, NR_registry name), void *cb_arg) +{ + int r, _status; + int i; + + for (i = 0; i < sizeof(CB_ACTIONS); ++i) { + if (action & CB_ACTIONS[i]) { + if ((r=nr_reg_register_callback(name, CB_ACTIONS[i], cb, cb_arg))) + ABORT(r); + + action &= ~(CB_ACTIONS[i]); + } + } + + if (action) + ABORT(R_BAD_ARGS); + + _status=0; + abort: + return(_status); +} + +int +NR_reg_unregister_callback(char *name, char action, void (*cb)(void *cb_arg, char action, NR_registry name)) +{ + int r, _status; + int i; + + for (i = 0; i < sizeof(CB_ACTIONS); ++i) { + if (action & CB_ACTIONS[i]) { + if ((r=nr_reg_unregister_callback(name, CB_ACTIONS[i], cb))) + ABORT(r); + + action &= ~(CB_ACTIONS[i]); + } + } + + if (action) + ABORT(R_BAD_ARGS); + + _status=0; + abort: + return(_status); +} |