tor  0.4.2.0-alpha-dev
typedvar.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-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
18 #include "orconfig.h"
19 #include "lib/conf/conftypes.h"
20 #include "lib/confmgt/type_defs.h"
21 #include "lib/confmgt/typedvar.h"
22 #include "lib/encoding/confline.h"
23 #include "lib/log/escape.h"
24 #include "lib/log/log.h"
25 #include "lib/log/util_bug.h"
26 #include "lib/malloc/malloc.h"
27 #include "lib/string/util_string.h"
28 
30 
31 #include <stddef.h>
32 #include <string.h>
33 
42 int
43 typed_var_assign(void *target, const char *value, char **errmsg,
44  const var_type_def_t *def)
45 {
46  if (BUG(!def))
47  return -1; // LCOV_EXCL_LINE
48  // clear old value if needed.
49  typed_var_free(target, def);
50 
51  tor_assert(def->fns->parse);
52  return def->fns->parse(target, value, errmsg, def->params);
53 }
54 
65 int
66 typed_var_kvassign(void *target, const config_line_t *line,
67  char **errmsg, const var_type_def_t *def)
68 {
69  if (BUG(!def))
70  return -1; // LCOV_EXCL_LINE
71 
72  if (def->fns->kv_parse) {
73  // We do _not_ free the old value here, since linelist options
74  // sometimes have append semantics.
75  return def->fns->kv_parse(target, line, errmsg, def->params);
76  }
77 
78  return typed_var_assign(target, line->value, errmsg, def);
79 }
80 
85 void
86 typed_var_free(void *target, const var_type_def_t *def)
87 {
88  if (BUG(!def))
89  return; // LCOV_EXCL_LINE
90  if (def->fns->clear) {
91  def->fns->clear(target, def->params);
92  }
93 }
94 
101 char *
102 typed_var_encode(const void *value, const var_type_def_t *def)
103 {
104  if (BUG(!def))
105  return NULL; // LCOV_EXCL_LINE
106  tor_assert(def->fns->encode);
107  return def->fns->encode(value, def->params);
108 }
109 
120 typed_var_kvencode(const char *key, const void *value,
121  const var_type_def_t *def)
122 {
123  if (BUG(!def))
124  return NULL; // LCOV_EXCL_LINE
125  if (def->fns->kv_encode) {
126  return def->fns->kv_encode(key, value, def->params);
127  }
128  char *encoded_value = typed_var_encode(value, def);
129  if (!encoded_value)
130  return NULL;
131 
132  config_line_t *result = tor_malloc_zero(sizeof(config_line_t));
133  result->key = tor_strdup(key);
134  result->value = encoded_value;
135  return result;
136 }
137 
144 int
145 typed_var_copy(void *dest, const void *src, const var_type_def_t *def)
146 {
147  if (BUG(!def))
148  return -1; // LCOV_EXCL_LINE
149  if (def->fns->copy) {
150  // If we have been provided a copy fuction, use it.
151  return def->fns->copy(dest, src, def);
152  }
153 
154  // Otherwise, encode 'src' and parse the result into 'def'.
155  char *enc = typed_var_encode(src, def);
156  if (!enc) {
157  typed_var_free(dest, def);
158  return 0;
159  }
160  char *err = NULL;
161  int rv = typed_var_assign(dest, enc, &err, def);
162  if (BUG(rv < 0)) {
163  // LCOV_EXCL_START
164  log_warn(LD_BUG, "Encoded value %s was not parseable as a %s: %s",
165  escaped(enc), def->name, err?err:"");
166  // LCOV_EXCL_STOP
167  }
168  tor_free(err);
169  tor_free(enc);
170  return rv;
171 }
172 
177 bool
178 typed_var_eq(const void *a, const void *b, const var_type_def_t *def)
179 {
180  if (BUG(!def))
181  return false; // LCOV_EXCL_LINE
182 
183  if (def->fns->eq) {
184  // Use a provided eq function if we got one.
185  return def->fns->eq(a, b, def->params);
186  }
187 
188  // Otherwise, encode the values and compare them.
189  char *enc_a = typed_var_encode(a, def);
190  char *enc_b = typed_var_encode(b, def);
191  bool eq = !strcmp_opt(enc_a,enc_b);
192  tor_free(enc_a);
193  tor_free(enc_b);
194  return eq;
195 }
196 
201 bool
202 typed_var_ok(const void *value, const var_type_def_t *def)
203 {
204  if (BUG(!def))
205  return false; // LCOV_EXCL_LINE
206 
207  if (def->fns->ok)
208  return def->fns->ok(value, def->params);
209 
210  return true;
211 }
212 
218 void
219 typed_var_mark_fragile(void *value, const var_type_def_t *def)
220 {
221  if (BUG(!def)) {
222  return; // LCOV_EXCL_LINE
223  }
224 
225  if (def->fns->mark_fragile)
226  def->fns->mark_fragile(value, def->params);
227 }
bool typed_var_ok(const void *value, const var_type_def_t *def)
Definition: typedvar.c:202
char * typed_var_encode(const void *value, const var_type_def_t *def)
Definition: typedvar.c:102
Header for confline.c.
int(* kv_parse)(void *target, const struct config_line_t *line, char **errmsg, const void *params)
void typed_var_free(void *target, const var_type_def_t *def)
Definition: typedvar.c:86
void typed_var_mark_fragile(void *value, const var_type_def_t *def)
Definition: typedvar.c:219
bool typed_var_eq(const void *a, const void *b, const var_type_def_t *def)
Definition: typedvar.c:178
Structure declarations for typedvar type definitions.
#define tor_free(p)
Definition: malloc.h:52
Header for util_string.c.
int typed_var_assign(void *target, const char *value, char **errmsg, const var_type_def_t *def)
Definition: typedvar.c:43
Headers for util_malloc.c.
int(* copy)(void *target, const void *value, const void *params)
struct config_line_t *(* kv_encode)(const char *key, const void *value, const void *params)
int(* parse)(void *target, const char *value, char **errmsg, const void *params)
tor_assert(buffer)
Header for lib/confmgt/typedvar.c.
const struct var_type_fns_t * fns
const void * params
char *(* encode)(const void *value, const void *params)
int typed_var_copy(void *dest, const void *src, const var_type_def_t *def)
Definition: typedvar.c:145
void(* mark_fragile)(void *value, const void *params)
Header for lib/confmgt/type_defs.c.
Types used to specify configurable options.
bool(* ok)(const void *value, const void *params)
const char * escaped(const char *s)
Definition: escape.c:126
Header for escape.c.
int typed_var_kvassign(void *target, const config_line_t *line, char **errmsg, const var_type_def_t *def)
Definition: typedvar.c:66
int strcmp_opt(const char *s1, const char *s2)
Definition: util_string.c:188
bool(* eq)(const void *a, const void *b, const void *params)
void(* clear)(void *arg, const void *params)
const char * name
Headers for log.c.
Macros to manage assertions, fatal and non-fatal.
config_line_t * typed_var_kvencode(const char *key, const void *value, const var_type_def_t *def)
Definition: typedvar.c:120
#define LD_BUG
Definition: log.h:84