diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-01-30 10:09:47 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-01-30 10:09:47 -0500 |
commit | 4d83999213712c731b9fdd6eb739f29289ff00d7 (patch) | |
tree | 29c342f8ce29b3845460ed2ce1b25c61a049c7f6 /src/or/confparse.c | |
parent | 088cc3604baa1325dd159fdd764088e4e1f8e2c7 (diff) | |
download | tor-4d83999213712c731b9fdd6eb739f29289ff00d7.tar.gz tor-4d83999213712c731b9fdd6eb739f29289ff00d7.zip |
Make "GETCONF SocksPort" work again
I broke "GETCONF *Port" in 20956, when I made SocksPort a
subordinate option of the virtual option SocksPortLines, so that I
could make SocksPort and __SocksPort provide qthe same
functionality. The problem was that you can't pass a subordinate
option to GETCONF.
So, this patch fixes that by letting you fetch subordinate options.
It won't always be meaningful to consider these options
out-of-context, but that can be the controller-user's
responsibility to check.
Closes ticket 21300.
Diffstat (limited to 'src/or/confparse.c')
-rw-r--r-- | src/or/confparse.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/or/confparse.c b/src/or/confparse.c index 92a66a4b5a..9e352aca27 100644 --- a/src/or/confparse.c +++ b/src/or/confparse.c @@ -31,6 +31,8 @@ static int config_parse_msec_interval(const char *s, int *ok); static int config_parse_interval(const char *s, int *ok); static void config_reset(const config_format_t *fmt, void *options, const config_var_t *var, int use_defaults); +static config_line_t *config_lines_dup_and_filter(const config_line_t *inp, + const char *key); /** Allocate an empty configuration object of a given format type. */ void * @@ -635,9 +637,22 @@ config_value_needs_escape(const char *value) config_line_t * config_lines_dup(const config_line_t *inp) { + return config_lines_dup_and_filter(inp, NULL); +} + +/** Return a newly allocated deep copy of the lines in <b>inp</b>, + * but only the ones that match <b>key</b>. */ +static config_line_t * +config_lines_dup_and_filter(const config_line_t *inp, + const char *key) +{ config_line_t *result = NULL; config_line_t **next_out = &result; while (inp) { + if (key && strcasecmpstart(inp->key, key)) { + inp = inp->next; + continue; + } *next_out = tor_malloc_zero(sizeof(config_line_t)); (*next_out)->key = tor_strdup(inp->key); (*next_out)->value = tor_strdup(inp->value); @@ -764,11 +779,10 @@ config_get_assigned_option(const config_format_t *fmt, const void *options, tor_free(result); return NULL; case CONFIG_TYPE_LINELIST_S: - log_warn(LD_CONFIG, - "Can't return context-sensitive '%s' on its own", key); - tor_free(result->key); tor_free(result); - return NULL; + result = config_lines_dup_and_filter(*(const config_line_t **)value, + key); + break; case CONFIG_TYPE_LINELIST: case CONFIG_TYPE_LINELIST_V: tor_free(result->key); |