mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
Write most of the implementation for SAVECONF.
svn:r2820
This commit is contained in:
parent
5109de5626
commit
eabcf6618e
5
doc/TODO
5
doc/TODO
@ -53,7 +53,10 @@ ARMA - arma claims
|
||||
o stop calling a *_policy an exit_policy_t
|
||||
- Regenerate our server descriptor when a relevant option is changed from
|
||||
control.c.
|
||||
- Writing out the machine-readable torrc file
|
||||
. Writing out the machine-readable torrc file
|
||||
o Function to check whether an option has changed.
|
||||
o Function to generate the contents for a torrc file.
|
||||
- Function to safely replace a torrc file.
|
||||
- fix print_usage()
|
||||
- Download and use running-routers
|
||||
- document signals in man page
|
||||
|
123
src/or/config.c
123
src/or/config.c
@ -160,6 +160,8 @@ static config_var_t config_vars[] = {
|
||||
|
||||
static void option_reset(or_options_t *options, config_var_t *var);
|
||||
static void options_free(or_options_t *options);
|
||||
static int option_is_same(or_options_t *o1, or_options_t *o2,
|
||||
config_var_t *var);
|
||||
static or_options_t *options_dup(or_options_t *old);
|
||||
static int options_validate(or_options_t *options);
|
||||
static int options_transition_allowed(or_options_t *old, or_options_t *new);
|
||||
@ -311,6 +313,18 @@ options_act(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
char *smin, *smax;
|
||||
smin = config_dump_options(options, 1);
|
||||
smax = config_dump_options(options, 0);
|
||||
log_fn(LOG_DEBUG, "These are our options:\n%s",smax);
|
||||
log_fn(LOG_DEBUG, "We changed these options:\n%s",smin);
|
||||
tor_free(smin);
|
||||
tor_free(smax);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -938,6 +952,71 @@ options_free(or_options_t *options)
|
||||
}
|
||||
}
|
||||
|
||||
/** Return true iff the option <b>var</b> has the same value in <b>o1</b>
|
||||
* and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
|
||||
*/
|
||||
static int
|
||||
option_is_same(or_options_t *o1, or_options_t *o2, config_var_t *var)
|
||||
{
|
||||
void *v1, *v2;
|
||||
tor_assert(o1);
|
||||
tor_assert(o2);
|
||||
tor_assert(var);
|
||||
|
||||
v1 = ((char*)o1) + var-> var_offset;
|
||||
v2 = ((char*)o2) + var-> var_offset;
|
||||
switch (var->type)
|
||||
{
|
||||
case CONFIG_TYPE_UINT:
|
||||
case CONFIG_TYPE_BOOL:
|
||||
return (*(int*)v1) == (*(int*)v2);
|
||||
case CONFIG_TYPE_STRING: {
|
||||
const char *s1 = *(const char**)v1;
|
||||
const char *s2 = *(const char**)v2;
|
||||
return (!s1 && !s2) || (s1 && s2 && !strcmp(s1, s2));
|
||||
}
|
||||
case CONFIG_TYPE_DOUBLE:
|
||||
return (*(double*)v1) == (*(double*)v2);
|
||||
case CONFIG_TYPE_CSV: {
|
||||
smartlist_t *sl1 = *(smartlist_t**)v1;
|
||||
smartlist_t *sl2 = *(smartlist_t**)v2;
|
||||
int i;
|
||||
if ((sl1 && !sl2) || (!sl1 && sl2))
|
||||
return 0;
|
||||
else if (!sl1 && !sl2)
|
||||
return 1;
|
||||
else if (smartlist_len(sl1) != smartlist_len(sl2))
|
||||
return 0;
|
||||
for (i=0;i<smartlist_len(sl1);++i) {
|
||||
if (strcmp(smartlist_get(sl1,i), smartlist_get(sl2,i)))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case CONFIG_TYPE_LINELIST:
|
||||
case CONFIG_TYPE_LINELIST_V: {
|
||||
struct config_line_t *cl1 = *(struct config_line_t**)v1;
|
||||
struct config_line_t *cl2 = *(struct config_line_t**)v2;
|
||||
while (cl1 && cl2) {
|
||||
if (strcasecmp(cl1->key,cl2->key) || strcmp(cl1->value,cl2->value))
|
||||
return 0;
|
||||
cl1 = cl1->next;
|
||||
cl2 = cl2->next;
|
||||
}
|
||||
if (!cl1 && !cl2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
case CONFIG_TYPE_LINELIST_S:
|
||||
case CONFIG_TYPE_OBSOLETE:
|
||||
default:
|
||||
log_fn(LOG_ERR,"Internal error: can't compare configuration option '%s'",
|
||||
var->name);
|
||||
tor_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy storage held by <b>old</b> into a new or_options_t and return it. */
|
||||
static or_options_t *
|
||||
options_dup(or_options_t *old)
|
||||
@ -981,6 +1060,50 @@ options_init(or_options_t *options)
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a string containing a possible configuration file that would give
|
||||
* the configuration in <b>options</b>. If <b>minimal</b> is true, do not
|
||||
* include options that are the same as Tor's defaults.
|
||||
*/
|
||||
char *
|
||||
config_dump_options(or_options_t *options, int minimal)
|
||||
{
|
||||
smartlist_t *elements;
|
||||
or_options_t *defaults;
|
||||
struct config_line_t *line;
|
||||
char *result;
|
||||
int i;
|
||||
|
||||
defaults = tor_malloc_zero(sizeof(or_options_t));
|
||||
options_init(defaults);
|
||||
options_validate(defaults); /* ??? will this work? */
|
||||
|
||||
elements = smartlist_create();
|
||||
for (i=0; config_vars[i].name; ++i) {
|
||||
if (config_vars[i].type == CONFIG_TYPE_OBSOLETE ||
|
||||
config_vars[i].type == CONFIG_TYPE_LINELIST_S)
|
||||
continue;
|
||||
if (minimal && option_is_same(options, defaults, &config_vars[i]))
|
||||
continue;
|
||||
line = config_get_assigned_option(options, config_vars[i].name);
|
||||
for (; line; line = line->next) {
|
||||
size_t len = strlen(line->key) + strlen(line->value) + 3;
|
||||
char *tmp;
|
||||
tmp = tor_malloc(len);
|
||||
if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
|
||||
log_fn(LOG_ERR, "Internal error writing log option");
|
||||
tor_assert(0);
|
||||
}
|
||||
smartlist_add(elements, tmp);
|
||||
}
|
||||
config_free_lines(line);
|
||||
}
|
||||
|
||||
result = smartlist_join_strings(elements, "", 0, NULL);
|
||||
SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
|
||||
smartlist_free(elements);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return 0 if every setting in <b>options</b> is reasonable. Else
|
||||
* warn and return -1. Should have no side effects, except for
|
||||
* normalizing the contents of <b>options</b>. */
|
||||
|
@ -1116,6 +1116,7 @@ struct config_line_t *config_get_assigned_option(or_options_t *options,
|
||||
const char *key);
|
||||
struct config_line_t *config_line_prepend(struct config_line_t *front,
|
||||
const char *key, const char *val);
|
||||
char *config_dump_options(or_options_t *options, int minimal);
|
||||
|
||||
/********************************* connection.c ***************************/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user