aboutsummaryrefslogtreecommitdiff
path: root/src/lib/confmgt
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2019-08-20 13:57:05 -0400
committerNick Mathewson <nickm@torproject.org>2019-08-20 13:57:05 -0400
commitedf5a327c5a27db218b4240b758669f5572e9565 (patch)
treec7a1f09943439f74b22dfc2e6761ba8a6dcbaafe /src/lib/confmgt
parent4b1e0dd5b53528996a3a0f92717e5ccbb8819a4b (diff)
parente8790971f6120cc3e4fd2acd41f5dd0512f52068 (diff)
downloadtor-edf5a327c5a27db218b4240b758669f5572e9565.tar.gz
tor-edf5a327c5a27db218b4240b758669f5572e9565.zip
Merge branch 'ticket30914' into ticket30914_merged
Diffstat (limited to 'src/lib/confmgt')
-rw-r--r--src/lib/confmgt/include.am2
-rw-r--r--src/lib/confmgt/structvar.c226
-rw-r--r--src/lib/confmgt/structvar.h54
-rw-r--r--src/lib/confmgt/typedvar.c18
4 files changed, 292 insertions, 8 deletions
diff --git a/src/lib/confmgt/include.am b/src/lib/confmgt/include.am
index a2c7649957..aa5b37fdb5 100644
--- a/src/lib/confmgt/include.am
+++ b/src/lib/confmgt/include.am
@@ -6,6 +6,7 @@ endif
# ADD_C_FILE: INSERT SOURCES HERE.
src_lib_libtor_confmgt_a_SOURCES = \
+ src/lib/confmgt/structvar.c \
src/lib/confmgt/type_defs.c \
src/lib/confmgt/typedvar.c \
src/lib/confmgt/unitparse.c
@@ -17,6 +18,7 @@ src_lib_libtor_confmgt_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
# ADD_C_FILE: INSERT HEADERS HERE.
noinst_HEADERS += \
+ src/lib/confmgt/structvar.h \
src/lib/confmgt/type_defs.h \
src/lib/confmgt/typedvar.h \
src/lib/confmgt/unitparse.h \
diff --git a/src/lib/confmgt/structvar.c b/src/lib/confmgt/structvar.c
new file mode 100644
index 0000000000..38f8e5dd7a
--- /dev/null
+++ b/src/lib/confmgt/structvar.c
@@ -0,0 +1,226 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file structvar.c
+ * @brief Functions to manipulate named and typed elements of
+ * a structure.
+ *
+ * These functions represent a low-level API for accessing a member of a
+ * structure. They use typedvar.c to work, and they are used in turn by the
+ * configuration system to examine and set fields in configuration objects
+ * used by individual modules.
+ *
+ * Almost no code should call these directly.
+ **/
+
+#include "orconfig.h"
+#include "lib/confmgt/structvar.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/conf/conftypes.h"
+#include "lib/confmgt/type_defs.h"
+#include "lib/confmgt/typedvar.h"
+#include "lib/log/util_bug.h"
+
+#include "lib/confmgt/var_type_def_st.h"
+
+#include <stddef.h>
+
+/**
+ * Set the 'magic number' on <b>object</b> to correspond to decl.
+ **/
+void
+struct_set_magic(void *object, const struct_magic_decl_t *decl)
+{
+ tor_assert(object);
+ tor_assert(decl);
+ uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
+ *ptr = decl->magic_val;
+}
+
+/**
+ * Assert that the 'magic number' on <b>object</b> to corresponds to decl.
+ **/
+void
+struct_check_magic(const void *object, const struct_magic_decl_t *decl)
+{
+ tor_assert(object);
+ tor_assert(decl);
+
+ const uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
+ tor_assertf(*ptr == decl->magic_val,
+ "Bad magic number on purported %s object. "
+ "Expected %"PRIu32"x but got "PRIu32"x.",
+ decl->magic_val, *ptr);
+}
+
+/**
+ * Return a mutable pointer to the member of <b>object</b> described
+ * by <b>member</b>.
+ **/
+void *
+struct_get_mptr(void *object, const struct_member_t *member)
+{
+ tor_assert(object);
+ return STRUCT_VAR_P(object, member->offset);
+}
+
+/**
+ * Return a const pointer to the member of <b>object</b> described
+ * by <b>member</b>.
+ **/
+const void *
+struct_get_ptr(const void *object, const struct_member_t *member)
+{
+ tor_assert(object);
+ return STRUCT_VAR_P(object, member->offset);
+}
+
+/**
+ * Helper: given a struct_member_t, look up the type definition for its
+ * variable.
+ */
+static const var_type_def_t *
+get_type_def(const struct_member_t *member)
+{
+ if (member->type_def)
+ return member->type_def;
+
+ return lookup_type_def(member->type);
+}
+
+/**
+ * (As typed_var_assign, but assign a value to the member of <b>object</b>
+ * defined by <b>member</b>.)
+ **/
+int
+struct_var_assign(void *object, const char *value, char **errmsg,
+ const struct_member_t *member)
+{
+ void *p = struct_get_mptr(object, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ return typed_var_assign_ex(p, value, errmsg, def);
+}
+
+/**
+ * (As typed_var_free, but free and clear the member of <b>object</b> defined
+ * by <b>member</b>.)
+ **/
+void
+struct_var_free(void *object, const struct_member_t *member)
+{
+ void *p = struct_get_mptr(object, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ typed_var_free_ex(p, def);
+}
+
+/**
+ * (As typed_var_encode, but encode the member of <b>object</b> defined
+ * by <b>member</b>.)
+ **/
+char *
+struct_var_encode(const void *object, const struct_member_t *member)
+{
+ const void *p = struct_get_ptr(object, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ return typed_var_encode_ex(p, def);
+}
+
+/**
+ * (As typed_var_copy, but copy from <b>src</b> to <b>dest</b> the member
+ * defined by <b>member</b>.)
+ **/
+int
+struct_var_copy(void *dest, const void *src, const struct_member_t *member)
+{
+ void *p_dest = struct_get_mptr(dest, member);
+ const void *p_src = struct_get_ptr(src, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ return typed_var_copy_ex(p_dest, p_src, def);
+}
+
+/**
+ * (As typed_var_eq, but compare the members of <b>a</b> and <b>b</b>
+ * defined by <b>member</b>.)
+ **/
+bool
+struct_var_eq(const void *a, const void *b, const struct_member_t *member)
+{
+ const void *p_a = struct_get_ptr(a, member);
+ const void *p_b = struct_get_ptr(b, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ return typed_var_eq_ex(p_a, p_b, def);
+}
+
+/**
+ * (As typed_var_ok, but validate the member of <b>object</b> defined by
+ * <b>member</b>.)
+ **/
+bool
+struct_var_ok(const void *object, const struct_member_t *member)
+{
+ const void *p = struct_get_ptr(object, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ return typed_var_ok_ex(p, def);
+}
+
+/**
+ * (As typed_var_kvassign, but assign a value to the member of <b>object</b>
+ * defined by <b>member</b>.)
+ **/
+int
+struct_var_kvassign(void *object, const struct config_line_t *line,
+ char **errmsg,
+ const struct_member_t *member)
+{
+ void *p = struct_get_mptr(object, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ return typed_var_kvassign_ex(p, line, errmsg, def);
+}
+
+/**
+ * (As typed_var_kvencode, but encode the value of the member of <b>object</b>
+ * defined by <b>member</b>.)
+ **/
+struct config_line_t *
+struct_var_kvencode(const void *object, const struct_member_t *member)
+{
+ const void *p = struct_get_ptr(object, member);
+ const var_type_def_t *def = get_type_def(member);
+
+ return typed_var_kvencode_ex(member->name, p, def);
+}
+
+/**
+ * Return the official name of this struct member.
+ **/
+const char *
+struct_var_get_name(const struct_member_t *member)
+{
+ return member->name;
+}
+
+/**
+ * Return the type name for this struct member.
+ *
+ * Do not use the output of this function to inspect a type within Tor. It is
+ * suitable for debugging, informing the controller or user of a variable's
+ * type, etc.
+ **/
+const char *
+struct_var_get_typename(const struct_member_t *member)
+{
+ const var_type_def_t *def = get_type_def(member);
+
+ return def ? def->name : NULL;
+}
diff --git a/src/lib/confmgt/structvar.h b/src/lib/confmgt/structvar.h
new file mode 100644
index 0000000000..92b9b6fc71
--- /dev/null
+++ b/src/lib/confmgt/structvar.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file structvar.h
+ * @brief Header for lib/confmgt/structvar.c
+ **/
+
+#ifndef TOR_LIB_CONFMGT_STRUCTVAR_H
+#define TOR_LIB_CONFMGT_STRUCTVAR_H
+
+struct struct_magic_decl_t;
+struct struct_member_t;
+struct config_line_t;
+
+#include <stdbool.h>
+
+void struct_set_magic(void *object,
+ const struct struct_magic_decl_t *decl);
+void struct_check_magic(const void *object,
+ const struct struct_magic_decl_t *decl);
+
+void *struct_get_mptr(void *object,
+ const struct struct_member_t *member);
+const void *struct_get_ptr(const void *object,
+ const struct struct_member_t *member);
+
+int struct_var_assign(void *object, const char *value, char **errmsg,
+ const struct struct_member_t *member);
+void struct_var_free(void *object,
+ const struct struct_member_t *member);
+char *struct_var_encode(const void *object,
+ const struct struct_member_t *member);
+int struct_var_copy(void *dest, const void *src,
+ const struct struct_member_t *member);
+bool struct_var_eq(const void *a, const void *b,
+ const struct struct_member_t *member);
+bool struct_var_ok(const void *object,
+ const struct struct_member_t *member);
+
+const char *struct_var_get_name(const struct struct_member_t *member);
+const char *struct_var_get_typename(const struct struct_member_t *member);
+
+int struct_var_kvassign(void *object, const struct config_line_t *line,
+ char **errmsg,
+ const struct struct_member_t *member);
+struct config_line_t *struct_var_kvencode(
+ const void *object,
+ const struct struct_member_t *member);
+
+#endif /* !defined(TOR_LIB_CONFMGT_STRUCTVAR_H) */
diff --git a/src/lib/confmgt/typedvar.c b/src/lib/confmgt/typedvar.c
index fc45c44481..c2b9b45725 100644
--- a/src/lib/confmgt/typedvar.c
+++ b/src/lib/confmgt/typedvar.c
@@ -44,7 +44,7 @@ typed_var_assign_ex(void *target, const char *value, char **errmsg,
const var_type_def_t *def)
{
if (BUG(!def))
- return -1;
+ return -1; // LCOV_EXCL_LINE
// clear old value if needed.
typed_var_free_ex(target, def);
@@ -67,7 +67,7 @@ typed_var_kvassign_ex(void *target, const config_line_t *line,
char **errmsg, const var_type_def_t *def)
{
if (BUG(!def))
- return -1;
+ return -1; // LCOV_EXCL_LINE
if (def->fns->kv_parse) {
// We do _not_ free the old value here, since linelist options
@@ -86,7 +86,7 @@ void
typed_var_free_ex(void *target, const var_type_def_t *def)
{
if (BUG(!def))
- return;
+ return; // LCOV_EXCL_LINE
if (def->fns->clear) {
def->fns->clear(target, def->params);
}
@@ -102,7 +102,7 @@ char *
typed_var_encode_ex(const void *value, const var_type_def_t *def)
{
if (BUG(!def))
- return NULL;
+ return NULL; // LCOV_EXCL_LINE
tor_assert(def->fns->encode);
return def->fns->encode(value, def->params);
}
@@ -121,7 +121,7 @@ typed_var_kvencode_ex(const char *key, const void *value,
const var_type_def_t *def)
{
if (BUG(!def))
- return NULL;
+ return NULL; // LCOV_EXCL_LINE
if (def->fns->kv_encode) {
return def->fns->kv_encode(key, value, def->params);
}
@@ -145,7 +145,7 @@ int
typed_var_copy_ex(void *dest, const void *src, const var_type_def_t *def)
{
if (BUG(!def))
- return -1;
+ return -1; // LCOV_EXCL_LINE
if (def->fns->copy) {
// If we have been provided a copy fuction, use it.
return def->fns->copy(dest, src, def);
@@ -160,8 +160,10 @@ typed_var_copy_ex(void *dest, const void *src, const var_type_def_t *def)
char *err = NULL;
int rv = typed_var_assign_ex(dest, enc, &err, def);
if (BUG(rv < 0)) {
+ // LCOV_EXCL_START
log_warn(LD_BUG, "Encoded value %s was not parseable as a %s: %s",
escaped(enc), def->name, err?err:"");
+ // LCOV_EXCL_STOP
}
tor_free(err);
tor_free(enc);
@@ -176,7 +178,7 @@ bool
typed_var_eq_ex(const void *a, const void *b, const var_type_def_t *def)
{
if (BUG(!def))
- return false;
+ return false; // LCOV_EXCL_LINE
if (def->fns->eq) {
// Use a provided eq function if we got one.
@@ -200,7 +202,7 @@ bool
typed_var_ok_ex(const void *value, const var_type_def_t *def)
{
if (BUG(!def))
- return false;
+ return false; // LCOV_EXCL_LINE
if (def->fns->ok)
return def->fns->ok(value, def->params);