Add a --dump-config option to help testing option parsing.

This commit is contained in:
Nick Mathewson 2013-09-03 10:30:50 -04:00
parent 7972af7073
commit aac4f30d23
7 changed files with 75 additions and 12 deletions

View file

@ -9,3 +9,10 @@
- No longer allow 'tor --hash-password' with no arguments. Fixes bug - No longer allow 'tor --hash-password' with no arguments. Fixes bug
9573; bugfix on 0.0.9pre5. 9573; bugfix on 0.0.9pre5.
o Minor features:
- Support a --dump-config optoin to dump some or all of the configured
options. Mainly useful for debugging the command-line option parsing
code.

View file

@ -1801,6 +1801,7 @@ static const struct {
{ "-f", 1 }, { "-f", 1 },
{ "--defaults-torrc", 1 }, { "--defaults-torrc", 1 },
{ "--hash-password", 1 }, { "--hash-password", 1 },
{ "--dump-config", 1 },
{ "--list-fingerprint", 0 }, { "--list-fingerprint", 0 },
{ "--verify-config", 0 }, { "--verify-config", 0 },
{ "--ignore-missing-torrc", 0 }, { "--ignore-missing-torrc", 0 },
@ -2268,10 +2269,29 @@ options_init(or_options_t *options)
* include options that are the same as Tor's defaults. * include options that are the same as Tor's defaults.
*/ */
char * char *
options_dump(const or_options_t *options, int minimal) options_dump(const or_options_t *options, int how_to_dump)
{ {
return config_dump(&options_format, global_default_options, const or_options_t *use_defaults;
options, minimal, 0); int minimal;
switch (how_to_dump) {
case OPTIONS_DUMP_MINIMAL:
use_defaults = global_default_options;
minimal = 1;
break;
case OPTIONS_DUMP_DEFAULTS:
use_defaults = NULL;
minimal = 1;
break;
case OPTIONS_DUMP_ALL:
use_defaults = NULL;
minimal = 0;
break;
default:
log_warn(LD_BUG, "Bogus value for how_to_dump==%d", how_to_dump);
return NULL;
}
return config_dump(&options_format, use_defaults, options, minimal, 0);
} }
/** Return 0 if every element of sl is a string holding a decimal /** Return 0 if every element of sl is a string holding a decimal
@ -3894,6 +3914,9 @@ options_init_from_torrc(int argc, char **argv)
} else if (!strcmp(p_index->key, "--hash-password")) { } else if (!strcmp(p_index->key, "--hash-password")) {
command = CMD_HASH_PASSWORD; command = CMD_HASH_PASSWORD;
command_arg = p_index->value; command_arg = p_index->value;
} else if (!strcmp(p_index->key, "--dump-config")) {
command = CMD_DUMP_CONFIG;
command_arg = p_index->value;
} else if (!strcmp(p_index->key, "--verify-config")) { } else if (!strcmp(p_index->key, "--verify-config")) {
command = CMD_VERIFY_CONFIG; command = CMD_VERIFY_CONFIG;
} }
@ -6119,7 +6142,7 @@ write_configuration_file(const char *fname, const or_options_t *options)
return -1; return -1;
} }
if (!(new_conf = options_dump(options, 1))) { if (!(new_conf = options_dump(options, OPTIONS_DUMP_MINIMAL))) {
log_warn(LD_BUG, "Couldn't get configuration string"); log_warn(LD_BUG, "Couldn't get configuration string");
goto err; goto err;
} }

View file

@ -1074,8 +1074,8 @@ config_dump(const config_format_t *fmt, const void *default_options,
/* XXX use a 1 here so we don't add a new log line while dumping */ /* XXX use a 1 here so we don't add a new log line while dumping */
if (default_options == NULL) { if (default_options == NULL) {
if (fmt->validate_fn(NULL, defaults_tmp, 1, &msg) < 0) { if (fmt->validate_fn(NULL, defaults_tmp, defaults_tmp, 1, &msg) < 0) {
log_err(LD_BUG, "Failed to validate default config."); log_err(LD_BUG, "Failed to validate default config: %s", msg);
tor_free(msg); tor_free(msg);
tor_assert(0); tor_assert(0);
} }

View file

@ -71,7 +71,7 @@ typedef struct config_var_description_t {
/** Type of a callback to validate whether a given configuration is /** Type of a callback to validate whether a given configuration is
* well-formed and consistent. See options_trial_assign() for documentation * well-formed and consistent. See options_trial_assign() for documentation
* of arguments. */ * of arguments. */
typedef int (*validate_fn_t)(void*,void*,int,char**); typedef int (*validate_fn_t)(void*,void*,void*,int,char**);
/** Information on the keys, value types, key-to-struct-member mappings, /** Information on the keys, value types, key-to-struct-member mappings,
* variable descriptions, validation functions, and abbreviations for a * variable descriptions, validation functions, and abbreviations for a

View file

@ -1406,7 +1406,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
} else if (!strcmp(question, "config-defaults-file")) { } else if (!strcmp(question, "config-defaults-file")) {
*answer = tor_strdup(get_torrc_fname(1)); *answer = tor_strdup(get_torrc_fname(1));
} else if (!strcmp(question, "config-text")) { } else if (!strcmp(question, "config-text")) {
*answer = options_dump(get_options(), 1); *answer = options_dump(get_options(), OPTIONS_DUMP_MINIMAL);
} else if (!strcmp(question, "info/names")) { } else if (!strcmp(question, "info/names")) {
*answer = list_getinfo_options(); *answer = list_getinfo_options();
} else if (!strcmp(question, "dormant")) { } else if (!strcmp(question, "dormant")) {

View file

@ -2343,10 +2343,12 @@ tor_init(int argc, char *argv[])
for (cl = cmdline_opts; cl; cl = cl->next) { for (cl = cmdline_opts; cl; cl = cl->next) {
if (!strcmp(cl->key, "--hush")) if (!strcmp(cl->key, "--hush"))
quiet = 1; quiet = 1;
if (!strcmp(cl->key, "--quiet")) if (!strcmp(cl->key, "--quiet") ||
!strcmp(cl->key, "--dump-config"))
quiet = 2; quiet = 2;
/* --version, --digests, and --help imply --quiet */ /* --version, --digests, and --help imply --husth */
if (!strcmp(cl->key, "--version") || !strcmp(cl->key, "--digests") || if (!strcmp(cl->key, "--version") || !strcmp(cl->key, "--digests") ||
!strcmp(cl->key, "--list-torrc-options") ||
!strcmp(cl->key, "-h") || !strcmp(cl->key, "--help")) !strcmp(cl->key, "-h") || !strcmp(cl->key, "--help"))
quiet = 1; quiet = 1;
} }
@ -2597,7 +2599,7 @@ do_list_fingerprint(void)
const char *nickname = get_options()->Nickname; const char *nickname = get_options()->Nickname;
if (!server_mode(get_options())) { if (!server_mode(get_options())) {
log_err(LD_GENERAL, log_err(LD_GENERAL,
"Clients don't have long-term identity keys. Exiting.\n"); "Clients don't have long-term identity keys. Exiting.");
return -1; return -1;
} }
tor_assert(nickname); tor_assert(nickname);
@ -2635,6 +2637,34 @@ do_hash_password(void)
printf("16:%s\n",output); printf("16:%s\n",output);
} }
/** Entry point for configuration dumping: write the configuration to
* stdout. */
static int
do_dump_config(void)
{
const or_options_t *options = get_options();
const char *arg = options->command_arg;
int how;
char *opts;
if (!strcmp(arg, "short")) {
how = OPTIONS_DUMP_MINIMAL;
} else if (!strcmp(arg, "non-builtin")) {
how = OPTIONS_DUMP_DEFAULTS;
} else if (!strcmp(arg, "full")) {
how = OPTIONS_DUMP_ALL;
} else {
printf("%s is not a recognized argument to --dump-config. "
"Please select 'short', 'non-builtin', or 'full'", arg);
return -1;
}
opts = options_dump(options, how);
printf("%s", opts);
tor_free(opts);
return 0;
}
#if defined (WINCE) #if defined (WINCE)
int int
find_flashcard_path(PWCHAR path, size_t size) find_flashcard_path(PWCHAR path, size_t size)
@ -2752,6 +2782,9 @@ tor_main(int argc, char *argv[])
printf("Configuration was valid\n"); printf("Configuration was valid\n");
result = 0; result = 0;
break; break;
case CMD_DUMP_CONFIG:
result = do_dump_config();
break;
case CMD_RUN_UNITTESTS: /* only set by test.c */ case CMD_RUN_UNITTESTS: /* only set by test.c */
default: default:
log_warn(LD_BUG,"Illegal command number %d: internal error.", log_warn(LD_BUG,"Illegal command number %d: internal error.",

View file

@ -3398,7 +3398,7 @@ typedef struct {
/** What should the tor process actually do? */ /** What should the tor process actually do? */
enum { enum {
CMD_RUN_TOR=0, CMD_LIST_FINGERPRINT, CMD_HASH_PASSWORD, CMD_RUN_TOR=0, CMD_LIST_FINGERPRINT, CMD_HASH_PASSWORD,
CMD_VERIFY_CONFIG, CMD_RUN_UNITTESTS CMD_VERIFY_CONFIG, CMD_RUN_UNITTESTS, CMD_DUMP_CONFIG
} command; } command;
char *command_arg; /**< Argument for command-line option. */ char *command_arg; /**< Argument for command-line option. */