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-2013, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
11 static uint64_t config_parse_memunit(const char *s
, int *ok
);
12 static int config_parse_msec_interval(const char *s
, int *ok
);
13 static int config_parse_interval(const char *s
, int *ok
);
14 static void config_reset(const config_format_t
*fmt
, void *options
,
15 const config_var_t
*var
, int use_defaults
);
17 /** Allocate an empty configuration object of a given format type. */
19 config_new(const config_format_t
*fmt
)
21 void *opts
= tor_malloc_zero(fmt
->size
);
22 *(uint32_t*)STRUCT_VAR_P(opts
, fmt
->magic_offset
) = fmt
->magic
;
23 CONFIG_CHECK(fmt
, opts
);
28 * Functions to parse config options
31 /** If <b>option</b> is an official abbreviation for a longer option,
32 * return the longer option. Otherwise return <b>option</b>.
33 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
34 * apply abbreviations that work for the config file and the command line.
35 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
37 config_expand_abbrev(const config_format_t
*fmt
, const char *option
,
38 int command_line
, int warn_obsolete
)
43 for (i
=0; fmt
->abbrevs
[i
].abbreviated
; ++i
) {
44 /* Abbreviations are case insensitive. */
45 if (!strcasecmp(option
,fmt
->abbrevs
[i
].abbreviated
) &&
46 (command_line
|| !fmt
->abbrevs
[i
].commandline_only
)) {
47 if (warn_obsolete
&& fmt
->abbrevs
[i
].warn
) {
49 "The configuration option '%s' is deprecated; "
51 fmt
->abbrevs
[i
].abbreviated
,
52 fmt
->abbrevs
[i
].full
);
54 /* Keep going through the list in case we want to rewrite it more.
55 * (We could imagine recursing here, but I don't want to get the
56 * user into an infinite loop if we craft our list wrong.) */
57 option
= fmt
->abbrevs
[i
].full
;
63 /** Helper: allocate a new configuration option mapping 'key' to 'val',
64 * append it to *<b>lst</b>. */
66 config_line_append(config_line_t
**lst
,
70 config_line_t
*newline
;
72 newline
= tor_malloc_zero(sizeof(config_line_t
));
73 newline
->key
= tor_strdup(key
);
74 newline
->value
= tor_strdup(val
);
77 lst
= &((*lst
)->next
);
82 /** Return the line in <b>lines</b> whose key is exactly <b>key</b>, or NULL
83 * if no such key exists. For handling commandline-only options only; other
84 * options should be looked up in the appropriate data structure. */
86 config_line_find(const config_line_t
*lines
,
89 const config_line_t
*cl
;
90 for (cl
= lines
; cl
; cl
= cl
->next
) {
91 if (!strcmp(cl
->key
, key
))
97 /** Helper: parse the config string and strdup into key/value
98 * strings. Set *result to the list, or NULL if parsing the string
99 * failed. Return 0 on success, -1 on failure. Warn and ignore any
100 * misformatted lines.
102 * If <b>extended</b> is set, then treat keys beginning with / and with + as
103 * indicating "clear" and "append" respectively. */
105 config_get_lines(const char *string
, config_line_t
**result
, int extended
)
107 config_line_t
*list
= NULL
, **next
;
109 const char *parse_err
;
114 string
= parse_config_line_from_str_verbose(string
, &k
, &v
, &parse_err
);
116 log_warn(LD_CONFIG
, "Error while parsing configuration: %s",
117 parse_err
?parse_err
:"<unknown>");
118 config_free_lines(list
);
124 unsigned command
= CONFIG_LINE_NORMAL
;
127 char *k_new
= tor_strdup(k
+1);
130 command
= CONFIG_LINE_APPEND
;
131 } else if (k
[0] == '/') {
132 char *k_new
= tor_strdup(k
+1);
137 command
= CONFIG_LINE_CLEAR
;
140 /* This list can get long, so we keep a pointer to the end of it
141 * rather than using config_line_append over and over and getting
142 * n^2 performance. */
143 *next
= tor_malloc_zero(sizeof(config_line_t
));
146 (*next
)->next
= NULL
;
147 (*next
)->command
= command
;
148 next
= &((*next
)->next
);
160 * Free all the configuration lines on the linked list <b>front</b>.
163 config_free_lines(config_line_t
*front
)
172 tor_free(tmp
->value
);
177 /** As config_find_option, but return a non-const pointer. */
179 config_find_option_mutable(config_format_t
*fmt
, const char *key
)
182 size_t keylen
= strlen(key
);
184 return NULL
; /* if they say "--" on the command line, it's not an option */
185 /* First, check for an exact (case-insensitive) match */
186 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
187 if (!strcasecmp(key
, fmt
->vars
[i
].name
)) {
188 return &fmt
->vars
[i
];
191 /* If none, check for an abbreviated match */
192 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
193 if (!strncasecmp(key
, fmt
->vars
[i
].name
, keylen
)) {
194 log_warn(LD_CONFIG
, "The abbreviation '%s' is deprecated. "
195 "Please use '%s' instead",
196 key
, fmt
->vars
[i
].name
);
197 return &fmt
->vars
[i
];
200 /* Okay, unrecognized option */
204 /** If <b>key</b> is a configuration option, return the corresponding const
205 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
206 * warn, and return the corresponding const config_var_t. Otherwise return
210 config_find_option(const config_format_t
*fmt
, const char *key
)
212 return config_find_option_mutable((config_format_t
*)fmt
, key
);
215 /** Return the number of option entries in <b>fmt</b>. */
217 config_count_options(const config_format_t
*fmt
)
220 for (i
=0; fmt
->vars
[i
].name
; ++i
)
226 * Functions to assign config options.
229 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
230 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
232 * Called from config_assign_line() and option_reset().
235 config_assign_value(const config_format_t
*fmt
, void *options
,
236 config_line_t
*c
, char **msg
)
239 const config_var_t
*var
;
242 smartlist_t
*csv_str
;
244 CONFIG_CHECK(fmt
, options
);
246 var
= config_find_option(fmt
, c
->key
);
249 lvalue
= STRUCT_VAR_P(options
, var
->var_offset
);
253 case CONFIG_TYPE_PORT
:
254 if (!strcasecmp(c
->value
, "auto")) {
255 *(int *)lvalue
= CFG_AUTO_PORT
;
259 case CONFIG_TYPE_INT
:
260 case CONFIG_TYPE_UINT
:
261 i
= (int)tor_parse_long(c
->value
, 10,
262 var
->type
==CONFIG_TYPE_INT
? INT_MIN
: 0,
263 var
->type
==CONFIG_TYPE_PORT
? 65535 : INT_MAX
,
267 "Int keyword '%s %s' is malformed or out of bounds.",
274 case CONFIG_TYPE_INTERVAL
: {
275 i
= config_parse_interval(c
->value
, &ok
);
278 "Interval '%s %s' is malformed or out of bounds.",
286 case CONFIG_TYPE_MSEC_INTERVAL
: {
287 i
= config_parse_msec_interval(c
->value
, &ok
);
290 "Msec interval '%s %s' is malformed or out of bounds.",
298 case CONFIG_TYPE_MEMUNIT
: {
299 uint64_t u64
= config_parse_memunit(c
->value
, &ok
);
302 "Value '%s %s' is malformed or out of bounds.",
306 *(uint64_t *)lvalue
= u64
;
310 case CONFIG_TYPE_BOOL
:
311 i
= (int)tor_parse_long(c
->value
, 10, 0, 1, &ok
, NULL
);
314 "Boolean '%s %s' expects 0 or 1.",
321 case CONFIG_TYPE_AUTOBOOL
:
322 if (!strcmp(c
->value
, "auto"))
324 else if (!strcmp(c
->value
, "0"))
326 else if (!strcmp(c
->value
, "1"))
329 tor_asprintf(msg
, "Boolean '%s %s' expects 0, 1, or 'auto'.",
335 case CONFIG_TYPE_STRING
:
336 case CONFIG_TYPE_FILENAME
:
337 tor_free(*(char **)lvalue
);
338 *(char **)lvalue
= tor_strdup(c
->value
);
341 case CONFIG_TYPE_DOUBLE
:
342 *(double *)lvalue
= atof(c
->value
);
345 case CONFIG_TYPE_ISOTIME
:
346 if (parse_iso_time(c
->value
, (time_t *)lvalue
)) {
348 "Invalid time '%s' for keyword '%s'", c
->value
, c
->key
);
353 case CONFIG_TYPE_ROUTERSET
:
354 if (*(routerset_t
**)lvalue
) {
355 routerset_free(*(routerset_t
**)lvalue
);
357 *(routerset_t
**)lvalue
= routerset_new();
358 if (routerset_parse(*(routerset_t
**)lvalue
, c
->value
, c
->key
)<0) {
359 tor_asprintf(msg
, "Invalid exit list '%s' for option '%s'",
365 case CONFIG_TYPE_CSV
:
366 if (*(smartlist_t
**)lvalue
) {
367 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, char *, cp
, tor_free(cp
));
368 smartlist_clear(*(smartlist_t
**)lvalue
);
370 *(smartlist_t
**)lvalue
= smartlist_new();
373 smartlist_split_string(*(smartlist_t
**)lvalue
, c
->value
, ",",
374 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
377 case CONFIG_TYPE_CSV_INTERVAL
:
378 if (*(smartlist_t
**)lvalue
) {
379 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, int *, cp
, tor_free(cp
));
380 smartlist_clear(*(smartlist_t
**)lvalue
);
382 *(smartlist_t
**)lvalue
= smartlist_new();
384 csv_str
= smartlist_new();
385 smartlist_split_string(csv_str
, c
->value
, ",",
386 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
387 SMARTLIST_FOREACH_BEGIN(csv_str
, char *, str
)
389 i
= config_parse_interval(str
, &ok
);
392 "Interval in '%s %s' is malformed or out of bounds.",
394 SMARTLIST_FOREACH(csv_str
, char *, cp
, tor_free(cp
));
395 smartlist_free(csv_str
);
398 csv_int
= tor_malloc_zero(sizeof(int));
400 smartlist_add(*(smartlist_t
**)lvalue
, csv_int
);
402 SMARTLIST_FOREACH_END(str
);
403 SMARTLIST_FOREACH(csv_str
, char *, cp
, tor_free(cp
));
404 smartlist_free(csv_str
);
407 case CONFIG_TYPE_LINELIST
:
408 case CONFIG_TYPE_LINELIST_S
:
410 config_line_t
*lastval
= *(config_line_t
**)lvalue
;
411 if (lastval
&& lastval
->fragile
) {
412 if (c
->command
!= CONFIG_LINE_APPEND
) {
413 config_free_lines(lastval
);
414 *(config_line_t
**)lvalue
= NULL
;
416 lastval
->fragile
= 0;
420 config_line_append((config_line_t
**)lvalue
, c
->key
, c
->value
);
423 case CONFIG_TYPE_OBSOLETE
:
424 log_warn(LD_CONFIG
, "Skipping obsolete configuration option '%s'", c
->key
);
426 case CONFIG_TYPE_LINELIST_V
:
428 "You may not provide a value for virtual option '%s'", c
->key
);
437 /** Mark every linelist in <b>options</b> "fragile", so that fresh assignments
438 * to it will replace old ones. */
440 config_mark_lists_fragile(const config_format_t
*fmt
, void *options
)
446 for (i
= 0; fmt
->vars
[i
].name
; ++i
) {
447 const config_var_t
*var
= &fmt
->vars
[i
];
449 if (var
->type
!= CONFIG_TYPE_LINELIST
&&
450 var
->type
!= CONFIG_TYPE_LINELIST_V
)
453 list
= *(config_line_t
**)STRUCT_VAR_P(options
, var
->var_offset
);
459 /** If <b>c</b> is a syntactically valid configuration line, update
460 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
461 * key, -2 for bad value.
463 * If <b>clear_first</b> is set, clear the value first. Then if
464 * <b>use_defaults</b> is set, set the value to the default.
466 * Called from config_assign().
469 config_assign_line(const config_format_t
*fmt
, void *options
,
470 config_line_t
*c
, int use_defaults
,
471 int clear_first
, bitarray_t
*options_seen
, char **msg
)
473 const config_var_t
*var
;
475 CONFIG_CHECK(fmt
, options
);
477 var
= config_find_option(fmt
, c
->key
);
480 void *lvalue
= STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
482 "Found unrecognized option '%s'; saving it.", c
->key
);
483 config_line_append((config_line_t
**)lvalue
, c
->key
, c
->value
);
487 "Unknown option '%s'. Failing.", c
->key
);
492 /* Put keyword into canonical case. */
493 if (strcmp(var
->name
, c
->key
)) {
495 c
->key
= tor_strdup(var
->name
);
498 if (!strlen(c
->value
)) {
499 /* reset or clear it, then return */
501 if ((var
->type
== CONFIG_TYPE_LINELIST
||
502 var
->type
== CONFIG_TYPE_LINELIST_S
) &&
503 c
->command
!= CONFIG_LINE_CLEAR
) {
504 /* We got an empty linelist from the torrc or command line.
505 As a special case, call this an error. Warn and ignore. */
507 "Linelist option '%s' has no value. Skipping.", c
->key
);
508 } else { /* not already cleared */
509 config_reset(fmt
, options
, var
, use_defaults
);
513 } else if (c
->command
== CONFIG_LINE_CLEAR
&& !clear_first
) {
514 config_reset(fmt
, options
, var
, use_defaults
);
517 if (options_seen
&& (var
->type
!= CONFIG_TYPE_LINELIST
&&
518 var
->type
!= CONFIG_TYPE_LINELIST_S
)) {
519 /* We're tracking which options we've seen, and this option is not
520 * supposed to occur more than once. */
521 int var_index
= (int)(var
- fmt
->vars
);
522 if (bitarray_is_set(options_seen
, var_index
)) {
523 log_warn(LD_CONFIG
, "Option '%s' used more than once; all but the last "
524 "value will be ignored.", var
->name
);
526 bitarray_set(options_seen
, var_index
);
529 if (config_assign_value(fmt
, options
, c
, msg
) < 0)
534 /** Restore the option named <b>key</b> in options to its default value.
535 * Called from config_assign(). */
537 config_reset_line(const config_format_t
*fmt
, void *options
,
538 const char *key
, int use_defaults
)
540 const config_var_t
*var
;
542 CONFIG_CHECK(fmt
, options
);
544 var
= config_find_option(fmt
, key
);
546 return; /* give error on next pass. */
548 config_reset(fmt
, options
, var
, use_defaults
);
551 /** Return true iff value needs to be quoted and escaped to be used in
552 * a configuration file. */
554 config_value_needs_escape(const char *value
)
564 /* Note: quotes and backspaces need special handling when we are using
565 * quotes, not otherwise, so they don't trigger escaping on their
569 if (!TOR_ISPRINT(*value
))
577 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
579 config_lines_dup(const config_line_t
*inp
)
581 config_line_t
*result
= NULL
;
582 config_line_t
**next_out
= &result
;
584 *next_out
= tor_malloc_zero(sizeof(config_line_t
));
585 (*next_out
)->key
= tor_strdup(inp
->key
);
586 (*next_out
)->value
= tor_strdup(inp
->value
);
588 next_out
= &((*next_out
)->next
);
594 /** Return newly allocated line or lines corresponding to <b>key</b> in the
595 * configuration <b>options</b>. If <b>escape_val</b> is true and a
596 * value needs to be quoted before it's put in a config file, quote and
597 * escape that value. Return NULL if no such key exists. */
599 config_get_assigned_option(const config_format_t
*fmt
, const void *options
,
600 const char *key
, int escape_val
)
602 const config_var_t
*var
;
604 config_line_t
*result
;
605 smartlist_t
*csv_str
;
606 tor_assert(options
&& key
);
608 CONFIG_CHECK(fmt
, options
);
610 var
= config_find_option(fmt
, key
);
612 log_warn(LD_CONFIG
, "Unknown option '%s'. Failing.", key
);
615 value
= STRUCT_VAR_P(options
, var
->var_offset
);
617 result
= tor_malloc_zero(sizeof(config_line_t
));
618 result
->key
= tor_strdup(var
->name
);
621 case CONFIG_TYPE_STRING
:
622 case CONFIG_TYPE_FILENAME
:
623 if (*(char**)value
) {
624 result
->value
= tor_strdup(*(char**)value
);
626 tor_free(result
->key
);
631 case CONFIG_TYPE_ISOTIME
:
632 if (*(time_t*)value
) {
633 result
->value
= tor_malloc(ISO_TIME_LEN
+1);
634 format_iso_time(result
->value
, *(time_t*)value
);
636 tor_free(result
->key
);
639 escape_val
= 0; /* Can't need escape. */
641 case CONFIG_TYPE_PORT
:
642 if (*(int*)value
== CFG_AUTO_PORT
) {
643 result
->value
= tor_strdup("auto");
648 case CONFIG_TYPE_INTERVAL
:
649 case CONFIG_TYPE_MSEC_INTERVAL
:
650 case CONFIG_TYPE_UINT
:
651 case CONFIG_TYPE_INT
:
652 /* This means every or_options_t uint or bool element
653 * needs to be an int. Not, say, a uint16_t or char. */
654 tor_asprintf(&result
->value
, "%d", *(int*)value
);
655 escape_val
= 0; /* Can't need escape. */
657 case CONFIG_TYPE_MEMUNIT
:
658 tor_asprintf(&result
->value
, U64_FORMAT
,
659 U64_PRINTF_ARG(*(uint64_t*)value
));
660 escape_val
= 0; /* Can't need escape. */
662 case CONFIG_TYPE_DOUBLE
:
663 tor_asprintf(&result
->value
, "%f", *(double*)value
);
664 escape_val
= 0; /* Can't need escape. */
667 case CONFIG_TYPE_AUTOBOOL
:
668 if (*(int*)value
== -1) {
669 result
->value
= tor_strdup("auto");
674 case CONFIG_TYPE_BOOL
:
675 result
->value
= tor_strdup(*(int*)value
? "1" : "0");
676 escape_val
= 0; /* Can't need escape. */
678 case CONFIG_TYPE_ROUTERSET
:
679 result
->value
= routerset_to_string(*(routerset_t
**)value
);
681 case CONFIG_TYPE_CSV
:
682 if (*(smartlist_t
**)value
)
684 smartlist_join_strings(*(smartlist_t
**)value
, ",", 0, NULL
);
686 result
->value
= tor_strdup("");
688 case CONFIG_TYPE_CSV_INTERVAL
:
689 if (*(smartlist_t
**)value
) {
690 csv_str
= smartlist_new();
691 SMARTLIST_FOREACH_BEGIN(*(smartlist_t
**)value
, int *, i
)
693 smartlist_add_asprintf(csv_str
, "%d", *i
);
695 SMARTLIST_FOREACH_END(i
);
696 result
->value
= smartlist_join_strings(csv_str
, ",", 0, NULL
);
697 SMARTLIST_FOREACH(csv_str
, char *, cp
, tor_free(cp
));
698 smartlist_free(csv_str
);
700 result
->value
= tor_strdup("");
702 case CONFIG_TYPE_OBSOLETE
:
703 log_fn(LOG_INFO
, LD_CONFIG
,
704 "You asked me for the value of an obsolete config option '%s'.",
706 tor_free(result
->key
);
709 case CONFIG_TYPE_LINELIST_S
:
711 "Can't return context-sensitive '%s' on its own", key
);
712 tor_free(result
->key
);
715 case CONFIG_TYPE_LINELIST
:
716 case CONFIG_TYPE_LINELIST_V
:
717 tor_free(result
->key
);
719 result
= config_lines_dup(*(const config_line_t
**)value
);
722 tor_free(result
->key
);
724 log_warn(LD_BUG
,"Unknown type %d for known key '%s'",
731 for (line
= result
; line
; line
= line
->next
) {
732 if (line
->value
&& config_value_needs_escape(line
->value
)) {
733 char *newval
= esc_for_log(line
->value
);
734 tor_free(line
->value
);
735 line
->value
= newval
;
742 /** Iterate through the linked list of requested options <b>list</b>.
743 * For each item, convert as appropriate and assign to <b>options</b>.
744 * If an item is unrecognized, set *msg and return -1 immediately,
745 * else return 0 for success.
747 * If <b>clear_first</b>, interpret config options as replacing (not
748 * extending) their previous values. If <b>clear_first</b> is set,
749 * then <b>use_defaults</b> to decide if you set to defaults after
750 * clearing, or make the value 0 or NULL.
752 * Here are the use cases:
753 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
754 * if linelist, replaces current if csv.
755 * 2. An empty AllowInvalid line in your torrc. Should clear it.
756 * 3. "RESETCONF AllowInvalid" sets it to default.
757 * 4. "SETCONF AllowInvalid" makes it NULL.
758 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
760 * Use_defaults Clear_first
762 * 1 0 undefined, don't use
763 * 0 1 "set to null first"
764 * 1 1 "set to defaults first"
765 * Return 0 on success, -1 on bad key, -2 on bad value.
767 * As an additional special case, if a LINELIST config option has
768 * no value and clear_first is 0, then warn and ignore it.
772 There are three call cases for config_assign() currently.
774 Case one: Torrc entry
775 options_init_from_torrc() calls config_assign(0, 0)
776 calls config_assign_line(0, 0).
777 if value is empty, calls config_reset(0) and returns.
778 calls config_assign_value(), appends.
781 options_trial_assign() calls config_assign(0, 1)
782 calls config_reset_line(0)
783 calls config_reset(0)
784 calls option_clear().
785 calls config_assign_line(0, 1).
786 if value is empty, returns.
787 calls config_assign_value(), appends.
789 Case three: resetconf
790 options_trial_assign() calls config_assign(1, 1)
791 calls config_reset_line(1)
792 calls config_reset(1)
793 calls option_clear().
794 calls config_assign_value(default)
795 calls config_assign_line(1, 1).
799 config_assign(const config_format_t
*fmt
, void *options
, config_line_t
*list
,
800 int use_defaults
, int clear_first
, char **msg
)
803 bitarray_t
*options_seen
;
804 const int n_options
= config_count_options(fmt
);
806 CONFIG_CHECK(fmt
, options
);
808 /* pass 1: normalize keys */
809 for (p
= list
; p
; p
= p
->next
) {
810 const char *full
= config_expand_abbrev(fmt
, p
->key
, 0, 1);
811 if (strcmp(full
,p
->key
)) {
813 p
->key
= tor_strdup(full
);
817 /* pass 2: if we're reading from a resetting source, clear all
818 * mentioned config options, and maybe set to their defaults. */
820 for (p
= list
; p
; p
= p
->next
)
821 config_reset_line(fmt
, options
, p
->key
, use_defaults
);
824 options_seen
= bitarray_init_zero(n_options
);
825 /* pass 3: assign. */
828 if ((r
=config_assign_line(fmt
, options
, list
, use_defaults
,
829 clear_first
, options_seen
, msg
))) {
830 bitarray_free(options_seen
);
835 bitarray_free(options_seen
);
837 /** Now we're done assigning a group of options to the configuration.
838 * Subsequent group assignments should _replace_ linelists, not extend
840 config_mark_lists_fragile(fmt
, options
);
845 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
846 * Called from config_reset() and config_free(). */
848 config_clear(const config_format_t
*fmt
, void *options
,
849 const config_var_t
*var
)
851 void *lvalue
= STRUCT_VAR_P(options
, var
->var_offset
);
852 (void)fmt
; /* unused */
854 case CONFIG_TYPE_STRING
:
855 case CONFIG_TYPE_FILENAME
:
856 tor_free(*(char**)lvalue
);
858 case CONFIG_TYPE_DOUBLE
:
859 *(double*)lvalue
= 0.0;
861 case CONFIG_TYPE_ISOTIME
:
862 *(time_t*)lvalue
= 0;
864 case CONFIG_TYPE_INTERVAL
:
865 case CONFIG_TYPE_MSEC_INTERVAL
:
866 case CONFIG_TYPE_UINT
:
867 case CONFIG_TYPE_INT
:
868 case CONFIG_TYPE_PORT
:
869 case CONFIG_TYPE_BOOL
:
872 case CONFIG_TYPE_AUTOBOOL
:
875 case CONFIG_TYPE_MEMUNIT
:
876 *(uint64_t*)lvalue
= 0;
878 case CONFIG_TYPE_ROUTERSET
:
879 if (*(routerset_t
**)lvalue
) {
880 routerset_free(*(routerset_t
**)lvalue
);
881 *(routerset_t
**)lvalue
= NULL
;
884 case CONFIG_TYPE_CSV
:
885 if (*(smartlist_t
**)lvalue
) {
886 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, char *, cp
, tor_free(cp
));
887 smartlist_free(*(smartlist_t
**)lvalue
);
888 *(smartlist_t
**)lvalue
= NULL
;
891 case CONFIG_TYPE_CSV_INTERVAL
:
892 if (*(smartlist_t
**)lvalue
) {
893 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, int *, cp
, tor_free(cp
));
894 smartlist_free(*(smartlist_t
**)lvalue
);
895 *(smartlist_t
**)lvalue
= NULL
;
898 case CONFIG_TYPE_LINELIST
:
899 case CONFIG_TYPE_LINELIST_S
:
900 config_free_lines(*(config_line_t
**)lvalue
);
901 *(config_line_t
**)lvalue
= NULL
;
903 case CONFIG_TYPE_LINELIST_V
:
904 /* handled by linelist_s. */
906 case CONFIG_TYPE_OBSOLETE
:
911 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
912 * <b>use_defaults</b>, set it to its default value.
913 * Called by config_init() and option_reset_line() and option_assign_line(). */
915 config_reset(const config_format_t
*fmt
, void *options
,
916 const config_var_t
*var
, int use_defaults
)
920 CONFIG_CHECK(fmt
, options
);
921 config_clear(fmt
, options
, var
); /* clear it first */
923 return; /* all done */
924 if (var
->initvalue
) {
925 c
= tor_malloc_zero(sizeof(config_line_t
));
926 c
->key
= tor_strdup(var
->name
);
927 c
->value
= tor_strdup(var
->initvalue
);
928 if (config_assign_value(fmt
, options
, c
, &msg
) < 0) {
929 log_warn(LD_BUG
, "Failed to assign default: %s", msg
);
930 tor_free(msg
); /* if this happens it's a bug */
932 config_free_lines(c
);
936 /** Release storage held by <b>options</b>. */
938 config_free(const config_format_t
*fmt
, void *options
)
947 for (i
=0; fmt
->vars
[i
].name
; ++i
)
948 config_clear(fmt
, options
, &(fmt
->vars
[i
]));
950 config_line_t
**linep
= STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
951 config_free_lines(*linep
);
957 /** Return true iff a and b contain identical keys and values in identical
960 config_lines_eq(config_line_t
*a
, config_line_t
*b
)
963 if (strcasecmp(a
->key
, b
->key
) || strcmp(a
->value
, b
->value
))
973 /** Return the number of lines in <b>a</b> whose key is <b>key</b>. */
975 config_count_key(const config_line_t
*a
, const char *key
)
979 if (!strcasecmp(a
->key
, key
)) {
987 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
988 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
991 config_is_same(const config_format_t
*fmt
,
992 const void *o1
, const void *o2
,
995 config_line_t
*c1
, *c2
;
997 CONFIG_CHECK(fmt
, o1
);
998 CONFIG_CHECK(fmt
, o2
);
1000 c1
= config_get_assigned_option(fmt
, o1
, name
, 0);
1001 c2
= config_get_assigned_option(fmt
, o2
, name
, 0);
1002 r
= config_lines_eq(c1
, c2
);
1003 config_free_lines(c1
);
1004 config_free_lines(c2
);
1008 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
1010 config_dup(const config_format_t
*fmt
, const void *old
)
1014 config_line_t
*line
;
1016 newopts
= config_new(fmt
);
1017 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1018 if (fmt
->vars
[i
].type
== CONFIG_TYPE_LINELIST_S
)
1020 if (fmt
->vars
[i
].type
== CONFIG_TYPE_OBSOLETE
)
1022 line
= config_get_assigned_option(fmt
, old
, fmt
->vars
[i
].name
, 0);
1025 if (config_assign(fmt
, newopts
, line
, 0, 0, &msg
) < 0) {
1026 log_err(LD_BUG
, "config_get_assigned_option() generated "
1027 "something we couldn't config_assign(): %s", msg
);
1032 config_free_lines(line
);
1036 /** Set all vars in the configuration object <b>options</b> to their default
1039 config_init(const config_format_t
*fmt
, void *options
)
1042 const config_var_t
*var
;
1043 CONFIG_CHECK(fmt
, options
);
1045 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1046 var
= &fmt
->vars
[i
];
1047 if (!var
->initvalue
)
1048 continue; /* defaults to NULL or 0 */
1049 config_reset(fmt
, options
, var
, 1);
1053 /** Allocate and return a new string holding the written-out values of the vars
1054 * in 'options'. If 'minimal', do not write out any default-valued vars.
1055 * Else, if comment_defaults, write default values as comments.
1058 config_dump(const config_format_t
*fmt
, const void *default_options
,
1059 const void *options
, int minimal
,
1060 int comment_defaults
)
1062 smartlist_t
*elements
;
1063 const void *defaults
= default_options
;
1064 void *defaults_tmp
= NULL
;
1065 config_line_t
*line
, *assigned
;
1070 if (defaults
== NULL
) {
1071 defaults
= defaults_tmp
= config_new(fmt
);
1072 config_init(fmt
, defaults_tmp
);
1075 /* XXX use a 1 here so we don't add a new log line while dumping */
1076 if (default_options
== NULL
) {
1077 if (fmt
->validate_fn(NULL
, defaults_tmp
, defaults_tmp
, 1, &msg
) < 0) {
1078 log_err(LD_BUG
, "Failed to validate default config: %s", msg
);
1084 elements
= smartlist_new();
1085 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1086 int comment_option
= 0;
1087 if (fmt
->vars
[i
].type
== CONFIG_TYPE_OBSOLETE
||
1088 fmt
->vars
[i
].type
== CONFIG_TYPE_LINELIST_S
)
1090 /* Don't save 'hidden' control variables. */
1091 if (!strcmpstart(fmt
->vars
[i
].name
, "__"))
1093 if (minimal
&& config_is_same(fmt
, options
, defaults
, fmt
->vars
[i
].name
))
1095 else if (comment_defaults
&&
1096 config_is_same(fmt
, options
, defaults
, fmt
->vars
[i
].name
))
1100 config_get_assigned_option(fmt
, options
, fmt
->vars
[i
].name
, 1);
1102 for (; line
; line
= line
->next
) {
1103 smartlist_add_asprintf(elements
, "%s%s %s\n",
1104 comment_option
? "# " : "",
1105 line
->key
, line
->value
);
1107 config_free_lines(assigned
);
1111 line
= *(config_line_t
**)STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
1112 for (; line
; line
= line
->next
) {
1113 smartlist_add_asprintf(elements
, "%s %s\n", line
->key
, line
->value
);
1117 result
= smartlist_join_strings(elements
, "", 0, NULL
);
1118 SMARTLIST_FOREACH(elements
, char *, cp
, tor_free(cp
));
1119 smartlist_free(elements
);
1121 config_free(fmt
, defaults_tmp
);
1125 /** Mapping from a unit name to a multiplier for converting that unit into a
1126 * base unit. Used by config_parse_unit. */
1127 struct unit_table_t
{
1128 const char *unit
; /**< The name of the unit */
1129 uint64_t multiplier
; /**< How many of the base unit appear in this unit */
1132 /** Table to map the names of memory units to the number of bytes they
1134 static struct unit_table_t memory_units
[] = {
1141 { "kbytes", 1<<10 },
1142 { "kilobyte", 1<<10 },
1143 { "kilobytes", 1<<10 },
1144 { "kilobits", 1<<7 },
1145 { "kilobit", 1<<7 },
1151 { "mbytes", 1<<20 },
1152 { "megabyte", 1<<20 },
1153 { "megabytes", 1<<20 },
1154 { "megabits", 1<<17 },
1155 { "megabit", 1<<17 },
1160 { "gbytes", 1<<30 },
1161 { "gigabyte", 1<<30 },
1162 { "gigabytes", 1<<30 },
1163 { "gigabits", 1<<27 },
1164 { "gigabit", 1<<27 },
1167 { "tb", U64_LITERAL(1)<<40 },
1168 { "terabyte", U64_LITERAL(1)<<40 },
1169 { "terabytes", U64_LITERAL(1)<<40 },
1170 { "terabits", U64_LITERAL(1)<<37 },
1171 { "terabit", U64_LITERAL(1)<<37 },
1172 { "tbits", U64_LITERAL(1)<<37 },
1173 { "tbit", U64_LITERAL(1)<<37 },
1177 /** Table to map the names of time units to the number of seconds they
1179 static struct unit_table_t time_units
[] = {
1187 { "day", 24*60*60 },
1188 { "days", 24*60*60 },
1189 { "week", 7*24*60*60 },
1190 { "weeks", 7*24*60*60 },
1191 { "month", 2629728, }, /* about 30.437 days */
1192 { "months", 2629728, },
1196 /** Table to map the names of time units to the number of milliseconds
1198 static struct unit_table_t time_msec_units
[] = {
1201 { "millisecond", 1 },
1202 { "milliseconds", 1 },
1204 { "seconds", 1000 },
1205 { "minute", 60*1000 },
1206 { "minutes", 60*1000 },
1207 { "hour", 60*60*1000 },
1208 { "hours", 60*60*1000 },
1209 { "day", 24*60*60*1000 },
1210 { "days", 24*60*60*1000 },
1211 { "week", 7*24*60*60*1000 },
1212 { "weeks", 7*24*60*60*1000 },
1216 /** Parse a string <b>val</b> containing a number, zero or more
1217 * spaces, and an optional unit string. If the unit appears in the
1218 * table <b>u</b>, then multiply the number by the unit multiplier.
1219 * On success, set *<b>ok</b> to 1 and return this product.
1220 * Otherwise, set *<b>ok</b> to 0.
1223 config_parse_units(const char *val
, struct unit_table_t
*u
, int *ok
)
1232 v
= tor_parse_uint64(val
, 10, 0, UINT64_MAX
, ok
, &cp
);
1233 if (!*ok
|| (cp
&& *cp
== '.')) {
1234 d
= tor_parse_double(val
, 0, UINT64_MAX
, ok
, &cp
);
1242 v
= use_float
? DBL_TO_U64(d
) : v
;
1246 cp
= (char*) eat_whitespace(cp
);
1248 for ( ;u
->unit
;++u
) {
1249 if (!strcasecmp(u
->unit
, cp
)) {
1251 v
= u
->multiplier
* d
;
1258 log_warn(LD_CONFIG
, "Unknown unit '%s'.", cp
);
1268 /** Parse a string in the format "number unit", where unit is a unit of
1269 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
1270 * and return the number of bytes specified. Otherwise, set
1271 * *<b>ok</b> to false and return 0. */
1273 config_parse_memunit(const char *s
, int *ok
)
1275 uint64_t u
= config_parse_units(s
, memory_units
, ok
);
1279 /** Parse a string in the format "number unit", where unit is a unit of
1280 * time in milliseconds. On success, set *<b>ok</b> to true and return
1281 * the number of milliseconds in the provided interval. Otherwise, set
1282 * *<b>ok</b> to 0 and return -1. */
1284 config_parse_msec_interval(const char *s
, int *ok
)
1287 r
= config_parse_units(s
, time_msec_units
, ok
);
1291 log_warn(LD_CONFIG
, "Msec interval '%s' is too long", s
);
1298 /** Parse a string in the format "number unit", where unit is a unit of time.
1299 * On success, set *<b>ok</b> to true and return the number of seconds in
1300 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
1303 config_parse_interval(const char *s
, int *ok
)
1306 r
= config_parse_units(s
, time_units
, ok
);
1310 log_warn(LD_CONFIG
, "Interval '%s' is too long", s
);