mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Port confparse to use struct_var in place of typed_var.
This requires changes to config_var_t, causing corresponding changes throughout its users.
This commit is contained in:
+64
-41
@@ -253,23 +253,45 @@ static config_abbrev_t option_abbrevs_[] = {
|
||||
* members with CONF_CHECK_VAR_TYPE. */
|
||||
DUMMY_TYPECHECK_INSTANCE(or_options_t);
|
||||
|
||||
/** An entry for config_vars: "The option <b>name</b> has type
|
||||
/** An entry for config_vars: "The option <b>varname</b> has type
|
||||
* CONFIG_TYPE_<b>conftype</b>, and corresponds to
|
||||
* or_options_t.<b>member</b>"
|
||||
*/
|
||||
#define VAR(name,conftype,member,initvalue) \
|
||||
{ name, CONFIG_TYPE_ ## conftype, offsetof(or_options_t, member), \
|
||||
#define VAR(varname,conftype,member,initvalue) \
|
||||
{ { .name = varname, \
|
||||
.type = CONFIG_TYPE_ ## conftype, \
|
||||
.offset = offsetof(or_options_t, member), \
|
||||
}, \
|
||||
initvalue CONF_TEST_MEMBERS(or_options_t, conftype, member) }
|
||||
/** As VAR, but the option name and member name are the same. */
|
||||
#define V(member,conftype,initvalue) \
|
||||
VAR(#member, conftype, member, initvalue)
|
||||
/** An entry for config_vars: "The option <b>name</b> is obsolete." */
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
#define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL, {.INT=NULL} }
|
||||
#define DUMMY_TEST_MEMBERS , {.INT=NULL}
|
||||
#else
|
||||
#define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
|
||||
#define DUMMY_TEST_MEMBERS
|
||||
#endif
|
||||
|
||||
/* As VAR, but uses a type definition in addition to a type enum. */
|
||||
#define VAR_D(varname,conftype,member,initvalue) \
|
||||
{ { .name = varname, \
|
||||
.type = CONFIG_TYPE_ ## conftype, \
|
||||
.type_def = &conftype ## _type_defn, \
|
||||
.offset = offsetof(or_options_t, member), \
|
||||
}, \
|
||||
initvalue DUMMY_TEST_MEMBERS }
|
||||
|
||||
/** As VAR, but the option name and member name are the same. */
|
||||
#define V(member,conftype,initvalue) \
|
||||
VAR(#member, conftype, member, initvalue)
|
||||
|
||||
/** As V, but uses a type definition instead of a type enum */
|
||||
#define V_D(member,type,initvalue) \
|
||||
VAR_D(#member, type, member, initvalue)
|
||||
|
||||
/** An entry for config_vars: "The option <b>varname</b> is obsolete." */
|
||||
#define OBSOLETE(varname) \
|
||||
{ { .name = varname, .type = CONFIG_TYPE_OBSOLETE, }, NULL \
|
||||
DUMMY_TEST_MEMBERS }
|
||||
|
||||
/**
|
||||
* Macro to declare *Port options. Each one comes in three entries.
|
||||
* For example, most users should use "SocksPort" to configure the
|
||||
@@ -418,17 +440,17 @@ static config_var_t option_vars_[] = {
|
||||
V(TestingEnableCellStatsEvent, BOOL, "0"),
|
||||
OBSOLETE("TestingEnableTbEmptyEvent"),
|
||||
V(EnforceDistinctSubnets, BOOL, "1"),
|
||||
V(EntryNodes, ROUTERSET, NULL),
|
||||
V_D(EntryNodes, ROUTERSET, NULL),
|
||||
V(EntryStatistics, BOOL, "0"),
|
||||
V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
|
||||
V(ExcludeNodes, ROUTERSET, NULL),
|
||||
V(ExcludeExitNodes, ROUTERSET, NULL),
|
||||
V_D(ExcludeNodes, ROUTERSET, NULL),
|
||||
V_D(ExcludeExitNodes, ROUTERSET, NULL),
|
||||
OBSOLETE("ExcludeSingleHopRelays"),
|
||||
V(ExitNodes, ROUTERSET, NULL),
|
||||
V_D(ExitNodes, ROUTERSET, NULL),
|
||||
/* Researchers need a way to tell their clients to use specific
|
||||
* middles that they also control, to allow safe live-network
|
||||
* experimentation with new padding machines. */
|
||||
V(MiddleNodes, ROUTERSET, NULL),
|
||||
V_D(MiddleNodes, ROUTERSET, NULL),
|
||||
V(ExitPolicy, LINELIST, NULL),
|
||||
V(ExitPolicyRejectPrivate, BOOL, "1"),
|
||||
V(ExitPolicyRejectLocalInterfaces, BOOL, "0"),
|
||||
@@ -507,8 +529,8 @@ static config_var_t option_vars_[] = {
|
||||
V(Socks5ProxyPassword, STRING, NULL),
|
||||
VAR("KeyDirectory", FILENAME, KeyDirectory_option, NULL),
|
||||
V(KeyDirectoryGroupReadable, BOOL, "0"),
|
||||
VAR("HSLayer2Nodes", ROUTERSET, HSLayer2Nodes, NULL),
|
||||
VAR("HSLayer3Nodes", ROUTERSET, HSLayer3Nodes, NULL),
|
||||
VAR_D("HSLayer2Nodes", ROUTERSET, HSLayer2Nodes, NULL),
|
||||
VAR_D("HSLayer3Nodes", ROUTERSET, HSLayer3Nodes, NULL),
|
||||
V(KeepalivePeriod, INTERVAL, "5 minutes"),
|
||||
V(KeepBindCapabilities, AUTOBOOL, "auto"),
|
||||
VAR("Log", LINELIST, Logs, NULL),
|
||||
@@ -732,11 +754,11 @@ static config_var_t option_vars_[] = {
|
||||
OBSOLETE("TestingDescriptorMaxDownloadTries"),
|
||||
OBSOLETE("TestingMicrodescMaxDownloadTries"),
|
||||
OBSOLETE("TestingCertMaxDownloadTries"),
|
||||
V(TestingDirAuthVoteExit, ROUTERSET, NULL),
|
||||
V_D(TestingDirAuthVoteExit, ROUTERSET, NULL),
|
||||
V(TestingDirAuthVoteExitIsStrict, BOOL, "0"),
|
||||
V(TestingDirAuthVoteGuard, ROUTERSET, NULL),
|
||||
V_D(TestingDirAuthVoteGuard, ROUTERSET, NULL),
|
||||
V(TestingDirAuthVoteGuardIsStrict, BOOL, "0"),
|
||||
V(TestingDirAuthVoteHSDir, ROUTERSET, NULL),
|
||||
V_D(TestingDirAuthVoteHSDir, ROUTERSET, NULL),
|
||||
V(TestingDirAuthVoteHSDirIsStrict, BOOL, "0"),
|
||||
VAR("___UsingTestNetworkDefaults", BOOL, UsingTestNetworkDefaults_, "0"),
|
||||
|
||||
@@ -949,11 +971,11 @@ set_options(or_options_t *new_val, char **msg)
|
||||
* just starting up then the old_options will be undefined. */
|
||||
if (old_options && old_options != global_options) {
|
||||
elements = smartlist_new();
|
||||
for (i=0; options_format.vars[i].name; ++i) {
|
||||
for (i=0; options_format.vars[i].member.name; ++i) {
|
||||
const config_var_t *var = &options_format.vars[i];
|
||||
const char *var_name = var->name;
|
||||
if (var->type == CONFIG_TYPE_LINELIST_S ||
|
||||
var->type == CONFIG_TYPE_OBSOLETE) {
|
||||
const char *var_name = var->member.name;
|
||||
if (var->member.type == CONFIG_TYPE_LINELIST_S ||
|
||||
var->member.type == CONFIG_TYPE_OBSOLETE) {
|
||||
continue;
|
||||
}
|
||||
if (!config_is_same(&options_format, new_val, old_options, var_name)) {
|
||||
@@ -969,7 +991,7 @@ set_options(or_options_t *new_val, char **msg)
|
||||
tor_free(line);
|
||||
}
|
||||
} else {
|
||||
smartlist_add_strdup(elements, options_format.vars[i].name);
|
||||
smartlist_add_strdup(elements, options_format.vars[i].member.name);
|
||||
smartlist_add(elements, NULL);
|
||||
}
|
||||
}
|
||||
@@ -2571,7 +2593,7 @@ const char *
|
||||
option_get_canonical_name(const char *key)
|
||||
{
|
||||
const config_var_t *var = config_find_option(&options_format, key);
|
||||
return var ? var->name : NULL;
|
||||
return var ? var->member.name : NULL;
|
||||
}
|
||||
|
||||
/** Return a canonical list of the options assigned for key.
|
||||
@@ -2653,12 +2675,12 @@ static void
|
||||
list_torrc_options(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; option_vars_[i].name; ++i) {
|
||||
for (i = 0; option_vars_[i].member.name; ++i) {
|
||||
const config_var_t *var = &option_vars_[i];
|
||||
if (var->type == CONFIG_TYPE_OBSOLETE ||
|
||||
var->type == CONFIG_TYPE_LINELIST_V)
|
||||
if (var->member.type == CONFIG_TYPE_OBSOLETE ||
|
||||
var->member.type == CONFIG_TYPE_LINELIST_V)
|
||||
continue;
|
||||
printf("%s\n", var->name);
|
||||
printf("%s\n", var->member.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5445,18 +5467,18 @@ options_init_from_string(const char *cf_defaults, const char *cf,
|
||||
* let's clean it up. -NM */
|
||||
|
||||
/* Change defaults. */
|
||||
for (int i = 0; testing_tor_network_defaults[i].name; ++i) {
|
||||
for (int i = 0; testing_tor_network_defaults[i].member.name; ++i) {
|
||||
const config_var_t *new_var = &testing_tor_network_defaults[i];
|
||||
config_var_t *old_var =
|
||||
config_find_option_mutable(&options_format, new_var->name);
|
||||
config_find_option_mutable(&options_format, new_var->member.name);
|
||||
tor_assert(new_var);
|
||||
tor_assert(old_var);
|
||||
old_var->initvalue = new_var->initvalue;
|
||||
|
||||
if ((config_find_deprecation(&options_format, new_var->name))) {
|
||||
if ((config_find_deprecation(&options_format, new_var->member.name))) {
|
||||
log_warn(LD_GENERAL, "Testing options override the deprecated "
|
||||
"option %s. Is that intentional?",
|
||||
new_var->name);
|
||||
new_var->member.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8168,13 +8190,13 @@ getinfo_helper_config(control_connection_t *conn,
|
||||
if (!strcmp(question, "config/names")) {
|
||||
smartlist_t *sl = smartlist_new();
|
||||
int i;
|
||||
for (i = 0; option_vars_[i].name; ++i) {
|
||||
for (i = 0; option_vars_[i].member.name; ++i) {
|
||||
const config_var_t *var = &option_vars_[i];
|
||||
const char *type;
|
||||
/* don't tell controller about triple-underscore options */
|
||||
if (!strncmp(option_vars_[i].name, "___", 3))
|
||||
if (!strncmp(option_vars_[i].member.name, "___", 3))
|
||||
continue;
|
||||
switch (var->type) {
|
||||
switch (var->member.type) {
|
||||
case CONFIG_TYPE_STRING: type = "String"; break;
|
||||
case CONFIG_TYPE_FILENAME: type = "Filename"; break;
|
||||
case CONFIG_TYPE_POSINT: type = "Integer"; break;
|
||||
@@ -8198,11 +8220,12 @@ getinfo_helper_config(control_connection_t *conn,
|
||||
case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
|
||||
default:
|
||||
case CONFIG_TYPE_OBSOLETE:
|
||||
case CONFIG_TYPE_EXTENDED:
|
||||
type = NULL; break;
|
||||
}
|
||||
if (!type)
|
||||
continue;
|
||||
smartlist_add_asprintf(sl, "%s %s\n",var->name,type);
|
||||
smartlist_add_asprintf(sl, "%s %s\n",var->member.name,type);
|
||||
}
|
||||
*answer = smartlist_join_strings(sl, "", 0, NULL);
|
||||
SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
|
||||
@@ -8210,17 +8233,17 @@ getinfo_helper_config(control_connection_t *conn,
|
||||
} else if (!strcmp(question, "config/defaults")) {
|
||||
smartlist_t *sl = smartlist_new();
|
||||
int dirauth_lines_seen = 0, fallback_lines_seen = 0;
|
||||
for (int i = 0; option_vars_[i].name; ++i) {
|
||||
for (int i = 0; option_vars_[i].member.name; ++i) {
|
||||
const config_var_t *var = &option_vars_[i];
|
||||
if (var->initvalue != NULL) {
|
||||
if (strcmp(option_vars_[i].name, "DirAuthority") == 0) {
|
||||
if (strcmp(option_vars_[i].member.name, "DirAuthority") == 0) {
|
||||
/*
|
||||
* Count dirauth lines we have a default for; we'll use the
|
||||
* count later to decide whether to add the defaults manually
|
||||
*/
|
||||
++dirauth_lines_seen;
|
||||
}
|
||||
if (strcmp(option_vars_[i].name, "FallbackDir") == 0) {
|
||||
if (strcmp(option_vars_[i].member.name, "FallbackDir") == 0) {
|
||||
/*
|
||||
* Similarly count fallback lines, so that we can decided later
|
||||
* to add the defaults manually.
|
||||
@@ -8228,7 +8251,7 @@ getinfo_helper_config(control_connection_t *conn,
|
||||
++fallback_lines_seen;
|
||||
}
|
||||
char *val = esc_for_log(var->initvalue);
|
||||
smartlist_add_asprintf(sl, "%s %s\n",var->name,val);
|
||||
smartlist_add_asprintf(sl, "%s %s\n",var->member.name,val);
|
||||
tor_free(val);
|
||||
}
|
||||
}
|
||||
|
||||
+45
-65
@@ -29,8 +29,7 @@
|
||||
#include "lib/confmgt/unitparse.h"
|
||||
#include "lib/container/bitarray.h"
|
||||
#include "lib/encoding/confline.h"
|
||||
|
||||
#include "lib/confmgt/typedvar.h"
|
||||
#include "lib/confmgt/structvar.h"
|
||||
|
||||
static void config_reset(const config_format_t *fmt, void *options,
|
||||
const config_var_t *var, int use_defaults);
|
||||
@@ -110,17 +109,17 @@ config_find_option_mutable(config_format_t *fmt, const char *key)
|
||||
if (!keylen)
|
||||
return NULL; /* if they say "--" on the command line, it's not an option */
|
||||
/* First, check for an exact (case-insensitive) match */
|
||||
for (i=0; fmt->vars[i].name; ++i) {
|
||||
if (!strcasecmp(key, fmt->vars[i].name)) {
|
||||
for (i=0; fmt->vars[i].member.name; ++i) {
|
||||
if (!strcasecmp(key, fmt->vars[i].member.name)) {
|
||||
return &fmt->vars[i];
|
||||
}
|
||||
}
|
||||
/* If none, check for an abbreviated match */
|
||||
for (i=0; fmt->vars[i].name; ++i) {
|
||||
if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
|
||||
for (i=0; fmt->vars[i].member.name; ++i) {
|
||||
if (!strncasecmp(key, fmt->vars[i].member.name, keylen)) {
|
||||
log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
|
||||
"Please use '%s' instead",
|
||||
key, fmt->vars[i].name);
|
||||
key, fmt->vars[i].member.name);
|
||||
return &fmt->vars[i];
|
||||
}
|
||||
}
|
||||
@@ -144,7 +143,7 @@ static int
|
||||
config_count_options(const config_format_t *fmt)
|
||||
{
|
||||
int i;
|
||||
for (i=0; fmt->vars[i].name; ++i)
|
||||
for (i=0; fmt->vars[i].member.name; ++i)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
@@ -163,23 +162,14 @@ config_assign_value(const config_format_t *fmt, void *options,
|
||||
config_line_t *c, char **msg)
|
||||
{
|
||||
const config_var_t *var;
|
||||
void *lvalue;
|
||||
|
||||
CONFIG_CHECK(fmt, options);
|
||||
|
||||
var = config_find_option(fmt, c->key);
|
||||
tor_assert(var);
|
||||
tor_assert(!strcmp(c->key, var->name));
|
||||
tor_assert(!strcmp(c->key, var->member.name));
|
||||
|
||||
lvalue = STRUCT_VAR_P(options, var->var_offset);
|
||||
|
||||
if (var->type == CONFIG_TYPE_ROUTERSET) {
|
||||
// XXXX make the backend extensible so that we don't have to
|
||||
// XXXX special-case this type.
|
||||
return typed_var_kvassign_ex(lvalue, c, msg, &routerset_type_defn);
|
||||
}
|
||||
|
||||
return typed_var_kvassign(lvalue, c, msg, var->type);
|
||||
return struct_var_kvassign(options, c, msg, &var->member);
|
||||
}
|
||||
|
||||
/** Mark every linelist in <b>options</b> "fragile", so that fresh assignments
|
||||
@@ -191,14 +181,14 @@ config_mark_lists_fragile(const config_format_t *fmt, void *options)
|
||||
tor_assert(fmt);
|
||||
tor_assert(options);
|
||||
|
||||
for (i = 0; fmt->vars[i].name; ++i) {
|
||||
for (i = 0; fmt->vars[i].member.name; ++i) {
|
||||
const config_var_t *var = &fmt->vars[i];
|
||||
config_line_t *list;
|
||||
if (var->type != CONFIG_TYPE_LINELIST &&
|
||||
var->type != CONFIG_TYPE_LINELIST_V)
|
||||
if (var->member.type != CONFIG_TYPE_LINELIST &&
|
||||
var->member.type != CONFIG_TYPE_LINELIST_V)
|
||||
continue;
|
||||
|
||||
list = *(config_line_t **)STRUCT_VAR_P(options, var->var_offset);
|
||||
list = *(config_line_t **)STRUCT_VAR_P(options, var->member.offset);
|
||||
if (list)
|
||||
list->fragile = 1;
|
||||
}
|
||||
@@ -238,7 +228,7 @@ config_assign_line(const config_format_t *fmt, void *options,
|
||||
var = config_find_option(fmt, c->key);
|
||||
if (!var) {
|
||||
if (fmt->extra) {
|
||||
void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
|
||||
void *lvalue = STRUCT_VAR_P(options, fmt->extra->offset);
|
||||
log_info(LD_CONFIG,
|
||||
"Found unrecognized option '%s'; saving it.", c->key);
|
||||
config_line_append((config_line_t**)lvalue, c->key, c->value);
|
||||
@@ -251,22 +241,22 @@ config_assign_line(const config_format_t *fmt, void *options,
|
||||
}
|
||||
|
||||
/* Put keyword into canonical case. */
|
||||
if (strcmp(var->name, c->key)) {
|
||||
if (strcmp(var->member.name, c->key)) {
|
||||
tor_free(c->key);
|
||||
c->key = tor_strdup(var->name);
|
||||
c->key = tor_strdup(var->member.name);
|
||||
}
|
||||
|
||||
const char *deprecation_msg;
|
||||
if (warn_deprecations &&
|
||||
(deprecation_msg = config_find_deprecation(fmt, var->name))) {
|
||||
warn_deprecated_option(var->name, deprecation_msg);
|
||||
(deprecation_msg = config_find_deprecation(fmt, var->member.name))) {
|
||||
warn_deprecated_option(var->member.name, deprecation_msg);
|
||||
}
|
||||
|
||||
if (!strlen(c->value)) {
|
||||
/* reset or clear it, then return */
|
||||
if (!clear_first) {
|
||||
if ((var->type == CONFIG_TYPE_LINELIST ||
|
||||
var->type == CONFIG_TYPE_LINELIST_S) &&
|
||||
if ((var->member.type == CONFIG_TYPE_LINELIST ||
|
||||
var->member.type == CONFIG_TYPE_LINELIST_S) &&
|
||||
c->command != CONFIG_LINE_CLEAR) {
|
||||
/* We got an empty linelist from the torrc or command line.
|
||||
As a special case, call this an error. Warn and ignore. */
|
||||
@@ -283,14 +273,14 @@ config_assign_line(const config_format_t *fmt, void *options,
|
||||
config_reset(fmt, options, var, use_defaults); // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
|
||||
var->type != CONFIG_TYPE_LINELIST_S)) {
|
||||
if (options_seen && (var->member.type != CONFIG_TYPE_LINELIST &&
|
||||
var->member.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);
|
||||
"value will be ignored.", var->member.name);
|
||||
}
|
||||
bitarray_set(options_seen, var_index);
|
||||
}
|
||||
@@ -352,7 +342,6 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
|
||||
const char *key, int escape_val)
|
||||
{
|
||||
const config_var_t *var;
|
||||
const void *value;
|
||||
config_line_t *result;
|
||||
tor_assert(options && key);
|
||||
|
||||
@@ -363,15 +352,8 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
|
||||
log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
|
||||
return NULL;
|
||||
}
|
||||
value = STRUCT_VAR_P(options, var->var_offset);
|
||||
|
||||
if (var->type == CONFIG_TYPE_ROUTERSET) {
|
||||
// XXXX make the backend extensible so that we don't have to
|
||||
// XXXX special-case this type.
|
||||
result = typed_var_kvencode_ex(var->name, value, &routerset_type_defn);
|
||||
} else {
|
||||
result = typed_var_kvencode(var->name, value, var->type);
|
||||
}
|
||||
result = struct_var_kvencode(options, &var->member);
|
||||
|
||||
if (escape_val) {
|
||||
config_line_t *line;
|
||||
@@ -497,14 +479,10 @@ static void
|
||||
config_clear(const config_format_t *fmt, void *options,
|
||||
const config_var_t *var)
|
||||
{
|
||||
void *lvalue = STRUCT_VAR_P(options, var->var_offset);
|
||||
(void)fmt; /* unused */
|
||||
if (var->type == CONFIG_TYPE_ROUTERSET) {
|
||||
typed_var_free_ex(lvalue, &routerset_type_defn);
|
||||
return;
|
||||
}
|
||||
|
||||
typed_var_free(lvalue, var->type);
|
||||
(void)fmt; /* unused */
|
||||
|
||||
struct_var_free(options, &var->member);
|
||||
}
|
||||
|
||||
/** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
|
||||
@@ -522,7 +500,7 @@ config_reset(const config_format_t *fmt, void *options,
|
||||
return; /* all done */
|
||||
if (var->initvalue) {
|
||||
c = tor_malloc_zero(sizeof(config_line_t));
|
||||
c->key = tor_strdup(var->name);
|
||||
c->key = tor_strdup(var->member.name);
|
||||
c->value = tor_strdup(var->initvalue);
|
||||
if (config_assign_value(fmt, options, c, &msg) < 0) {
|
||||
// LCOV_EXCL_START
|
||||
@@ -545,10 +523,11 @@ config_free_(const config_format_t *fmt, void *options)
|
||||
|
||||
tor_assert(fmt);
|
||||
|
||||
for (i=0; fmt->vars[i].name; ++i)
|
||||
for (i=0; fmt->vars[i].member.name; ++i)
|
||||
config_clear(fmt, options, &(fmt->vars[i]));
|
||||
|
||||
if (fmt->extra) {
|
||||
config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
|
||||
config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->offset);
|
||||
config_free_lines(*linep);
|
||||
*linep = NULL;
|
||||
}
|
||||
@@ -585,12 +564,12 @@ config_dup(const config_format_t *fmt, const void *old)
|
||||
config_line_t *line;
|
||||
|
||||
newopts = config_new(fmt);
|
||||
for (i=0; fmt->vars[i].name; ++i) {
|
||||
if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
|
||||
for (i=0; fmt->vars[i].member.name; ++i) {
|
||||
if (fmt->vars[i].member.type == CONFIG_TYPE_LINELIST_S)
|
||||
continue;
|
||||
if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
|
||||
if (fmt->vars[i].member.type == CONFIG_TYPE_OBSOLETE)
|
||||
continue;
|
||||
line = config_get_assigned_option(fmt, old, fmt->vars[i].name, 0);
|
||||
line = config_get_assigned_option(fmt, old, fmt->vars[i].member.name, 0);
|
||||
if (line) {
|
||||
char *msg = NULL;
|
||||
if (config_assign(fmt, newopts, line, 0, &msg) < 0) {
|
||||
@@ -615,7 +594,7 @@ config_init(const config_format_t *fmt, void *options)
|
||||
const config_var_t *var;
|
||||
CONFIG_CHECK(fmt, options);
|
||||
|
||||
for (i=0; fmt->vars[i].name; ++i) {
|
||||
for (i=0; fmt->vars[i].member.name; ++i) {
|
||||
var = &fmt->vars[i];
|
||||
if (!var->initvalue)
|
||||
continue; /* defaults to NULL or 0 */
|
||||
@@ -657,22 +636,23 @@ config_dump(const config_format_t *fmt, const void *default_options,
|
||||
}
|
||||
|
||||
elements = smartlist_new();
|
||||
for (i=0; fmt->vars[i].name; ++i) {
|
||||
for (i=0; fmt->vars[i].member.name; ++i) {
|
||||
int comment_option = 0;
|
||||
if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
|
||||
fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
|
||||
if (fmt->vars[i].member.type == CONFIG_TYPE_OBSOLETE ||
|
||||
fmt->vars[i].member.type == CONFIG_TYPE_LINELIST_S)
|
||||
continue;
|
||||
/* Don't save 'hidden' control variables. */
|
||||
if (!strcmpstart(fmt->vars[i].name, "__"))
|
||||
if (!strcmpstart(fmt->vars[i].member.name, "__"))
|
||||
continue;
|
||||
if (minimal && config_is_same(fmt, options, defaults, fmt->vars[i].name))
|
||||
if (minimal && config_is_same(fmt, options, defaults,
|
||||
fmt->vars[i].member.name))
|
||||
continue;
|
||||
else if (comment_defaults &&
|
||||
config_is_same(fmt, options, defaults, fmt->vars[i].name))
|
||||
config_is_same(fmt, options, defaults, fmt->vars[i].member.name))
|
||||
comment_option = 1;
|
||||
|
||||
line = assigned =
|
||||
config_get_assigned_option(fmt, options, fmt->vars[i].name, 1);
|
||||
config_get_assigned_option(fmt, options, fmt->vars[i].member.name, 1);
|
||||
|
||||
for (; line; line = line->next) {
|
||||
if (!strcmpstart(line->key, "__")) {
|
||||
@@ -688,7 +668,7 @@ config_dump(const config_format_t *fmt, const void *default_options,
|
||||
}
|
||||
|
||||
if (fmt->extra) {
|
||||
line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
|
||||
line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->offset);
|
||||
for (; line; line = line->next) {
|
||||
smartlist_add_asprintf(elements, "%s %s\n", line->key, line->value);
|
||||
}
|
||||
|
||||
@@ -34,10 +34,8 @@ typedef struct config_deprecation_t {
|
||||
|
||||
/** A variable allowed in the configuration file or on the command line. */
|
||||
typedef struct config_var_t {
|
||||
const char *name; /**< The full keyword (case insensitive). */
|
||||
config_type_t type; /**< How to interpret the type and turn it into a
|
||||
* value. */
|
||||
off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
|
||||
struct_member_t member; /** A struct member corresponding to this
|
||||
* variable. */
|
||||
const char *initvalue; /**< String (or null) describing initial value. */
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
@@ -74,12 +72,12 @@ typedef struct config_var_t {
|
||||
#define CONF_TEST_MEMBERS(tp, conftype, member) \
|
||||
, CONF_CHECK_VAR_TYPE(tp, conftype, member)
|
||||
#define END_OF_CONFIG_VARS \
|
||||
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, { .INT=NULL } }
|
||||
{ { .name = NULL }, NULL, { .INT=NULL } }
|
||||
#define DUMMY_TYPECHECK_INSTANCE(tp) \
|
||||
static tp tp ## _dummy
|
||||
#else /* !(defined(TOR_UNIT_TESTS)) */
|
||||
#define CONF_TEST_MEMBERS(tp, conftype, member)
|
||||
#define END_OF_CONFIG_VARS { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
|
||||
#define END_OF_CONFIG_VARS { { .name = NULL, }, NULL }
|
||||
/* Repeatedly declarable incomplete struct to absorb redundant semicolons */
|
||||
#define DUMMY_TYPECHECK_INSTANCE(tp) \
|
||||
struct tor_semicolon_eater
|
||||
@@ -108,9 +106,9 @@ typedef struct config_format_t {
|
||||
* values, and where we stick them in the structure. */
|
||||
validate_fn_t validate_fn; /**< Function to validate config. */
|
||||
free_cfg_fn_t free_fn; /**< Function to free the configuration. */
|
||||
/** If present, extra is a LINELIST variable for unrecognized
|
||||
/** If present, extra denotes a LINELIST variable for unrecognized
|
||||
* lines. Otherwise, unrecognized lines are an error. */
|
||||
config_var_t *extra;
|
||||
struct_member_t *extra;
|
||||
} config_format_t;
|
||||
|
||||
/** Macro: assert that <b>cfg</b> has the right magic field for format
|
||||
|
||||
@@ -71,8 +71,10 @@ static config_abbrev_t state_abbrevs_[] = {
|
||||
DUMMY_TYPECHECK_INSTANCE(or_state_t);
|
||||
|
||||
/*XXXX these next two are duplicates or near-duplicates from config.c */
|
||||
#define VAR(name,conftype,member,initvalue) \
|
||||
{ name, CONFIG_TYPE_ ## conftype, offsetof(or_state_t, member), \
|
||||
#define VAR(varname,conftype,member,initvalue) \
|
||||
{ { .name = varname, \
|
||||
.type = CONFIG_TYPE_ ## conftype, \
|
||||
.offset = offsetof(or_state_t, member), }, \
|
||||
initvalue CONF_TEST_MEMBERS(or_state_t, conftype, member) }
|
||||
/** As VAR, but the option name and member name are the same. */
|
||||
#define V(member,conftype,initvalue) \
|
||||
@@ -155,9 +157,10 @@ static void or_state_free_cb(void *state);
|
||||
|
||||
/** "Extra" variable in the state that receives lines we can't parse. This
|
||||
* lets us preserve options from versions of Tor newer than us. */
|
||||
static config_var_t state_extra_var = {
|
||||
"__extra", CONFIG_TYPE_LINELIST, offsetof(or_state_t, ExtraLines), NULL
|
||||
CONF_TEST_MEMBERS(or_state_t, LINELIST, ExtraLines)
|
||||
static struct_member_t state_extra_var = {
|
||||
.name = "__extra",
|
||||
.type = CONFIG_TYPE_LINELIST,
|
||||
.offset = offsetof(or_state_t, ExtraLines),
|
||||
};
|
||||
|
||||
/** Configuration format for or_state_t. */
|
||||
|
||||
@@ -52,9 +52,11 @@ static const char dstate_cur_srv_key[] = "SharedRandCurrentValue";
|
||||
DUMMY_TYPECHECK_INSTANCE(sr_disk_state_t);
|
||||
|
||||
/* These next two are duplicates or near-duplicates from config.c */
|
||||
#define VAR(name, conftype, member, initvalue) \
|
||||
{ name, CONFIG_TYPE_ ## conftype, offsetof(sr_disk_state_t, member), \
|
||||
initvalue CONF_TEST_MEMBERS(sr_disk_state_t, conftype, member) }
|
||||
#define VAR(varname, conftype, member, initvalue) \
|
||||
{ { .name = varname, \
|
||||
.type = CONFIG_TYPE_ ## conftype, \
|
||||
.offset = offsetof(sr_disk_state_t, member), }, \
|
||||
initvalue CONF_TEST_MEMBERS(sr_disk_state_t, conftype, member) }
|
||||
/* As VAR, but the option name and member name are the same. */
|
||||
#define V(member, conftype, initvalue) \
|
||||
VAR(#member, conftype, member, initvalue)
|
||||
@@ -83,10 +85,10 @@ static config_var_t state_vars[] = {
|
||||
|
||||
/* "Extra" variable in the state that receives lines we can't parse. This
|
||||
* lets us preserve options from versions of Tor newer than us. */
|
||||
static config_var_t state_extra_var = {
|
||||
"__extra", CONFIG_TYPE_LINELIST,
|
||||
offsetof(sr_disk_state_t, ExtraLines), NULL
|
||||
CONF_TEST_MEMBERS(sr_disk_state_t, LINELIST, ExtraLines)
|
||||
static struct_member_t state_extra_var = {
|
||||
.name = "__extra",
|
||||
.type = CONFIG_TYPE_LINELIST,
|
||||
.offset = offsetof(sr_disk_state_t, ExtraLines),
|
||||
};
|
||||
|
||||
/* Configuration format of sr_disk_state_t. */
|
||||
|
||||
@@ -519,7 +519,7 @@ static const var_type_fns_t routerset_type_fns = {
|
||||
.copy = routerset_copy
|
||||
};
|
||||
|
||||
const var_type_def_t routerset_type_defn = {
|
||||
const var_type_def_t ROUTERSET_type_defn = {
|
||||
.name = "RouterList",
|
||||
.fns = &routerset_type_fns
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ void routerset_free_(routerset_t *routerset);
|
||||
int routerset_len(const routerset_t *set);
|
||||
|
||||
struct var_type_def_t;
|
||||
extern const struct var_type_def_t routerset_type_defn;
|
||||
extern const struct var_type_def_t ROUTERSET_type_defn;
|
||||
|
||||
#ifdef ROUTERSET_PRIVATE
|
||||
#include "lib/container/bitarray.h"
|
||||
|
||||
@@ -48,15 +48,17 @@ typedef struct test_struct_t {
|
||||
|
||||
static test_struct_t test_struct_t_dummy;
|
||||
|
||||
#define VAR(name,conftype,member,initvalue) \
|
||||
{ name, CONFIG_TYPE_##conftype, offsetof(test_struct_t, member), \
|
||||
#define VAR(varname,conftype,member,initvalue) \
|
||||
{ { .name = varname, \
|
||||
.type = CONFIG_TYPE_##conftype, \
|
||||
.offset = offsetof(test_struct_t, member), }, \
|
||||
initvalue CONF_TEST_MEMBERS(test_struct_t, conftype, member) }
|
||||
|
||||
#define V(name,conftype,initvalue) \
|
||||
VAR( #name, conftype, name, initvalue )
|
||||
|
||||
#define OBSOLETE(name) \
|
||||
{ name, CONFIG_TYPE_OBSOLETE, 0, NULL, {.INT=NULL} }
|
||||
#define OBSOLETE(varname) \
|
||||
{ { .name=varname, .type=CONFIG_TYPE_OBSOLETE }, NULL, {.INT=NULL} }
|
||||
|
||||
static config_var_t test_vars[] = {
|
||||
V(s, STRING, "hello"),
|
||||
@@ -79,7 +81,14 @@ static config_var_t test_vars[] = {
|
||||
VAR("LineTypeA", LINELIST_S, mixed_lines, NULL),
|
||||
VAR("LineTypeB", LINELIST_S, mixed_lines, NULL),
|
||||
OBSOLETE("obsolete"),
|
||||
V(routerset, ROUTERSET, NULL),
|
||||
{
|
||||
{ .name = "routerset",
|
||||
.type = CONFIG_TYPE_ROUTERSET,
|
||||
.type_def = &ROUTERSET_type_defn,
|
||||
.offset = offsetof(test_struct_t, routerset),
|
||||
},
|
||||
NULL, {.INT=NULL}
|
||||
},
|
||||
VAR("__HiddenInt", POSINT, hidden_int, "0"),
|
||||
VAR("MixedHiddenLines", LINELIST_V, mixed_hidden_lines, NULL),
|
||||
VAR("__HiddenLineA", LINELIST_S, mixed_hidden_lines, NULL),
|
||||
@@ -757,7 +766,11 @@ test_confparse_get_assigned(void *arg)
|
||||
/* Another variant, which accepts and stores unrecognized lines.*/
|
||||
#define ETEST_MAGIC 13371337
|
||||
|
||||
static config_var_t extra = VAR("__extra", LINELIST, extra_lines, NULL);
|
||||
static struct_member_t extra = {
|
||||
.name = "__extra",
|
||||
.type = CONFIG_TYPE_LINELIST,
|
||||
.offset = offsetof(test_struct_t, extra_lines),
|
||||
};
|
||||
|
||||
static config_format_t etest_fmt = {
|
||||
sizeof(test_struct_t),
|
||||
|
||||
Reference in New Issue
Block a user