Tor  0.4.7.0-alpha-dev
type_defs.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 type_defs.c
9  * @brief Definitions for various low-level configuration types.
10  *
11  * This module creates a number of var_type_def_t objects, to be used by
12  * typedvar.c in manipulating variables.
13  *
14  * The types here are common types that can be implemented with Tor's
15  * low-level functionality. To define new types, see var_type_def_st.h.
16  **/
17 
18 #include "orconfig.h"
19 #include "lib/conf/conftypes.h"
20 #include "lib/conf/confdecl.h"
21 #include "lib/confmgt/typedvar.h"
22 #include "lib/confmgt/type_defs.h"
23 #include "lib/confmgt/unitparse.h"
24 
25 #include "lib/cc/compat_compiler.h"
27 #include "lib/encoding/confline.h"
28 #include "lib/encoding/time_fmt.h"
29 #include "lib/log/escape.h"
30 #include "lib/log/log.h"
31 #include "lib/log/util_bug.h"
32 #include "lib/malloc/malloc.h"
33 #include "lib/string/parse_int.h"
34 #include "lib/string/printf.h"
35 
37 
38 #include <stddef.h>
39 #include <string.h>
40 #include <errno.h>
41 
42 //////
43 // CONFIG_TYPE_STRING
44 // CONFIG_TYPE_FILENAME
45 //
46 // These two types are the same for now, but they have different names.
47 //
48 // Warning: For this type, the default value (NULL) and "" are considered
49 // different values. That is generally risky, and best avoided for other
50 // types in the future.
51 //////
52 
53 static int
54 string_parse(void *target, const char *value, char **errmsg,
55  const void *params)
56 {
57  (void)params;
58  (void)errmsg;
59  char **p = (char**)target;
60  *p = tor_strdup(value);
61  return 0;
62 }
63 
64 static char *
65 string_encode(const void *value, const void *params)
66 {
67  (void)params;
68  const char **p = (const char**)value;
69  return *p ? tor_strdup(*p) : NULL;
70 }
71 
72 static void
73 string_clear(void *value, const void *params)
74 {
75  (void)params;
76  char **p = (char**)value;
77  tor_free(*p); // sets *p to NULL.
78 }
79 
80 static const var_type_fns_t string_fns = {
81  .parse = string_parse,
82  .encode = string_encode,
83  .clear = string_clear,
84 };
85 
86 /////
87 // CONFIG_TYPE_INT
88 // CONFIG_TYPE_POSINT
89 //
90 // These types are implemented as int, possibly with a restricted range.
91 /////
92 
93 /**
94  * Parameters for parsing an integer type.
95  **/
96 typedef struct int_type_params_t {
97  int minval; /**< Lowest allowed value */
98  int maxval; /**< Highest allowed value */
100 
101 static const int_parse_params_t INT_PARSE_UNRESTRICTED = {
102  .minval = INT_MIN,
103  .maxval = INT_MAX,
104 };
105 
106 static const int_parse_params_t INT_PARSE_POSINT = {
107  .minval = 0,
108  .maxval = INT_MAX,
109 };
110 
111 static int
112 int_parse(void *target, const char *value, char **errmsg, const void *params)
113 {
114  const int_parse_params_t *pp;
115  if (params) {
116  pp = params;
117  } else {
118  pp = &INT_PARSE_UNRESTRICTED;
119  }
120  int *p = target;
121  int ok=0;
122  *p = (int)tor_parse_long(value, 10, pp->minval, pp->maxval, &ok, NULL);
123  if (!ok) {
124  tor_asprintf(errmsg, "Integer %s is malformed or out of bounds. "
125  "Allowed values are between %d and %d.",
126  value, pp->minval, pp->maxval);
127  return -1;
128  }
129  return 0;
130 }
131 
132 static char *
133 int_encode(const void *value, const void *params)
134 {
135  (void)params;
136  int v = *(int*)value;
137  char *result;
138  tor_asprintf(&result, "%d", v);
139  return result;
140 }
141 
142 static void
143 int_clear(void *value, const void *params)
144 {
145  (void)params;
146  *(int*)value = 0;
147 }
148 
149 static bool
150 int_ok(const void *value, const void *params)
151 {
152  const int_parse_params_t *pp = params;
153  if (pp) {
154  int v = *(int*)value;
155  return pp->minval <= v && v <= pp->maxval;
156  } else {
157  return true;
158  }
159 }
160 
161 static const var_type_fns_t int_fns = {
162  .parse = int_parse,
163  .encode = int_encode,
164  .clear = int_clear,
165  .ok = int_ok,
166 };
167 
168 /////
169 // CONFIG_TYPE_UINT64
170 //
171 // This type is an unrestricted u64.
172 /////
173 
174 static int
175 uint64_parse(void *target, const char *value, char **errmsg,
176  const void *params)
177 {
178  (void)params;
179  (void)errmsg;
180  uint64_t *p = target;
181  int ok=0;
182  *p = tor_parse_uint64(value, 10, 0, UINT64_MAX, &ok, NULL);
183  if (!ok) {
184  tor_asprintf(errmsg, "Integer %s is malformed or out of bounds.",
185  value);
186  return -1;
187  }
188  return 0;
189 }
190 
191 static char *
192 uint64_encode(const void *value, const void *params)
193 {
194  (void)params;
195  uint64_t v = *(uint64_t*)value;
196  char *result;
197  tor_asprintf(&result, "%"PRIu64, v);
198  return result;
199 }
200 
201 static void
202 uint64_clear(void *value, const void *params)
203 {
204  (void)params;
205  *(uint64_t*)value = 0;
206 }
207 
208 static const var_type_fns_t uint64_fns = {
209  .parse = uint64_parse,
210  .encode = uint64_encode,
211  .clear = uint64_clear,
212 };
213 
214 /////
215 // CONFIG_TYPE_INTERVAL
216 // CONFIG_TYPE_MSEC_INTERVAL
217 // CONFIG_TYPE_MEMUNIT
218 //
219 // These types are implemented using the config_parse_units() function.
220 // The intervals are stored as ints, whereas memory units are stored as
221 // uint64_ts.
222 /////
223 
224 static int
225 units_parse_u64(void *target, const char *value, char **errmsg,
226  const void *params)
227 {
228  const unit_table_t *table = params;
229  tor_assert(table);
230  uint64_t *v = (uint64_t*)target;
231  int ok=1;
232  char *msg = NULL;
233  *v = config_parse_units(value, table, &ok, &msg);
234  if (!ok) {
235  tor_asprintf(errmsg, "Provided value is malformed or out of bounds: %s",
236  msg);
237  tor_free(msg);
238  return -1;
239  }
240  if (BUG(msg)) {
241  tor_free(msg);
242  }
243  return 0;
244 }
245 
246 static int
247 units_parse_int(void *target, const char *value, char **errmsg,
248  const void *params)
249 {
250  const unit_table_t *table = params;
251  tor_assert(table);
252  int *v = (int*)target;
253  int ok=1;
254  char *msg = NULL;
255  uint64_t u64 = config_parse_units(value, table, &ok, &msg);
256  if (!ok) {
257  tor_asprintf(errmsg, "Provided value is malformed or out of bounds: %s",
258  msg);
259  tor_free(msg);
260  return -1;
261  }
262  if (BUG(msg)) {
263  tor_free(msg);
264  }
265  if (u64 > INT_MAX) {
266  tor_asprintf(errmsg, "Provided value %s is too large", value);
267  return -1;
268  }
269  *v = (int) u64;
270  return 0;
271 }
272 
273 static bool
274 units_ok_int(const void *value, const void *params)
275 {
276  (void)params;
277  int v = *(int*)value;
278  return v >= 0;
279 }
280 
281 static const var_type_fns_t memunit_fns = {
282  .parse = units_parse_u64,
283  .encode = uint64_encode, // doesn't use params
284  .clear = uint64_clear, // doesn't use params
285 };
286 
287 static const var_type_fns_t interval_fns = {
288  .parse = units_parse_int,
289  .encode = int_encode, // doesn't use params
290  .clear = int_clear, // doesn't use params,
291  .ok = units_ok_int // can't use int_ok, since that expects int params.
292 };
293 
294 /////
295 // CONFIG_TYPE_DOUBLE
296 //
297 // This is a nice simple double.
298 /////
299 
300 static int
301 double_parse(void *target, const char *value, char **errmsg,
302  const void *params)
303 {
304  (void)params;
305  (void)errmsg;
306  double *v = (double*)target;
307  char *endptr=NULL;
308  errno = 0;
309  *v = strtod(value, &endptr);
310  if (endptr == value || *endptr != '\0') {
311  // Either there are no converted characters, or there were some characters
312  // that didn't get converted.
313  tor_asprintf(errmsg, "Could not convert %s to a number.", escaped(value));
314  return -1;
315  }
316  if (errno == ERANGE) {
317  // strtod will set errno to ERANGE on underflow or overflow.
318  bool underflow = -.00001 < *v && *v < .00001;
319  tor_asprintf(errmsg,
320  "%s is too %s to express as a floating-point number.",
321  escaped(value), underflow ? "small" : "large");
322  return -1;
323  }
324  return 0;
325 }
326 
327 static char *
328 double_encode(const void *value, const void *params)
329 {
330  (void)params;
331  double v = *(double*)value;
332  char *result;
333  tor_asprintf(&result, "%f", v);
334  return result;
335 }
336 
337 static void
338 double_clear(void *value, const void *params)
339 {
340  (void)params;
341  double *v = (double *)value;
342  *v = 0.0;
343 }
344 
345 static const var_type_fns_t double_fns = {
346  .parse = double_parse,
347  .encode = double_encode,
348  .clear = double_clear,
349 };
350 
351 /////
352 // CONFIG_TYPE_BOOL
353 // CONFIG_TYPE_AUTOBOOL
354 //
355 // These types are implemented as a case-insensitive string-to-integer
356 // mapping.
357 /////
358 
359 typedef struct enumeration_table_t {
360  const char *name;
361  int value;
363 
364 typedef struct enumeration_params_t {
365  const char *allowed_val_string;
366  const enumeration_table_t *table;
368 
369 static int
370 enum_parse(void *target, const char *value, char **errmsg,
371  const void *params_)
372 {
373  const enumeration_params_t *params = params_;
374  const enumeration_table_t *table = params->table;
375  int *p = (int *)target;
376  for (; table->name; ++table) {
377  if (!strcasecmp(value, table->name)) {
378  *p = table->value;
379  return 0;
380  }
381  }
382  tor_asprintf(errmsg, "Unrecognized value %s. %s",
383  value, params->allowed_val_string);
384  return -1;
385 }
386 
387 static char *
388 enum_encode(const void *value, const void *params_)
389 {
390  int v = *(const int*)value;
391  const enumeration_params_t *params = params_;
392  const enumeration_table_t *table = params->table;
393  for (; table->name; ++table) {
394  if (v == table->value)
395  return tor_strdup(table->name);
396  }
397  return NULL; // error.
398 }
399 
400 static void
401 enum_clear(void *value, const void *params_)
402 {
403  int *p = (int*)value;
404  const enumeration_params_t *params = params_;
405  const enumeration_table_t *table = params->table;
406  tor_assert(table->name);
407  *p = table->value;
408 }
409 
410 static bool
411 enum_ok(const void *value, const void *params_)
412 {
413  int v = *(const int*)value;
414  const enumeration_params_t *params = params_;
415  const enumeration_table_t *table = params->table;
416  for (; table->name; ++table) {
417  if (v == table->value)
418  return true;
419  }
420  return false;
421 }
422 
423 static const enumeration_table_t enum_table_bool[] = {
424  { "0", 0 },
425  { "1", 1 },
426  { NULL, 0 },
427 };
428 
429 static const enumeration_params_t enum_params_bool = {
430  "Allowed values are 0 and 1.",
431  enum_table_bool
432 };
433 
434 static const enumeration_table_t enum_table_autobool[] = {
435  { "0", 0 },
436  { "1", 1 },
437  { "auto", -1 },
438  { NULL, 0 },
439 };
440 
441 static const enumeration_params_t enum_params_autobool = {
442  "Allowed values are 0, 1, and auto.",
443  enum_table_autobool
444 };
445 
446 static const var_type_fns_t enum_fns = {
447  .parse = enum_parse,
448  .encode = enum_encode,
449  .clear = enum_clear,
450  .ok = enum_ok,
451 };
452 
453 /////
454 // CONFIG_TYPE_ISOTIME
455 //
456 // This is a time_t, encoded in ISO8601 format.
457 /////
458 
459 static int
460 time_parse(void *target, const char *value, char **errmsg,
461  const void *params)
462 {
463  (void) params;
464  time_t *p = target;
465  if (parse_iso_time(value, p) < 0) {
466  tor_asprintf(errmsg, "Invalid time %s", escaped(value));
467  return -1;
468  }
469  return 0;
470 }
471 
472 static char *
473 time_encode(const void *value, const void *params)
474 {
475  (void)params;
476  time_t v = *(const time_t *)value;
477  char *result = tor_malloc(ISO_TIME_LEN+1);
478  format_iso_time(result, v);
479  return result;
480 }
481 
482 static void
483 time_clear(void *value, const void *params)
484 {
485  (void)params;
486  time_t *t = value;
487  *t = 0;
488 }
489 
490 static const var_type_fns_t time_fns = {
491  .parse = time_parse,
492  .encode = time_encode,
493  .clear = time_clear,
494 };
495 
496 /////
497 // CONFIG_TYPE_CSV
498 //
499 // This type is a comma-separated list of strings, stored in a smartlist_t.
500 // An empty list may be encoded either as an empty smartlist, or as NULL.
501 /////
502 
503 static int
504 csv_parse(void *target, const char *value, char **errmsg,
505  const void *params)
506 {
507  (void)params;
508  (void)errmsg;
509  smartlist_t **sl = (smartlist_t**)target;
510  *sl = smartlist_new();
511  smartlist_split_string(*sl, value, ",",
512  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
513  return 0;
514 }
515 
516 static char *
517 csv_encode(const void *value, const void *params)
518 {
519  (void)params;
520  const smartlist_t *sl = *(const smartlist_t **)value;
521  if (! sl)
522  return tor_strdup("");
523 
524  return smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
525 }
526 
527 static void
528 csv_clear(void *value, const void *params)
529 {
530  (void)params;
531  smartlist_t **sl = (smartlist_t**)value;
532  if (!*sl)
533  return;
534  SMARTLIST_FOREACH(*sl, char *, cp, tor_free(cp));
535  smartlist_free(*sl); // clears pointer.
536 }
537 
538 static const var_type_fns_t csv_fns = {
539  .parse = csv_parse,
540  .encode = csv_encode,
541  .clear = csv_clear,
542 };
543 
544 /////
545 // CONFIG_TYPE_CSV_INTERVAL
546 //
547 // This type used to be a list of time intervals, used to determine a download
548 // schedule. Now, only the first interval counts: everything after the first
549 // comma is discarded.
550 /////
551 
552 static int
553 legacy_csv_interval_parse(void *target, const char *value, char **errmsg,
554  const void *params)
555 {
556  (void)params;
557  /* We used to have entire smartlists here. But now that all of our
558  * download schedules use exponential backoff, only the first part
559  * matters. */
560  const char *comma = strchr(value, ',');
561  const char *val = value;
562  char *tmp = NULL;
563  if (comma) {
564  tmp = tor_strndup(val, comma - val);
565  val = tmp;
566  }
567 
568  int rv = units_parse_int(target, val, errmsg, &time_units);
569  tor_free(tmp);
570  return rv;
571 }
572 
573 static const var_type_fns_t legacy_csv_interval_fns = {
574  .parse = legacy_csv_interval_parse,
575  .encode = int_encode,
576  .clear = int_clear,
577 };
578 
579 /////
580 // CONFIG_TYPE_LINELIST
581 // CONFIG_TYPE_LINELIST_S
582 // CONFIG_TYPE_LINELIST_V
583 //
584 // A linelist is a raw config_line_t list. Order is preserved.
585 //
586 // The LINELIST type is used for homogeneous lists, where all the lines
587 // have the same key.
588 //
589 // The LINELIST_S and LINELIST_V types are used for the case where multiple
590 // lines of different keys are kept in a single list, to preserve their
591 // relative order. The unified list is stored as a "virtual" variable whose
592 // type is LINELIST_V; the individual sublists are treated as variables of
593 // type LINELIST_S.
594 //
595 // A linelist may be fragile or non-fragile. Assigning a line to a fragile
596 // linelist replaces the list with the line. If the line has the "APPEND"
597 // command set on it, or if the list is non-fragile, the line is appended.
598 // Either way, the new list is non-fragile.
599 /////
600 
601 static int
602 linelist_kv_parse(void *target, const struct config_line_t *line,
603  char **errmsg, const void *params)
604 {
605  (void)params;
606  (void)errmsg;
607  config_line_t **lines = target;
608 
609  if (*lines && (*lines)->fragile) {
610  if (line->command == CONFIG_LINE_APPEND) {
611  (*lines)->fragile = 0;
612  } else {
613  config_free_lines(*lines); // sets it to NULL
614  }
615  }
616 
617  config_line_append(lines, line->key, line->value);
618  return 0;
619 }
620 
621 static int
622 linelist_kv_virt_noparse(void *target, const struct config_line_t *line,
623  char **errmsg, const void *params)
624 {
625  (void)target;
626  (void)line;
627  (void)params;
628  *errmsg = tor_strdup("Cannot assign directly to virtual option.");
629  return -1;
630 }
631 
632 static struct config_line_t *
633 linelist_kv_encode(const char *key, const void *value,
634  const void *params)
635 {
636  (void)key;
637  (void)params;
638  config_line_t *lines = *(config_line_t **)value;
639  return config_lines_dup(lines);
640 }
641 
642 static struct config_line_t *
643 linelist_s_kv_encode(const char *key, const void *value,
644  const void *params)
645 {
646  (void)params;
647  config_line_t *lines = *(config_line_t **)value;
648  return config_lines_dup_and_filter(lines, key);
649 }
650 
651 static void
652 linelist_clear(void *target, const void *params)
653 {
654  (void)params;
655  config_line_t **lines = target;
656  config_free_lines(*lines); // sets it to NULL
657 }
658 
659 static bool
660 linelist_eq(const void *a, const void *b, const void *params)
661 {
662  (void)params;
663  const config_line_t *lines_a = *(const config_line_t **)a;
664  const config_line_t *lines_b = *(const config_line_t **)b;
665  return config_lines_eq(lines_a, lines_b);
666 }
667 
668 static int
669 linelist_copy(void *target, const void *value, const void *params)
670 {
671  (void)params;
672  config_line_t **ptr = (config_line_t **)target;
673  const config_line_t *val = *(const config_line_t **)value;
674  config_free_lines(*ptr);
675  *ptr = config_lines_dup(val);
676  return 0;
677 }
678 
679 static void
680 linelist_mark_fragile(void *target, const void *params)
681 {
682  (void)params;
683  config_line_t **ptr = (config_line_t **)target;
684  if (*ptr)
685  (*ptr)->fragile = 1;
686 }
687 
688 static const var_type_fns_t linelist_fns = {
689  .kv_parse = linelist_kv_parse,
690  .kv_encode = linelist_kv_encode,
691  .clear = linelist_clear,
692  .eq = linelist_eq,
693  .copy = linelist_copy,
694  .mark_fragile = linelist_mark_fragile,
695 };
696 
697 static const var_type_fns_t linelist_v_fns = {
698  .kv_parse = linelist_kv_virt_noparse,
699  .kv_encode = linelist_kv_encode,
700  .clear = linelist_clear,
701  .eq = linelist_eq,
702  .copy = linelist_copy,
703  .mark_fragile = linelist_mark_fragile,
704 };
705 
706 static const var_type_fns_t linelist_s_fns = {
707  .kv_parse = linelist_kv_parse,
708  .kv_encode = linelist_s_kv_encode,
709  .clear = linelist_clear,
710  .eq = linelist_eq,
711  .copy = linelist_copy,
712 };
713 
714 /////
715 // CONFIG_TYPE_ROUTERSET
716 //
717 // XXXX to this module.
718 /////
719 
720 /////
721 // CONFIG_TYPE_IGNORE
722 //
723 // Used to indicate an option that cannot be stored or encoded.
724 /////
725 
726 static int
727 ignore_parse(void *target, const char *value, char **errmsg,
728  const void *params)
729 {
730  (void)target;
731  (void)value;
732  (void)errmsg;
733  (void)params;
734  return 0;
735 }
736 
737 static char *
738 ignore_encode(const void *value, const void *params)
739 {
740  (void)value;
741  (void)params;
742  return NULL;
743 }
744 
745 static const var_type_fns_t ignore_fns = {
746  .parse = ignore_parse,
747  .encode = ignore_encode,
748 };
749 
750 const var_type_def_t STRING_type_defn = {
751  .name="String", .fns=&string_fns };
752 const var_type_def_t FILENAME_type_defn = {
753  .name="Filename", .fns=&string_fns };
754 const var_type_def_t INT_type_defn = {
755  .name="SignedInteger", .fns=&int_fns,
756  .params=&INT_PARSE_UNRESTRICTED };
757 const var_type_def_t POSINT_type_defn = {
758  .name="Integer", .fns=&int_fns,
759  .params=&INT_PARSE_POSINT };
760 const var_type_def_t UINT64_type_defn = {
761  .name="Integer", .fns=&uint64_fns, };
762 const var_type_def_t MEMUNIT_type_defn = {
763  .name="DataSize", .fns=&memunit_fns,
764  .params=&memory_units };
765 const var_type_def_t INTERVAL_type_defn = {
766  .name="TimeInterval", .fns=&interval_fns,
767  .params=&time_units };
768 const var_type_def_t MSEC_INTERVAL_type_defn = {
769  .name="TimeMsecInterval",
770  .fns=&interval_fns,
771  .params=&time_msec_units };
772 const var_type_def_t DOUBLE_type_defn = {
773  .name="Float", .fns=&double_fns, };
774 const var_type_def_t BOOL_type_defn = {
775  .name="Boolean", .fns=&enum_fns,
776  .params=&enum_params_bool };
777 const var_type_def_t AUTOBOOL_type_defn = {
778  .name="Boolean+Auto", .fns=&enum_fns,
779  .params=&enum_params_autobool };
780 const var_type_def_t ISOTIME_type_defn = {
781  .name="Time", .fns=&time_fns, };
782 const var_type_def_t CSV_type_defn = {
783  .name="CommaList", .fns=&csv_fns, };
784 const var_type_def_t CSV_INTERVAL_type_defn = {
785  .name="TimeInterval",
786  .fns=&legacy_csv_interval_fns, };
787 const var_type_def_t LINELIST_type_defn = {
788  .name="LineList", .fns=&linelist_fns,
789  .flags=CFLG_NOREPLACE };
790 /*
791  * A "linelist_s" is a derived view of a linelist_v: inspecting
792  * it gets part of a linelist_v, and setting it adds to the linelist_v.
793  */
794 const var_type_def_t LINELIST_S_type_defn = {
795  .name="Dependent", .fns=&linelist_s_fns,
796  .flags=CFLG_NOREPLACE|
797  /* The operations we disable here are
798  * handled by the linelist_v. */
800 const var_type_def_t LINELIST_V_type_defn = {
801  .name="Virtual", .fns=&linelist_v_fns,
802  .flags=CFLG_NOREPLACE|CFLG_NOSET };
803 const var_type_def_t IGNORE_type_defn = {
804  .name="Ignored", .fns=&ignore_fns,
806 };
807 const var_type_def_t OBSOLETE_type_defn = {
808  .name="Obsolete", .fns=&ignore_fns,
809  .flags=CFLG_GROUP_OBSOLETE,
810 };
811 
812 /**
813  * Table mapping conf_type_t values to var_type_def_t objects.
814  **/
816  [CONFIG_TYPE_STRING] = &STRING_type_defn,
817  [CONFIG_TYPE_FILENAME] = &FILENAME_type_defn,
818  [CONFIG_TYPE_INT] = &INT_type_defn,
819  [CONFIG_TYPE_POSINT] = &POSINT_type_defn,
820  [CONFIG_TYPE_UINT64] = &UINT64_type_defn,
821  [CONFIG_TYPE_MEMUNIT] = &MEMUNIT_type_defn,
822  [CONFIG_TYPE_INTERVAL] = &INTERVAL_type_defn,
823  [CONFIG_TYPE_MSEC_INTERVAL] = &MSEC_INTERVAL_type_defn,
824  [CONFIG_TYPE_DOUBLE] = &DOUBLE_type_defn,
825  [CONFIG_TYPE_BOOL] = &BOOL_type_defn,
826  [CONFIG_TYPE_AUTOBOOL] = &AUTOBOOL_type_defn,
827  [CONFIG_TYPE_ISOTIME] = &ISOTIME_type_defn,
828  [CONFIG_TYPE_CSV] = &CSV_type_defn,
829  [CONFIG_TYPE_CSV_INTERVAL] = &CSV_INTERVAL_type_defn,
830  [CONFIG_TYPE_LINELIST] = &LINELIST_type_defn,
831  [CONFIG_TYPE_LINELIST_S] = &LINELIST_S_type_defn,
832  [CONFIG_TYPE_LINELIST_V] = &LINELIST_V_type_defn,
833  [CONFIG_TYPE_IGNORE] = &IGNORE_type_defn,
834  [CONFIG_TYPE_OBSOLETE] = &OBSOLETE_type_defn,
835 };
836 
837 /**
838  * Return a pointer to the var_type_def_t object for the given
839  * config_type_t value, or NULL if no such type definition exists.
840  **/
841 const var_type_def_t *
843 {
844  int t = type;
845  tor_assert(t >= 0);
846  if (t >= (int)ARRAY_LENGTH(type_definitions_table))
847  return NULL;
848  return type_definitions_table[t];
849 }
Utility macros to handle different features and behavior in different compilers.
#define ARRAY_LENGTH(x)
Macros for generating a configuration struct from a list of its individual fields.
config_line_t * config_lines_dup_and_filter(const config_line_t *inp, const char *key)
Definition: confline.c:235
config_line_t * config_lines_dup(const config_line_t *inp)
Definition: confline.c:226
void config_line_append(config_line_t **lst, const char *key, const char *val)
Definition: confline.c:32
int config_lines_eq(const config_line_t *a, const config_line_t *b)
Definition: confline.c:287
Header for confline.c.
#define CONFIG_LINE_APPEND
Definition: confline.h:22
Types used to specify configurable options.
config_type_t
Definition: conftypes.h:39
@ CONFIG_TYPE_AUTOBOOL
Definition: conftypes.h:51
@ CONFIG_TYPE_ISOTIME
Definition: conftypes.h:53
@ CONFIG_TYPE_CSV_INTERVAL
Definition: conftypes.h:56
@ CONFIG_TYPE_LINELIST_V
Definition: conftypes.h:64
@ CONFIG_TYPE_CSV
Definition: conftypes.h:54
@ CONFIG_TYPE_LINELIST_S
Definition: conftypes.h:62
@ CONFIG_TYPE_DOUBLE
Definition: conftypes.h:49
@ CONFIG_TYPE_IGNORE
Definition: conftypes.h:77
@ CONFIG_TYPE_INTERVAL
Definition: conftypes.h:45
@ CONFIG_TYPE_MSEC_INTERVAL
Definition: conftypes.h:46
@ CONFIG_TYPE_INT
Definition: conftypes.h:43
@ CONFIG_TYPE_FILENAME
Definition: conftypes.h:41
@ CONFIG_TYPE_MEMUNIT
Definition: conftypes.h:48
@ CONFIG_TYPE_STRING
Definition: conftypes.h:40
@ CONFIG_TYPE_OBSOLETE
Definition: conftypes.h:71
@ CONFIG_TYPE_UINT64
Definition: conftypes.h:44
@ CONFIG_TYPE_BOOL
Definition: conftypes.h:50
@ CONFIG_TYPE_POSINT
Definition: conftypes.h:42
@ CONFIG_TYPE_LINELIST
Definition: conftypes.h:61
#define CFLG_GROUP_OBSOLETE
Definition: conftypes.h:214
#define CFLG_NODUMP
Definition: conftypes.h:154
#define CFLG_NOCMP
Definition: conftypes.h:186
#define CFLG_NOCOPY
Definition: conftypes.h:176
#define CFLG_NOREPLACE
Definition: conftypes.h:194
#define CFLG_NOSET
Definition: conftypes.h:167
const char * escaped(const char *s)
Definition: escape.c:126
Header for escape.c.
Headers for log.c.
Headers for util_malloc.c.
#define tor_free(p)
Definition: malloc.h:52
uint64_t tor_parse_uint64(const char *s, int base, uint64_t min, uint64_t max, int *ok, char **next)
Definition: parse_int.c:110
long tor_parse_long(const char *s, int base, long min, long max, int *ok, char **next)
Definition: parse_int.c:59
Header for parse_int.c.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
Header for printf.c.
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
Header for smartlist.c.
smartlist_t * smartlist_new(void)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)
unsigned int command
Definition: confline.h:35
unsigned int fragile
Definition: confline.h:39
const char * name
int(* parse)(void *target, const char *value, char **errmsg, const void *params)
int(* kv_parse)(void *target, const struct config_line_t *line, char **errmsg, const void *params)
int parse_iso_time(const char *cp, time_t *t)
Definition: time_fmt.c:392
void format_iso_time(char *buf, time_t t)
Definition: time_fmt.c:295
Header for time_fmt.c.
static const var_type_def_t * type_definitions_table[]
Definition: type_defs.c:815
const var_type_def_t * lookup_type_def(config_type_t type)
Definition: type_defs.c:842
Header for lib/confmgt/type_defs.c.
Header for lib/confmgt/typedvar.c.
const struct unit_table_t time_units[]
Definition: unitparse.c:76
const struct unit_table_t time_msec_units[]
Definition: unitparse.c:97
const struct unit_table_t memory_units[]
Definition: unitparse.c:27
uint64_t config_parse_units(const char *val, const unit_table_t *u, int *ok, char **errmsg_out)
Definition: unitparse.c:127
Header for lib/confmgt/unitparse.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102
Structure declarations for typedvar type definitions.