summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2010-08-02 12:53:52 -0400
committerNick Mathewson <nickm@torproject.org>2010-08-02 12:53:52 -0400
commit9265190b16cae3b95f73bfb478e97b4fcfba0e17 (patch)
treef926c9d90e1af35c34298149a132c782d24dac58
parent73a4c0690edd49ea8fec2b8034bc2b0b681acdb0 (diff)
parenta9d055c5c516924b2e87e416b154bf220b0a914e (diff)
downloadtor-9265190b16cae3b95f73bfb478e97b4fcfba0e17.tar.gz
tor-9265190b16cae3b95f73bfb478e97b4fcfba0e17.zip
Merge branch 'bug1384'
-rw-r--r--changes/bug13845
-rw-r--r--doc/tor.1.txt3
-rw-r--r--src/or/config.c33
3 files changed, 38 insertions, 3 deletions
diff --git a/changes/bug1384 b/changes/bug1384
new file mode 100644
index 0000000000..9c406d9e25
--- /dev/null
+++ b/changes/bug1384
@@ -0,0 +1,5 @@
+ o Minor features:
+ - Warn when the same option is provided more then once in a torrc file,
+ on the command line, or in a single SETCONF statement, and option
+ is one that only accepts a single value. Closes bug 1384.
+
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 222aaf103c..db623c8da9 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -64,7 +64,8 @@ OPTIONS
Other options can be specified either on the command-line (--option
value), or in the configuration file (option value or option "value").
Options are case-insensitive. C-style escaped characters are allowed inside
- quoted values.
+ quoted values. Options on the command line take precedence over
+ options found in the configuration file.
**BandwidthRate** __N__ **bytes**|**KB**|**MB**|**GB**::
A token bucket limits the average incoming bandwidth usage on this node to
diff --git a/src/or/config.c b/src/or/config.c
index 46066b1862..77cd518b1d 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1562,6 +1562,16 @@ config_find_option(config_format_t *fmt, const char *key)
return NULL;
}
+/** Return the number of option entries in <b>fmt</b>. */
+static int
+config_count_options(config_format_t *fmt)
+{
+ int i;
+ for (i=0; fmt->vars[i].name; ++i)
+ ;
+ return i;
+}
+
/*
* Functions to assign config options.
*/
@@ -1706,7 +1716,7 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
static int
config_assign_line(config_format_t *fmt, or_options_t *options,
config_line_t *c, int use_defaults,
- int clear_first, char **msg)
+ int clear_first, bitarray_t *options_seen, char **msg)
{
config_var_t *var;
@@ -1726,6 +1736,7 @@ config_assign_line(config_format_t *fmt, or_options_t *options,
return -1;
}
}
+
/* Put keyword into canonical case. */
if (strcmp(var->name, c->key)) {
tor_free(c->key);
@@ -1748,6 +1759,18 @@ config_assign_line(config_format_t *fmt, or_options_t *options,
return 0;
}
+ if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
+ var->type != CONFIG_TYPE_LINELIST_S)) {
+ /* We're tracking which options we've seen, and this option is not
+ * supposed to occur more than once. */
+ int var_index = (int)(var - fmt->vars);
+ if (bitarray_is_set(options_seen, var_index)) {
+ log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
+ "value will be ignored.", var->name);
+ }
+ bitarray_set(options_seen, var_index);
+ }
+
if (config_assign_value(fmt, options, c, msg) < 0)
return -2;
return 0;
@@ -2016,6 +2039,8 @@ config_assign(config_format_t *fmt, void *options, config_line_t *list,
int use_defaults, int clear_first, char **msg)
{
config_line_t *p;
+ bitarray_t *options_seen;
+ const int n_options = config_count_options(fmt);
CHECK(fmt, options);
@@ -2035,14 +2060,18 @@ config_assign(config_format_t *fmt, void *options, config_line_t *list,
config_reset_line(fmt, options, p->key, use_defaults);
}
+ options_seen = bitarray_init_zero(n_options);
/* pass 3: assign. */
while (list) {
int r;
if ((r=config_assign_line(fmt, options, list, use_defaults,
- clear_first, msg)))
+ clear_first, options_seen, msg))) {
+ bitarray_free(options_seen);
return r;
+ }
list = list->next;
}
+ bitarray_free(options_seen);
return 0;
}