Tor  0.4.7.0-alpha-dev
confmgt.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 confmgt.c
9  *
10  * \brief Back-end for parsing and generating key-value files, used to
11  * implement the torrc file format and the state file.
12  *
13  * This module is used by config.c to parse and encode torrc
14  * configuration files, and by statefile.c to parse and encode the
15  * $DATADIR/state file.
16  *
17  * To use this module, its callers provide an instance of
18  * config_format_t to describe the mappings from a set of configuration
19  * options to a number of fields in a C structure. With this mapping,
20  * the functions here can convert back and forth between the C structure
21  * specified, and a linked list of key-value pairs.
22  */
23 
24 #define CONFMGT_PRIVATE
25 #include "orconfig.h"
26 #include "lib/confmgt/confmgt.h"
27 
28 #include "lib/confmgt/structvar.h"
29 #include "lib/confmgt/unitparse.h"
30 #include "lib/container/bitarray.h"
32 #include "lib/encoding/confline.h"
33 #include "lib/log/escape.h"
34 #include "lib/log/log.h"
35 #include "lib/log/util_bug.h"
37 #include "lib/string/printf.h"
38 #include "lib/string/util_string.h"
39 
40 #include "ext/siphash.h"
41 
42 /**
43  * A managed_var_t is an internal wrapper around a config_var_t in
44  * a config_format_t structure. It is used by config_mgr_t to
45  * keep track of which option goes with which structure. */
46 typedef struct managed_var_t {
47  /**
48  * A pointer to the config_var_t for this option.
49  */
51  /**
52  * The index of the object in which this option is stored. It is
53  * IDX_TOPLEVEL to indicate that the object is the top-level object.
54  **/
57 
58 static void config_reset(const config_mgr_t *fmt, void *options,
59  const managed_var_t *var, int use_defaults);
60 static void config_mgr_register_fmt(config_mgr_t *mgr,
61  const config_format_t *fmt,
62  int object_idx);
63 
64 /** Release all storage held in a managed_var_t. */
65 static void
67 {
68  if (!mv)
69  return;
70  tor_free(mv);
71 }
72 #define managed_var_free(mv) \
73  FREE_AND_NULL(managed_var_t, managed_var_free_, (mv))
74 
76  /** A list of configuration objects managed by a given configuration
77  * manager. They are stored in the same order as the config_format_t
78  * objects in the manager's list of subformats. */
80 };
81 
82 /**
83  * Allocate a new empty config_suite_t.
84  **/
85 static config_suite_t *
87 {
88  config_suite_t *suite = tor_malloc_zero(sizeof(config_suite_t));
89  suite->configs = smartlist_new();
90  return suite;
91 }
92 
93 /** Release all storage held by a config_suite_t. (Does not free
94  * any configuration objects it holds; the caller must do that first.) */
95 static void
97 {
98  if (!suite)
99  return;
100  smartlist_free(suite->configs);
101  tor_free(suite);
102 }
103 
104 #define config_suite_free(suite) \
105  FREE_AND_NULL(config_suite_t, config_suite_free_, (suite))
106 
107 struct config_mgr_t {
108  /** The 'top-level' configuration format. This one is used for legacy
109  * options that have not yet been assigned to different sub-modules.
110  *
111  * (NOTE: for now, this is the only config_format_t that a config_mgr_t
112  * contains. A subsequent commit will add more. XXXX)
113  */
115  /**
116  * List of second-level configuration format objects that this manager
117  * also knows about.
118  */
120  /** A smartlist of managed_var_t objects for all configuration formats. */
122  /** A smartlist of config_abbrev_t objects for all configuration
123  * formats. These objects are used to track synonyms and abbreviations for
124  * different configuration options. */
126  /** A smartlist of config_deprecation_t for all configuration formats. */
128  /** True if this manager has been frozen and cannot have any more formats
129  * added to it. A manager must be frozen before it can be used to construct
130  * or manipulate objects. */
131  bool frozen;
132  /** A replacement for the magic number of the toplevel object. We override
133  * that number to make it unique for this particular config_mgr_t, so that
134  * an object constructed with one mgr can't be used with another, even if
135  * those managers' contents are equal.
136  */
138 };
139 
140 #define IDX_TOPLEVEL (-1)
141 
142 /** Create a new config_mgr_t to manage a set of configuration objects to be
143  * wrapped under <b>toplevel_fmt</b>. */
144 config_mgr_t *
145 config_mgr_new(const config_format_t *toplevel_fmt)
146 {
147  config_mgr_t *mgr = tor_malloc_zero(sizeof(config_mgr_t));
148  mgr->subconfigs = smartlist_new();
149  mgr->all_vars = smartlist_new();
150  mgr->all_abbrevs = smartlist_new();
152 
153  config_mgr_register_fmt(mgr, toplevel_fmt, IDX_TOPLEVEL);
154  mgr->toplevel = toplevel_fmt;
155 
156  return mgr;
157 }
158 
159 /** Add a config_format_t to a manager, with a specified (unique) index. */
160 static void
162  const config_format_t *fmt,
163  int object_idx)
164 {
165  int i;
166 
167  tor_assertf(!mgr->frozen,
168  "Tried to add a format to a configuration manager after "
169  "it had been frozen.");
170 
171  if (object_idx != IDX_TOPLEVEL) {
172  tor_assertf(! fmt->has_config_suite,
173  "Tried to register a toplevel format in a non-toplevel position");
174  }
175  if (fmt->config_suite_offset) {
176  tor_assertf(fmt->has_config_suite,
177  "config_suite_offset was set, but has_config_suite was not.");
178  }
179 
180  tor_assertf(fmt != mgr->toplevel &&
181  ! smartlist_contains(mgr->subconfigs, fmt),
182  "Tried to register an already-registered format.");
183 
184  /* register variables */
185  for (i = 0; fmt->vars[i].member.name; ++i) {
186  managed_var_t *mv = tor_malloc_zero(sizeof(managed_var_t));
187  mv->cvar = &fmt->vars[i];
188  mv->object_idx = object_idx;
189  smartlist_add(mgr->all_vars, mv);
190  }
191 
192  /* register abbrevs */
193  if (fmt->abbrevs) {
194  for (i = 0; fmt->abbrevs[i].abbreviated; ++i) {
195  smartlist_add(mgr->all_abbrevs, (void*)&fmt->abbrevs[i]);
196  }
197  }
198 
199  /* register deprecations. */
200  if (fmt->deprecations) {
201  const config_deprecation_t *d;
202  for (d = fmt->deprecations; d->name; ++d) {
203  smartlist_add(mgr->all_deprecations, (void*)d);
204  }
205  }
206 }
207 
208 /**
209  * Add a new format to this configuration object. Asserts on failure.
210  *
211  * Returns an internal "index" value used to identify this format within
212  * all of those formats contained in <b>mgr</b>. This index value
213  * should not generally be used outside of this module.
214  **/
215 int
217  const config_format_t *fmt)
218 {
219  tor_assert(mgr);
220  int idx = smartlist_len(mgr->subconfigs);
221  config_mgr_register_fmt(mgr, fmt, idx);
222  smartlist_add(mgr->subconfigs, (void *)fmt);
223  return idx;
224 }
225 
226 /** Return a pointer to the config_suite_t * pointer inside a
227  * configuration object; returns NULL if there is no such member. */
228 static inline config_suite_t **
229 config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel)
230 {
231  if (! mgr->toplevel->has_config_suite)
232  return NULL;
233  return STRUCT_VAR_P(toplevel, mgr->toplevel->config_suite_offset);
234 }
235 
236 /**
237  * Return a pointer to the configuration object within <b>toplevel</b> whose
238  * index is <b>idx</b>.
239  *
240  * NOTE: XXXX Eventually, there will be multiple objects supported within the
241  * toplevel object. For example, the or_options_t will contain pointers
242  * to configuration objects for other modules. This function gets
243  * the sub-object for a particular module.
244  */
245 void *
246 config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx)
247 {
248  tor_assert(mgr);
249  tor_assert(toplevel);
250  if (idx == IDX_TOPLEVEL)
251  return toplevel;
252 
253  tor_assertf(idx >= 0 && idx < smartlist_len(mgr->subconfigs),
254  "Index %d is out of range.", idx);
255  config_suite_t **suite = config_mgr_get_suite_ptr(mgr, toplevel);
256  tor_assert(suite);
257  tor_assert(smartlist_len(mgr->subconfigs) ==
258  smartlist_len((*suite)->configs));
259 
260  return smartlist_get((*suite)->configs, idx);
261 }
262 
263 /** As config_mgr_get_obj_mutable(), but return a const pointer. */
264 const void *
265 config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx)
266 {
267  return config_mgr_get_obj_mutable(mgr, (void*)toplevel, idx);
268 }
269 
270 /** Sorting helper for smartlist of managed_var_t */
271 static int
272 managed_var_cmp(const void **a, const void **b)
273 {
274  const managed_var_t *mv1 = *(const managed_var_t**)a;
275  const managed_var_t *mv2 = *(const managed_var_t**)b;
276 
277  return strcasecmp(mv1->cvar->member.name, mv2->cvar->member.name);
278 }
279 
280 /**
281  * Mark a configuration manager as "frozen", so that no more formats can be
282  * added, and so that it can be used for manipulating configuration objects.
283  **/
284 void
286 {
287  static uint64_t mgr_count = 0;
288 
290  memcpy(&mgr->toplevel_magic, &mgr->toplevel->magic,
291  sizeof(struct_magic_decl_t));
292  uint64_t magic_input[3] = { mgr->toplevel_magic.magic_val,
293  (uint64_t) (uintptr_t) mgr,
294  ++mgr_count };
296  (uint32_t)siphash24g(magic_input, sizeof(magic_input));
297  mgr->frozen = true;
298 }
299 
300 /** Release all storage held in <b>mgr</b> */
301 void
303 {
304  if (!mgr)
305  return;
306  SMARTLIST_FOREACH(mgr->all_vars, managed_var_t *, mv, managed_var_free(mv));
307  smartlist_free(mgr->all_vars);
308  smartlist_free(mgr->all_abbrevs);
309  smartlist_free(mgr->all_deprecations);
310  smartlist_free(mgr->subconfigs);
311  memset(mgr, 0, sizeof(*mgr));
312  tor_free(mgr);
313 }
314 
315 /** Return a new smartlist_t containing a config_var_t for every variable that
316  * <b>mgr</b> knows about. The elements of this smartlist do not need
317  * to be freed; they have the same lifespan as <b>mgr</b>. */
318 smartlist_t *
320 {
321  smartlist_t *result = smartlist_new();
322  tor_assert(mgr);
324  smartlist_add(result, (void*) mv->cvar));
325  return result;
326 }
327 
328 /** Return a new smartlist_t containing the names of all deprecated variables.
329  * The elements of this smartlist do not need to be freed; they have the same
330  * lifespan as <b>mgr</b>.
331  */
332 smartlist_t *
334 {
335  smartlist_t *result = smartlist_new();
336  tor_assert(mgr);
338  smartlist_add(result, (char*)d->name));
339  return result;
340 }
341 
342 /**
343  * Check the magic number on <b>object</b> to make sure it's a valid toplevel
344  * object, created with <b>mgr</b>. Exit with an assertion if it isn't.
345  **/
346 void
348  const void *object)
349 {
350  struct_check_magic(object, &mgr->toplevel_magic);
351 }
352 
353 /** Assert that the magic fields in <b>options</b> and its subsidiary
354  * objects are all okay. */
355 static void
357  const void *options)
358 {
359  tor_assert(mgr);
360  tor_assert(options);
361  tor_assert(mgr->frozen);
362  struct_check_magic(options, &mgr->toplevel_magic);
363 
364  config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, (void*)options);
365  if (suitep == NULL) {
366  tor_assert(smartlist_len(mgr->subconfigs) == 0);
367  return;
368  }
369 
370  tor_assert(smartlist_len((*suitep)->configs) ==
371  smartlist_len(mgr->subconfigs));
373  void *obj = smartlist_get((*suitep)->configs, fmt_sl_idx);
374  tor_assert(obj);
375  struct_check_magic(obj, &fmt->magic);
376  } SMARTLIST_FOREACH_END(fmt);
377 }
378 
379 /** Macro: assert that <b>cfg</b> has the right magic field for
380  * <b>mgr</b>. */
381 #define CONFIG_CHECK(mgr, cfg) STMT_BEGIN \
382  config_mgr_assert_magic_ok((mgr), (cfg)); \
383  STMT_END
384 
385 /** Allocate an empty configuration object of a given format type. */
386 void *
388 {
389  tor_assert(mgr->frozen);
390  void *opts = tor_malloc_zero(mgr->toplevel->size);
391  struct_set_magic(opts, &mgr->toplevel_magic);
392  config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, opts);
393  if (suitep) {
394  *suitep = config_suite_new();
396  void *obj = tor_malloc_zero(fmt->size);
397  struct_set_magic(obj, &fmt->magic);
398  smartlist_add((*suitep)->configs, obj);
399  } SMARTLIST_FOREACH_END(fmt);
400  }
401  CONFIG_CHECK(mgr, opts);
402  return opts;
403 }
404 
405 /*
406  * Functions to parse config options
407  */
408 
409 /** If <b>option</b> is an official abbreviation for a longer option,
410  * return the longer option. Otherwise return <b>option</b>.
411  * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
412  * apply abbreviations that work for the config file and the command line.
413  * If <b>warn_obsolete</b> is set, warn about deprecated names. */
414 const char *
415 config_expand_abbrev(const config_mgr_t *mgr, const char *option,
416  int command_line, int warn_obsolete)
417 {
418  SMARTLIST_FOREACH_BEGIN(mgr->all_abbrevs, const config_abbrev_t *, abbrev) {
419  /* Abbreviations are case insensitive. */
420  if (!strcasecmp(option, abbrev->abbreviated) &&
421  (command_line || !abbrev->commandline_only)) {
422  if (warn_obsolete && abbrev->warn) {
423  log_warn(LD_CONFIG,
424  "The configuration option '%s' is deprecated; "
425  "use '%s' instead.",
426  abbrev->abbreviated,
427  abbrev->full);
428  }
429  /* Keep going through the list in case we want to rewrite it more.
430  * (We could imagine recursing here, but I don't want to get the
431  * user into an infinite loop if we craft our list wrong.) */
432  option = abbrev->full;
433  }
434  } SMARTLIST_FOREACH_END(abbrev);
435  return option;
436 }
437 
438 /** If <b>key</b> is a deprecated configuration option, return the message
439  * explaining why it is deprecated (which may be an empty string). Return NULL
440  * if it is not deprecated. The <b>key</b> field must be fully expanded. */
441 const char *
442 config_find_deprecation(const config_mgr_t *mgr, const char *key)
443 {
444  if (BUG(mgr == NULL) || BUG(key == NULL))
445  return NULL; // LCOV_EXCL_LINE
446 
448  d) {
449  if (!strcasecmp(d->name, key)) {
450  return d->why_deprecated ? d->why_deprecated : "";
451  }
452  } SMARTLIST_FOREACH_END(d);
453  return NULL;
454 }
455 
456 /**
457  * Find the managed_var_t object for a variable whose name is <b>name</b>
458  * according to <b>mgr</b>. Return that object, or NULL if none exists.
459  *
460  * If <b>allow_truncated</b> is true, then accept any variable whose
461  * name begins with <b>name</b>.
462  *
463  * If <b>idx_out</b> is not NULL, set *<b>idx_out</b> to the position of
464  * that variable within mgr-&gt;all_vars, or to -1 if the variable is
465  * not found.
466  */
467 static const managed_var_t *
469  const char *key,
470  bool allow_truncated, int *idx_out)
471 {
472  const size_t keylen = strlen(key);
473  if (idx_out)
474  *idx_out = -1;
475 
476  if (!keylen)
477  return NULL; /* if they say "--" on the command line, it's not an option */
478 
479  /* First, check for an exact (case-insensitive) match */
480  SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
481  if (!strcasecmp(mv->cvar->member.name, key)) {
482  if (idx_out)
483  *idx_out = mv_sl_idx;
484  return mv;
485  }
486  } SMARTLIST_FOREACH_END(mv);
487 
488  if (!allow_truncated)
489  return NULL;
490 
491  /* If none, check for an abbreviated match */
492  SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
493  if (!strncasecmp(key, mv->cvar->member.name, keylen)) {
494  log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
495  "Please use '%s' instead",
496  key, mv->cvar->member.name);
497  if (idx_out)
498  *idx_out = mv_sl_idx;
499  return mv;
500  }
501  } SMARTLIST_FOREACH_END(mv);
502 
503  /* Okay, unrecognized option */
504  return NULL;
505 }
506 
507 /**
508  * If <b>key</b> is a name or an abbreviation configuration option, return
509  * the corresponding canonical name for it. Warn if the abbreviation is
510  * non-standard. Return NULL if the option does not exist.
511  */
512 const char *
513 config_find_option_name(const config_mgr_t *mgr, const char *key)
514 {
515  key = config_expand_abbrev(mgr, key, 0, 0);
516  const managed_var_t *mv = config_mgr_find_var(mgr, key, true, NULL);
517  if (mv)
518  return mv->cvar->member.name;
519  else
520  return NULL;
521 }
522 
523 /** Return the number of option entries in <b>fmt</b>. */
524 static int
526 {
527  return smartlist_len(mgr->all_vars);
528 }
529 
530 /**
531  * Return true iff at least one bit from <b>flag</b> is set on <b>var</b>,
532  * either in <b>var</b>'s flags, or on the flags of its type.
533  **/
534 static bool
535 config_var_has_flag(const config_var_t *var, uint32_t flag)
536 {
537  uint32_t have_flags = var->flags | struct_var_get_flags(&var->member);
538 
539  return (have_flags & flag) != 0;
540 }
541 
542 /**
543  * Return true if assigning a value to <b>var</b> replaces the previous
544  * value. Return false if assigning a value to <b>var</b> appends
545  * to the previous value.
546  **/
547 static bool
549 {
550  return ! config_var_has_flag(var, CFLG_NOREPLACE);
551 }
552 
553 /**
554  * Return true iff <b>var</b> may be assigned by name (e.g., via the
555  * CLI, the configuration files, or the controller API).
556  **/
557 bool
559 {
560  return ! config_var_has_flag(var, CFLG_NOSET);
561 }
562 
563 /**
564  * Return true iff the controller is allowed to fetch the value of
565  * <b>var</b>.
566  **/
567 static bool
569 {
570  /* Arguably, invisible or obsolete options should not be gettable. However,
571  * they have been gettable for a long time, and making them ungettable could
572  * have compatibility effects. For now, let's leave them alone.
573  */
574 
575  // return ! config_var_has_flag(var, CVFLAG_OBSOLETE|CFGLAGS_INVISIBLE);
576  (void)var;
577  return true;
578 }
579 
580 /**
581  * Return true iff we need to check <b>var</b> for changes when we are
582  * comparing config options for changes.
583  *
584  * A false result might mean that the variable is a derived variable, and that
585  * comparing the variable it derives from compares this one too-- or it might
586  * mean that there is no data to compare.
587  **/
588 static bool
590 {
591  return ! config_var_has_flag(var, CFLG_NOCMP);
592 }
593 
594 /**
595  * Return true iff we need to copy the data for <b>var</b> when we are
596  * copying a config option.
597  *
598  * A false option might mean that the variable is a derived variable, and that
599  * copying the variable it derives from copies it-- or it might mean that
600  * there is no data to copy.
601  **/
602 static bool
604 {
605  return ! config_var_has_flag(var, CFLG_NOCOPY);
606 }
607 
608 /**
609  * Return true iff variable <b>var</b> should appear on list of variable
610  * names given to the controller or the CLI.
611  *
612  * (Note that this option is imperfectly obeyed. The
613  * --list-torrc-options command looks at the "settable" flag, whereas
614  * "GETINFO config/defaults" and "list_deprecated_*()" do not filter
615  * their results. It would be good for consistency to try to converge
616  * these behaviors in the future.)
617  **/
618 bool
620 {
621  return ! config_var_has_flag(var, CFLG_NOLIST);
622 }
623 
624 /**
625  * Return true iff variable <b>var</b> should be written out when we
626  * are writing our configuration to disk, to a controller, or via the
627  * --dump-config command.
628  *
629  * This option may be set because a variable is hidden, or because it is
630  * derived from another variable which will already be written out.
631  **/
632 static bool
634 {
635  return ! config_var_has_flag(var, CFLG_NODUMP);
636 }
637 
638 /*
639  * Functions to assign config options.
640  */
641 
642 /** <b>c</b>->key is known to be a real key. Update <b>options</b>
643  * with <b>c</b>->value and return 0, or return -1 if bad value.
644  *
645  * Called from config_assign_line() and option_reset().
646  */
647 static int
648 config_assign_value(const config_mgr_t *mgr, void *options,
649  config_line_t *c, char **msg)
650 {
651  const managed_var_t *var;
652 
653  CONFIG_CHECK(mgr, options);
654 
655  var = config_mgr_find_var(mgr, c->key, true, NULL);
656  tor_assert(var);
657  tor_assert(!strcmp(c->key, var->cvar->member.name));
658  void *object = config_mgr_get_obj_mutable(mgr, options, var->object_idx);
659 
661  log_warn(LD_GENERAL, "Skipping obsolete configuration option \"%s\".",
662  var->cvar->member.name);
663  } else if (config_var_has_flag(var->cvar, CFLG_WARN_DISABLED)) {
664  log_warn(LD_GENERAL, "This copy of Tor was built without support for "
665  "the option \"%s\". Skipping.", var->cvar->member.name);
666  }
667 
668  return struct_var_kvassign(object, c, msg, &var->cvar->member);
669 }
670 
671 /** Mark every linelist in <b>options</b> "fragile", so that fresh assignments
672  * to it will replace old ones. */
673 static void
674 config_mark_lists_fragile(const config_mgr_t *mgr, void *options)
675 {
676  tor_assert(mgr);
677  tor_assert(options);
678 
679  SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
680  void *object = config_mgr_get_obj_mutable(mgr, options, mv->object_idx);
681  struct_var_mark_fragile(object, &mv->cvar->member);
682  } SMARTLIST_FOREACH_END(mv);
683 }
684 
685 /**
686  * Log a warning that declaring that the option called <b>what</b>
687  * is deprecated because of the reason in <b>why</b>.
688  *
689  * (Both arguments must be non-NULL.)
690  **/
691 void
692 warn_deprecated_option(const char *what, const char *why)
693 {
694  const char *space = (why && strlen(why)) ? " " : "";
695  log_warn(LD_CONFIG, "The %s option is deprecated, and will most likely "
696  "be removed in a future version of Tor.%s%s (If you think this is "
697  "a mistake, please let us know!)",
698  what, space, why);
699 }
700 
701 /** If <b>c</b> is a syntactically valid configuration line, update
702  * <b>options</b> with its value and return 0. Otherwise return -1 for bad
703  * key, -2 for bad value.
704  *
705  * If <b>clear_first</b> is set, clear the value first. Then if
706  * <b>use_defaults</b> is set, set the value to the default.
707  *
708  * Called from config_assign().
709  */
710 static int
711 config_assign_line(const config_mgr_t *mgr, void *options,
712  config_line_t *c, unsigned flags,
713  bitarray_t *options_seen, char **msg)
714 {
715  const unsigned use_defaults = flags & CAL_USE_DEFAULTS;
716  const unsigned clear_first = flags & CAL_CLEAR_FIRST;
717  const unsigned warn_deprecations = flags & CAL_WARN_DEPRECATIONS;
718  const managed_var_t *mvar;
719 
720  CONFIG_CHECK(mgr, options);
721 
722  int var_index = -1;
723  mvar = config_mgr_find_var(mgr, c->key, true, &var_index);
724  if (!mvar) {
725  const config_format_t *fmt = mgr->toplevel;
726  if (fmt->extra) {
727  void *lvalue = STRUCT_VAR_P(options, fmt->extra->offset);
728  log_info(LD_CONFIG,
729  "Found unrecognized option '%s'; saving it.", c->key);
730  config_line_append((config_line_t**)lvalue, c->key, c->value);
731  return 0;
732  } else {
733  tor_asprintf(msg,
734  "Unknown option '%s'. Failing.", c->key);
735  return -1;
736  }
737  }
738 
739  const config_var_t *cvar = mvar->cvar;
740  tor_assert(cvar);
741 
742  /* Put keyword into canonical case. */
743  if (strcmp(cvar->member.name, c->key)) {
744  tor_free(c->key);
745  c->key = tor_strdup(cvar->member.name);
746  }
747 
748  const char *deprecation_msg;
749  if (warn_deprecations &&
750  (deprecation_msg = config_find_deprecation(mgr, cvar->member.name))) {
751  warn_deprecated_option(cvar->member.name, deprecation_msg);
752  }
753 
754  if (!strlen(c->value)) {
755  /* reset or clear it, then return */
756  if (!clear_first) {
757  if (! config_var_is_replaced_on_set(cvar) &&
758  c->command != CONFIG_LINE_CLEAR) {
759  /* We got an empty linelist from the torrc or command line.
760  As a special case, call this an error. Warn and ignore. */
761  log_warn(LD_CONFIG,
762  "Linelist option '%s' has no value. Skipping.", c->key);
763  } else { /* not already cleared */
764  config_reset(mgr, options, mvar, use_defaults);
765  }
766  }
767  return 0;
768  } else if (c->command == CONFIG_LINE_CLEAR && !clear_first) {
769  // This block is unreachable, since a CLEAR line always has an
770  // empty value, and so will trigger be handled by the previous
771  // "if (!strlen(c->value))" block.
772 
773  // LCOV_EXCL_START
775  config_reset(mgr, options, mvar, use_defaults);
776  // LCOV_EXCL_STOP
777  }
778 
779  if (options_seen && config_var_is_replaced_on_set(cvar)) {
780  /* We're tracking which options we've seen, and this option is not
781  * supposed to occur more than once. */
782  tor_assert(var_index >= 0);
783  if (bitarray_is_set(options_seen, var_index)) {
784  log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
785  "value will be ignored.", cvar->member.name);
786  }
787  bitarray_set(options_seen, var_index);
788  }
789 
790  if (config_assign_value(mgr, options, c, msg) < 0)
791  return -2;
792  return 0;
793 }
794 
795 /** Restore the option named <b>key</b> in options to its default value.
796  * Called from config_assign(). */
797 STATIC void
798 config_reset_line(const config_mgr_t *mgr, void *options,
799  const char *key, int use_defaults)
800 {
801  const managed_var_t *var;
802 
803  CONFIG_CHECK(mgr, options);
804 
805  var = config_mgr_find_var(mgr, key, true, NULL);
806  if (!var)
807  return; /* give error on next pass. */
808 
809  config_reset(mgr, options, var, use_defaults);
810 }
811 
812 /** Return true iff value needs to be quoted and escaped to be used in
813  * a configuration file. */
814 static int
815 config_value_needs_escape(const char *value)
816 {
817  if (*value == '\"')
818  return 1;
819  while (*value) {
820  switch (*value)
821  {
822  case '\r':
823  case '\n':
824  case '#':
825  /* Note: quotes and backspaces need special handling when we are using
826  * quotes, not otherwise, so they don't trigger escaping on their
827  * own. */
828  return 1;
829  default:
830  if (!TOR_ISPRINT(*value))
831  return 1;
832  }
833  ++value;
834  }
835  return 0;
836 }
837 
838 /** Return newly allocated line or lines corresponding to <b>key</b> in the
839  * configuration <b>options</b>. If <b>escape_val</b> is true and a
840  * value needs to be quoted before it's put in a config file, quote and
841  * escape that value. Return NULL if no such key exists. */
843 config_get_assigned_option(const config_mgr_t *mgr, const void *options,
844  const char *key, int escape_val)
845 {
846  const managed_var_t *var;
847  config_line_t *result;
848 
849  tor_assert(options && key);
850 
851  CONFIG_CHECK(mgr, options);
852 
853  var = config_mgr_find_var(mgr, key, true, NULL);
854  if (!var) {
855  log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
856  return NULL;
857  }
858  if (! config_var_is_gettable(var->cvar)) {
859  log_warn(LD_CONFIG, "Option '%s' is obsolete or unfetchable. Failing.",
860  key);
861  return NULL;
862  }
863  const void *object = config_mgr_get_obj(mgr, options, var->object_idx);
864 
865  result = struct_var_kvencode(object, &var->cvar->member);
866 
867  if (escape_val) {
868  config_line_t *line;
869  for (line = result; line; line = line->next) {
870  if (line->value && config_value_needs_escape(line->value)) {
871  char *newval = esc_for_log(line->value);
872  tor_free(line->value);
873  line->value = newval;
874  }
875  }
876  }
877 
878  return result;
879 }
880 /** Iterate through the linked list of requested options <b>list</b>.
881  * For each item, convert as appropriate and assign to <b>options</b>.
882  * If an item is unrecognized, set *msg and return -1 immediately,
883  * else return 0 for success.
884  *
885  * If <b>clear_first</b>, interpret config options as replacing (not
886  * extending) their previous values. If <b>clear_first</b> is set,
887  * then <b>use_defaults</b> to decide if you set to defaults after
888  * clearing, or make the value 0 or NULL.
889  *
890  * Here are the use cases:
891  * 1. A non-empty AllowInvalid line in your torrc. Appends to current
892  * if linelist, replaces current if csv.
893  * 2. An empty AllowInvalid line in your torrc. Should clear it.
894  * 3. "RESETCONF AllowInvalid" sets it to default.
895  * 4. "SETCONF AllowInvalid" makes it NULL.
896  * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
897  *
898  * Use_defaults Clear_first
899  * 0 0 "append"
900  * 1 0 undefined, don't use
901  * 0 1 "set to null first"
902  * 1 1 "set to defaults first"
903  * Return 0 on success, -1 on bad key, -2 on bad value.
904  *
905  * As an additional special case, if a LINELIST config option has
906  * no value and clear_first is 0, then warn and ignore it.
907  */
908 
909 /*
910 There are three call cases for config_assign() currently.
911 
912 Case one: Torrc entry
913 options_init_from_torrc() calls config_assign(0, 0)
914  calls config_assign_line(0, 0).
915  if value is empty, calls config_reset(0) and returns.
916  calls config_assign_value(), appends.
917 
918 Case two: setconf
919 options_trial_assign() calls config_assign(0, 1)
920  calls config_reset_line(0)
921  calls config_reset(0)
922  calls option_clear().
923  calls config_assign_line(0, 1).
924  if value is empty, returns.
925  calls config_assign_value(), appends.
926 
927 Case three: resetconf
928 options_trial_assign() calls config_assign(1, 1)
929  calls config_reset_line(1)
930  calls config_reset(1)
931  calls option_clear().
932  calls config_assign_value(default)
933  calls config_assign_line(1, 1).
934  returns.
935 */
936 int
937 config_assign(const config_mgr_t *mgr, void *options, config_line_t *list,
938  unsigned config_assign_flags, char **msg)
939 {
940  config_line_t *p;
941  bitarray_t *options_seen;
942  const int n_options = config_count_options(mgr);
943  const unsigned clear_first = config_assign_flags & CAL_CLEAR_FIRST;
944  const unsigned use_defaults = config_assign_flags & CAL_USE_DEFAULTS;
945 
946  CONFIG_CHECK(mgr, options);
947 
948  /* pass 1: normalize keys */
949  for (p = list; p; p = p->next) {
950  const char *full = config_expand_abbrev(mgr, p->key, 0, 1);
951  if (strcmp(full,p->key)) {
952  tor_free(p->key);
953  p->key = tor_strdup(full);
954  }
955  }
956 
957  /* pass 2: if we're reading from a resetting source, clear all
958  * mentioned config options, and maybe set to their defaults. */
959  if (clear_first) {
960  for (p = list; p; p = p->next)
961  config_reset_line(mgr, options, p->key, use_defaults);
962  }
963 
964  options_seen = bitarray_init_zero(n_options);
965  /* pass 3: assign. */
966  while (list) {
967  int r;
968  if ((r=config_assign_line(mgr, options, list, config_assign_flags,
969  options_seen, msg))) {
970  bitarray_free(options_seen);
971  return r;
972  }
973  list = list->next;
974  }
975  bitarray_free(options_seen);
976 
977  /** Now we're done assigning a group of options to the configuration.
978  * Subsequent group assignments should _replace_ linelists, not extend
979  * them. */
980  config_mark_lists_fragile(mgr, options);
981 
982  return 0;
983 }
984 
985 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
986  * Called from config_reset() and config_free(). */
987 static void
988 config_clear(const config_mgr_t *mgr, void *options, const managed_var_t *var)
989 {
990  void *object = config_mgr_get_obj_mutable(mgr, options, var->object_idx);
991  struct_var_free(object, &var->cvar->member);
992 }
993 
994 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
995  * <b>use_defaults</b>, set it to its default value.
996  * Called by config_init() and option_reset_line() and option_assign_line(). */
997 static void
998 config_reset(const config_mgr_t *mgr, void *options,
999  const managed_var_t *var, int use_defaults)
1000 {
1001  config_line_t *c;
1002  char *msg = NULL;
1003  CONFIG_CHECK(mgr, options);
1004  config_clear(mgr, options, var); /* clear it first */
1005 
1006  if (!use_defaults)
1007  return; /* all done */
1008 
1009  if (var->cvar->initvalue) {
1010  c = tor_malloc_zero(sizeof(config_line_t));
1011  c->key = tor_strdup(var->cvar->member.name);
1012  c->value = tor_strdup(var->cvar->initvalue);
1013  if (config_assign_value(mgr, options, c, &msg) < 0) {
1014  // LCOV_EXCL_START
1015  log_warn(LD_BUG, "Failed to assign default: %s", msg);
1016  tor_free(msg); /* if this happens it's a bug */
1017  // LCOV_EXCL_STOP
1018  }
1019  config_free_lines(c);
1020  }
1021 }
1022 
1023 /** Release storage held by <b>options</b>. */
1024 void
1025 config_free_(const config_mgr_t *mgr, void *options)
1026 {
1027  if (!options)
1028  return;
1029 
1030  tor_assert(mgr);
1031 
1032  if (mgr->toplevel->clear_fn) {
1033  mgr->toplevel->clear_fn(mgr, options);
1034  }
1035  config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, options);
1036  if (suitep) {
1037  tor_assert(smartlist_len((*suitep)->configs) ==
1038  smartlist_len(mgr->subconfigs));
1039  SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
1040  void *obj = smartlist_get((*suitep)->configs, fmt_sl_idx);
1041  if (fmt->clear_fn) {
1042  fmt->clear_fn(mgr, obj);
1043  }
1044  } SMARTLIST_FOREACH_END(fmt);
1045  }
1046 
1047  SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
1048  config_clear(mgr, options, mv);
1049  } SMARTLIST_FOREACH_END(mv);
1050 
1051  if (mgr->toplevel->extra) {
1052  config_line_t **linep = STRUCT_VAR_P(options,
1053  mgr->toplevel->extra->offset);
1054  config_free_lines(*linep);
1055  *linep = NULL;
1056  }
1057 
1058  if (suitep) {
1059  SMARTLIST_FOREACH((*suitep)->configs, void *, obj, tor_free(obj));
1060  config_suite_free(*suitep);
1061  }
1062 
1063  tor_free(options);
1064 }
1065 
1066 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
1067  * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
1068  */
1069 int
1071  const void *o1, const void *o2,
1072  const char *name)
1073 {
1074  CONFIG_CHECK(mgr, o1);
1075  CONFIG_CHECK(mgr, o2);
1076 
1077  const managed_var_t *var = config_mgr_find_var(mgr, name, true, NULL);
1078  if (!var) {
1079  return true;
1080  }
1081  const void *obj1 = config_mgr_get_obj(mgr, o1, var->object_idx);
1082  const void *obj2 = config_mgr_get_obj(mgr, o2, var->object_idx);
1083 
1084  return struct_var_eq(obj1, obj2, &var->cvar->member);
1085 }
1086 
1087 /**
1088  * Return a list of the options which have changed between <b>options1</b> and
1089  * <b>options2</b>. If an option has reverted to its default value, it has a
1090  * value entry of NULL.
1091  *
1092  * <b>options1</b> and <b>options2</b> must be top-level configuration objects
1093  * of the type managed by <b>mgr</b>.
1094  **/
1095 config_line_t *
1097  const void *options1, const void *options2)
1098 {
1099  config_line_t *result = NULL;
1100  config_line_t **next = &result;
1102  if (! config_var_should_list_changes(mv->cvar)) {
1103  /* something else will check this var, or it doesn't need checking */
1104  continue;
1105  }
1106  const void *obj1 = config_mgr_get_obj(mgr, options1, mv->object_idx);
1107  const void *obj2 = config_mgr_get_obj(mgr, options2, mv->object_idx);
1108 
1109  if (struct_var_eq(obj1, obj2, &mv->cvar->member)) {
1110  continue;
1111  }
1112 
1113  const char *varname = mv->cvar->member.name;
1114  config_line_t *line =
1115  config_get_assigned_option(mgr, options2, varname, 1);
1116 
1117  if (line) {
1118  *next = line;
1119  } else {
1120  *next = tor_malloc_zero(sizeof(config_line_t));
1121  (*next)->key = tor_strdup(varname);
1122  }
1123  while (*next)
1124  next = &(*next)->next;
1125  } SMARTLIST_FOREACH_END(mv);
1126 
1127  return result;
1128 }
1129 
1130 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
1131 void *
1132 config_dup(const config_mgr_t *mgr, const void *old)
1133 {
1134  void *newopts;
1135 
1136  newopts = config_new(mgr);
1138  if (! config_var_needs_copy(mv->cvar)) {
1139  // Something else will copy this option, or it doesn't need copying.
1140  continue;
1141  }
1142  const void *oldobj = config_mgr_get_obj(mgr, old, mv->object_idx);
1143  void *newobj = config_mgr_get_obj_mutable(mgr, newopts, mv->object_idx);
1144  if (struct_var_copy(newobj, oldobj, &mv->cvar->member) < 0) {
1145  // LCOV_EXCL_START
1146  log_err(LD_BUG, "Unable to copy value for %s.",
1147  mv->cvar->member.name);
1148  tor_assert_unreached();
1149  // LCOV_EXCL_STOP
1150  }
1151  } SMARTLIST_FOREACH_END(mv);
1152 
1153  return newopts;
1154 }
1155 /** Set all vars in the configuration object <b>options</b> to their default
1156  * values. */
1157 void
1158 config_init(const config_mgr_t *mgr, void *options)
1159 {
1160  CONFIG_CHECK(mgr, options);
1161 
1162  SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
1163  if (!mv->cvar->initvalue)
1164  continue; /* defaults to NULL or 0 */
1165  config_reset(mgr, options, mv, 1);
1166  } SMARTLIST_FOREACH_END(mv);
1167 }
1168 
1169 /**
1170  * Helper for config_validate_single: see whether any immutable option
1171  * has changed between old_options and new_options.
1172  *
1173  * On success return 0; on failure set *msg_out to a newly allocated
1174  * string explaining what is wrong, and return -1.
1175  */
1176 static int
1178  const void *old_options,
1179  const void *new_options,
1180  char **msg_out)
1181 {
1182  tor_assert(fmt);
1183  tor_assert(new_options);
1184  if (BUG(! old_options))
1185  return 0;
1186 
1187  unsigned i;
1188  for (i = 0; fmt->vars[i].member.name; ++i) {
1189  const config_var_t *v = &fmt->vars[i];
1191  continue;
1192 
1193  if (! struct_var_eq(old_options, new_options, &v->member)) {
1194  tor_asprintf(msg_out,
1195  "While Tor is running, changing %s is not allowed",
1196  v->member.name);
1197  return -1;
1198  }
1199  }
1200 
1201  return 0;
1202 }
1203 
1204 /**
1205  * Normalize and validate a single object `options` within a configuration
1206  * suite, according to its format. `options` may be modified as appropriate
1207  * in order to set ancillary data. If `old_options` is provided, make sure
1208  * that the transition from `old_options` to `options` is permitted.
1209  *
1210  * On success return VSTAT_OK; on failure set *msg_out to a newly allocated
1211  * string explaining what is wrong, and return a different validation_status_t
1212  * to describe which step failed.
1213  **/
1214 static validation_status_t
1216  const void *old_options, void *options,
1217  char **msg_out)
1218 {
1219  tor_assert(fmt);
1220  tor_assert(options);
1221 
1222  if (fmt->pre_normalize_fn) {
1223  if (fmt->pre_normalize_fn(options, msg_out) < 0) {
1224  return VSTAT_PRE_NORMALIZE_ERR;
1225  }
1226  }
1227 
1228  if (fmt->legacy_validate_fn) {
1229  if (fmt->legacy_validate_fn(old_options, options, msg_out) < 0) {
1230  return VSTAT_LEGACY_ERR;
1231  }
1232  }
1233 
1234  if (fmt->validate_fn) {
1235  if (fmt->validate_fn(options, msg_out) < 0) {
1236  return VSTAT_VALIDATE_ERR;
1237  }
1238  }
1239 
1240  if (old_options) {
1241  if (config_check_immutable_flags(fmt, old_options, options, msg_out) < 0) {
1242  return VSTAT_TRANSITION_ERR;
1243  }
1244 
1245  if (fmt->check_transition_fn) {
1246  if (fmt->check_transition_fn(old_options, options, msg_out) < 0) {
1247  return VSTAT_TRANSITION_ERR;
1248  }
1249  }
1250  }
1251 
1252  if (fmt->post_normalize_fn) {
1253  if (fmt->post_normalize_fn(options, msg_out) < 0) {
1254  return VSTAT_POST_NORMALIZE_ERR;
1255  }
1256  }
1257 
1258  return VSTAT_OK;
1259 }
1260 
1261 /**
1262  * Normalize and validate all the options in configuration object `options`
1263  * and its sub-objects. `options` may be modified as appropriate in order to
1264  * set ancillary data. If `old_options` is provided, make sure that the
1265  * transition from `old_options` to `options` is permitted.
1266  *
1267  * On success return VSTAT_OK; on failure set *msg_out to a newly allocated
1268  * string explaining what is wrong, and return a different validation_status_t
1269  * to describe which step failed.
1270  **/
1273  const void *old_options, void *options,
1274  char **msg_out)
1275 {
1277  CONFIG_CHECK(mgr, options);
1278  if (old_options) {
1279  CONFIG_CHECK(mgr, old_options);
1280  }
1281 
1282  config_suite_t **suitep_new = config_mgr_get_suite_ptr(mgr, options);
1283  config_suite_t **suitep_old = NULL;
1284  if (old_options)
1285  suitep_old = config_mgr_get_suite_ptr(mgr, (void*) old_options);
1286 
1287  /* Validate the sub-objects */
1288  if (suitep_new) {
1289  SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
1290  void *obj = smartlist_get((*suitep_new)->configs, fmt_sl_idx);
1291  const void *obj_old=NULL;
1292  if (suitep_old)
1293  obj_old = smartlist_get((*suitep_old)->configs, fmt_sl_idx);
1294 
1295  rv = config_validate_single(fmt, obj_old, obj, msg_out);
1296  if (rv < 0)
1297  return rv;
1298  } SMARTLIST_FOREACH_END(fmt);
1299  }
1300 
1301  /* Validate the top-level object. */
1302  rv = config_validate_single(mgr->toplevel, old_options, options, msg_out);
1303  if (rv < 0)
1304  return rv;
1305 
1306  return VSTAT_OK;
1307 }
1308 
1309 /** Allocate and return a new string holding the written-out values of the vars
1310  * in 'options'. If 'minimal', do not write out any default-valued vars.
1311  * Else, if comment_defaults, write default values as comments.
1312  */
1313 char *
1314 config_dump(const config_mgr_t *mgr, const void *default_options,
1315  const void *options, int minimal,
1316  int comment_defaults)
1317 {
1318  const config_format_t *fmt = mgr->toplevel;
1319  smartlist_t *elements;
1320  const void *defaults = default_options;
1321  void *defaults_tmp = NULL;
1322  config_line_t *line, *assigned;
1323  char *result;
1324  char *msg = NULL;
1325 
1326  if (defaults == NULL) {
1327  defaults = defaults_tmp = config_new(mgr);
1328  config_init(mgr, defaults_tmp);
1329  }
1330 
1331  /* XXX use a 1 here so we don't add a new log line while dumping */
1332  if (default_options == NULL) {
1333  if (config_validate(mgr, NULL, defaults_tmp, &msg) < 0) {
1334  // LCOV_EXCL_START
1335  log_err(LD_BUG, "Failed to validate default config: %s", msg);
1336  tor_free(msg);
1337  tor_assert(0);
1338  // LCOV_EXCL_STOP
1339  }
1340  }
1341 
1342  elements = smartlist_new();
1344  int comment_option = 0;
1345  /* Don't save 'hidden' control variables. */
1346  if (! config_var_is_dumpable(mv->cvar))
1347  continue;
1348  const char *name = mv->cvar->member.name;
1349  if (minimal && config_is_same(mgr, options, defaults, name))
1350  continue;
1351  else if (comment_defaults &&
1352  config_is_same(mgr, options, defaults, name))
1353  comment_option = 1;
1354 
1355  line = assigned =
1356  config_get_assigned_option(mgr, options, name, 1);
1357 
1358  for (; line; line = line->next) {
1359  if (!strcmpstart(line->key, "__")) {
1360  /* This check detects "hidden" variables inside LINELIST_V structures.
1361  */
1362  continue;
1363  }
1364  int value_exists = line->value && *(line->value);
1365  smartlist_add_asprintf(elements, "%s%s%s%s\n",
1366  comment_option ? "# " : "",
1367  line->key, value_exists ? " " : "", line->value);
1368  }
1369  config_free_lines(assigned);
1370  } SMARTLIST_FOREACH_END(mv);
1371 
1372  if (fmt->extra) {
1373  line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->offset);
1374  for (; line; line = line->next) {
1375  int value_exists = line->value && *(line->value);
1376  smartlist_add_asprintf(elements, "%s%s%s\n",
1377  line->key, value_exists ? " " : "", line->value);
1378  }
1379  }
1380 
1381  result = smartlist_join_strings(elements, "", 0, NULL);
1382  SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
1383  smartlist_free(elements);
1384  config_free(mgr, defaults_tmp);
1385  return result;
1386 }
1387 
1388 /**
1389  * Return true if every member of <b>options</b> is in-range and well-formed.
1390  * Return false otherwise. Log errors at level <b>severity</b>.
1391  */
1392 bool
1393 config_check_ok(const config_mgr_t *mgr, const void *options, int severity)
1394 {
1395  bool all_ok = true;
1396 
1397  SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
1398  if (!struct_var_ok(options, &mv->cvar->member)) {
1399  log_fn(severity, LD_BUG, "Invalid value for %s",
1400  mv->cvar->member.name);
1401  all_ok = false;
1402  }
1403  } SMARTLIST_FOREACH_END(mv);
1404 
1405  return all_ok;
1406 }
Implements a variable-sized (but non-resizeable) bit-array.
unsigned int bitarray_t
Definition: bitarray.h:30
static void bitarray_set(bitarray_t *b, int bit)
Definition: bitarray.h:68
static unsigned int bitarray_is_set(bitarray_t *b, int bit)
Definition: bitarray.h:81
static bitarray_t * bitarray_init_zero(unsigned int n_bits)
Definition: bitarray.h:33
#define STRUCT_VAR_P(st, off)
Locale-independent character-type inspection (header)
const char * name
Definition: config.c:2434
void config_line_append(config_line_t **lst, const char *key, const char *val)
Definition: confline.c:32
Header for confline.c.
static void config_clear(const config_mgr_t *mgr, void *options, const managed_var_t *var)
Definition: confmgt.c:988
static config_suite_t ** config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel)
Definition: confmgt.c:229
const char * config_find_deprecation(const config_mgr_t *mgr, const char *key)
Definition: confmgt.c:442
static void config_mgr_register_fmt(config_mgr_t *mgr, const config_format_t *fmt, int object_idx)
Definition: confmgt.c:161
void config_init(const config_mgr_t *mgr, void *options)
Definition: confmgt.c:1158
static bool config_var_needs_copy(const config_var_t *var)
Definition: confmgt.c:603
static bool config_var_has_flag(const config_var_t *var, uint32_t flag)
Definition: confmgt.c:535
static int config_count_options(const config_mgr_t *mgr)
Definition: confmgt.c:525
static int config_check_immutable_flags(const config_format_t *fmt, const void *old_options, const void *new_options, char **msg_out)
Definition: confmgt.c:1177
void config_mgr_freeze(config_mgr_t *mgr)
Definition: confmgt.c:285
void warn_deprecated_option(const char *what, const char *why)
Definition: confmgt.c:692
char * config_dump(const config_mgr_t *mgr, const void *default_options, const void *options, int minimal, int comment_defaults)
Definition: confmgt.c:1314
bool config_var_is_listable(const config_var_t *var)
Definition: confmgt.c:619
static int managed_var_cmp(const void **a, const void **b)
Definition: confmgt.c:272
static int config_assign_line(const config_mgr_t *mgr, void *options, config_line_t *c, unsigned flags, bitarray_t *options_seen, char **msg)
Definition: confmgt.c:711
bool config_check_ok(const config_mgr_t *mgr, const void *options, int severity)
Definition: confmgt.c:1393
void config_free_(const config_mgr_t *mgr, void *options)
Definition: confmgt.c:1025
void * config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx)
Definition: confmgt.c:246
static int config_assign_value(const config_mgr_t *mgr, void *options, config_line_t *c, char **msg)
Definition: confmgt.c:648
int config_is_same(const config_mgr_t *mgr, const void *o1, const void *o2, const char *name)
Definition: confmgt.c:1070
void config_check_toplevel_magic(const config_mgr_t *mgr, const void *object)
Definition: confmgt.c:347
config_line_t * config_get_assigned_option(const config_mgr_t *mgr, const void *options, const char *key, int escape_val)
Definition: confmgt.c:843
static bool config_var_is_replaced_on_set(const config_var_t *var)
Definition: confmgt.c:548
static void config_reset(const config_mgr_t *fmt, void *options, const managed_var_t *var, int use_defaults)
Definition: confmgt.c:998
const void * config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx)
Definition: confmgt.c:265
config_line_t * config_get_changes(const config_mgr_t *mgr, const void *options1, const void *options2)
Definition: confmgt.c:1096
bool config_var_is_settable(const config_var_t *var)
Definition: confmgt.c:558
static void managed_var_free_(managed_var_t *mv)
Definition: confmgt.c:66
static void config_mgr_assert_magic_ok(const config_mgr_t *mgr, const void *options)
Definition: confmgt.c:356
static bool config_var_should_list_changes(const config_var_t *var)
Definition: confmgt.c:589
static void config_mark_lists_fragile(const config_mgr_t *mgr, void *options)
Definition: confmgt.c:674
static void config_suite_free_(config_suite_t *suite)
Definition: confmgt.c:96
void * config_new(const config_mgr_t *mgr)
Definition: confmgt.c:387
static int config_value_needs_escape(const char *value)
Definition: confmgt.c:815
config_mgr_t * config_mgr_new(const config_format_t *toplevel_fmt)
Definition: confmgt.c:145
const char * config_expand_abbrev(const config_mgr_t *mgr, const char *option, int command_line, int warn_obsolete)
Definition: confmgt.c:415
static config_suite_t * config_suite_new(void)
Definition: confmgt.c:86
const char * config_find_option_name(const config_mgr_t *mgr, const char *key)
Definition: confmgt.c:513
validation_status_t config_validate(const config_mgr_t *mgr, const void *old_options, void *options, char **msg_out)
Definition: confmgt.c:1272
int config_assign(const config_mgr_t *mgr, void *options, config_line_t *list, unsigned config_assign_flags, char **msg)
Definition: confmgt.c:937
static bool config_var_is_dumpable(const config_var_t *var)
Definition: confmgt.c:633
static bool config_var_is_gettable(const config_var_t *var)
Definition: confmgt.c:568
static const managed_var_t * config_mgr_find_var(const config_mgr_t *mgr, const char *key, bool allow_truncated, int *idx_out)
Definition: confmgt.c:468
static validation_status_t config_validate_single(const config_format_t *fmt, const void *old_options, void *options, char **msg_out)
Definition: confmgt.c:1215
STATIC void config_reset_line(const config_mgr_t *mgr, void *options, const char *key, int use_defaults)
Definition: confmgt.c:798
void * config_dup(const config_mgr_t *mgr, const void *old)
Definition: confmgt.c:1132
#define CONFIG_CHECK(mgr, cfg)
Definition: confmgt.c:381
smartlist_t * config_mgr_list_deprecated_vars(const config_mgr_t *mgr)
Definition: confmgt.c:333
smartlist_t * config_mgr_list_vars(const config_mgr_t *mgr)
Definition: confmgt.c:319
void config_mgr_free_(config_mgr_t *mgr)
Definition: confmgt.c:302
int config_mgr_add_format(config_mgr_t *mgr, const config_format_t *fmt)
Definition: confmgt.c:216
Header for confmgt.c.
#define CAL_WARN_DEPRECATIONS
Definition: confmgt.h:63
validation_status_t
Definition: confmgt.h:83
#define CAL_USE_DEFAULTS
Definition: confmgt.h:50
#define CAL_CLEAR_FIRST
Definition: confmgt.h:59
#define CFLG_IMMUTABLE
Definition: conftypes.h:199
#define CFLG_NODUMP
Definition: conftypes.h:154
#define CFLG_WARN_DISABLED
Definition: conftypes.h:209
#define CFLG_NOCMP
Definition: conftypes.h:186
#define CFLG_WARN_OBSOLETE
Definition: conftypes.h:204
#define CFLG_NOCOPY
Definition: conftypes.h:176
#define CFLG_NOREPLACE
Definition: conftypes.h:194
#define CFLG_NOSET
Definition: conftypes.h:167
#define CFLG_NOLIST
Definition: conftypes.h:161
char * esc_for_log(const char *s)
Definition: escape.c:30
Header for escape.c.
Headers for log.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:283
#define LD_BUG
Definition: log.h:86
#define LD_GENERAL
Definition: log.h:62
#define LD_CONFIG
Definition: log.h:68
#define tor_free(p)
Definition: malloc.h:52
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Header for printf.c.
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition: smartlist.c:36
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
Definition: smartlist.c:334
Header for smartlist.c.
smartlist_t * smartlist_new(void)
int smartlist_contains(const smartlist_t *sl, const void *element)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
const char * name
Definition: conftypes.h:258
const struct_member_t * extra
Definition: conftypes.h:371
ptrdiff_t config_suite_offset
Definition: conftypes.h:380
bool has_config_suite
Definition: conftypes.h:376
struct_magic_decl_t magic
Definition: conftypes.h:349
clear_cfg_fn_t clear_fn
Definition: conftypes.h:368
unsigned int command
Definition: confline.h:35
smartlist_t * subconfigs
Definition: confmgt.c:119
smartlist_t * all_deprecations
Definition: confmgt.c:127
smartlist_t * all_abbrevs
Definition: confmgt.c:125
const config_format_t * toplevel
Definition: confmgt.c:114
bool frozen
Definition: confmgt.c:131
struct_magic_decl_t toplevel_magic
Definition: confmgt.c:137
smartlist_t * all_vars
Definition: confmgt.c:121
smartlist_t * configs
Definition: confmgt.c:79
const char * initvalue
Definition: conftypes.h:229
uint32_t flags
Definition: conftypes.h:230
int object_idx
Definition: confmgt.c:55
const config_var_t * cvar
Definition: confmgt.c:50
uint32_t magic_val
Definition: conftypes.h:142
ptrdiff_t offset
Definition: conftypes.h:125
const char * name
Definition: conftypes.h:98
void struct_set_magic(void *object, const struct_magic_decl_t *decl)
Definition: structvar.c:48
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
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
struct config_line_t * struct_var_kvencode(const void *object, const struct_member_t *member)
Definition: structvar.c:187
uint32_t struct_var_get_flags(const struct_member_t *member)
Definition: structvar.c:234
Header for lib/confmgt/structvar.c.
#define STATIC
Definition: testsupport.h:32
Header for lib/confmgt/unitparse.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:176
#define tor_assert(expr)
Definition: util_bug.h:102
int strcmpstart(const char *s1, const char *s2)
Definition: util_string.c:215
Header for util_string.c.