|
@@ -744,16 +744,12 @@ config_find_option(config_format_t *fmt, const char *key)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-/** If <b>c</b> is a syntactically valid configuration line, update
|
|
|
- * <b>options</b> with its value and return 0. Otherwise return -1 for bad key,
|
|
|
- * -2 for bad value.
|
|
|
- *
|
|
|
- * If 'reset' is set, and we get a line containing no value, restore the
|
|
|
- * option to its default value.
|
|
|
+/** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
|
|
|
+ * with <b>c</b>-\>value and return 0, or return -1 if bad value.
|
|
|
*/
|
|
|
static int
|
|
|
-config_assign_line(config_format_t *fmt,
|
|
|
- or_options_t *options, config_line_t *c, int reset)
|
|
|
+config_assign_value(config_format_t *fmt, or_options_t *options,
|
|
|
+ config_line_t *c)
|
|
|
{
|
|
|
int i, ok;
|
|
|
config_var_t *var;
|
|
@@ -762,25 +758,10 @@ config_assign_line(config_format_t *fmt,
|
|
|
CHECK(fmt, options);
|
|
|
|
|
|
var = config_find_option(fmt, c->key);
|
|
|
- if (!var) {
|
|
|
- log_fn(LOG_WARN, "Unknown option '%s'. Failing.", c->key);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- /* Put keyword into canonical case. */
|
|
|
- if (strcmp(var->name, c->key)) {
|
|
|
- tor_free(c->key);
|
|
|
- c->key = tor_strdup(var->name);
|
|
|
- }
|
|
|
-
|
|
|
- if (!strlen(c->value)) { /* reset or clear it, then return */
|
|
|
- if (reset)
|
|
|
- option_reset(fmt, options, var);
|
|
|
- else
|
|
|
- option_clear(fmt, options, var);
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ tor_assert(var);
|
|
|
|
|
|
lvalue = ((char*)options) + var->var_offset;
|
|
|
+
|
|
|
switch (var->type) {
|
|
|
|
|
|
case CONFIG_TYPE_UINT:
|
|
@@ -788,7 +769,7 @@ config_assign_line(config_format_t *fmt,
|
|
|
if (!ok) {
|
|
|
log(LOG_WARN, "Int keyword '%s %s' is malformed or out of bounds.",
|
|
|
c->key,c->value);
|
|
|
- return -2;
|
|
|
+ return -1;
|
|
|
}
|
|
|
*(int *)lvalue = i;
|
|
|
break;
|
|
@@ -796,7 +777,7 @@ config_assign_line(config_format_t *fmt,
|
|
|
case CONFIG_TYPE_INTERVAL: {
|
|
|
i = config_parse_interval(c->value, &ok);
|
|
|
if (!ok) {
|
|
|
- return -2;
|
|
|
+ return -1;
|
|
|
}
|
|
|
*(int *)lvalue = i;
|
|
|
break;
|
|
@@ -805,7 +786,7 @@ config_assign_line(config_format_t *fmt,
|
|
|
case CONFIG_TYPE_MEMUNIT: {
|
|
|
uint64_t u64 = config_parse_memunit(c->value, &ok);
|
|
|
if (!ok) {
|
|
|
- return -2;
|
|
|
+ return -1;
|
|
|
}
|
|
|
*(uint64_t *)lvalue = u64;
|
|
|
break;
|
|
@@ -815,7 +796,7 @@ config_assign_line(config_format_t *fmt,
|
|
|
i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
|
|
|
if (!ok) {
|
|
|
log(LOG_WARN, "Boolean keyword '%s' expects 0 or 1.", c->key);
|
|
|
- return -2;
|
|
|
+ return -1;
|
|
|
}
|
|
|
*(int *)lvalue = i;
|
|
|
break;
|
|
@@ -832,7 +813,7 @@ config_assign_line(config_format_t *fmt,
|
|
|
case CONFIG_TYPE_ISOTIME:
|
|
|
if (parse_iso_time(c->value, (time_t *)lvalue)) {
|
|
|
log(LOG_WARN, "Invalid time '%s' for keyword '%s'", c->value, c->key);
|
|
|
- return -2;
|
|
|
+ return -1;
|
|
|
}
|
|
|
break;
|
|
|
|
|
@@ -858,7 +839,7 @@ config_assign_line(config_format_t *fmt,
|
|
|
break;
|
|
|
case CONFIG_TYPE_LINELIST_V:
|
|
|
log_fn(LOG_WARN, "Can't provide value for virtual option '%s'", c->key);
|
|
|
- return -2;
|
|
|
+ return -1;
|
|
|
default:
|
|
|
tor_assert(0);
|
|
|
break;
|
|
@@ -866,6 +847,45 @@ config_assign_line(config_format_t *fmt,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/** If <b>c</b> is a syntactically valid configuration line, update
|
|
|
+ * <b>options</b> with its value and return 0. Otherwise return -1 for bad key,
|
|
|
+ * -2 for bad value.
|
|
|
+ *
|
|
|
+ * If 'reset' is set, and we get a line containing no value, restore the
|
|
|
+ * option to its default value.
|
|
|
+ */
|
|
|
+static int
|
|
|
+config_assign_line(config_format_t *fmt, or_options_t *options,
|
|
|
+ config_line_t *c, int reset)
|
|
|
+{
|
|
|
+ config_var_t *var;
|
|
|
+
|
|
|
+ CHECK(fmt, options);
|
|
|
+
|
|
|
+ var = config_find_option(fmt, c->key);
|
|
|
+ if (!var) {
|
|
|
+ log_fn(LOG_WARN, "Unknown option '%s'. Failing.", c->key);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ /* Put keyword into canonical case. */
|
|
|
+ if (strcmp(var->name, c->key)) {
|
|
|
+ tor_free(c->key);
|
|
|
+ c->key = tor_strdup(var->name);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!strlen(c->value)) { /* reset or clear it, then return */
|
|
|
+ if (reset)
|
|
|
+ option_reset(fmt, options, var);
|
|
|
+ else
|
|
|
+ option_clear(fmt, options, var);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (config_assign_value(fmt, options, c) < 0)
|
|
|
+ return -2;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/** restore the option named <b>key</b> in options to its default value. */
|
|
|
static void
|
|
|
config_reset_line(config_format_t *fmt, or_options_t *options, const char *key)
|
|
@@ -1143,7 +1163,7 @@ option_reset(config_format_t *fmt, or_options_t *options, config_var_t *var)
|
|
|
c = tor_malloc_zero(sizeof(config_line_t));
|
|
|
c->key = tor_strdup(var->name);
|
|
|
c->value = tor_strdup(var->initvalue);
|
|
|
- config_assign_line(fmt, options,c,0);
|
|
|
+ config_assign_value(fmt, options, c);
|
|
|
config_free_lines(c);
|
|
|
}
|
|
|
}
|
|
@@ -2275,8 +2295,8 @@ options_init_from_torrc(int argc, char **argv)
|
|
|
}
|
|
|
|
|
|
/* Go through command-line variables too */
|
|
|
- cl = config_get_commandlines(argc,argv);
|
|
|
- retval = config_assign(&options_format, newoptions,cl,0);
|
|
|
+ cl = config_get_commandlines(argc, argv);
|
|
|
+ retval = config_assign(&options_format, newoptions, cl, 0);
|
|
|
config_free_lines(cl);
|
|
|
if (retval < 0)
|
|
|
goto err;
|