diff --git a/src/or/config.c b/src/or/config.c index 64c9796792..2f5ba6c6f7 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -636,6 +636,7 @@ STATIC config_format_t options_format = { OR_OPTIONS_MAGIC, STRUCT_OFFSET(or_options_t, magic_), option_abbrevs_, + NULL, option_vars_, options_validate_cb, NULL diff --git a/src/or/confparse.c b/src/or/confparse.c index 3532b39d93..233cc7c77d 100644 --- a/src/or/confparse.c +++ b/src/or/confparse.c @@ -181,6 +181,26 @@ config_free_lines(config_line_t *front) } } +/** If key is a deprecated configuration option, return the message + * explaining why it is deprecated (which may be an empty string). Return NULL + * if it is not deprecated. The key field must be fully expanded. */ +static const char * +config_find_deprecation(const config_format_t *fmt, const char *key) +{ + if (BUG(fmt == NULL) || BUG(key == NULL)) + return NULL; + if (fmt->deprecations == NULL) + return NULL; + + config_deprecation_t *d; + for (d = fmt->deprecations; d->name; ++d) { + if (!strcasecmp(d->name, key)) { + return d->why_deprecated ? d->why_deprecated : ""; + } + } + return NULL; +} + /** As config_find_option, but return a non-const pointer. */ config_var_t * config_find_option_mutable(config_format_t *fmt, const char *key) @@ -463,6 +483,15 @@ config_mark_lists_fragile(const config_format_t *fmt, void *options) } } +void +warn_deprecated_option(const char *what, const char *why) +{ + log_warn(LD_CONFIG, "The %s option is deprecated, and will most likely " + "be removed in a future version of Tor.%s (If you think this is " + "a mistake, please let us know!)", + what, why); +} + /** If c is a syntactically valid configuration line, update * options with its value and return 0. Otherwise return -1 for bad * key, -2 for bad value. @@ -502,6 +531,11 @@ config_assign_line(const config_format_t *fmt, void *options, c->key = tor_strdup(var->name); } + const char *deprecation_msg = config_find_deprecation(fmt, var->name); + if (deprecation_msg) { + warn_deprecated_option(var->name, deprecation_msg); + } + if (!strlen(c->value)) { /* reset or clear it, then return */ if (!clear_first) { diff --git a/src/or/confparse.h b/src/or/confparse.h index ca6fb5ec43..415d680d2e 100644 --- a/src/or/confparse.h +++ b/src/or/confparse.h @@ -48,6 +48,11 @@ typedef struct config_abbrev_t { int warn; } config_abbrev_t; +typedef struct config_deprecation_t { + const char *name; + const char *why_deprecated; +} config_deprecation_t; + /* Handy macro for declaring "In the config file or on the command line, * you can abbreviate toks as tok". */ #define PLURAL(tok) { #tok, #tok "s", 0, 0 } @@ -76,6 +81,7 @@ typedef struct config_format_t { off_t magic_offset; /**< Offset of the magic value within the struct. */ config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when * parsing this format. */ + config_deprecation_t *deprecations; /** List of deprecated options */ config_var_t *vars; /**< List of variables we recognize, their default * values, and where we stick them in the structure. */ validate_fn_t validate_fn; /**< Function to validate config. */ @@ -125,6 +131,8 @@ void config_free_lines(config_line_t *front); const char *config_expand_abbrev(const config_format_t *fmt, const char *option, int command_line, int warn_obsolete); +void warn_deprecated_option(const char *what, const char *why); + #endif diff --git a/src/or/shared_random_state.c b/src/or/shared_random_state.c index 52a0034db7..c344a45b7c 100644 --- a/src/or/shared_random_state.c +++ b/src/or/shared_random_state.c @@ -86,6 +86,7 @@ static const config_format_t state_format = { SR_DISK_STATE_MAGIC, STRUCT_OFFSET(sr_disk_state_t, magic_), NULL, + NULL, state_vars, disk_state_validate_cb, &state_extra_var, diff --git a/src/or/statefile.c b/src/or/statefile.c index 9594d9cec3..c2f31d69e5 100644 --- a/src/or/statefile.c +++ b/src/or/statefile.c @@ -121,6 +121,7 @@ static const config_format_t state_format = { OR_STATE_MAGIC, STRUCT_OFFSET(or_state_t, magic_), state_abbrevs_, + NULL, state_vars_, or_state_validate_cb, &state_extra_var,