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