commit 9826fb19815794507cbc55358439758fbf700291 Author: Nick Mathewson nickm@torproject.org Date: Tue Oct 8 11:47:43 2019 -0400
Add a return type for the parsed commandline.
Previously it was stored in two outvars, but this is more elegant. I'm going to be expanding this struct in later commits. --- src/app/config/config.c | 89 ++++++++++++++++++++++++++----------------------- src/app/config/config.h | 17 ++++++++-- src/app/main/main.c | 14 ++++---- 3 files changed, 69 insertions(+), 51 deletions(-)
diff --git a/src/app/config/config.c b/src/app/config/config.c index 1abe1e13a..74cd70ad3 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -885,12 +885,8 @@ static or_options_t *global_default_options = NULL; static char *torrc_fname = NULL; /** Name of the most recently read torrc-defaults file.*/ static char *torrc_defaults_fname = NULL; -/** Configuration options set by command line. */ -static config_line_t *global_cmdline_options = 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; +/** Result of parsing the command line. */ +static parsed_cmdline_t *global_cmdline = NULL; /** Contents of most recently read DirPortFrontPage file. */ static char *global_dirfrontpagecontents = NULL; /** List of port_cfg_t for all configured ports. */ @@ -1064,11 +1060,7 @@ config_free_all(void) or_options_free(global_default_options); global_default_options = NULL;
- config_free_lines(global_cmdline_options); - global_cmdline_options = NULL; - - config_free_lines(global_cmdline_only_options); - global_cmdline_only_options = NULL; + parsed_cmdline_free(global_cmdline);
if (configured_ports) { SMARTLIST_FOREACH(configured_ports, @@ -1083,7 +1075,6 @@ config_free_all(void)
cleanup_protocol_warning_severity_level();
- have_parsed_cmdline = 0; libevent_initialized = 0;
config_mgr_free(options_mgr); @@ -2459,8 +2450,12 @@ typedef enum { ARGUMENT_OPTIONAL = 2 } 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 { + /** The string that the user has to provide. */ const char *name; + /** Does this option accept an argument? */ takes_argument_t takes_argument; } CMDLINE_ONLY_OPTIONS[] = { { .name="-f", @@ -2497,22 +2492,20 @@ static const struct { };
/** 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 - * commandline-only options in *<b>cmdline_result</b>, and return 0; - * otherwise, return -1 and leave *<b>result</b> and <b>cmdline_result</b> - * alone. */ -int -config_parse_commandline(int argc, char **argv, int ignore_errors, - config_line_t **result, - config_line_t **cmdline_result) + * successful, return a newly allocated parsed_cmdline_t; otherwise return + * NULL. + * + * If <b>ignore_errors</b> is set, try to recover from all recoverable + * errors and return the best command line we can. + */ +parsed_cmdline_t * +config_parse_commandline(int argc, char **argv, int ignore_errors) { + parsed_cmdline_t *result = tor_malloc_zero(sizeof(parsed_cmdline_t)); config_line_t *param = NULL;
- config_line_t *front = NULL; - config_line_t **new = &front; - - config_line_t *front_cmdline = NULL; - config_line_t **new_cmdline = &front_cmdline; + config_line_t **new_cmdline = &result->cmdline_opts; + config_line_t **new = &result->other_opts;
char *s, *arg; int i = 1; @@ -2557,9 +2550,8 @@ config_parse_commandline(int argc, char **argv, int ignore_errors, } else { log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.", argv[i]); - config_free_lines(front); - config_free_lines(front_cmdline); - return -1; + parsed_cmdline_free(result); + return NULL; } } else if (want_arg == ARGUMENT_OPTIONAL && is_last) { arg = tor_strdup(""); @@ -2587,9 +2579,19 @@ config_parse_commandline(int argc, char **argv, int ignore_errors,
i += want_arg ? 2 : 1; } - *cmdline_result = front_cmdline; - *result = front; - return 0; + + return result; +} + +/** 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. */ @@ -5199,24 +5201,20 @@ int options_init_from_torrc(int argc, char **argv) { char *cf=NULL, *cf_defaults=NULL; - int command; int retval = -1; - char *command_arg = NULL; char *errmsg=NULL; - config_line_t *p_index = NULL; - config_line_t *cmdline_only_options = NULL; + const config_line_t *cmdline_only_options;
/* 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. * It does not really matter */ - if (config_parse_commandline(argc, argv, 0, &global_cmdline_options, - &global_cmdline_only_options) < 0) { + global_cmdline = config_parse_commandline(argc, argv, 0); + if (global_cmdline == NULL) { 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") || config_line_find(cmdline_only_options, "--help")) { @@ -5465,8 +5463,15 @@ options_init_from_string(const char *cf_defaults, const char *cf, }
/* 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) { err = SETOPT_ERR_PARSE; goto err; diff --git a/src/app/config/config.h b/src/app/config/config.h index 44f09e5ee..fe4e272d8 100644 --- a/src/app/config/config.h +++ b/src/app/config/config.h @@ -197,9 +197,20 @@ int init_cookie_authentication(const char *fname, const char *header,
or_options_t *options_new(void);
-int config_parse_commandline(int argc, char **argv, int ignore_errors, - struct config_line_t **result, - struct config_line_t **cmdline_result); +/** Options settings parsed from the command-line. */ +typedef struct { + /** 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; +} 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); /* XXXX move to connection_edge.h */ diff --git a/src/app/main/main.c b/src/app/main/main.c index 3bdf8f146..0edda66fd 100644 --- a/src/app/main/main.c +++ b/src/app/main/main.c @@ -549,10 +549,13 @@ tor_init(int argc, char *argv[]) { /* We search for the "quiet" option first, since it decides whether we * will log anything at all to the command line. */ - config_line_t *opts = NULL, *cmdline_opts = NULL; - const config_line_t *cl; - (void) config_parse_commandline(argc, argv, 1, &opts, &cmdline_opts); - for (cl = cmdline_opts; cl; cl = cl->next) { + parsed_cmdline_t *cmdline; + const config_line_t *cl = NULL; + cmdline = config_parse_commandline(argc, argv, 1); + if (cmdline != NULL) { + cl = cmdline->cmdline_opts; + } + for (; cl; cl = cl->next) { if (!strcmp(cl->key, "--hush")) quiet = 1; if (!strcmp(cl->key, "--quiet") || @@ -569,8 +572,7 @@ tor_init(int argc, char *argv[]) quiet = 1; } } - config_free_lines(opts); - config_free_lines(cmdline_opts); + parsed_cmdline_free(cmdline); }
/* give it somewhere to log to initially */
tor-commits@lists.torproject.org