Line data Source code
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 2270713 : magic_is_null(const struct_magic_decl_t *decl)
38 : {
39 2270713 : return decl->typename == NULL &&
40 2270713 : decl->magic_offset == 0 &&
41 0 : decl->magic_val == 0;
42 : }
43 :
44 : /**
45 : * Set the 'magic number' on <b>object</b> to correspond to decl.
46 : **/
47 : void
48 26905 : struct_set_magic(void *object, const struct_magic_decl_t *decl)
49 : {
50 26905 : tor_assert(decl);
51 26905 : if (magic_is_null(decl))
52 : return;
53 :
54 26905 : tor_assert(object);
55 26905 : uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
56 26905 : *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 2243808 : struct_check_magic(const void *object, const struct_magic_decl_t *decl)
64 : {
65 2243808 : tor_assert(decl);
66 2243808 : if (magic_is_null(decl))
67 : return;
68 :
69 2243808 : tor_assert(object);
70 :
71 2243808 : const uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
72 2243808 : 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 4241595 : struct_get_mptr(void *object, const struct_member_t *member)
84 : {
85 4241595 : tor_assert(object);
86 4241595 : 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 171760 : struct_get_ptr(const void *object, const struct_member_t *member)
95 : {
96 171760 : tor_assert(object);
97 171760 : 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 4916245 : get_type_def(const struct_member_t *member)
106 : {
107 4916245 : if (member->type_def)
108 : return member->type_def;
109 :
110 4360291 : 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 3063579 : struct_var_free(void *object, const struct_member_t *member)
119 : {
120 3063579 : void *p = struct_get_mptr(object, member);
121 3063579 : const var_type_def_t *def = get_type_def(member);
122 :
123 3063579 : typed_var_free(p, def);
124 3063579 : }
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 75905 : struct_var_copy(void *dest, const void *src, const struct_member_t *member)
132 : {
133 75905 : void *p_dest = struct_get_mptr(dest, member);
134 75905 : const void *p_src = struct_get_ptr(src, member);
135 75905 : const var_type_def_t *def = get_type_def(member);
136 :
137 75905 : 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 42794 : struct_var_eq(const void *a, const void *b, const struct_member_t *member)
146 : {
147 42794 : const void *p_a = struct_get_ptr(a, member);
148 42794 : const void *p_b = struct_get_ptr(b, member);
149 42794 : const var_type_def_t *def = get_type_def(member);
150 :
151 42794 : 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 75 : struct_var_ok(const void *object, const struct_member_t *member)
160 : {
161 75 : const void *p = struct_get_ptr(object, member);
162 75 : const var_type_def_t *def = get_type_def(member);
163 :
164 75 : 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 231416 : struct_var_kvassign(void *object, const struct config_line_t *line,
173 : char **errmsg,
174 : const struct_member_t *member)
175 : {
176 231416 : void *p = struct_get_mptr(object, member);
177 231416 : const var_type_def_t *def = get_type_def(member);
178 :
179 231416 : 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 10192 : struct_var_kvencode(const void *object, const struct_member_t *member)
188 : {
189 10192 : const void *p = struct_get_ptr(object, member);
190 10192 : const var_type_def_t *def = get_type_def(member);
191 :
192 10192 : 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 870695 : struct_var_mark_fragile(void *object, const struct_member_t *member)
202 : {
203 870695 : void *p = struct_get_mptr(object, member);
204 870695 : const var_type_def_t *def = get_type_def(member);
205 870695 : return typed_var_mark_fragile(p, def);
206 : }
207 :
208 : /**
209 : * Return the official name of this struct member.
210 : **/
211 : const char *
212 0 : struct_var_get_name(const struct_member_t *member)
213 : {
214 0 : 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 355 : struct_var_get_typename(const struct_member_t *member)
226 : {
227 355 : const var_type_def_t *def = get_type_def(member);
228 :
229 355 : return def ? def->name : NULL;
230 : }
231 :
232 : /** Return all of the flags set for this struct member. */
233 : uint32_t
234 621234 : struct_var_get_flags(const struct_member_t *member)
235 : {
236 621234 : const var_type_def_t *def = get_type_def(member);
237 :
238 621234 : return def ? def->flags : 0;
239 : }
|