Tor 0.4.9.0-alpha-dev
structvar.c
Go to the documentation of this file.
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"
23#include "lib/conf/conftypes.h"
26#include "lib/log/util_bug.h"
27
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 **/
36static inline bool
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 **/
47void
48struct_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 **/
62void
63struct_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 **/
82void *
83struct_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 **/
93const void *
94struct_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 */
104static const var_type_def_t *
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 **/
117void
118struct_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 **/
130int
131struct_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 **/
144bool
145struct_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 **/
158bool
159struct_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 **/
171int
172struct_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 **/
186struct config_line_t *
187struct_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 */
200void
201struct_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 **/
211const char *
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 **/
224const char *
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. */
233uint32_t
235{
236 const var_type_def_t *def = get_type_def(member);
237
238 return def ? def->flags : 0;
239}
Utility macros to handle different features and behavior in different compilers.
#define STRUCT_VAR_P(st, off)
Types used to specify configurable options.
ptrdiff_t magic_offset
Definition: conftypes.h:145
const char * typename
Definition: conftypes.h:140
uint32_t magic_val
Definition: conftypes.h:142
ptrdiff_t offset
Definition: conftypes.h:125
const struct var_type_def_t * type_def
Definition: conftypes.h:120
const char * name
Definition: conftypes.h:98
config_type_t type
Definition: conftypes.h:114
void * struct_get_mptr(void *object, const struct_member_t *member)
Definition: structvar.c:83
const char * struct_var_get_name(const struct_member_t *member)
Definition: structvar.c:212
void struct_set_magic(void *object, const struct_magic_decl_t *decl)
Definition: structvar.c:48
const void * struct_get_ptr(const void *object, const struct_member_t *member)
Definition: structvar.c:94
void struct_check_magic(const void *object, const struct_magic_decl_t *decl)
Definition: structvar.c:63
bool struct_var_eq(const void *a, const void *b, const struct_member_t *member)
Definition: structvar.c:145
int struct_var_kvassign(void *object, const struct config_line_t *line, char **errmsg, const struct_member_t *member)
Definition: structvar.c:172
int struct_var_copy(void *dest, const void *src, const struct_member_t *member)
Definition: structvar.c:131
static const var_type_def_t * get_type_def(const struct_member_t *member)
Definition: structvar.c:105
void struct_var_free(void *object, const struct_member_t *member)
Definition: structvar.c:118
void struct_var_mark_fragile(void *object, const struct_member_t *member)
Definition: structvar.c:201
bool struct_var_ok(const void *object, const struct_member_t *member)
Definition: structvar.c:159
static bool magic_is_null(const struct_magic_decl_t *decl)
Definition: structvar.c:37
const char * struct_var_get_typename(const struct_member_t *member)
Definition: structvar.c:225
uint32_t struct_var_get_flags(const struct_member_t *member)
Definition: structvar.c:234
struct config_line_t * struct_var_kvencode(const void *object, const struct_member_t *member)
Definition: structvar.c:187
Header for lib/confmgt/structvar.c.
const char * name
const var_type_def_t * lookup_type_def(config_type_t type)
Definition: type_defs.c:842
Header for lib/confmgt/type_defs.c.
void typed_var_mark_fragile(void *value, const var_type_def_t *def)
Definition: typedvar.c:228
config_line_t * typed_var_kvencode(const char *key, const void *value, const var_type_def_t *def)
Definition: typedvar.c:129
void typed_var_free(void *target, const var_type_def_t *def)
Definition: typedvar.c:95
bool typed_var_eq(const void *a, const void *b, const var_type_def_t *def)
Definition: typedvar.c:187
bool typed_var_ok(const void *value, const var_type_def_t *def)
Definition: typedvar.c:211
int typed_var_kvassign(void *target, const config_line_t *line, char **errmsg, const var_type_def_t *def)
Definition: typedvar.c:67
int typed_var_copy(void *dest, const void *src, const var_type_def_t *def)
Definition: typedvar.c:154
Header for lib/confmgt/typedvar.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103
Structure declarations for typedvar type definitions.