confparse.c 38 KB

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