tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

structvar.c (6216B)


      1 /* Copyright (c) 2001 Matej Pfajfar.
      2 * Copyright (c) 2001-2004, Roger Dingledine.
      3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * @file structvar.c
      9 * @brief Functions to manipulate named and typed elements of
     10 *    a structure.
     11 *
     12 * These functions represent a low-level API for accessing a member of a
     13 * structure.  They use typedvar.c to work, and they are used in turn by the
     14 * configuration system to examine and set fields in configuration objects
     15 * used by individual modules.
     16 *
     17 * Almost no code should call these directly.
     18 **/
     19 
     20 #include "orconfig.h"
     21 #include "lib/confmgt/structvar.h"
     22 #include "lib/cc/compat_compiler.h"
     23 #include "lib/conf/conftypes.h"
     24 #include "lib/confmgt/type_defs.h"
     25 #include "lib/confmgt/typedvar.h"
     26 #include "lib/log/util_bug.h"
     27 
     28 #include "lib/confmgt/var_type_def_st.h"
     29 
     30 #include <stddef.h>
     31 
     32 /**
     33 * Return true iff all fields on <b>decl</b> are NULL or 0, indicating that
     34 * there is no object or no magic number to check.
     35 **/
     36 static inline bool
     37 magic_is_null(const struct_magic_decl_t *decl)
     38 {
     39  return decl->typename == NULL &&
     40    decl->magic_offset == 0 &&
     41    decl->magic_val == 0;
     42 }
     43 
     44 /**
     45 * Set the 'magic number' on <b>object</b> to correspond to decl.
     46 **/
     47 void
     48 struct_set_magic(void *object, const struct_magic_decl_t *decl)
     49 {
     50  tor_assert(decl);
     51  if (magic_is_null(decl))
     52    return;
     53 
     54  tor_assert(object);
     55  uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
     56  *ptr = decl->magic_val;
     57 }
     58 
     59 /**
     60 * Assert that the 'magic number' on <b>object</b> to corresponds to decl.
     61 **/
     62 void
     63 struct_check_magic(const void *object, const struct_magic_decl_t *decl)
     64 {
     65  tor_assert(decl);
     66  if (magic_is_null(decl))
     67    return;
     68 
     69  tor_assert(object);
     70 
     71  const uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
     72  tor_assertf(*ptr == decl->magic_val,
     73              "Bad magic number on purported %s object. "
     74              "Expected %"PRIu32"x but got %"PRIu32"x.",
     75              decl->typename, decl->magic_val, *ptr);
     76 }
     77 
     78 /**
     79 * Return a mutable pointer to the member of <b>object</b> described
     80 * by <b>member</b>.
     81 **/
     82 void *
     83 struct_get_mptr(void *object, const struct_member_t *member)
     84 {
     85  tor_assert(object);
     86  return STRUCT_VAR_P(object, member->offset);
     87 }
     88 
     89 /**
     90 * Return a const pointer to the member of <b>object</b> described
     91 * by <b>member</b>.
     92 **/
     93 const void *
     94 struct_get_ptr(const void *object, const struct_member_t *member)
     95 {
     96  tor_assert(object);
     97  return STRUCT_VAR_P(object, member->offset);
     98 }
     99 
    100 /**
    101 * Helper: given a struct_member_t, look up the type definition for its
    102 * variable.
    103 */
    104 static const var_type_def_t *
    105 get_type_def(const struct_member_t *member)
    106 {
    107  if (member->type_def)
    108    return member->type_def;
    109 
    110  return lookup_type_def(member->type);
    111 }
    112 
    113 /**
    114 * (As typed_var_free, but free and clear the member of <b>object</b> defined
    115 * by <b>member</b>.)
    116 **/
    117 void
    118 struct_var_free(void *object, const struct_member_t *member)
    119 {
    120  void *p = struct_get_mptr(object, member);
    121  const var_type_def_t *def = get_type_def(member);
    122 
    123  typed_var_free(p, def);
    124 }
    125 
    126 /**
    127 * (As typed_var_copy, but copy from <b>src</b> to <b>dest</b> the member
    128 * defined by <b>member</b>.)
    129 **/
    130 int
    131 struct_var_copy(void *dest, const void *src, const struct_member_t *member)
    132 {
    133  void *p_dest = struct_get_mptr(dest, member);
    134  const void *p_src = struct_get_ptr(src, member);
    135  const var_type_def_t *def = get_type_def(member);
    136 
    137  return typed_var_copy(p_dest, p_src, def);
    138 }
    139 
    140 /**
    141 * (As typed_var_eq, but compare the members of <b>a</b> and <b>b</b>
    142 * defined by <b>member</b>.)
    143 **/
    144 bool
    145 struct_var_eq(const void *a, const void *b, const struct_member_t *member)
    146 {
    147  const void *p_a = struct_get_ptr(a, member);
    148  const void *p_b = struct_get_ptr(b, member);
    149  const var_type_def_t *def = get_type_def(member);
    150 
    151  return typed_var_eq(p_a, p_b, def);
    152 }
    153 
    154 /**
    155 * (As typed_var_ok, but validate the member of <b>object</b> defined by
    156 * <b>member</b>.)
    157 **/
    158 bool
    159 struct_var_ok(const void *object, const struct_member_t *member)
    160 {
    161  const void *p = struct_get_ptr(object, member);
    162  const var_type_def_t *def = get_type_def(member);
    163 
    164  return typed_var_ok(p, def);
    165 }
    166 
    167 /**
    168 * (As typed_var_kvassign, but assign a value to the member of <b>object</b>
    169 * defined by <b>member</b>.)
    170 **/
    171 int
    172 struct_var_kvassign(void *object, const struct config_line_t *line,
    173                    char **errmsg,
    174                    const struct_member_t *member)
    175 {
    176  void *p = struct_get_mptr(object, member);
    177  const var_type_def_t *def = get_type_def(member);
    178 
    179  return typed_var_kvassign(p, line, errmsg, def);
    180 }
    181 
    182 /**
    183 * (As typed_var_kvencode, but encode the value of the member of <b>object</b>
    184 * defined by <b>member</b>.)
    185 **/
    186 struct config_line_t *
    187 struct_var_kvencode(const void *object, const struct_member_t *member)
    188 {
    189  const void *p = struct_get_ptr(object, member);
    190  const var_type_def_t *def = get_type_def(member);
    191 
    192  return typed_var_kvencode(member->name, p, def);
    193 }
    194 
    195 /**
    196 * Mark the field in <b>object</b> determined by <b>member</b> -- a variable
    197 * that ordinarily would be extended by assignment -- as "fragile", so that it
    198 * will get replaced by the next assignment instead.
    199 */
    200 void
    201 struct_var_mark_fragile(void *object, const struct_member_t *member)
    202 {
    203  void *p = struct_get_mptr(object, member);
    204  const var_type_def_t *def = get_type_def(member);
    205  return typed_var_mark_fragile(p, def);
    206 }
    207 
    208 /**
    209 * Return the official name of this struct member.
    210 **/
    211 const char *
    212 struct_var_get_name(const struct_member_t *member)
    213 {
    214  return member->name;
    215 }
    216 
    217 /**
    218 * Return the type name for this struct member.
    219 *
    220 * Do not use the output of this function to inspect a type within Tor.  It is
    221 * suitable for debugging, informing the controller or user of a variable's
    222 * type, etc.
    223 **/
    224 const char *
    225 struct_var_get_typename(const struct_member_t *member)
    226 {
    227  const var_type_def_t *def = get_type_def(member);
    228 
    229  return def ? def->name : NULL;
    230 }
    231 
    232 /** Return all of the flags set for this struct member. */
    233 uint32_t
    234 struct_var_get_flags(const struct_member_t *member)
    235 {
    236  const var_type_def_t *def = get_type_def(member);
    237 
    238  return def ? def->flags : 0;
    239 }