Merge branch 'wk/stable-2.2-global-options' into STABLE-BRANCH-2-2

--
This commit is contained in:
Werner Koch 2020-12-18 11:23:01 +01:00
commit 9e8d299e18
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
25 changed files with 2590 additions and 1458 deletions

View File

@ -1,6 +1,7 @@
/* gpg-agent.c - The GnuPG Agent /* gpg-agent.c - The GnuPG Agent
* Copyright (C) 2000-2007, 2009-2010 Free Software Foundation, Inc. * Copyright (C) 2000-2020 Free Software Foundation, Inc.
* Copyright (C) 2000-2016 Werner Koch * Copyright (C) 2000-2019 Werner Koch
* Copyright (C) 2015-2020 g10 Code GmbH
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -16,6 +17,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -169,7 +171,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")), ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")),
ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")), ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")),
ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")), ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")),
ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")), ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")),
ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oDebug, "debug", "@"),
ARGPARSE_s_n (oDebugAll, "debug-all", "@"), ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
@ -264,6 +266,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"), ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"), ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
/* Dummy options for backward compatibility. */ /* Dummy options for backward compatibility. */
ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"), ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
@ -397,7 +400,9 @@ static char *default_lc_ctype;
static char *default_lc_messages; static char *default_lc_messages;
static char *default_xauthority; static char *default_xauthority;
/* Name of a config file, which will be reread on a HUP if it is not NULL. */ /* Name of a config file which was last read on startup or, if missing,
* the name of the standard config file. Any value here enables the
* rereading of the standard config files on SIGHUP. */
static char *config_filename; static char *config_filename;
/* Helper to implement --debug-level */ /* Helper to implement --debug-level */
@ -514,9 +519,11 @@ my_strusage (int level)
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@GPG_AGENT@ (@GNUPG@)"; case 11: p = "@GPG_AGENT@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
/* TRANSLATORS: @EMAIL@ will get replaced by the actual bug /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug
reporting address. This is so that we can change the reporting address. This is so that we can change the
@ -1007,12 +1014,10 @@ main (int argc, char **argv )
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
int orig_argc; int orig_argc;
char **orig_argv; char **orig_argv;
FILE *configfp = NULL; char *last_configname = NULL;
char *configname = NULL; const char *configname = NULL;
int debug_argparser = 0;
const char *shell; const char *shell;
unsigned configlineno;
int parse_debug = 0;
int default_config =1;
int pipe_server = 0; int pipe_server = 0;
int is_daemon = 0; int is_daemon = 0;
int nodetach = 0; int nodetach = 0;
@ -1111,80 +1116,67 @@ main (int argc, char **argv )
orig_argv = argv; orig_argv = argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
while (arg_parse( &pargs, opts)) while (gnupg_argparse (NULL, &pargs, opts))
{ {
if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) switch (pargs.r_opt)
parse_debug++; {
else if (pargs.r_opt == oOptions) case oDebug:
{ /* yes there is one, so we do not try the default one, but case oDebugAll:
read the option file when it is encountered at the debug_argparser++;
commandline */ break;
default_config = 0;
}
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
gnupg_set_homedir (pargs.r.ret_str);
else if (pargs.r_opt == oDebugQuickRandom)
{
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
}
case oHomedir:
gnupg_set_homedir (pargs.r.ret_str);
break;
case oDebugQuickRandom:
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
break;
}
} }
/* Reset the flags. */
pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
/* Initialize the secure memory. */ /* Initialize the secure memory. */
gcry_control (GCRYCTL_INIT_SECMEM, SECMEM_BUFFER_SIZE, 0); gcry_control (GCRYCTL_INIT_SECMEM, SECMEM_BUFFER_SIZE, 0);
maybe_setuid = 0; maybe_setuid = 0;
/* /*
Now we are now working under our real uid * Now we are now working under our real uid
*/ */
if (default_config) gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ());
configname = make_filename (gnupg_homedir (), gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ());
GPG_AGENT_NAME EXTSEP_S "conf", NULL);
argc = orig_argc; argc = orig_argc;
argv = orig_argv; argv = orig_argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* do not remove the args */ /* We are re-using the struct, thus the reset flag. We OR the
next_pass: * flags so that the internal intialized flag won't be cleared. */
if (configname) pargs.flags |= (ARGPARSE_FLAG_RESET
{ | ARGPARSE_FLAG_KEEP
configlineno = 0; | ARGPARSE_FLAG_SYS
configfp = gnupg_fopen (configname, "r"); | ARGPARSE_FLAG_USER);
if (!configfp)
{
if (default_config)
{
if( parse_debug )
log_info (_("Note: no default option file '%s'\n"),
configname );
/* Save the default conf file name so that
reread_configuration is able to test whether the
config file has been created in the meantime. */
xfree (config_filename);
config_filename = configname;
configname = NULL;
}
else
{
log_error (_("option file '%s': %s\n"),
configname, strerror(errno) );
exit(2);
}
xfree (configname);
configname = NULL;
}
if (parse_debug && configname )
log_info (_("reading options from '%s'\n"), configname );
default_config = 0;
}
while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) ) while (gnupg_argparser (&pargs, opts, GPG_AGENT_NAME EXTSEP_S "conf"))
{ {
if (pargs.r_opt == ARGPARSE_CONFFILE)
{
if (debug_argparser)
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
if (pargs.r_type)
{
xfree (last_configname);
last_configname = xstrdup (pargs.r.ret_str);
configname = last_configname;
}
else
configname = NULL;
continue;
}
if (parse_rereadable_options (&pargs, 0)) if (parse_rereadable_options (&pargs, 0))
continue; /* Already handled */ continue; /* Already handled */
switch (pargs.r_opt) switch (pargs.r_opt)
@ -1196,18 +1188,8 @@ main (int argc, char **argv )
case oDebugWait: debug_wait = pargs.r.ret_int; break; case oDebugWait: debug_wait = pargs.r.ret_int; break;
case oOptions:
/* config files may not be nested (silently ignore them) */
if (!configfp)
{
xfree(configname);
configname = xstrdup(pargs.r.ret_str);
goto next_pass;
}
break;
case oNoGreeting: /* Dummy option. */ break; case oNoGreeting: /* Dummy option. */ break;
case oNoVerbose: opt.verbose = 0; break; case oNoVerbose: opt.verbose = 0; break;
case oNoOptions: break; /* no-options */
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oNoDetach: nodetach = 1; break; case oNoDetach: nodetach = 1; break;
case oLogFile: logfile = pargs.r.ret_str; break; case oLogFile: logfile = pargs.r.ret_str; break;
@ -1228,7 +1210,7 @@ main (int argc, char **argv )
case oUseStandardSocket: case oUseStandardSocket:
case oNoUseStandardSocket: case oNoUseStandardSocket:
obsolete_option (configname, configlineno, "use-standard-socket"); obsolete_option (configname, pargs.lineno, "use-standard-socket");
break; break;
case oFakedSystemTime: case oFakedSystemTime:
@ -1280,28 +1262,29 @@ main (int argc, char **argv )
break; break;
case oWriteEnvFile: case oWriteEnvFile:
obsolete_option (configname, configlineno, "write-env-file"); obsolete_option (configname, pargs.lineno, "write-env-file");
break; break;
default : pargs.err = configfp? 1:2; break; default:
if (configname)
pargs.err = ARGPARSE_PRINT_WARNING;
else
pargs.err = ARGPARSE_PRINT_ERROR;
break;
} }
} }
if (configfp) gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (!last_configname)
config_filename = make_filename (gnupg_homedir (),
GPG_AGENT_NAME EXTSEP_S "conf",
NULL);
else
{ {
fclose( configfp ); config_filename = last_configname;
configfp = NULL; last_configname = NULL;
/* Keep a copy of the name so that it can be read on SIGHUP. */
if (config_filename != configname)
{
xfree (config_filename);
config_filename = configname;
}
configname = NULL;
goto next_pass;
} }
xfree (configname);
configname = NULL;
if (log_get_errorcount(0)) if (log_get_errorcount(0))
exit(2); exit(2);
@ -1398,18 +1381,13 @@ main (int argc, char **argv )
agent_exit (0); agent_exit (0);
else if (gpgconf_list) else if (gpgconf_list)
{ {
char *filename;
char *filename_esc; char *filename_esc;
/* List options and default values in the GPG Conf format. */ /* List options and default values in the GPG Conf format. */
filename = make_filename (gnupg_homedir (), filename_esc = percent_escape (config_filename, NULL);
GPG_AGENT_NAME EXTSEP_S "conf", NULL);
filename_esc = percent_escape (filename, NULL);
es_printf ("%s-%s.conf:%lu:\"%s\n", es_printf ("%s-%s.conf:%lu:\"%s\n",
GPGCONF_NAME, GPG_AGENT_NAME, GPGCONF_NAME, GPG_AGENT_NAME,
GC_OPT_FLAG_DEFAULT, filename_esc); GC_OPT_FLAG_DEFAULT, filename_esc);
xfree (filename);
xfree (filename_esc); xfree (filename_esc);
es_printf ("verbose:%lu:\n" es_printf ("verbose:%lu:\n"
@ -2019,35 +1997,39 @@ static void
reread_configuration (void) reread_configuration (void)
{ {
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
FILE *fp; char *twopart;
unsigned int configlineno = 0;
int dummy; int dummy;
if (!config_filename) if (!config_filename)
return; /* No config file. */ return; /* No config file. */
fp = gnupg_fopen (config_filename, "r"); twopart = strconcat (GPG_AGENT_NAME EXTSEP_S "conf" PATHSEP_S,
if (!fp) config_filename, NULL);
{ if (!twopart)
log_info (_("option file '%s': %s\n"), return; /* Out of core. */
config_filename, strerror(errno) );
return;
}
parse_rereadable_options (NULL, 1); /* Start from the default values. */ parse_rereadable_options (NULL, 1); /* Start from the default values. */
memset (&pargs, 0, sizeof pargs); memset (&pargs, 0, sizeof pargs);
dummy = 0; dummy = 0;
pargs.argc = &dummy; pargs.argc = &dummy;
pargs.flags = 1; /* do not remove the args */ pargs.flags = (ARGPARSE_FLAG_KEEP
while (optfile_parse (fp, config_filename, &configlineno, &pargs, opts) ) |ARGPARSE_FLAG_SYS
|ARGPARSE_FLAG_USER);
while (gnupg_argparser (&pargs, opts, twopart))
{ {
if (pargs.r_opt < -1) if (pargs.r_opt == ARGPARSE_CONFFILE)
pargs.err = 1; /* Print a warning. */ {
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
}
else if (pargs.r_opt < -1)
pargs.err = ARGPARSE_PRINT_WARNING;
else /* Try to parse this option - ignore unchangeable ones. */ else /* Try to parse this option - ignore unchangeable ones. */
parse_rereadable_options (&pargs, 1); parse_rereadable_options (&pargs, 1);
} }
fclose (fp); gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
xfree (twopart);
finalize_rereadable_options (); finalize_rereadable_options ();
set_debug (); set_debug ();
} }

View File

@ -15,6 +15,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -90,9 +91,11 @@ my_strusage (int level)
const char *p; const char *p;
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "gpg-preset-passphrase (@GNUPG@)"; case 11: p = "gpg-preset-passphrase (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -218,8 +221,8 @@ main (int argc, char **argv)
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* (do not remove the args) */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (arg_parse (&pargs, opts) ) while (gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -233,6 +236,7 @@ main (int argc, char **argv)
default : pargs.err = 2; break; default : pargs.err = 2; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount(0)) if (log_get_errorcount(0))
exit(2); exit(2);

View File

@ -15,6 +15,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -145,9 +146,11 @@ my_strusage (int level)
const char *p; const char *p;
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "gpg-protect-tool (" GNUPG_NAME ")"; case 11: p = "gpg-protect-tool (" GNUPG_NAME ")";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -551,7 +554,6 @@ show_keygrip (const char *fname)
putchar ('\n'); putchar ('\n');
} }
@ -577,8 +579,8 @@ main (int argc, char **argv )
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* (do not remove the args) */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (arg_parse (&pargs, opts) ) while (gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -608,6 +610,8 @@ main (int argc, char **argv )
default: pargs.err = ARGPARSE_PRINT_ERROR; break; default: pargs.err = ARGPARSE_PRINT_ERROR; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,15 @@
#define GNUPG_COMMON_ARGPARSE_H #define GNUPG_COMMON_ARGPARSE_H
#include <stdio.h> #include <stdio.h>
#include <gpg-error.h>
#if GPGRT_VERSION_NUMBER < 0x012600 /* 1.38 */
#define USE_INTERNAL_ARGPARSE 1
/* We use a copy of the code from the new gpgrt parser. */
struct _argparse_internal_s;
typedef struct typedef struct
{ {
int *argc; /* Pointer to ARGC (value subject to change). */ int *argc; /* Pointer to ARGC (value subject to change). */
@ -42,7 +50,7 @@ typedef struct
int err; /* Print error description for last option. int err; /* Print error description for last option.
Either 0, ARGPARSE_PRINT_WARNING or Either 0, ARGPARSE_PRINT_WARNING or
ARGPARSE_PRINT_ERROR. */ ARGPARSE_PRINT_ERROR. */
unsigned int lineno;/* The current line number. */
int r_opt; /* Returns option code. */ int r_opt; /* Returns option code. */
int r_type; /* Returns type of option value. */ int r_type; /* Returns type of option value. */
union { union {
@ -52,16 +60,9 @@ typedef struct
char *ret_str; char *ret_str;
} r; /* Return values */ } r; /* Return values */
struct { struct _argparse_internal_s *internal;
int idx; } gnupg_argparse_t;
int inarg;
int stopped;
const char *last;
void *aliases;
const void *cur_alias;
void *iio_list;
} internal; /* Private - do not change. */
} ARGPARSE_ARGS;
typedef struct typedef struct
{ {
@ -69,7 +70,11 @@ typedef struct
const char *long_opt; const char *long_opt;
unsigned int flags; unsigned int flags;
const char *description; /* Optional option description. */ const char *description; /* Optional option description. */
} ARGPARSE_OPTS; } gnupg_opt_t;
typedef gnupg_argparse_t ARGPARSE_ARGS;
typedef gnupg_opt_t ARGPARSE_OPTS;
/* Short options. */ /* Short options. */
#define ARGPARSE_SHORTOPT_HELP 32768 #define ARGPARSE_SHORTOPT_HELP 32768
@ -87,8 +92,14 @@ typedef struct
#define ARGPARSE_FLAG_ARG0 16 /* Do not skip the first arg. */ #define ARGPARSE_FLAG_ARG0 16 /* Do not skip the first arg. */
#define ARGPARSE_FLAG_ONEDASH 32 /* Allow long options with one dash. */ #define ARGPARSE_FLAG_ONEDASH 32 /* Allow long options with one dash. */
#define ARGPARSE_FLAG_NOVERSION 64 /* No output for "--version". */ #define ARGPARSE_FLAG_NOVERSION 64 /* No output for "--version". */
#define ARGPARSE_FLAG_RESET 128 /* Request to reset the internal state. */
#define ARGPARSE_FLAG_STOP_SEEN 256 /* Set to true if a "--" has been seen. */ #define ARGPARSE_FLAG_STOP_SEEN 256 /* Set to true if a "--" has been seen. */
#define ARGPARSE_FLAG_NOLINENO 512 /* Do not zero the lineno field. */
#define ARGPARSE_FLAG_SYS 1024 /* Use system config file. */
#define ARGPARSE_FLAG_USER 2048 /* Use user config file. */
#define ARGPARSE_FLAG_VERBOSE 4096 /* Print additional argparser info. */
#define ARGPARSE_FLAG_USERVERS 8192 /* Try version-ed user config files. */
#define ARGPARSE_FLAG_WITHATTR 16384 /* Return attribute bits. */
/* Flags for each option (ARGPARSE_OPTS). The type code may be /* Flags for each option (ARGPARSE_OPTS). The type code may be
ORed with the OPT flags. */ ORed with the OPT flags. */
@ -101,6 +112,11 @@ typedef struct
#define ARGPARSE_OPT_PREFIX (1<<4) /* Allow 0x etc. prefixed values. */ #define ARGPARSE_OPT_PREFIX (1<<4) /* Allow 0x etc. prefixed values. */
#define ARGPARSE_OPT_IGNORE (1<<6) /* Ignore command or option. */ #define ARGPARSE_OPT_IGNORE (1<<6) /* Ignore command or option. */
#define ARGPARSE_OPT_COMMAND (1<<7) /* The argument is a command. */ #define ARGPARSE_OPT_COMMAND (1<<7) /* The argument is a command. */
#define ARGPARSE_OPT_CONFFILE (1<<8) /* The value is a conffile. */
#define ARGPARSE_OPT_HEADER (1<<9) /* The value is printed as a header. */
#define ARGPARSE_OPT_VERBATIM (1<<10)/* The value is printed verbatim. */
#define ARGPARSE_ATTR_FORCE (1<<14)/* Attribute force is set. */
#define ARGPARSE_ATTR_IGNORE (1<<15)/* Attribute ignore is set. */
#define ARGPARSE_TYPE_MASK 7 /* Mask for the type values (internal). */ #define ARGPARSE_TYPE_MASK 7 /* Mask for the type values (internal). */
@ -169,19 +185,32 @@ typedef struct
#define ARGPARSE_c(s,l,d) \ #define ARGPARSE_c(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_COMMAND), (d) } { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_COMMAND), (d) }
#define ARGPARSE_conffile(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_STRING|ARGPARSE_OPT_CONFFILE), (d) }
#define ARGPARSE_noconffile(s,l,d) \
{ (s), (l), (ARGPARSE_TYPE_NONE|ARGPARSE_OPT_CONFFILE), (d) }
#define ARGPARSE_ignore(s,l) \ #define ARGPARSE_ignore(s,l) \
{ (s), (l), (ARGPARSE_OPT_IGNORE), "@" } { (s), (l), (ARGPARSE_OPT_IGNORE), "@" }
#define ARGPARSE_group(s,d) \ #define ARGPARSE_group(s,d) \
{ (s), NULL, 0, (d) } { (s), NULL, 0, (d) }
/* Placeholder options for help, version, warranty and dump-options. See arg_parse(). */ /* Verbatim print the string D in the help output. It does not make
* use of the "@" hack as ARGPARSE_group does. */
#define ARGPARSE_verbatim(d) \
{ 1, NULL, (ARGPARSE_OPT_VERBATIM), (d) }
/* Same as ARGPARSE_verbatim but also print a colon and a LF. N can
* be used give a symbolic name to the header. Nothing is printed if
* D is the empty string. */
#define ARGPARSE_header(n,d) \
{ 1, (n), (ARGPARSE_OPT_HEADER), (d) }
/* Mark the end of the list (mandatory). */
#define ARGPARSE_end() \ #define ARGPARSE_end() \
{ 0, NULL, 0, NULL }, \ { 0, NULL, 0, NULL }
{ 0, NULL, 0, NULL }, \
{ 0, NULL, 0, NULL }, \
{ 0, NULL, 0, NULL }, \
{ 0, NULL, 0, NULL }
/* Other constants. */ /* Other constants. */
@ -202,14 +231,51 @@ typedef struct
#define ARGPARSE_INVALID_ALIAS (-10) #define ARGPARSE_INVALID_ALIAS (-10)
#define ARGPARSE_OUT_OF_CORE (-11) #define ARGPARSE_OUT_OF_CORE (-11)
#define ARGPARSE_INVALID_ARG (-12) #define ARGPARSE_INVALID_ARG (-12)
#define ARGPARSE_PERMISSION_ERROR (-13)
#define ARGPARSE_NO_CONFFILE (-14)
#define ARGPARSE_CONFFILE (-15)
#define ARGPARSE_INVALID_META (-16)
#define ARGPARSE_UNKNOWN_META (-17)
#define ARGPARSE_UNEXPECTED_META (-18)
/* Values used for gnupg_set_confdir. */
#define GNUPG_CONFDIR_USER 1 /* The user's configuration dir. */
#define GNUPG_CONFDIR_SYS 2 /* The systems's configuration dir. */
/* Take care: gpgrt_argparse keeps state in ARG and requires that
* either ARGPARSE_FLAG_RESET is used after OPTS has been changed or
* gpgrt_argparse (NULL, ARG, NULL) is called first. */
int gnupg_argparse (gpgrt_stream_t fp,
gnupg_argparse_t *arg, gnupg_opt_t *opts);
int gnupg_argparser (gnupg_argparse_t *arg, gnupg_opt_t *opts,
const char *confname);
int arg_parse (ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
int optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
void usage (int level);
const char *strusage (int level); const char *strusage (int level);
void set_strusage (const char *(*f)( int )); void set_strusage (const char *(*f)( int ));
void argparse_register_outfnc (int (*fnc)(int, const char *)); void gnupg_set_usage_outfnc (int (*f)(int, const char *));
void gnupg_set_fixed_string_mapper (const char *(*f)(const char*));
void gnupg_set_confdir (int what, const char *name);
#else /* !USE_INTERNAL_ARGPARSE */
#define GNUPG_CONFDIR_USER GPGRT_CONFDIR_USER
#define GNUPG_CONFDIR_SYS GPGRT_CONFDIR_SYS
typedef gpgrt_argparse_t gnupg_argparse_t;
typedef gpgrt_opt_t gnupg_opt_t;
typedef gpgrt_argparse_t ARGPARSE_ARGS;
typedef gpgrt_opt_t ARGPARSE_OPTS;
#define gnupg_argparse(a,b,c) gpgrt_argparse ((a),(b),(c))
#define gnupg_argparser(a,b,c) gpgrt_argparser ((a),(b),(c))
#define strusage(a) gpgrt_strusage (a)
#define set_strusage(a) gpgrt_set_strusage (a)
#define gnupg_set_usage_outfnc(a) gpgrt_set_usage_outfnc ((a))
#define gnupg_set_fixed_string_mapper(a) gpgrt_set_fixed_string_mapper ((a))
#define gnupg_set_confdir(a,b) gpgrt_set_confdir ((a),(b))
#endif /* !USE_INTERNAL_ARGPARSE */
void usage (int level);
#endif /*GNUPG_COMMON_ARGPARSE_H*/ #endif /*GNUPG_COMMON_ARGPARSE_H*/

View File

@ -210,7 +210,10 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
} }
/* --version et al shall use estream as well. */ /* --version et al shall use estream as well. */
argparse_register_outfnc (writestring_via_estream); gnupg_set_usage_outfnc (writestring_via_estream);
/* Register our string mapper with gpgrt. */
gnupg_set_fixed_string_mapper (map_static_macro_string);
/* Logging shall use the standard socket directory as fallback. */ /* Logging shall use the standard socket directory as fallback. */
log_set_socket_dir_cb (gnupg_socketdir); log_set_socket_dir_cb (gnupg_socketdir);

View File

@ -510,6 +510,22 @@ AH_BOTTOM([
#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d" #define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d"
#define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d" #define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d"
/* GnuPG has always been a part of the GNU project and thus we have
* shown the FSF as holder of the copyright. We continue to do so for
* the reason that without the FSF the free software used all over the
* world would not have come into existence. However, under Windows
* we print a different copyright string with --version because the
* copyright assignments of g10 Code and Werner Koch were terminated
* many years ago, g10 Code is still the major contributor to the
* code, and Windows is not an FSF endorsed platform. Note that the
* actual list of copyright holders can be found in the AUTHORS file. */
#ifdef HAVE_W32_SYSTEM
#define GNUPG_DEF_COPYRIGHT_LINE "Copyright (C) 2020 g10 Code GmbH"
#else
#define GNUPG_DEF_COPYRIGHT_LINE "Copyright (C) 2020 Free Software Foundation, Inc."
#endif
/* For some systems (DOS currently), we hardcode the path here. For /* For some systems (DOS currently), we hardcode the path here. For
POSIX systems the values are constructed by the Makefiles, so that POSIX systems the values are constructed by the Makefiles, so that
the values may be overridden by the make invocations; this is to the values may be overridden by the make invocations; this is to
@ -563,6 +579,9 @@ AH_BOTTOM([
/* Provide the es_ macro for estream. */ /* Provide the es_ macro for estream. */
#define GPGRT_ENABLE_ES_MACROS 1 #define GPGRT_ENABLE_ES_MACROS 1
/* We want the argparse macros from gpgrt. */
#define GPGRT_ENABLE_ARGPARSE_MACROS 1
/* Tell libgcrypt not to use its own libgpg-error implementation. */ /* Tell libgcrypt not to use its own libgpg-error implementation. */
#define USE_LIBGPG_ERROR 1 #define USE_LIBGPG_ERROR 1

View File

@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -158,9 +159,11 @@ my_strusage (int level)
switch(level) switch(level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "dirmngr-client (@GNUPG@)"; case 11: p = "dirmngr-client (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
case 49: p = PACKAGE_BUGREPORT; break; case 49: p = PACKAGE_BUGREPORT; break;
@ -202,6 +205,9 @@ main (int argc, char **argv )
set_strusage (my_strusage); set_strusage (my_strusage);
log_set_prefix ("dirmngr-client", log_set_prefix ("dirmngr-client",
GPGRT_LOG_WITH_PREFIX); GPGRT_LOG_WITH_PREFIX);
/* Register our string mapper. Usually done in
* init_common_subsystems, but we don't use that here. */
gnupg_set_fixed_string_mapper (map_static_macro_string);
/* For W32 we need to initialize the socket subsystem. Because we /* For W32 we need to initialize the socket subsystem. Because we
don't use Pth we need to do this explicit. */ don't use Pth we need to do this explicit. */
@ -223,8 +229,8 @@ main (int argc, char **argv )
/* Parse the command line. */ /* Parse the command line. */
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* Do not remove the args. */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (arg_parse (&pargs, opts) ) while (gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -247,9 +253,11 @@ main (int argc, char **argv )
break; break;
case oForceDefaultResponder: opt.force_default_responder = 1; break; case oForceDefaultResponder: opt.force_default_responder = 1; break;
default : pargs.err = 2; break; default : pargs.err = ARGPARSE_PRINT_ERROR; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);

View File

@ -1,6 +1,6 @@
/* dirmngr.c - Keyserver and X.509 LDAP access /* dirmngr.c - Keyserver and X.509 LDAP access
* Copyright (C) 2002 Klarälvdalens Datakonsult AB * Copyright (C) 2002 Klarälvdalens Datakonsult AB
* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2010, 2011 g10 Code GmbH * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2010, 2011, 2020 g10 Code GmbH
* Copyright (C) 2014 Werner Koch * Copyright (C) 2014 Werner Koch
* *
* This file is part of GnuPG. * This file is part of GnuPG.
@ -17,8 +17,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* * SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-License-Identifier: GPL-3.0+
*/ */
#include <config.h> #include <config.h>
@ -183,7 +182,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")), ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")),
ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")), ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")),
ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")), ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")),
ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")), ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")),
ARGPARSE_s_s (oDebugLevel, "debug-level", ARGPARSE_s_s (oDebugLevel, "debug-level",
N_("|LEVEL|set the debugging level to LEVEL")), N_("|LEVEL|set the debugging level to LEVEL")),
ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")), ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
@ -261,6 +260,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"), ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"),
ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"), ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"), ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing " ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
"of all commands and options)\n")), "of all commands and options)\n")),
@ -392,9 +392,11 @@ my_strusage( int level )
const char *p; const char *p;
switch ( level ) switch ( level )
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@DIRMNGR@ (@GNUPG@)"; case 11: p = "@DIRMNGR@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
/* TRANSLATORS: @EMAIL@ will get replaced by the actual bug /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug
reporting address. This is so that we can change the reporting address. This is so that we can change the
@ -828,12 +830,10 @@ main (int argc, char **argv)
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
int orig_argc; int orig_argc;
char **orig_argv; char **orig_argv;
FILE *configfp = NULL; char *last_configname = NULL;
char *configname = NULL; const char *configname = NULL;
const char *shell; const char *shell;
unsigned configlineno; int debug_argparser = 0;
int parse_debug = 0;
int default_config =1;
int greeting = 0; int greeting = 0;
int nogreeting = 0; int nogreeting = 0;
int nodetach = 0; int nodetach = 0;
@ -915,63 +915,56 @@ main (int argc, char **argv)
orig_argv = argv; orig_argv = argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
while (arg_parse( &pargs, opts)) while (gnupg_argparse (NULL, &pargs, opts))
{ {
if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) switch (pargs.r_opt)
parse_debug++;
else if (pargs.r_opt == oOptions)
{ /* Yes there is one, so we do not try the default one, but
read the option file when it is encountered at the
commandline */
default_config = 0;
}
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
{ {
case oDebug:
case oDebugAll:
debug_argparser++;
break;
case oHomedir:
gnupg_set_homedir (pargs.r.ret_str); gnupg_set_homedir (pargs.r.ret_str);
break;
} }
} }
/* Reset the flags. */
pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
socket_name = dirmngr_socket_name (); socket_name = dirmngr_socket_name ();
if (default_config)
configname = make_filename (gnupg_homedir (), DIRMNGR_NAME".conf", NULL );
/* The configuraton directories for use by gpgrt_argparser. */
gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ());
gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ());
/* We are re-using the struct, thus the reset flag. We OR the
* flags so that the internal intialized flag won't be cleared. */
argc = orig_argc; argc = orig_argc;
argv = orig_argv; argv = orig_argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* do not remove the args */ pargs.flags |= (ARGPARSE_FLAG_RESET
next_pass: | ARGPARSE_FLAG_KEEP
if (configname) | ARGPARSE_FLAG_SYS
| ARGPARSE_FLAG_USER);
while (gnupg_argparser (&pargs, opts, DIRMNGR_NAME EXTSEP_S "conf"))
{ {
configlineno = 0; if (pargs.r_opt == ARGPARSE_CONFFILE)
configfp = gnupg_fopen (configname, "r");
if (!configfp)
{ {
if (default_config) if (debug_argparser)
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
if (pargs.r_type)
{ {
if( parse_debug ) xfree (last_configname);
log_info (_("Note: no default option file '%s'\n"), last_configname = xstrdup (pargs.r.ret_str);
configname ); configname = last_configname;
} }
else else
{ configname = NULL;
log_error (_("option file '%s': %s\n"), continue;
configname, strerror(errno) ); }
exit(2);
}
xfree (configname);
configname = NULL;
}
if (parse_debug && configname )
log_info (_("reading options from '%s'\n"), configname );
default_config = 0;
}
while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
{
if (parse_rereadable_options (&pargs, 0)) if (parse_rereadable_options (&pargs, 0))
continue; /* Already handled */ continue; /* Already handled */
switch (pargs.r_opt) switch (pargs.r_opt)
@ -996,18 +989,8 @@ main (int argc, char **argv)
case oDebugWait: debug_wait = pargs.r.ret_int; break; case oDebugWait: debug_wait = pargs.r.ret_int; break;
case oOptions:
/* Config files may not be nested (silently ignore them) */
if (!configfp)
{
xfree(configname);
configname = xstrdup(pargs.r.ret_str);
goto next_pass;
}
break;
case oNoGreeting: nogreeting = 1; break; case oNoGreeting: nogreeting = 1; break;
case oNoVerbose: opt.verbose = 0; break; case oNoVerbose: opt.verbose = 0; break;
case oNoOptions: break; /* no-options */
case oHomedir: /* Ignore this option here. */; break; case oHomedir: /* Ignore this option here. */; break;
case oNoDetach: nodetach = 1; break; case oNoDetach: nodetach = 1; break;
case oLogFile: logfile = pargs.r.ret_str; break; case oLogFile: logfile = pargs.r.ret_str; break;
@ -1035,20 +1018,26 @@ main (int argc, char **argv)
listen_backlog = pargs.r.ret_int; listen_backlog = pargs.r.ret_int;
break; break;
default : pargs.err = configfp? 1:2; break; default:
if (configname)
pargs.err = ARGPARSE_PRINT_WARNING;
else
pargs.err = ARGPARSE_PRINT_ERROR;
break;
} }
} }
if (configfp) gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (!last_configname)
opt.config_filename = make_filename (gnupg_homedir (),
DIRMNGR_NAME EXTSEP_S "conf",
NULL);
else
{ {
fclose (configfp); opt.config_filename = last_configname;
configfp = NULL; last_configname = NULL;
/* Keep a copy of the name so that it can be read on SIGHUP. */
opt.config_filename = configname;
configname = NULL;
goto next_pass;
} }
xfree (configname);
configname = NULL;
if (log_get_errorcount(0)) if (log_get_errorcount(0))
exit(2); exit(2);
if (nogreeting ) if (nogreeting )
@ -1479,12 +1468,6 @@ main (int argc, char **argv)
char *filename; char *filename;
char *filename_esc; char *filename_esc;
/* First the configuration file. This is not an option, but it
is vital information for GPG Conf. */
if (!opt.config_filename)
opt.config_filename = make_filename (gnupg_homedir (),
"dirmngr.conf", NULL );
filename = percent_escape (opt.config_filename, NULL); filename = percent_escape (opt.config_filename, NULL);
es_printf ("gpgconf-dirmngr.conf:%lu:\"%s\n", es_printf ("gpgconf-dirmngr.conf:%lu:\"%s\n",
GC_OPT_FLAG_DEFAULT, filename); GC_OPT_FLAG_DEFAULT, filename);
@ -1543,7 +1526,6 @@ main (int argc, char **argv)
filename_esc); filename_esc);
xfree (filename_esc); xfree (filename_esc);
es_printf ("nameserver:%lu:\n", flags | GC_OPT_FLAG_NONE); es_printf ("nameserver:%lu:\n", flags | GC_OPT_FLAG_NONE);
es_printf ("resolver-timeout:%lu:%u\n", es_printf ("resolver-timeout:%lu:%u\n",
flags | GC_OPT_FLAG_DEFAULT, 0); flags | GC_OPT_FLAG_DEFAULT, 0);
@ -1833,36 +1815,39 @@ static void
reread_configuration (void) reread_configuration (void)
{ {
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
FILE *fp; char *twopart;
unsigned int configlineno = 0;
int dummy; int dummy;
if (!opt.config_filename) if (!opt.config_filename)
return; /* No config file. */ return; /* No config file. */
fp = gnupg_fopen (opt.config_filename, "r"); twopart = strconcat (DIRMNGR_NAME EXTSEP_S "conf" PATHSEP_S,
if (!fp) opt.config_filename, NULL);
{ if (!twopart)
log_error (_("option file '%s': %s\n"), return; /* Out of core. */
opt.config_filename, strerror(errno) );
return;
}
parse_rereadable_options (NULL, 1); /* Start from the default values. */ parse_rereadable_options (NULL, 1); /* Start from the default values. */
memset (&pargs, 0, sizeof pargs); memset (&pargs, 0, sizeof pargs);
dummy = 0; dummy = 0;
pargs.argc = &dummy; pargs.argc = &dummy;
pargs.flags = 1; /* do not remove the args */ pargs.flags = (ARGPARSE_FLAG_KEEP
while (optfile_parse (fp, opt.config_filename, &configlineno, &pargs, opts) ) |ARGPARSE_FLAG_SYS
|ARGPARSE_FLAG_USER);
while (gnupg_argparser (&pargs, opts, twopart))
{ {
if (pargs.r_opt < -1) if (pargs.r_opt == ARGPARSE_CONFFILE)
pargs.err = 1; /* Print a warning. */ {
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
}
else if (pargs.r_opt < -1)
pargs.err = ARGPARSE_PRINT_WARNING;
else /* Try to parse this option - ignore unchangeable ones. */ else /* Try to parse this option - ignore unchangeable ones. */
parse_rereadable_options (&pargs, 1); parse_rereadable_options (&pargs, 1);
} }
fclose (fp); gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
xfree (twopart);
post_option_parsing (); post_option_parsing ();
} }

View File

@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -197,9 +198,11 @@ my_strusage (int level)
switch(level) switch(level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "dirmngr_ldap (@GNUPG@)"; case 11: p = "dirmngr_ldap (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
case 49: p = PACKAGE_BUGREPORT; break; case 49: p = PACKAGE_BUGREPORT; break;
@ -267,8 +270,8 @@ ldap_wrapper_main (char **argv, estream_t outstream)
/* Parse the command line. */ /* Parse the command line. */
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* Do not remove the args. */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (arg_parse (&pargs, opts) ) while (gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -309,6 +312,7 @@ ldap_wrapper_main (char **argv, estream_t outstream)
break; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (only_search_timeout) if (only_search_timeout)
myopt->alarm_timeout = 0; myopt->alarm_timeout = 0;

280
g10/gpg.c
View File

@ -1,7 +1,7 @@
/* gpg.c - The GnuPG utility (main for gpg) /* gpg.c - The GnuPG utility (main for gpg)
* Copyright (C) 1998-2019 Free Software Foundation, Inc. * Copyright (C) 1998-2020 Free Software Foundation, Inc.
* Copyright (C) 1997-2019 Werner Koch * Copyright (C) 1997-2019 Werner Koch
* Copyright (C) 2015-2019 g10 Code GmbH * Copyright (C) 2015-2020 g10 Code GmbH
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -17,6 +17,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -634,7 +635,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oDisplayCharset, "display-charset", "@"), ARGPARSE_s_s (oDisplayCharset, "display-charset", "@"),
ARGPARSE_s_s (oDisplayCharset, "charset", "@"), ARGPARSE_s_s (oDisplayCharset, "charset", "@"),
ARGPARSE_s_s (oOptions, "options", "@"), ARGPARSE_conffile (oOptions, "options", "@"),
ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oDebug, "debug", "@"),
ARGPARSE_s_s (oDebugLevel, "debug-level", "@"), ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
@ -737,7 +738,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoDefKeyring, "no-default-keyring", "@"), ARGPARSE_s_n (oNoDefKeyring, "no-default-keyring", "@"),
ARGPARSE_s_n (oNoKeyring, "no-keyring", "@"), ARGPARSE_s_n (oNoKeyring, "no-keyring", "@"),
ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"), ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
ARGPARSE_s_n (oNoOptions, "no-options", "@"), ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_n (oNoBatch, "no-batch", "@"), ARGPARSE_s_n (oNoBatch, "no-batch", "@"),
ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_n (oWithColons, "with-colons", "@"),
@ -1058,10 +1059,13 @@ my_strusage( int level )
static char *digests, *pubkeys, *ciphers, *zips, *ver_gcry; static char *digests, *pubkeys, *ciphers, *zips, *ver_gcry;
const char *p; const char *p;
switch( level ) { switch (level)
{
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@GPG@ (@GNUPG@)"; case 11: p = "@GPG@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -2301,13 +2305,11 @@ main (int argc, char **argv)
strlist_t nrings = NULL; strlist_t nrings = NULL;
armor_filter_context_t *afx = NULL; armor_filter_context_t *afx = NULL;
int detached_sig = 0; int detached_sig = 0;
FILE *configfp = NULL; char *last_configname = NULL;
char *configname = NULL; const char *configname = NULL; /* NULL or points to last_configname.
char *save_configname = NULL; * NULL also indicates that we are
char *default_configname = NULL; * processing options from the cmdline. */
unsigned configlineno; int debug_argparser = 0;
int parse_debug = 0;
int default_config = 1;
int default_keyring = 1; int default_keyring = 1;
int greeting = 0; int greeting = 0;
int nogreeting = 0; int nogreeting = 0;
@ -2430,41 +2432,42 @@ main (int argc, char **argv)
opt.emit_version = 0; opt.emit_version = 0;
opt.weak_digests = NULL; opt.weak_digests = NULL;
/* Check whether we have a config file on the command line. */ /* Check special options given on the command line. */
orig_argc = argc; orig_argc = argc;
orig_argv = argv; orig_argv = argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION); pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
while( arg_parse( &pargs, opts) ) { while (gnupg_argparse (NULL, &pargs, opts))
if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll ) {
parse_debug++; switch (pargs.r_opt)
else if (pargs.r_opt == oDebugIOLBF)
es_setvbuf (es_stdout, NULL, _IOLBF, 0);
else if( pargs.r_opt == oOptions ) {
/* yes there is one, so we do not try the default one, but
* read the option file when it is encountered at the commandline
*/
default_config = 0;
}
else if( pargs.r_opt == oNoOptions )
{ {
default_config = 0; /* --no-options */ case oDebug:
case oDebugAll:
debug_argparser++;
break;
case oDebugIOLBF:
es_setvbuf (es_stdout, NULL, _IOLBF, 0);
break;
case oNoOptions:
/* Set here here because the homedir would otherwise be
* created before main option parsing starts. */
opt.no_homedir_creation = 1; opt.no_homedir_creation = 1;
break;
case oHomedir:
gnupg_set_homedir (pargs.r.ret_str);
break;
case oNoPermissionWarn:
opt.no_perm_warn = 1;
break;
} }
else if( pargs.r_opt == oHomedir ) }
gnupg_set_homedir (pargs.r.ret_str); /* Reset the flags. */
else if( pargs.r_opt == oNoPermissionWarn ) pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
opt.no_perm_warn=1;
else if (pargs.r_opt == oStrict )
{
/* Not used */
}
else if (pargs.r_opt == oNoStrict )
{
/* Not used */
}
}
#ifdef HAVE_DOSISH_SYSTEM #ifdef HAVE_DOSISH_SYSTEM
if ( strchr (gnupg_homedir (), '\\') ) { if ( strchr (gnupg_homedir (), '\\') ) {
@ -2508,64 +2511,67 @@ main (int argc, char **argv)
additional_weak_digest ("MD5"); additional_weak_digest ("MD5");
parse_auto_key_locate (DEFAULT_AKL_LIST); parse_auto_key_locate (DEFAULT_AKL_LIST);
/* Try for a version specific config file first */
default_configname = get_default_configname ();
if (default_config)
configname = xstrdup (default_configname);
argc = orig_argc; argc = orig_argc;
argv = orig_argv; argv = orig_argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= ARGPARSE_FLAG_KEEP; /* We are re-using the struct, thus the reset flag. We OR the
* flags so that the internal intialized flag won't be cleared. */
pargs.flags |= (ARGPARSE_FLAG_RESET
| ARGPARSE_FLAG_KEEP
| ARGPARSE_FLAG_SYS
| ARGPARSE_FLAG_USER
| ARGPARSE_FLAG_USERVERS);
/* By this point we have a homedir, and cannot change it. */ /* By this point we have a homedir, and cannot change it. */
check_permissions (gnupg_homedir (), 0); check_permissions (gnupg_homedir (), 0);
next_pass: /* The configuraton directories for use by gpgrt_argparser. */
if( configname ) { gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ());
if(check_permissions(configname,1)) gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ());
{
/* If any options file is unsafe, then disable any external
programs for keyserver calls or photo IDs. Since the
external program to call is set in the options file, a
unsafe options file can lead to an arbitrary program
being run. */
opt.exec_disable=1; while (gnupg_argparser (&pargs, opts, GPG_NAME EXTSEP_S "conf"))
}
configlineno = 0;
configfp = gnupg_fopen( configname, "r" );
if (configfp && is_secured_file (fileno (configfp)))
{
fclose (configfp);
configfp = NULL;
gpg_err_set_errno (EPERM);
}
if( !configfp ) {
if( default_config ) {
if( parse_debug )
log_info(_("Note: no default option file '%s'\n"),
configname );
}
else {
log_error(_("option file '%s': %s\n"),
configname, strerror(errno) );
g10_exit(2);
}
xfree(configname); configname = NULL;
}
if( parse_debug && configname )
log_info(_("reading options from '%s'\n"), configname );
default_config = 0;
}
while( optfile_parse( configfp, configname, &configlineno,
&pargs, opts) )
{ {
switch( pargs.r_opt ) switch (pargs.r_opt)
{ {
case ARGPARSE_CONFFILE:
if (debug_argparser)
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
if (pargs.r_type)
{
xfree (last_configname);
last_configname = xstrdup (pargs.r.ret_str);
configname = last_configname;
if (is_secured_filename (configname))
{
pargs.r_opt = ARGPARSE_PERMISSION_ERROR;
pargs.err = ARGPARSE_PRINT_ERROR;
}
else if (strncmp (configname, gnupg_sysconfdir (),
strlen (gnupg_sysconfdir ())))
{
/* This is not the global config file and thus we
* need to check the permissions: If the file is
* unsafe, then disable any external programs for
* keyserver calls or photo IDs. Since the
* external program to call is set in the options
* file, a unsafe options file can lead to an
* arbitrary program being run. */
if (check_permissions (configname, 1))
opt.exec_disable=1;
}
}
else
configname = NULL;
break;
/* case oOptions:
* case oNoOptions:
* We will never see these options here because
* gpgrt_argparse handles them for us.
*/
case aListConfig: case aListConfig:
case aListGcryptConfig: case aListGcryptConfig:
case aGPGConfList: case aGPGConfList:
@ -2702,25 +2708,25 @@ main (int argc, char **argv)
break; break;
case oNoUseAgent: case oNoUseAgent:
obsolete_option (configname, configlineno, "no-use-agent"); obsolete_option (configname, pargs.lineno, "no-use-agent");
break; break;
case oGpgAgentInfo: case oGpgAgentInfo:
obsolete_option (configname, configlineno, "gpg-agent-info"); obsolete_option (configname, pargs.lineno, "gpg-agent-info");
break; break;
case oReaderPort: case oReaderPort:
obsolete_scdaemon_option (configname, configlineno, "reader-port"); obsolete_scdaemon_option (configname, pargs.lineno, "reader-port");
break; break;
case octapiDriver: case octapiDriver:
obsolete_scdaemon_option (configname, configlineno, "ctapi-driver"); obsolete_scdaemon_option (configname, pargs.lineno, "ctapi-driver");
break; break;
case opcscDriver: case opcscDriver:
obsolete_scdaemon_option (configname, configlineno, "pcsc-driver"); obsolete_scdaemon_option (configname, pargs.lineno, "pcsc-driver");
break; break;
case oDisableCCID: case oDisableCCID:
obsolete_scdaemon_option (configname, configlineno, "disable-ccid"); obsolete_scdaemon_option (configname, pargs.lineno, "disable-ccid");
break; break;
case oHonorHttpProxy: case oHonorHttpProxy:
obsolete_option (configname, configlineno, "honor-http-proxy"); obsolete_option (configname, pargs.lineno, "honor-http-proxy");
break; break;
case oAnswerYes: opt.answer_yes = 1; break; case oAnswerYes: opt.answer_yes = 1; break;
@ -2731,7 +2737,7 @@ main (int argc, char **argv)
sl->flags = KEYDB_RESOURCE_FLAG_PRIMARY; sl->flags = KEYDB_RESOURCE_FLAG_PRIMARY;
break; break;
case oShowKeyring: case oShowKeyring:
deprecated_warning(configname,configlineno,"--show-keyring", deprecated_warning(configname,pargs.lineno,"--show-keyring",
"--list-options ","show-keyring"); "--list-options ","show-keyring");
opt.list_options|=LIST_SHOW_KEYRING; opt.list_options|=LIST_SHOW_KEYRING;
break; break;
@ -2803,14 +2809,6 @@ main (int argc, char **argv)
/* Ignore this old option. */ /* Ignore this old option. */
break; break;
case oOptions:
/* config files may not be nested (silently ignore them) */
if( !configfp ) {
xfree(configname);
configname = xstrdup(pargs.r.ret_str);
goto next_pass;
}
break;
case oNoArmor: opt.no_armor=1; opt.armor=0; break; case oNoArmor: opt.no_armor=1; opt.armor=0; break;
case oNoDefKeyring: case oNoDefKeyring:
@ -2843,7 +2841,7 @@ main (int argc, char **argv)
case oDefaultKey: case oDefaultKey:
sl = add_to_strlist (&opt.def_secret_key, pargs.r.ret_str); sl = add_to_strlist (&opt.def_secret_key, pargs.r.ret_str);
sl->flags = (pargs.r_opt << PK_LIST_SHIFT); sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
if (configfp) if (configname)
sl->flags |= PK_LIST_CONFIG; sl->flags |= PK_LIST_CONFIG;
break; break;
case oDefRecipient: case oDefRecipient:
@ -2861,7 +2859,6 @@ main (int argc, char **argv)
xfree(opt.def_recipient); opt.def_recipient = NULL; xfree(opt.def_recipient); opt.def_recipient = NULL;
opt.def_recipient_self = 0; opt.def_recipient_self = 0;
break; break;
case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
case oHomedir: break; case oHomedir: break;
case oNoBatch: opt.batch = 0; break; case oNoBatch: opt.batch = 0; break;
@ -2893,7 +2890,7 @@ main (int argc, char **argv)
opt.tofu_default_policy = parse_tofu_policy (pargs.r.ret_str); opt.tofu_default_policy = parse_tofu_policy (pargs.r.ret_str);
break; break;
case oTOFUDBFormat: case oTOFUDBFormat:
obsolete_option (configname, configlineno, "tofu-db-format"); obsolete_option (configname, pargs.lineno, "tofu-db-format");
break; break;
case oForceOwnertrust: case oForceOwnertrust:
@ -2951,17 +2948,17 @@ main (int argc, char **argv)
case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break; case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break; case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
case oShowPolicyURL: case oShowPolicyURL:
deprecated_warning(configname,configlineno,"--show-policy-url", deprecated_warning(configname,pargs.lineno,"--show-policy-url",
"--list-options ","show-policy-urls"); "--list-options ","show-policy-urls");
deprecated_warning(configname,configlineno,"--show-policy-url", deprecated_warning(configname,pargs.lineno,"--show-policy-url",
"--verify-options ","show-policy-urls"); "--verify-options ","show-policy-urls");
opt.list_options|=LIST_SHOW_POLICY_URLS; opt.list_options|=LIST_SHOW_POLICY_URLS;
opt.verify_options|=VERIFY_SHOW_POLICY_URLS; opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
break; break;
case oNoShowPolicyURL: case oNoShowPolicyURL:
deprecated_warning(configname,configlineno,"--no-show-policy-url", deprecated_warning(configname,pargs.lineno,"--no-show-policy-url",
"--list-options ","no-show-policy-urls"); "--list-options ","no-show-policy-urls");
deprecated_warning(configname,configlineno,"--no-show-policy-url", deprecated_warning(configname,pargs.lineno,"--no-show-policy-url",
"--verify-options ","no-show-policy-urls"); "--verify-options ","no-show-policy-urls");
opt.list_options&=~LIST_SHOW_POLICY_URLS; opt.list_options&=~LIST_SHOW_POLICY_URLS;
opt.verify_options&=~VERIFY_SHOW_POLICY_URLS; opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
@ -2978,7 +2975,7 @@ main (int argc, char **argv)
append_to_strlist(&opt.comments,pargs.r.ret_str); append_to_strlist(&opt.comments,pargs.r.ret_str);
break; break;
case oDefaultComment: case oDefaultComment:
deprecated_warning(configname,configlineno, deprecated_warning(configname,pargs.lineno,
"--default-comment","--no-comments",""); "--default-comment","--no-comments","");
/* fall through */ /* fall through */
case oNoComments: case oNoComments:
@ -2988,17 +2985,17 @@ main (int argc, char **argv)
case oThrowKeyids: opt.throw_keyids = 1; break; case oThrowKeyids: opt.throw_keyids = 1; break;
case oNoThrowKeyids: opt.throw_keyids = 0; break; case oNoThrowKeyids: opt.throw_keyids = 0; break;
case oShowPhotos: case oShowPhotos:
deprecated_warning(configname,configlineno,"--show-photos", deprecated_warning(configname,pargs.lineno,"--show-photos",
"--list-options ","show-photos"); "--list-options ","show-photos");
deprecated_warning(configname,configlineno,"--show-photos", deprecated_warning(configname,pargs.lineno,"--show-photos",
"--verify-options ","show-photos"); "--verify-options ","show-photos");
opt.list_options|=LIST_SHOW_PHOTOS; opt.list_options|=LIST_SHOW_PHOTOS;
opt.verify_options|=VERIFY_SHOW_PHOTOS; opt.verify_options|=VERIFY_SHOW_PHOTOS;
break; break;
case oNoShowPhotos: case oNoShowPhotos:
deprecated_warning(configname,configlineno,"--no-show-photos", deprecated_warning(configname,pargs.lineno,"--no-show-photos",
"--list-options ","no-show-photos"); "--list-options ","no-show-photos");
deprecated_warning(configname,configlineno,"--no-show-photos", deprecated_warning(configname,pargs.lineno,"--no-show-photos",
"--verify-options ","no-show-photos"); "--verify-options ","no-show-photos");
opt.list_options&=~LIST_SHOW_PHOTOS; opt.list_options&=~LIST_SHOW_PHOTOS;
opt.verify_options&=~VERIFY_SHOW_PHOTOS; opt.verify_options&=~VERIFY_SHOW_PHOTOS;
@ -3029,7 +3026,7 @@ main (int argc, char **argv)
* enough space for the flags. */ * enough space for the flags. */
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
sl->flags = (pargs.r_opt << PK_LIST_SHIFT); sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
if (configfp) if (configname)
sl->flags |= PK_LIST_CONFIG; sl->flags |= PK_LIST_CONFIG;
if (pargs.r_opt == oHiddenRecipient if (pargs.r_opt == oHiddenRecipient
|| pargs.r_opt == oHiddenRecipientFile) || pargs.r_opt == oHiddenRecipientFile)
@ -3045,7 +3042,7 @@ main (int argc, char **argv)
/* Store an additional recipient. */ /* Store an additional recipient. */
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO); sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO);
if (configfp) if (configname)
sl->flags |= PK_LIST_CONFIG; sl->flags |= PK_LIST_CONFIG;
if (pargs.r_opt == oHiddenEncryptTo) if (pargs.r_opt == oHiddenEncryptTo)
sl->flags |= PK_LIST_HIDDEN; sl->flags |= PK_LIST_HIDDEN;
@ -3055,7 +3052,7 @@ main (int argc, char **argv)
opt.no_encrypt_to = 1; opt.no_encrypt_to = 1;
break; break;
case oEncryptToDefaultKey: case oEncryptToDefaultKey:
opt.encrypt_to_default_key = configfp ? 2 : 1; opt.encrypt_to_default_key = configname ? 2 : 1;
break; break;
case oTrySecretKey: case oTrySecretKey:
@ -3101,7 +3098,7 @@ main (int argc, char **argv)
case oLocalUser: /* store the local users */ case oLocalUser: /* store the local users */
sl = add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings ); sl = add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
sl->flags = (pargs.r_opt << PK_LIST_SHIFT); sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
if (configfp) if (configname)
sl->flags |= PK_LIST_CONFIG; sl->flags |= PK_LIST_CONFIG;
break; break;
case oSender: case oSender:
@ -3241,7 +3238,7 @@ main (int argc, char **argv)
{ {
if(configname) if(configname)
log_error(_("%s:%d: invalid keyserver options\n"), log_error(_("%s:%d: invalid keyserver options\n"),
configname,configlineno); configname,pargs.lineno);
else else
log_error(_("invalid keyserver options\n")); log_error(_("invalid keyserver options\n"));
} }
@ -3251,7 +3248,7 @@ main (int argc, char **argv)
{ {
if(configname) if(configname)
log_error(_("%s:%d: invalid import options\n"), log_error(_("%s:%d: invalid import options\n"),
configname,configlineno); configname,pargs.lineno);
else else
log_error(_("invalid import options\n")); log_error(_("invalid import options\n"));
} }
@ -3266,7 +3263,7 @@ main (int argc, char **argv)
{ {
if(configname) if(configname)
log_error(_("%s:%d: invalid export options\n"), log_error(_("%s:%d: invalid export options\n"),
configname,configlineno); configname,pargs.lineno);
else else
log_error(_("invalid export options\n")); log_error(_("invalid export options\n"));
} }
@ -3281,7 +3278,7 @@ main (int argc, char **argv)
{ {
if(configname) if(configname)
log_error(_("%s:%d: invalid list options\n"), log_error(_("%s:%d: invalid list options\n"),
configname,configlineno); configname,pargs.lineno);
else else
log_error(_("invalid list options\n")); log_error(_("invalid list options\n"));
} }
@ -3321,7 +3318,7 @@ main (int argc, char **argv)
{ {
if(configname) if(configname)
log_error(_("%s:%d: invalid verify options\n"), log_error(_("%s:%d: invalid verify options\n"),
configname,configlineno); configname,pargs.lineno);
else else
log_error(_("invalid verify options\n")); log_error(_("invalid verify options\n"));
} }
@ -3342,17 +3339,17 @@ main (int argc, char **argv)
case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break; case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
case oKnownNotation: register_known_notation (pargs.r.ret_str); break; case oKnownNotation: register_known_notation (pargs.r.ret_str); break;
case oShowNotation: case oShowNotation:
deprecated_warning(configname,configlineno,"--show-notation", deprecated_warning(configname,pargs.lineno,"--show-notation",
"--list-options ","show-notations"); "--list-options ","show-notations");
deprecated_warning(configname,configlineno,"--show-notation", deprecated_warning(configname,pargs.lineno,"--show-notation",
"--verify-options ","show-notations"); "--verify-options ","show-notations");
opt.list_options|=LIST_SHOW_NOTATIONS; opt.list_options|=LIST_SHOW_NOTATIONS;
opt.verify_options|=VERIFY_SHOW_NOTATIONS; opt.verify_options|=VERIFY_SHOW_NOTATIONS;
break; break;
case oNoShowNotation: case oNoShowNotation:
deprecated_warning(configname,configlineno,"--no-show-notation", deprecated_warning(configname,pargs.lineno,"--no-show-notation",
"--list-options ","no-show-notations"); "--list-options ","no-show-notations");
deprecated_warning(configname,configlineno,"--no-show-notation", deprecated_warning(configname,pargs.lineno,"--no-show-notation",
"--verify-options ","no-show-notations"); "--verify-options ","no-show-notations");
opt.list_options&=~LIST_SHOW_NOTATIONS; opt.list_options&=~LIST_SHOW_NOTATIONS;
opt.verify_options&=~VERIFY_SHOW_NOTATIONS; opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
@ -3408,7 +3405,7 @@ main (int argc, char **argv)
ovrseskeyfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); ovrseskeyfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
break; break;
case oMergeOnly: case oMergeOnly:
deprecated_warning(configname,configlineno,"--merge-only", deprecated_warning(configname,pargs.lineno,"--merge-only",
"--import-options ","merge-only"); "--import-options ","merge-only");
opt.import_options|=IMPORT_MERGE_ONLY; opt.import_options|=IMPORT_MERGE_ONLY;
break; break;
@ -3536,7 +3533,7 @@ main (int argc, char **argv)
{ {
if(configname) if(configname)
log_error(_("%s:%d: invalid auto-key-locate list\n"), log_error(_("%s:%d: invalid auto-key-locate list\n"),
configname,configlineno); configname,pargs.lineno);
else else
log_error(_("invalid auto-key-locate list\n")); log_error(_("invalid auto-key-locate list\n"));
} }
@ -3558,7 +3555,7 @@ main (int argc, char **argv)
if (configname) if (configname)
log_info("%s:%d: WARNING: gpg not built with large secure " log_info("%s:%d: WARNING: gpg not built with large secure "
"memory buffer. Ignoring enable-large-rsa\n", "memory buffer. Ignoring enable-large-rsa\n",
configname,configlineno); configname,pargs.lineno);
else else
log_info("WARNING: gpg not built with large secure " log_info("WARNING: gpg not built with large secure "
"memory buffer. Ignoring --enable-large-rsa\n"); "memory buffer. Ignoring --enable-large-rsa\n");
@ -3620,7 +3617,7 @@ main (int argc, char **argv)
case oNoop: break; case oNoop: break;
default: default:
if (configfp) if (configname)
pargs.err = ARGPARSE_PRINT_WARNING; pargs.err = ARGPARSE_PRINT_WARNING;
else else
{ {
@ -3634,19 +3631,8 @@ main (int argc, char **argv)
} }
} }
if (configfp) gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
{
fclose( configfp );
configfp = NULL;
/* Remember the first config file name. */
if (!save_configname)
save_configname = configname;
else
xfree(configname);
configname = NULL;
goto next_pass;
}
xfree(configname); configname = NULL;
if (log_get_errorcount (0)) if (log_get_errorcount (0))
{ {
write_status_failure ("option-parser", gpg_error(GPG_ERR_GENERAL)); write_status_failure ("option-parser", gpg_error(GPG_ERR_GENERAL));
@ -3657,11 +3643,11 @@ main (int argc, char **argv)
directly after the option parsing. */ directly after the option parsing. */
if (cmd == aGPGConfList) if (cmd == aGPGConfList)
{ {
gpgconf_list (save_configname ? save_configname : default_configname); gpgconf_list (last_configname ? last_configname : "UNKNOWN");
g10_exit (0); g10_exit (0);
} }
xfree (save_configname); xfree (last_configname);
xfree (default_configname); last_configname = NULL;
if (print_dane_records) if (print_dane_records)
log_error ("invalid option \"%s\"; use \"%s\" instead\n", log_error ("invalid option \"%s\"; use \"%s\" instead\n",

View File

@ -1,6 +1,7 @@
/* gpgv.c - The GnuPG signature verify utility /* gpgv.c - The GnuPG signature verify utility
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2006, * Copyright (C) 1998-2020 Free Software Foundation, Inc.
* 2008, 2009, 2012 Free Software Foundation, Inc. * Copyright (C) 1998-2019 Werner Koch
* Copyright (C) 2015-2020 g10 Code GmbH
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -16,6 +17,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -138,9 +140,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@GPG@v (GnuPG)"; case 11: p = "@GPG@v (GnuPG)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -172,7 +176,6 @@ main( int argc, char **argv )
int rc=0; int rc=0;
strlist_t sl; strlist_t sl;
strlist_t nrings = NULL; strlist_t nrings = NULL;
unsigned configlineno;
ctrl_t ctrl; ctrl_t ctrl;
early_system_init (); early_system_init ();
@ -206,11 +209,13 @@ main( int argc, char **argv )
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* do not remove the args */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (optfile_parse( NULL, NULL, &configlineno, &pargs, opts)) while (gnupg_argparser (&pargs, opts, NULL))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
case ARGPARSE_CONFFILE: break;
case oQuiet: opt.quiet = 1; break; case oQuiet: opt.quiet = 1; break;
case oVerbose: case oVerbose:
opt.verbose++; opt.verbose++;
@ -250,6 +255,8 @@ main( int argc, char **argv )
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount (0)) if (log_get_errorcount (0))
g10_exit(2); g10_exit(2);

View File

@ -15,6 +15,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -145,9 +146,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@G13@-syshelp (@GNUPG@)"; case 11: p = "@G13@-syshelp (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
break; break;
@ -225,12 +228,10 @@ main ( int argc, char **argv)
gpg_error_t err = 0; gpg_error_t err = 0;
/* const char *fname; */ /* const char *fname; */
int may_coredump; int may_coredump;
FILE *configfp = NULL; char *last_configname = NULL;
char *configname = NULL; const char *configname = NULL;
unsigned configlineno; int debug_argparser = 0;
int parse_debug = 0;
int no_more_options = 0; int no_more_options = 0;
int default_config =1;
char *logfile = NULL; char *logfile = NULL;
/* int debug_wait = 0; */ /* int debug_wait = 0; */
int use_random_seed = 1; int use_random_seed = 1;
@ -265,30 +266,32 @@ main ( int argc, char **argv)
log_fatal ("error allocating session environment block: %s\n", log_fatal ("error allocating session environment block: %s\n",
strerror (errno)); strerror (errno));
/* Fixme: We enable verbose mode here because there is currently no
way to do this when starting g13-syshelp. To fix that we should
add a g13-syshelp.conf file in /etc/gnupg. */
opt.verbose = 1;
/* First check whether we have a debug option on the commandline. */ /* First check whether we have a debug option on the commandline. */
orig_argc = argc; orig_argc = argc;
orig_argv = argv; orig_argv = argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION); pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
while (arg_parse( &pargs, opts)) while (gnupg_argparse (NULL, &pargs, opts))
{ {
if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) switch (pargs.r_opt)
parse_debug++; {
case oDebug:
case oDebugAll:
debug_argparser++;
break;
}
} }
/* Reset the flags. */
pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
/* Initialize the secure memory. */ /* Initialize the secure memory. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
maybe_setuid = 0; maybe_setuid = 0;
/* /*
Now we are now working under our real uid * Now we are now working under our real uid
*/ */
/* Setup malloc hooks. */ /* Setup malloc hooks. */
{ {
@ -311,47 +314,40 @@ main ( int argc, char **argv)
ctrl.no_server = 1; ctrl.no_server = 1;
ctrl.status_fd = -1; /* No status output. */ ctrl.status_fd = -1; /* No status output. */
if (default_config ) /* The configuraton directories for use by gpgrt_argparser. */
configname = make_filename (gnupg_sysconfdir (), gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ());
G13_NAME"-syshelp.conf", NULL); gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ());
argc = orig_argc; argc = orig_argc;
argv = orig_argv; argv = orig_argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = 1; /* Do not remove the args. */ pargs.flags |= (ARGPARSE_FLAG_RESET
| ARGPARSE_FLAG_KEEP
next_pass: | ARGPARSE_FLAG_SYS
if (configname) | ARGPARSE_FLAG_USER);
{
configlineno = 0;
configfp = gnupg_fopen (configname, "r");
if (!configfp)
{
if (default_config)
{
if (parse_debug)
log_info (_("NOTE: no default option file '%s'\n"), configname);
}
else
{
log_error (_("option file '%s': %s\n"),
configname, strerror(errno));
g13_exit(2);
}
xfree (configname);
configname = NULL;
}
if (parse_debug && configname)
log_info (_("reading options from '%s'\n"), configname);
default_config = 0;
}
while (!no_more_options while (!no_more_options
&& optfile_parse (configfp, configname, &configlineno, &pargs, opts)) && gnupg_argparser (&pargs, opts, G13_NAME"-syshelp" EXTSEP_S "conf"))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
case ARGPARSE_CONFFILE:
{
if (debug_argparser)
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
if (pargs.r_type)
{
xfree (last_configname);
last_configname = xstrdup (pargs.r.ret_str);
configname = last_configname;
}
else
configname = NULL;
}
break;
case oQuiet: opt.quiet = 1; break; case oQuiet: opt.quiet = 1; break;
case oDryRun: opt.dry_run = 1; break; case oDryRun: opt.dry_run = 1; break;
@ -404,26 +400,21 @@ main ( int argc, char **argv)
case oNoRandomSeedFile: use_random_seed = 0; break; case oNoRandomSeedFile: use_random_seed = 0; break;
default: default:
pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; pargs.err = configname? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
break; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (configfp) if (!last_configname)
{
fclose (configfp);
configfp = NULL;
/* Keep a copy of the config filename. */
opt.config_filename = configname;
configname = NULL;
goto next_pass;
}
xfree (configname);
configname = NULL;
if (!opt.config_filename)
opt.config_filename = make_filename (gnupg_homedir (), opt.config_filename = make_filename (gnupg_homedir (),
G13_NAME".conf", NULL); G13_NAME"-syshelp" EXTSEP_S "conf",
NULL);
else
{
opt.config_filename = last_configname;
last_configname = NULL;
}
if (log_get_errorcount(0)) if (log_get_errorcount(0))
g13_exit(2); g13_exit(2);

150
g13/g13.c
View File

@ -15,6 +15,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -138,7 +139,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")), ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")),
ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oDebug, "debug", "@"),
ARGPARSE_s_s (oDebugLevel, "debug-level", ARGPARSE_s_s (oDebugLevel, "debug-level",
@ -163,7 +164,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"), ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"), ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"), ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
ARGPARSE_s_n (oNoOptions, "no-options", "@"), ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
ARGPARSE_s_s (oGpgProgram, "gpg-program", "@"), ARGPARSE_s_s (oGpgProgram, "gpg-program", "@"),
@ -235,9 +236,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@G13@ (@GNUPG@)"; case 11: p = "@G13@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
break; break;
@ -343,12 +346,10 @@ main ( int argc, char **argv)
gpg_error_t err = 0; gpg_error_t err = 0;
/* const char *fname; */ /* const char *fname; */
int may_coredump; int may_coredump;
FILE *configfp = NULL; char *last_configname = NULL;
char *configname = NULL; const char *configname = NULL;
unsigned configlineno; int debug_argparser = 0;
int parse_debug = 0;
int no_more_options = 0; int no_more_options = 0;
int default_config =1;
char *logfile = NULL; char *logfile = NULL;
int greeting = 0; int greeting = 0;
int nogreeting = 0; int nogreeting = 0;
@ -360,8 +361,6 @@ main ( int argc, char **argv)
struct server_control_s ctrl; struct server_control_s ctrl;
strlist_t recipients = NULL; strlist_t recipients = NULL;
/*mtrace();*/
early_system_init (); early_system_init ();
gnupg_reopen_std (G13_NAME); gnupg_reopen_std (G13_NAME);
set_strusage (my_strusage); set_strusage (my_strusage);
@ -395,29 +394,31 @@ main ( int argc, char **argv)
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1|(1<<6); /* Do not remove the args, ignore version. */ pargs.flags= 1|(1<<6); /* Do not remove the args, ignore version. */
while (arg_parse( &pargs, opts)) pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
while (gnupg_argparse (NULL, &pargs, opts))
{ {
if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) switch (pargs.r_opt)
parse_debug++; {
else if (pargs.r_opt == oOptions) case oDebug:
{ /* Yes, there is one, so we do not try the default one but case oDebugAll:
read the config file when it is encountered at the debug_argparser++;
commandline. */ break;
default_config = 0;
} case oHomedir:
else if (pargs.r_opt == oNoOptions) gnupg_set_homedir (pargs.r.ret_str);
default_config = 0; /* --no-options */ break;
else if (pargs.r_opt == oHomedir) }
gnupg_set_homedir (pargs.r.ret_str);
} }
/* Reset the flags. */
pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
/* Initialize the secure memory. */ /* Initialize the secure memory. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
maybe_setuid = 0; maybe_setuid = 0;
/* /*
Now we are now working under our real uid * Now we are now working under our real uid
*/ */
/* Setup malloc hooks. */ /* Setup malloc hooks. */
{ {
@ -440,47 +441,39 @@ main ( int argc, char **argv)
ctrl.no_server = 1; ctrl.no_server = 1;
ctrl.status_fd = -1; /* No status output. */ ctrl.status_fd = -1; /* No status output. */
/* Set the default option file */ /* The configuraton directories for use by gpgrt_argparser. */
if (default_config ) gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ());
configname = make_filename (gnupg_homedir (), G13_NAME".conf", NULL); gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ());
argc = orig_argc; argc = orig_argc;
argv = orig_argv; argv = orig_argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = 1; /* Do not remove the args. */ pargs.flags |= (ARGPARSE_FLAG_RESET
| ARGPARSE_FLAG_KEEP
next_pass: | ARGPARSE_FLAG_SYS
if (configname) | ARGPARSE_FLAG_USER);
{
configlineno = 0;
configfp = gnupg_fopen (configname, "r");
if (!configfp)
{
if (default_config)
{
if (parse_debug)
log_info (_("Note: no default option file '%s'\n"), configname);
}
else
{
log_error (_("option file '%s': %s\n"),
configname, strerror(errno));
g13_exit(2);
}
xfree (configname);
configname = NULL;
}
if (parse_debug && configname)
log_info (_("reading options from '%s'\n"), configname);
default_config = 0;
}
while (!no_more_options while (!no_more_options
&& optfile_parse (configfp, configname, &configlineno, &pargs, opts)) && gnupg_argparser (&pargs, opts, G13_NAME EXTSEP_S "conf"))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
case ARGPARSE_CONFFILE:
{
if (debug_argparser)
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
if (pargs.r_type)
{
xfree (last_configname);
last_configname = xstrdup (pargs.r.ret_str);
configname = last_configname;
}
else
configname = NULL;
}
break;
case aGPGConfList: case aGPGConfList:
case aGPGConfTest: case aGPGConfTest:
set_cmd (&cmd, pargs.r_opt); set_cmd (&cmd, pargs.r_opt);
@ -538,17 +531,6 @@ main ( int argc, char **argv)
case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break; case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
case oLoggerFD: log_set_fd (pargs.r.ret_int ); break; case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
case oNoOptions: break; /* no-options */
case oOptions:
/* Config files may not be nested (silently ignore them). */
if (!configfp)
{
xfree(configname);
configname = xstrdup (pargs.r.ret_str);
goto next_pass;
}
break;
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
@ -592,12 +574,16 @@ main ( int argc, char **argv)
break; break;
default: default:
pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; if (configname)
pargs.err = ARGPARSE_PRINT_WARNING;
else
pargs.err = ARGPARSE_PRINT_ERROR;
break; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
/* XXX Construct GPG arguments. */ /* Construct GPG arguments. */
{ {
strlist_t last; strlist_t last;
last = append_to_strlist (&opt.gpg_arguments, "-z"); last = append_to_strlist (&opt.gpg_arguments, "-z");
@ -607,21 +593,15 @@ main ( int argc, char **argv)
(void) last; (void) last;
} }
if (configfp) if (!last_configname)
{
fclose (configfp);
configfp = NULL;
/* Keep a copy of the config filename. */
opt.config_filename = configname;
configname = NULL;
goto next_pass;
}
xfree (configname);
configname = NULL;
if (!opt.config_filename)
opt.config_filename = make_filename (gnupg_homedir (), opt.config_filename = make_filename (gnupg_homedir (),
G13_NAME".conf", NULL); G13_NAME EXTSEP_S "conf",
NULL);
else
{
opt.config_filename = last_configname;
last_configname = NULL;
}
if (log_get_errorcount(0)) if (log_get_errorcount(0))
g13_exit(2); g13_exit(2);
@ -659,7 +639,9 @@ main ( int argc, char **argv)
if (logfile) if (logfile)
{ {
log_set_file (logfile); log_set_file (logfile);
log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
| GPGRT_LOG_WITH_TIME
| GPGRT_LOG_WITH_PID ));
} }
if (gnupg_faked_time_p ()) if (gnupg_faked_time_p ())

View File

@ -465,7 +465,8 @@ main( int argc, char **argv )
{ {
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
enum cmd_and_opt_values cmd = 0; enum cmd_and_opt_values cmd = 0;
unsigned long from = 0, to = ULONG_MAX; unsigned long from = 0;
unsigned long to = ULONG_MAX;
int dry_run = 0; int dry_run = 0;
early_system_init (); early_system_init ();
@ -487,8 +488,8 @@ main( int argc, char **argv )
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* do not remove the args */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (arg_parse( &pargs, opts) ) while (gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -524,6 +525,8 @@ main( int argc, char **argv )
} }
} }
gnupg_argparse (NULL, &pargs, NULL);
if (to < from) if (to < from)
log_error ("record number of \"--to\" is lower than \"--from\" one\n"); log_error ("record number of \"--to\" is lower than \"--from\" one\n");

View File

@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -121,7 +122,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")), ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")),
ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")), ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")),
ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")), ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")),
ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")), ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")),
ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oDebug, "debug", "@"),
ARGPARSE_s_n (oDebugAll, "debug-all", "@"), ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
ARGPARSE_s_s (oDebugLevel, "debug-level" , ARGPARSE_s_s (oDebugLevel, "debug-level" ,
@ -161,6 +162,7 @@ static ARGPARSE_OPTS opts[] = {
N_("use variable length input for pinpad")), N_("use variable length input for pinpad")),
ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"), ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
/* Stubs for options which are implemented by 2.3 or later. */ /* Stubs for options which are implemented by 2.3 or later. */
ARGPARSE_s_s (oNoop, "application-priority", "@"), ARGPARSE_s_s (oNoop, "application-priority", "@"),
@ -287,9 +289,11 @@ my_strusage (int level)
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@SCDAEMON@ (@GNUPG@)"; case 11: p = "@SCDAEMON@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -421,13 +425,11 @@ main (int argc, char **argv )
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
int orig_argc; int orig_argc;
char **orig_argv; char **orig_argv;
FILE *configfp = NULL; char *last_configname = NULL;
char *configname = NULL; const char *configname = NULL;
const char *shell; const char *shell;
unsigned int configlineno; int debug_argparser = 0;
int parse_debug = 0;
const char *debug_level = NULL; const char *debug_level = NULL;
int default_config =1;
int greeting = 0; int greeting = 0;
int nogreeting = 0; int nogreeting = 0;
int multi_server = 0; int multi_server = 0;
@ -437,7 +439,7 @@ main (int argc, char **argv )
char *logfile = NULL; char *logfile = NULL;
int debug_wait = 0; int debug_wait = 0;
int gpgconf_list = 0; int gpgconf_list = 0;
const char *config_filename = NULL; char *config_filename = NULL;
int allow_coredump = 0; int allow_coredump = 0;
struct assuan_malloc_hooks malloc_hooks; struct assuan_malloc_hooks malloc_hooks;
int res; int res;
@ -484,73 +486,61 @@ main (int argc, char **argv )
orig_argv = argv; orig_argv = argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
while (arg_parse( &pargs, opts)) while (gnupg_argparse (NULL, &pargs, opts))
{ {
if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) switch (pargs.r_opt)
parse_debug++; {
else if (pargs.r_opt == oOptions) case oDebug:
{ /* yes there is one, so we do not try the default one, but case oDebugAll:
read the option file when it is encountered at the debug_argparser++;
commandline */ break;
default_config = 0; case oHomedir:
}
else if (pargs.r_opt == oNoOptions)
default_config = 0; /* --no-options */
else if (pargs.r_opt == oHomedir)
gnupg_set_homedir (pargs.r.ret_str); gnupg_set_homedir (pargs.r.ret_str);
break;
}
} }
/* Reset the flags. */
pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
/* initialize the secure memory. */ /* Initialize the secure memory. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
maybe_setuid = 0; maybe_setuid = 0;
/* /*
Now we are working under our real uid * Now we are working under our real uid
*/ */
if (default_config)
configname = make_filename (gnupg_homedir (), SCDAEMON_NAME EXTSEP_S "conf",
NULL );
/* The configuraton directories for use by gpgrt_argparser. */
gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ());
gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ());
argc = orig_argc; argc = orig_argc;
argv = orig_argv; argv = orig_argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* do not remove the args */ pargs.flags |= (ARGPARSE_FLAG_RESET
next_pass: | ARGPARSE_FLAG_KEEP
if (configname) | ARGPARSE_FLAG_SYS
{ | ARGPARSE_FLAG_USER);
configlineno = 0; while (gnupg_argparser (&pargs, opts, SCDAEMON_NAME EXTSEP_S "conf"))
configfp = gnupg_fopen (configname, "r");
if (!configfp)
{
if (default_config)
{
if( parse_debug )
log_info (_("Note: no default option file '%s'\n"),
configname );
}
else
{
log_error (_("option file '%s': %s\n"),
configname, strerror(errno) );
exit(2);
}
xfree (configname);
configname = NULL;
}
if (parse_debug && configname )
log_info (_("reading options from '%s'\n"), configname );
default_config = 0;
}
while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
case ARGPARSE_CONFFILE:
if (debug_argparser)
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
if (pargs.r_type)
{
xfree (last_configname);
last_configname = xstrdup (pargs.r.ret_str);
configname = last_configname;
}
else
configname = NULL;
break;
case aGPGConfList: gpgconf_list = 1; break; case aGPGConfList: gpgconf_list = 1; break;
case aGPGConfTest: gpgconf_list = 2; break; case aGPGConfTest: gpgconf_list = 2; break;
case oQuiet: opt.quiet = 1; break; case oQuiet: opt.quiet = 1; break;
@ -583,18 +573,8 @@ main (int argc, char **argv )
set_libassuan_log_cats (pargs.r.ret_ulong); set_libassuan_log_cats (pargs.r.ret_ulong);
break; break;
case oOptions:
/* config files may not be nested (silently ignore them) */
if (!configfp)
{
xfree(configname);
configname = xstrdup(pargs.r.ret_str);
goto next_pass;
}
break;
case oNoGreeting: nogreeting = 1; break; case oNoGreeting: nogreeting = 1; break;
case oNoVerbose: opt.verbose = 0; break; case oNoVerbose: opt.verbose = 0; break;
case oNoOptions: break; /* no-options */
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oNoDetach: nodetach = 1; break; case oNoDetach: nodetach = 1; break;
case oLogFile: logfile = pargs.r.ret_str; break; case oLogFile: logfile = pargs.r.ret_str; break;
@ -631,21 +611,25 @@ main (int argc, char **argv )
case oNoop: break; case oNoop: break;
default: default:
pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; if (configname)
pargs.err = ARGPARSE_PRINT_WARNING;
else
pargs.err = ARGPARSE_PRINT_ERROR;
break; break;
} }
} }
if (configfp) gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (!last_configname)
config_filename = make_filename (gnupg_homedir (),
SCDAEMON_NAME EXTSEP_S "conf",
NULL);
else
{ {
fclose( configfp ); config_filename = last_configname;
configfp = NULL; last_configname = NULL;
/* Keep a copy of the config name for use by --gpgconf-list. */
config_filename = configname;
configname = NULL;
goto next_pass;
} }
xfree (configname);
configname = NULL;
if (log_get_errorcount(0)) if (log_get_errorcount(0))
exit(2); exit(2);
if (nogreeting ) if (nogreeting )
@ -692,21 +676,13 @@ main (int argc, char **argv )
if (gpgconf_list) if (gpgconf_list)
{ {
/* List options and default values in the GPG Conf format. */ /* List options and default values in the GPG Conf format. */
char *filename = NULL;
char *filename_esc; char *filename_esc;
if (config_filename) filename_esc = percent_escape (config_filename, NULL);
filename = xstrdup (config_filename);
else
filename = make_filename (gnupg_homedir (),
SCDAEMON_NAME EXTSEP_S "conf", NULL);
filename_esc = percent_escape (filename, NULL);
es_printf ("%s-%s.conf:%lu:\"%s\n", es_printf ("%s-%s.conf:%lu:\"%s\n",
GPGCONF_NAME, SCDAEMON_NAME, GPGCONF_NAME, SCDAEMON_NAME,
GC_OPT_FLAG_DEFAULT, filename_esc); GC_OPT_FLAG_DEFAULT, filename_esc);
xfree (filename_esc); xfree (filename_esc);
xfree (filename);
es_printf ("verbose:%lu:\n" es_printf ("verbose:%lu:\n"
"quiet:%lu:\n" "quiet:%lu:\n"
@ -960,9 +936,11 @@ main (int argc, char **argv )
close (fd); close (fd);
} }
xfree (config_filename);
return 0; return 0;
} }
void void
scd_exit (int rc) scd_exit (int rc)
{ {

View File

@ -1,6 +1,7 @@
/* gpgsm.c - GnuPG for S/MIME /* gpgsm.c - GnuPG for S/MIME
* Copyright (C) 2001-2008, 2010 Free Software Foundation, Inc. * Copyright (C) 2001-2020 Free Software Foundation, Inc.
* Copyright (C) 2001-2008, 2010 Werner Koch * Copyright (C) 2001-2019 Werner Koch
* Copyright (C) 2015-2020 g10 Code GmbH
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -16,6 +17,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -26,7 +28,6 @@
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
/*#include <mcheck.h>*/
#define INCLUDED_BY_MAIN_MODULE 1 #define INCLUDED_BY_MAIN_MODULE 1
@ -337,7 +338,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oKeyServer, "keyserver", ARGPARSE_s_s (oKeyServer, "keyserver",
N_("|SPEC|use this keyserver to lookup keys")), N_("|SPEC|use this keyserver to lookup keys")),
ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")), ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")),
ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oDebug, "debug", "@"),
ARGPARSE_s_s (oDebugLevel, "debug-level", ARGPARSE_s_s (oDebugLevel, "debug-level",
@ -373,7 +374,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oNoArmor, "no-armour", "@"), ARGPARSE_s_n (oNoArmor, "no-armour", "@"),
ARGPARSE_s_n (oNoDefKeyring, "no-default-keyring", "@"), ARGPARSE_s_n (oNoDefKeyring, "no-default-keyring", "@"),
ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"), ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
ARGPARSE_s_n (oNoOptions, "no-options", "@"), ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"),
ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
ARGPARSE_s_s (oDisplay, "display", "@"), ARGPARSE_s_s (oDisplay, "display", "@"),
@ -557,9 +558,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@GPGSM@ (@GNUPG@)"; case 11: p = "@GPGSM@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -893,12 +896,12 @@ main ( int argc, char **argv)
strlist_t sl, remusr= NULL, locusr=NULL; strlist_t sl, remusr= NULL, locusr=NULL;
strlist_t nrings=NULL; strlist_t nrings=NULL;
int detached_sig = 0; int detached_sig = 0;
FILE *configfp = NULL; char *last_configname = NULL;
char *configname = NULL; const char *configname = NULL; /* NULL or points to last_configname.
unsigned configlineno; * NULL also indicates that we are
int parse_debug = 0; * processing options from the cmdline. */
int debug_argparser = 0;
int no_more_options = 0; int no_more_options = 0;
int default_config =1;
int default_keyring = 1; int default_keyring = 1;
char *logfile = NULL; char *logfile = NULL;
char *auditlog = NULL; char *auditlog = NULL;
@ -921,7 +924,8 @@ main ( int argc, char **argv)
estream_t htmlauditfp = NULL; estream_t htmlauditfp = NULL;
struct assuan_malloc_hooks malloc_hooks; struct assuan_malloc_hooks malloc_hooks;
int pwfd = -1; int pwfd = -1;
/*mtrace();*/
static const char *homedirvalue;
early_system_init (); early_system_init ();
gnupg_reopen_std (GPGSM_NAME); gnupg_reopen_std (GPGSM_NAME);
@ -973,28 +977,35 @@ main ( int argc, char **argv)
orig_argv = argv; orig_argv = argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
while (arg_parse( &pargs, opts)) while (gnupg_argparse (NULL, &pargs, opts))
{ {
if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) switch (pargs.r_opt)
parse_debug++;
else if (pargs.r_opt == oOptions)
{ /* yes there is one, so we do not try the default one but
read the config file when it is encountered at the
commandline */
default_config = 0;
}
else if (pargs.r_opt == oNoOptions)
{ {
default_config = 0; /* --no-options */ case oDebug:
case oDebugAll:
debug_argparser++;
break;
case oNoOptions:
/* Set here here because the homedir would otherwise be
* created before main option parsing starts. */
opt.no_homedir_creation = 1; opt.no_homedir_creation = 1;
break;
case oHomedir:
homedirvalue = pargs.r.ret_str;
break;
case aCallProtectTool:
/* Make sure that --version and --help are passed to the
* protect-tool. */
goto leave_cmdline_parser;
} }
else if (pargs.r_opt == oHomedir)
gnupg_set_homedir (pargs.r.ret_str);
else if (pargs.r_opt == aCallProtectTool)
break; /* This break makes sure that --version and --help are
passed to the protect-tool. */
} }
leave_cmdline_parser:
/* Reset the flags. */
pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
/* Initialize the secure memory. */ /* Initialize the secure memory. */
@ -1002,8 +1013,8 @@ main ( int argc, char **argv)
maybe_setuid = 0; maybe_setuid = 0;
/* /*
Now we are now working under our real uid * Now we are now working under our real uid
*/ */
ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
@ -1014,6 +1025,9 @@ main ( int argc, char **argv)
assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
setup_libassuan_logging (&opt.debug, NULL); setup_libassuan_logging (&opt.debug, NULL);
/* Set homedir. */
gnupg_set_homedir (homedirvalue);
/* Setup a default control structure for command line mode */ /* Setup a default control structure for command line mode */
memset (&ctrl, 0, sizeof ctrl); memset (&ctrl, 0, sizeof ctrl);
gpgsm_init_default_ctrl (&ctrl); gpgsm_init_default_ctrl (&ctrl);
@ -1021,48 +1035,43 @@ main ( int argc, char **argv)
ctrl.status_fd = -1; /* No status output. */ ctrl.status_fd = -1; /* No status output. */
ctrl.autodetect_encoding = 1; ctrl.autodetect_encoding = 1;
/* Set the default option file */
if (default_config )
configname = make_filename (gnupg_homedir (),
GPGSM_NAME EXTSEP_S "conf", NULL);
/* Set the default policy file */ /* Set the default policy file */
opt.policy_file = make_filename (gnupg_homedir (), "policies.txt", NULL); opt.policy_file = make_filename (gnupg_homedir (), "policies.txt", NULL);
/* The configuraton directories for use by gpgrt_argparser. */
gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ());
gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ());
/* We are re-using the struct, thus the reset flag. We OR the
* flags so that the internal intialized flag won't be cleared. */
argc = orig_argc; argc = orig_argc;
argv = orig_argv; argv = orig_argv;
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = 1; /* do not remove the args */ pargs.flags |= (ARGPARSE_FLAG_RESET
| ARGPARSE_FLAG_KEEP
next_pass: | ARGPARSE_FLAG_SYS
if (configname) { | ARGPARSE_FLAG_USER);
configlineno = 0;
configfp = gnupg_fopen (configname, "r");
if (!configfp)
{
if (default_config)
{
if (parse_debug)
log_info (_("Note: no default option file '%s'\n"), configname);
}
else
{
log_error (_("option file '%s': %s\n"), configname, strerror(errno));
gpgsm_exit(2);
}
xfree(configname);
configname = NULL;
}
if (parse_debug && configname)
log_info (_("reading options from '%s'\n"), configname);
default_config = 0;
}
while (!no_more_options while (!no_more_options
&& optfile_parse (configfp, configname, &configlineno, &pargs, opts)) && gnupg_argparser (&pargs, opts, GPGSM_NAME EXTSEP_S "conf"))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
case ARGPARSE_CONFFILE:
if (debug_argparser)
log_info (_("reading options from '%s'\n"),
pargs.r_type? pargs.r.ret_str: "[cmdline]");
if (pargs.r_type)
{
xfree (last_configname);
last_configname = xstrdup (pargs.r.ret_str);
configname = last_configname;
}
else
configname = NULL;
break;
case aGPGConfList: case aGPGConfList:
case aGPGConfTest: case aGPGConfTest:
set_cmd (&cmd, pargs.r_opt); set_cmd (&cmd, pargs.r_opt);
@ -1308,16 +1317,6 @@ main ( int argc, char **argv)
opt.with_keygrip = 1; opt.with_keygrip = 1;
break; break;
case oOptions:
/* config files may not be nested (silently ignore them) */
if (!configfp)
{
xfree(configname);
configname = xstrdup (pargs.r.ret_str);
goto next_pass;
}
break;
case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
@ -1445,7 +1444,7 @@ main ( int argc, char **argv)
{ {
struct keyserver_spec *keyserver; struct keyserver_spec *keyserver;
keyserver = parse_keyserver_line (pargs.r.ret_str, keyserver = parse_keyserver_line (pargs.r.ret_str,
configname, configlineno); configname, pargs.lineno);
if (! keyserver) if (! keyserver)
log_error (_("could not parse keyserver\n")); log_error (_("could not parse keyserver\n"));
else else
@ -1483,27 +1482,28 @@ main ( int argc, char **argv)
break; break;
default: default:
pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; if (configname)
pargs.err = ARGPARSE_PRINT_WARNING;
else
{
pargs.err = ARGPARSE_PRINT_ERROR;
/* The argparse function calls a plain exit and thus we
* need to print a status here. */
gpgsm_status_with_error (&ctrl, STATUS_FAILURE, "option-parser",
gpg_error (GPG_ERR_GENERAL));
}
break; break;
} }
} }
if (configfp) gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
{
fclose (configfp);
configfp = NULL;
/* Keep a copy of the config filename. */
opt.config_filename = configname;
configname = NULL;
goto next_pass;
}
xfree (configname);
configname = NULL;
if (!opt.config_filename) if (!last_configname)
opt.config_filename = make_filename (gnupg_homedir (), opt.config_filename = make_filename (gnupg_homedir (),
GPGSM_NAME EXTSEP_S "conf", GPGSM_NAME EXTSEP_S "conf",
NULL); NULL);
else
opt.config_filename = last_configname;
if (log_get_errorcount(0)) if (log_get_errorcount(0))
{ {

View File

@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -78,9 +79,8 @@ size_t scmpath_len = 0;
static void static void
parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts) parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
{ {
int no_more_options = 0;
while (!no_more_options && optfile_parse (NULL, NULL, NULL, pargs, popts)) while (gnupg_argparse (NULL, pargs, popts))
{ {
switch (pargs->r_opt) switch (pargs->r_opt)
{ {
@ -89,7 +89,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
break; break;
default: default:
pargs->err = 2; pargs->err = ARGPARSE_PRINT_ERROR;
break; break;
} }
} }
@ -103,9 +103,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "gpgscm (@GNUPG@)"; case 11: p = "gpgscm (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -297,6 +299,7 @@ main (int argc, char **argv)
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = 0; pargs.flags = 0;
parse_arguments (&pargs, opts); parse_arguments (&pargs, opts);
gnupg_argparse (NULL, &pargs, NULL);
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);

View File

@ -15,6 +15,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -133,9 +134,11 @@ my_strusage (int level)
const char *p; const char *p;
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "gpg-check-pattern (@GnuPG@)"; case 11: p = "gpg-check-pattern (@GnuPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -176,8 +179,8 @@ main (int argc, char **argv )
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* (do not remove the args) */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (arg_parse (&pargs, opts) ) while (gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -189,6 +192,8 @@ main (int argc, char **argv )
default : pargs.err = 2; break; default : pargs.err = 2; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount(0)) if (log_get_errorcount(0))
exit (2); exit (2);
@ -489,4 +494,3 @@ process (FILE *fp, pattern_t *patarray)
if (opt.verbose) if (opt.verbose)
log_info ("no input line matches the pattern - accepted\n"); log_info ("no input line matches the pattern - accepted\n");
} }

View File

@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -195,9 +196,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@GPG@-connect-agent (@GNUPG@)"; case 11: p = "@GPG@-connect-agent (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -1190,8 +1193,8 @@ main (int argc, char **argv)
/* Parse the command line. */ /* Parse the command line. */
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = 1; /* Do not remove the args. */ pargs.flags = ARGPARSE_FLAG_KEEP;
while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts)) while (!no_more_options && gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -1219,6 +1222,7 @@ main (int argc, char **argv)
default: pargs.err = 2; break; default: pargs.err = 2; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);

View File

@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/ */
#include <config.h> #include <config.h>
@ -159,9 +160,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "LGPL-2.1-or-later"; break;
case 11: p = "gpg-wks-client"; break; case 11: p = "gpg-wks-client"; break;
case 12: p = "@GNUPG@"; break; case 12: p = "@GNUPG@"; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = ("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = ("Please report bugs to <@EMAIL@>.\n"); break;
@ -196,7 +199,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
enum cmd_and_opt_values cmd = 0; enum cmd_and_opt_values cmd = 0;
int no_more_options = 0; int no_more_options = 0;
while (!no_more_options && optfile_parse (NULL, NULL, NULL, pargs, popts)) while (!no_more_options && gnupg_argparse (NULL, pargs, popts))
{ {
switch (pargs->r_opt) switch (pargs->r_opt)
{ {
@ -244,7 +247,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
cmd = pargs->r_opt; cmd = pargs->r_opt;
break; break;
default: pargs->err = 2; break; default: pargs->err = ARGPARSE_PRINT_ERROR; break;
} }
} }
@ -277,6 +280,7 @@ main (int argc, char **argv)
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = ARGPARSE_FLAG_KEEP; pargs.flags = ARGPARSE_FLAG_KEEP;
cmd = parse_arguments (&pargs, opts); cmd = parse_arguments (&pargs, opts);
gnupg_argparse (NULL, &pargs, NULL);
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);

View File

@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/ */
/* The Web Key Service I-D defines an update protocol to store a /* The Web Key Service I-D defines an update protocol to store a
@ -172,9 +173,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "LGPL-2.1-or-later"; break;
case 11: p = "gpg-wks-server"; break; case 11: p = "gpg-wks-server"; break;
case 12: p = "@GNUPG@"; break; case 12: p = "@GNUPG@"; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = ("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = ("Please report bugs to <@EMAIL@>.\n"); break;
@ -209,7 +212,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
enum cmd_and_opt_values cmd = 0; enum cmd_and_opt_values cmd = 0;
int no_more_options = 0; int no_more_options = 0;
while (!no_more_options && optfile_parse (NULL, NULL, NULL, pargs, popts)) while (!no_more_options && gnupg_argparse (NULL, pargs, popts))
{ {
switch (pargs->r_opt) switch (pargs->r_opt)
{ {
@ -258,7 +261,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
cmd = pargs->r_opt; cmd = pargs->r_opt;
break; break;
default: pargs->err = 2; break; default: pargs->err = ARGPARSE_PRINT_ERROR; break;
} }
} }
@ -287,6 +290,7 @@ main (int argc, char **argv)
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = ARGPARSE_FLAG_KEEP; pargs.flags = ARGPARSE_FLAG_KEEP;
cmd = parse_arguments (&pargs, opts); cmd = parse_arguments (&pargs, opts);
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);

View File

@ -1,6 +1,6 @@
/* gpgconf.c - Configuration utility for GnuPG /* gpgconf.c - Configuration utility for GnuPG
* Copyright (C) 2003, 2007, 2009, 2011 Free Software Foundation, Inc. * Copyright (C) 2003, 2007, 2009, 2011 Free Software Foundation, Inc.
* Copyright (C) 2016 g10 Code GmbH. * Copyright (C) 2016, 2020 g10 Code GmbH.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -16,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -136,9 +137,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@GPGCONF@ (@GNUPG@)"; case 11: p = "@GPGCONF@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -564,17 +567,15 @@ main (int argc, char **argv)
/* Parse the command line. */ /* Parse the command line. */
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = 1; /* Do not remove the args. */ pargs.flags = ARGPARSE_FLAG_KEEP;
while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts)) while (!no_more_options && gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
case oOutput: opt.outfile = pargs.r.ret_str; break; case oOutput: opt.outfile = pargs.r.ret_str; break;
case oQuiet: opt.quiet = 1; break; case oQuiet: opt.quiet = 1; break;
case oDryRun: opt.dry_run = 1; break; case oDryRun: opt.dry_run = 1; break;
case oRuntime: case oRuntime: opt.runtime = 1; break;
opt.runtime = 1;
break;
case oVerbose: opt.verbose++; break; case oVerbose: opt.verbose++; break;
case oNoVerbose: opt.verbose = 0; break; case oNoVerbose: opt.verbose = 0; break;
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
@ -605,9 +606,10 @@ main (int argc, char **argv)
cmd = pargs.r_opt; cmd = pargs.r_opt;
break; break;
default: pargs.err = 2; break; default: pargs.err = ARGPARSE_PRINT_ERROR; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount (0)) if (log_get_errorcount (0))
gpgconf_failure (GPG_ERR_USER_2); gpgconf_failure (GPG_ERR_USER_2);

View File

@ -15,6 +15,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <config.h> #include <config.h>
@ -86,9 +87,11 @@ my_strusage (int level)
const char *p; const char *p;
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "gpgsplit (@GNUPG@)"; case 11: p = "gpgsplit (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = "Please report bugs to <@EMAIL@>.\n"; break; case 19: p = "Please report bugs to <@EMAIL@>.\n"; break;
@ -122,8 +125,8 @@ main (int argc, char **argv)
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags= 1; /* do not remove the args */ pargs.flags= ARGPARSE_FLAG_KEEP;
while (optfile_parse( NULL, NULL, NULL, &pargs, opts)) while (gnupg_argparse (NULL, &pargs, opts))
{ {
switch (pargs.r_opt) switch (pargs.r_opt)
{ {
@ -132,9 +135,10 @@ main (int argc, char **argv)
case oUncompress: opt_uncompress = 1; break; case oUncompress: opt_uncompress = 1; break;
case oSecretToPublic: opt_secret_to_public = 1; break; case oSecretToPublic: opt_secret_to_public = 1; break;
case oNoSplit: opt_no_split = 1; break; case oNoSplit: opt_no_split = 1; break;
default : pargs.err = 2; break; default : pargs.err = ARGPARSE_PRINT_ERROR; break;
} }
} }
gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */
if (log_get_errorcount(0)) if (log_get_errorcount(0))
g10_exit (2); g10_exit (2);

View File

@ -1,5 +1,6 @@
/* gpgtar.c - A simple TAR implementation mainly useful for Windows. /* gpgtar.c - A simple TAR implementation mainly useful for Windows.
* Copyright (C) 2010 Free Software Foundation, Inc. * Copyright (C) 2010 Free Software Foundation, Inc.
* Copyright (C) 2020 g10 Code GmbH
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -15,6 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>. * along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-3.0-or-later
*/ */
/* GnuPG comes with a shell script gpg-zip which creates archive files /* GnuPG comes with a shell script gpg-zip which creates archive files
@ -161,9 +163,11 @@ my_strusage( int level )
switch (level) switch (level)
{ {
case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "@GPGTAR@ (@GNUPG@)"; case 11: p = "@GPGTAR@ (@GNUPG@)";
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break; case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@ -314,7 +318,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
{ {
int no_more_options = 0; int no_more_options = 0;
while (!no_more_options && optfile_parse (NULL, NULL, NULL, pargs, popts)) while (!no_more_options && gnupg_argparse (NULL, pargs, popts))
{ {
switch (pargs->r_opt) switch (pargs->r_opt)
{ {
@ -385,7 +389,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
} }
break; break;
case oTarArgs:; case oTarArgs:
{ {
int tar_argc; int tar_argc;
char **tar_argv; char **tar_argv;
@ -400,6 +404,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
tar_args.argv = &tar_argv; tar_args.argv = &tar_argv;
tar_args.flags = ARGPARSE_FLAG_ARG0; tar_args.flags = ARGPARSE_FLAG_ARG0;
parse_arguments (&tar_args, tar_opts); parse_arguments (&tar_args, tar_opts);
gnupg_argparse (NULL, &tar_args, NULL);
if (tar_args.err) if (tar_args.err)
log_error ("unsupported tar arguments '%s'\n", log_error ("unsupported tar arguments '%s'\n",
pargs->r.ret_str); pargs->r.ret_str);
@ -426,8 +431,6 @@ main (int argc, char **argv)
const char *fname; const char *fname;
ARGPARSE_ARGS pargs; ARGPARSE_ARGS pargs;
assert (sizeof (struct ustar_raw_header) == 512);
gnupg_reopen_std (GPGTAR_NAME); gnupg_reopen_std (GPGTAR_NAME);
set_strusage (my_strusage); set_strusage (my_strusage);
log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX); log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX);
@ -436,11 +439,14 @@ main (int argc, char **argv)
i18n_init(); i18n_init();
init_common_subsystems (&argc, &argv); init_common_subsystems (&argc, &argv);
log_assert (sizeof (struct ustar_raw_header) == 512);
/* Parse the command line. */ /* Parse the command line. */
pargs.argc = &argc; pargs.argc = &argc;
pargs.argv = &argv; pargs.argv = &argv;
pargs.flags = ARGPARSE_FLAG_KEEP; pargs.flags = ARGPARSE_FLAG_KEEP;
parse_arguments (&pargs, opts); parse_arguments (&pargs, opts);
gnupg_argparse (NULL, &pargs, NULL);
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); exit (2);