Merge branch 'cmdline_refactor'

This commit is contained in:
Nick Mathewson 2019-10-17 12:01:45 -04:00
commit 800b823c29
13 changed files with 250 additions and 135 deletions

4
changes/ticket32003 Normal file
View file

@ -0,0 +1,4 @@
o Code simplification and refactoring:
- When parsing the command line, handle options that determine our "quiet
level" and our mode of operation (e.g., --dump-config and so on)
all in one table. Closes ticket 32003.

View file

@ -885,12 +885,8 @@ static or_options_t *global_default_options = NULL;
static char *torrc_fname = NULL; static char *torrc_fname = NULL;
/** Name of the most recently read torrc-defaults file.*/ /** Name of the most recently read torrc-defaults file.*/
static char *torrc_defaults_fname = NULL; static char *torrc_defaults_fname = NULL;
/** Configuration options set by command line. */ /** Result of parsing the command line. */
static config_line_t *global_cmdline_options = NULL; static parsed_cmdline_t *global_cmdline = NULL;
/** Non-configuration options set by the command line */
static config_line_t *global_cmdline_only_options = NULL;
/** Boolean: Have we parsed the command line? */
static int have_parsed_cmdline = 0;
/** Contents of most recently read DirPortFrontPage file. */ /** Contents of most recently read DirPortFrontPage file. */
static char *global_dirfrontpagecontents = NULL; static char *global_dirfrontpagecontents = NULL;
/** List of port_cfg_t for all configured ports. */ /** List of port_cfg_t for all configured ports. */
@ -1064,11 +1060,7 @@ config_free_all(void)
or_options_free(global_default_options); or_options_free(global_default_options);
global_default_options = NULL; global_default_options = NULL;
config_free_lines(global_cmdline_options); parsed_cmdline_free(global_cmdline);
global_cmdline_options = NULL;
config_free_lines(global_cmdline_only_options);
global_cmdline_only_options = NULL;
if (configured_ports) { if (configured_ports) {
SMARTLIST_FOREACH(configured_ports, SMARTLIST_FOREACH(configured_ports,
@ -1083,7 +1075,6 @@ config_free_all(void)
cleanup_protocol_warning_severity_level(); cleanup_protocol_warning_severity_level();
have_parsed_cmdline = 0;
libevent_initialized = 0; libevent_initialized = 0;
config_mgr_free(options_mgr); config_mgr_free(options_mgr);
@ -2447,60 +2438,102 @@ options_act(const or_options_t *old_options)
return 0; return 0;
} }
/**
* Enumeration to describe the syntax for a command-line option.
**/
typedef enum { typedef enum {
TAKES_NO_ARGUMENT = 0, /** Describe an option that does not take an argument. */
ARGUMENT_NONE = 0,
/** Describes an option that takes a single argument. */
ARGUMENT_NECESSARY = 1, ARGUMENT_NECESSARY = 1,
/** Describes an option that takes a single optional argument. */
ARGUMENT_OPTIONAL = 2 ARGUMENT_OPTIONAL = 2
} takes_argument_t; } takes_argument_t;
/** Table describing arguments that Tor accepts on the command line,
* other than those that are the same as in torrc. */
static const struct { static const struct {
/** The string that the user has to provide. */
const char *name; const char *name;
/** Does this option accept an argument? */
takes_argument_t takes_argument; takes_argument_t takes_argument;
/** If not CMD_RUN_TOR, what should Tor do when it starts? */
tor_cmdline_mode_t command;
/** If nonzero, set the quiet level to this. 1 is "hush", 2 is "quiet" */
int quiet;
} CMDLINE_ONLY_OPTIONS[] = { } CMDLINE_ONLY_OPTIONS[] = {
{ "-f", ARGUMENT_NECESSARY }, { .name="-f",
{ "--allow-missing-torrc", TAKES_NO_ARGUMENT }, .takes_argument=ARGUMENT_NECESSARY },
{ "--defaults-torrc", ARGUMENT_NECESSARY }, { .name="--allow-missing-torrc" },
{ "--hash-password", ARGUMENT_NECESSARY }, { .name="--defaults-torrc",
{ "--dump-config", ARGUMENT_OPTIONAL }, .takes_argument=ARGUMENT_NECESSARY },
{ "--list-fingerprint", TAKES_NO_ARGUMENT }, { .name="--hash-password",
{ "--keygen", TAKES_NO_ARGUMENT }, .takes_argument=ARGUMENT_NECESSARY,
{ "--key-expiration", ARGUMENT_OPTIONAL }, .command=CMD_HASH_PASSWORD,
{ "--newpass", TAKES_NO_ARGUMENT }, .quiet=QUIET_HUSH },
{ "--no-passphrase", TAKES_NO_ARGUMENT }, { .name="--dump-config",
{ "--passphrase-fd", ARGUMENT_NECESSARY }, .takes_argument=ARGUMENT_OPTIONAL,
{ "--verify-config", TAKES_NO_ARGUMENT }, .command=CMD_DUMP_CONFIG,
{ "--ignore-missing-torrc", TAKES_NO_ARGUMENT }, .quiet=QUIET_SILENT },
{ "--quiet", TAKES_NO_ARGUMENT }, { .name="--list-fingerprint",
{ "--hush", TAKES_NO_ARGUMENT }, .command=CMD_LIST_FINGERPRINT },
{ "--version", TAKES_NO_ARGUMENT }, { .name="--keygen",
{ "--list-modules", TAKES_NO_ARGUMENT }, .command=CMD_KEYGEN },
{ "--library-versions", TAKES_NO_ARGUMENT }, { .name="--key-expiration",
{ "-h", TAKES_NO_ARGUMENT }, .takes_argument=ARGUMENT_OPTIONAL,
{ "--help", TAKES_NO_ARGUMENT }, .command=CMD_KEY_EXPIRATION },
{ "--list-torrc-options", TAKES_NO_ARGUMENT }, { .name="--newpass" },
{ "--list-deprecated-options",TAKES_NO_ARGUMENT }, { .name="--no-passphrase" },
{ "--nt-service", TAKES_NO_ARGUMENT }, { .name="--passphrase-fd",
{ "-nt-service", TAKES_NO_ARGUMENT }, .takes_argument=ARGUMENT_NECESSARY },
{ NULL, 0 }, { .name="--verify-config",
.command=CMD_VERIFY_CONFIG },
{ .name="--ignore-missing-torrc" },
{ .name="--quiet",
.quiet=QUIET_SILENT },
{ .name="--hush",
.quiet=QUIET_HUSH },
{ .name="--version",
.command=CMD_IMMEDIATE,
.quiet=QUIET_HUSH },
{ .name="--list-modules",
.command=CMD_IMMEDIATE,
.quiet=QUIET_HUSH },
{ .name="--library-versions",
.command=CMD_IMMEDIATE,
.quiet=QUIET_HUSH },
{ .name="-h",
.command=CMD_IMMEDIATE,
.quiet=QUIET_HUSH },
{ .name="--help",
.command=CMD_IMMEDIATE,
.quiet=QUIET_HUSH },
{ .name="--list-torrc-options",
.command=CMD_IMMEDIATE,
.quiet=QUIET_HUSH },
{ .name="--list-deprecated-options",
.command=CMD_IMMEDIATE },
{ .name="--nt-service" },
{ .name="-nt-service" },
{ .name=NULL },
}; };
/** Helper: Read a list of configuration options from the command line. If /** Helper: Read a list of configuration options from the command line. If
* successful, or if ignore_errors is set, put them in *<b>result</b>, put the * successful, return a newly allocated parsed_cmdline_t; otherwise return
* commandline-only options in *<b>cmdline_result</b>, and return 0; * NULL.
* otherwise, return -1 and leave *<b>result</b> and <b>cmdline_result</b> *
* alone. */ * If <b>ignore_errors</b> is set, try to recover from all recoverable
int * errors and return the best command line we can.
config_parse_commandline(int argc, char **argv, int ignore_errors, */
config_line_t **result, parsed_cmdline_t *
config_line_t **cmdline_result) config_parse_commandline(int argc, char **argv, int ignore_errors)
{ {
parsed_cmdline_t *result = tor_malloc_zero(sizeof(parsed_cmdline_t));
result->command = CMD_RUN_TOR;
config_line_t *param = NULL; config_line_t *param = NULL;
config_line_t *front = NULL; config_line_t **new_cmdline = &result->cmdline_opts;
config_line_t **new = &front; config_line_t **new = &result->other_opts;
config_line_t *front_cmdline = NULL;
config_line_t **new_cmdline = &front_cmdline;
char *s, *arg; char *s, *arg;
int i = 1; int i = 1;
@ -2510,11 +2543,19 @@ config_parse_commandline(int argc, char **argv, int ignore_errors,
takes_argument_t want_arg = ARGUMENT_NECESSARY; takes_argument_t want_arg = ARGUMENT_NECESSARY;
int is_cmdline = 0; int is_cmdline = 0;
int j; int j;
bool is_a_command = false;
for (j = 0; CMDLINE_ONLY_OPTIONS[j].name != NULL; ++j) { for (j = 0; CMDLINE_ONLY_OPTIONS[j].name != NULL; ++j) {
if (!strcmp(argv[i], CMDLINE_ONLY_OPTIONS[j].name)) { if (!strcmp(argv[i], CMDLINE_ONLY_OPTIONS[j].name)) {
is_cmdline = 1; is_cmdline = 1;
want_arg = CMDLINE_ONLY_OPTIONS[j].takes_argument; want_arg = CMDLINE_ONLY_OPTIONS[j].takes_argument;
if (CMDLINE_ONLY_OPTIONS[j].command != CMD_RUN_TOR) {
is_a_command = true;
result->command = CMDLINE_ONLY_OPTIONS[j].command;
}
quiet_level_t quiet = CMDLINE_ONLY_OPTIONS[j].quiet;
if (quiet > result->quiet_level)
result->quiet_level = quiet;
break; break;
} }
} }
@ -2545,14 +2586,13 @@ config_parse_commandline(int argc, char **argv, int ignore_errors,
} else { } else {
log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.", log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
argv[i]); argv[i]);
config_free_lines(front); parsed_cmdline_free(result);
config_free_lines(front_cmdline); return NULL;
return -1;
} }
} else if (want_arg == ARGUMENT_OPTIONAL && is_last) { } else if (want_arg == ARGUMENT_OPTIONAL && is_last) {
arg = tor_strdup(""); arg = tor_strdup("");
} else { } else {
arg = (want_arg != TAKES_NO_ARGUMENT) ? tor_strdup(argv[i+1]) : arg = (want_arg != ARGUMENT_NONE) ? tor_strdup(argv[i+1]) :
tor_strdup(""); tor_strdup("");
} }
@ -2565,6 +2605,10 @@ config_parse_commandline(int argc, char **argv, int ignore_errors,
log_debug(LD_CONFIG, "command line: parsed keyword '%s', value '%s'", log_debug(LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
param->key, param->value); param->key, param->value);
if (is_a_command) {
result->command_arg = param->value;
}
if (is_cmdline) { if (is_cmdline) {
*new_cmdline = param; *new_cmdline = param;
new_cmdline = &((*new_cmdline)->next); new_cmdline = &((*new_cmdline)->next);
@ -2575,9 +2619,19 @@ config_parse_commandline(int argc, char **argv, int ignore_errors,
i += want_arg ? 2 : 1; i += want_arg ? 2 : 1;
} }
*cmdline_result = front_cmdline;
*result = front; return result;
return 0; }
/** Release all storage held by <b>cmdline</b>. */
void
parsed_cmdline_free_(parsed_cmdline_t *cmdline)
{
if (!cmdline)
return;
config_free_lines(cmdline->cmdline_opts);
config_free_lines(cmdline->other_opts);
tor_free(cmdline);
} }
/** Return true iff key is a valid configuration option. */ /** Return true iff key is a valid configuration option. */
@ -3006,7 +3060,9 @@ is_local_addr, (const tor_addr_t *addr))
or_options_t * or_options_t *
options_new(void) options_new(void)
{ {
return config_new(get_options_mgr()); or_options_t *options = config_new(get_options_mgr());
options->command = CMD_RUN_TOR;
return options;
} }
/** Set <b>options</b> to hold reasonable defaults for most options. /** Set <b>options</b> to hold reasonable defaults for most options.
@ -5048,12 +5104,12 @@ normalize_nickname_list(config_line_t **normalized_out,
* filename if it doesn't exist. * filename if it doesn't exist.
*/ */
static char * static char *
find_torrc_filename(config_line_t *cmd_arg, find_torrc_filename(const config_line_t *cmd_arg,
int defaults_file, int defaults_file,
int *using_default_fname, int *ignore_missing_torrc) int *using_default_fname, int *ignore_missing_torrc)
{ {
char *fname=NULL; char *fname=NULL;
config_line_t *p_index; const config_line_t *p_index;
const char *fname_opt = defaults_file ? "--defaults-torrc" : "-f"; const char *fname_opt = defaults_file ? "--defaults-torrc" : "-f";
const char *ignore_opt = defaults_file ? NULL : "--ignore-missing-torrc"; const char *ignore_opt = defaults_file ? NULL : "--ignore-missing-torrc";
@ -5132,7 +5188,7 @@ load_torrc_from_stdin(void)
* Return the contents of the file on success, and NULL on failure. * Return the contents of the file on success, and NULL on failure.
*/ */
static char * static char *
load_torrc_from_disk(config_line_t *cmd_arg, int defaults_file) load_torrc_from_disk(const config_line_t *cmd_arg, int defaults_file)
{ {
char *fname=NULL; char *fname=NULL;
char *cf = NULL; char *cf = NULL;
@ -5187,24 +5243,20 @@ int
options_init_from_torrc(int argc, char **argv) options_init_from_torrc(int argc, char **argv)
{ {
char *cf=NULL, *cf_defaults=NULL; char *cf=NULL, *cf_defaults=NULL;
int command;
int retval = -1; int retval = -1;
char *command_arg = NULL;
char *errmsg=NULL; char *errmsg=NULL;
config_line_t *p_index = NULL; const config_line_t *cmdline_only_options;
config_line_t *cmdline_only_options = NULL;
/* Go through command-line variables */ /* Go through command-line variables */
if (! have_parsed_cmdline) { if (global_cmdline == NULL) {
/* Or we could redo the list every time we pass this place. /* Or we could redo the list every time we pass this place.
* It does not really matter */ * It does not really matter */
if (config_parse_commandline(argc, argv, 0, &global_cmdline_options, global_cmdline = config_parse_commandline(argc, argv, 0);
&global_cmdline_only_options) < 0) { if (global_cmdline == NULL) {
goto err; goto err;
} }
have_parsed_cmdline = 1;
} }
cmdline_only_options = global_cmdline_only_options; cmdline_only_options = global_cmdline->cmdline_opts;
if (config_line_find(cmdline_only_options, "-h") || if (config_line_find(cmdline_only_options, "-h") ||
config_line_find(cmdline_only_options, "--help")) { config_line_find(cmdline_only_options, "--help")) {
@ -5267,25 +5319,10 @@ options_init_from_torrc(int argc, char **argv)
return 1; return 1;
} }
command = CMD_RUN_TOR; int command = global_cmdline->command;
for (p_index = cmdline_only_options; p_index; p_index = p_index->next) { const char *command_arg = global_cmdline->command_arg;
if (!strcmp(p_index->key,"--keygen")) { /* "immediate" has already been handled by this point. */
command = CMD_KEYGEN; tor_assert(command != CMD_IMMEDIATE);
} else if (!strcmp(p_index->key, "--key-expiration")) {
command = CMD_KEY_EXPIRATION;
command_arg = p_index->value;
} else if (!strcmp(p_index->key,"--list-fingerprint")) {
command = CMD_LIST_FINGERPRINT;
} else if (!strcmp(p_index->key, "--hash-password")) {
command = CMD_HASH_PASSWORD;
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")) {
command = CMD_VERIFY_CONFIG;
}
}
if (command == CMD_HASH_PASSWORD) { if (command == CMD_HASH_PASSWORD) {
cf_defaults = tor_strdup(""); cf_defaults = tor_strdup("");
@ -5453,8 +5490,15 @@ options_init_from_string(const char *cf_defaults, const char *cf,
} }
/* Go through command-line variables too */ /* Go through command-line variables too */
retval = config_assign(get_options_mgr(), newoptions, {
global_cmdline_options, CAL_WARN_DEPRECATIONS, msg); config_line_t *other_opts = NULL;
if (global_cmdline) {
other_opts = global_cmdline->other_opts;
}
retval = config_assign(get_options_mgr(), newoptions,
other_opts,
CAL_WARN_DEPRECATIONS, msg);
}
if (retval < 0) { if (retval < 0) {
err = SETOPT_ERR_PARSE; err = SETOPT_ERR_PARSE;
goto err; goto err;

View file

@ -14,6 +14,7 @@
#include "app/config/or_options_st.h" #include "app/config/or_options_st.h"
#include "lib/testsupport/testsupport.h" #include "lib/testsupport/testsupport.h"
#include "app/config/quiet_level.h"
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(DARWIN) #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(DARWIN)
#define KERNEL_MAY_SUPPORT_IPFW #define KERNEL_MAY_SUPPORT_IPFW
@ -197,9 +198,26 @@ int init_cookie_authentication(const char *fname, const char *header,
or_options_t *options_new(void); or_options_t *options_new(void);
int config_parse_commandline(int argc, char **argv, int ignore_errors, /** Options settings parsed from the command-line. */
struct config_line_t **result, typedef struct {
struct config_line_t **cmdline_result); /** List of options that can only be set from the command-line */
struct config_line_t *cmdline_opts;
/** List of other options, to be handled by the general Tor configuration
system. */
struct config_line_t *other_opts;
/** Subcommand that Tor has been told to run */
tor_cmdline_mode_t command;
/** Argument for the command mode, if any. */
const char *command_arg;
/** How quiet have we been told to be? */
quiet_level_t quiet_level;
} parsed_cmdline_t;
parsed_cmdline_t *config_parse_commandline(int argc, char **argv,
int ignore_errors);
void parsed_cmdline_free_(parsed_cmdline_t *cmdline);
#define parsed_cmdline_free(c) \
FREE_AND_NULL(parsed_cmdline_t, parsed_cmdline_free_, (c))
void config_register_addressmaps(const or_options_t *options); void config_register_addressmaps(const or_options_t *options);
/* XXXX move to connection_edge.h */ /* XXXX move to connection_edge.h */

View file

@ -15,6 +15,7 @@
#include "lib/cc/torint.h" #include "lib/cc/torint.h"
#include "lib/net/address.h" #include "lib/net/address.h"
#include "app/config/tor_cmdline_mode.h"
struct smartlist_t; struct smartlist_t;
struct config_line_t; struct config_line_t;
@ -31,12 +32,7 @@ struct or_options_t {
uint32_t magic_; uint32_t magic_;
/** What should the tor process actually do? */ /** What should the tor process actually do? */
enum { tor_cmdline_mode_t command;
CMD_RUN_TOR=0, CMD_LIST_FINGERPRINT, CMD_HASH_PASSWORD,
CMD_VERIFY_CONFIG, CMD_RUN_UNITTESTS, CMD_DUMP_CONFIG,
CMD_KEYGEN,
CMD_KEY_EXPIRATION,
} command;
char *command_arg; /**< Argument for command-line option. */ char *command_arg; /**< Argument for command-line option. */
struct config_line_t *Logs; /**< New-style list of configuration lines struct config_line_t *Logs; /**< New-style list of configuration lines

View file

@ -0,0 +1,28 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file quiet_level.h
* \brief Declare the quiet_level enumeration and global.
**/
#ifndef QUIET_LEVEL_H
#define QUIET_LEVEL_H
/** Enumeration to define how quietly Tor should log at startup. */
typedef enum {
/** Default quiet level: we log everything of level NOTICE or higher. */
QUIET_NONE = 0,
/** "--hush" quiet level: we log everything of level WARNING or higher. */
QUIET_HUSH = 1 ,
/** "--quiet" quiet level: we log nothing at all. */
QUIET_SILENT = 2
} quiet_level_t;
/** How quietly should Tor log at startup? */
extern quiet_level_t quiet_level;
#endif /* !defined(QUIET_LEVEL_H) */

View file

@ -0,0 +1,34 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file tor_cmdline_mode.h
* \brief Declare the tor_cmdline_mode_t enumeration
**/
#ifndef TOR_CMDLINE_MODE_H
#define TOR_CMDLINE_MODE_H
/**
* Enumeration to describe which command Tor is running. These commands
* are controlled by command-line options.
**/
typedef enum {
CMD_RUN_TOR=0, /**< The default: run Tor as a daemon. */
CMD_LIST_FINGERPRINT, /**< Running --list-fingerprint. */
CMD_HASH_PASSWORD, /**< Running --hash-password. */
CMD_VERIFY_CONFIG, /**< Running --verify-config. */
CMD_DUMP_CONFIG, /**< Running --dump-config. */
CMD_KEYGEN, /**< Running --keygen */
CMD_KEY_EXPIRATION, /**< Running --key-expiration */
CMD_IMMEDIATE, /**< Special value: indicates a command that is handled
* immediately during configuration processing. */
CMD_RUN_UNITTESTS, /**< Special value: indicates that we have entered
* the Tor code from the unit tests, not from the
* regular Tor binary at all. */
} tor_cmdline_mode_t;
#endif /* !defined(TOR_CMDLINE_MODE_H) */

View file

@ -13,6 +13,7 @@
#include "app/config/config.h" #include "app/config/config.h"
#include "app/config/statefile.h" #include "app/config/statefile.h"
#include "app/config/quiet_level.h"
#include "app/main/main.h" #include "app/main/main.h"
#include "app/main/ntmain.h" #include "app/main/ntmain.h"
#include "app/main/shutdown.h" #include "app/main/shutdown.h"
@ -110,11 +111,11 @@ static void process_signal(int sig);
/********* START VARIABLES **********/ /********* START VARIABLES **********/
/** Decides our behavior when no logs are configured/before any /** Decides our behavior when no logs are configured/before any logs have been
* logs have been configured. For 0, we log notice to stdout as normal. * configured. For QUIET_NONE, we log notice to stdout as normal. For
* For 1, we log warnings only. For 2, we log nothing. * QUIET_HUSH, we log warnings only. For QUIET_SILENT, we log nothing.
*/ */
int quiet_level = 0; quiet_level_t quiet_level = 0;
/********* END VARIABLES ************/ /********* END VARIABLES ************/
@ -528,7 +529,7 @@ int
tor_init(int argc, char *argv[]) tor_init(int argc, char *argv[])
{ {
char progname[256]; char progname[256];
int quiet = 0; quiet_level_t quiet = QUIET_NONE;
time_of_process_start = time(NULL); time_of_process_start = time(NULL);
tor_init_connection_lists(); tor_init_connection_lists();
@ -547,40 +548,25 @@ tor_init(int argc, char *argv[])
hs_init(); hs_init();
{ {
/* We search for the "quiet" option first, since it decides whether we /* We check for the "quiet"/"hush" settings first, since they decide
* will log anything at all to the command line. */ whether we log anything at all to stdout. */
config_line_t *opts = NULL, *cmdline_opts = NULL; parsed_cmdline_t *cmdline;
const config_line_t *cl; cmdline = config_parse_commandline(argc, argv, 1);
(void) config_parse_commandline(argc, argv, 1, &opts, &cmdline_opts); if (cmdline)
for (cl = cmdline_opts; cl; cl = cl->next) { quiet = cmdline->quiet_level;
if (!strcmp(cl->key, "--hush")) parsed_cmdline_free(cmdline);
quiet = 1;
if (!strcmp(cl->key, "--quiet") ||
!strcmp(cl->key, "--dump-config"))
quiet = 2;
/* The following options imply --hush */
if (!strcmp(cl->key, "--version") || !strcmp(cl->key, "--digests") ||
!strcmp(cl->key, "--list-torrc-options") ||
!strcmp(cl->key, "--library-versions") ||
!strcmp(cl->key, "--list-modules") ||
!strcmp(cl->key, "--hash-password") ||
!strcmp(cl->key, "-h") || !strcmp(cl->key, "--help")) {
if (quiet < 1)
quiet = 1;
}
}
config_free_lines(opts);
config_free_lines(cmdline_opts);
} }
/* give it somewhere to log to initially */ /* give it somewhere to log to initially */
switch (quiet) { switch (quiet) {
case 2: case QUIET_SILENT:
/* no initial logging */ /* --quiet: no initial logging */
break; break;
case 1: case QUIET_HUSH:
/* --hush: log at warning or higher. */
add_temp_log(LOG_WARN); add_temp_log(LOG_WARN);
break; break;
case QUIET_NONE: /* fall through */
default: default:
add_temp_log(LOG_NOTICE); add_temp_log(LOG_NOTICE);
} }
@ -1347,7 +1333,7 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
result = 0; result = 0;
break; break;
case CMD_VERIFY_CONFIG: case CMD_VERIFY_CONFIG:
if (quiet_level == 0) if (quiet_level == QUIET_NONE)
printf("Configuration was valid\n"); printf("Configuration was valid\n");
result = 0; result = 0;
break; break;
@ -1355,6 +1341,7 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
result = do_dump_config(); result = do_dump_config();
break; break;
case CMD_RUN_UNITTESTS: /* only set by test.c */ case CMD_RUN_UNITTESTS: /* only set by test.c */
case CMD_IMMEDIATE: /* Handled in config.c */
default: default:
log_warn(LD_BUG,"Illegal command number %d: internal error.", log_warn(LD_BUG,"Illegal command number %d: internal error.",
get_options()->command); get_options()->command);

View file

@ -340,6 +340,7 @@ nt_service_main(void)
"or --key-expiration) in NT service."); "or --key-expiration) in NT service.");
break; break;
case CMD_RUN_UNITTESTS: case CMD_RUN_UNITTESTS:
case CMD_IMMEDIATE:
default: default:
log_err(LD_CONFIG, "Illegal command number %d: internal error.", log_err(LD_CONFIG, "Illegal command number %d: internal error.",
get_options()->command); get_options()->command);

View file

@ -215,7 +215,9 @@ noinst_HEADERS += \
src/app/config/config.h \ src/app/config/config.h \
src/app/config/or_options_st.h \ src/app/config/or_options_st.h \
src/app/config/or_state_st.h \ src/app/config/or_state_st.h \
src/app/config/quiet_level.h \
src/app/config/statefile.h \ src/app/config/statefile.h \
src/app/config/tor_cmdline_mode.h \
src/app/main/main.h \ src/app/main/main.h \
src/app/main/ntmain.h \ src/app/main/ntmain.h \
src/app/main/shutdown.h \ src/app/main/shutdown.h \

View file

@ -94,7 +94,6 @@ void tor_mainloop_free_all(void);
struct token_bucket_rw_t; struct token_bucket_rw_t;
extern time_t time_of_process_start; extern time_t time_of_process_start;
extern int quiet_level;
extern struct token_bucket_rw_t global_bucket; extern struct token_bucket_rw_t global_bucket;
extern struct token_bucket_rw_t global_relayed_bucket; extern struct token_bucket_rw_t global_relayed_bucket;

View file

@ -0,0 +1 @@
--hash-password

View file

@ -0,0 +1 @@
Command-line option '--hash-password' with no value.