1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

conf: New option --status-fd.

* tools/gpgconf.c (oStatusFD): New const.
(opts): New option --status-fd.
(statusfp): New var.
(set_status_fd): New.
(gpgconf_write_status): New.
(gpgconf_failure): New.
(main): Set status fd and replace exit by gpgconf_failure.
* tools/gpgconf-comp.c: Repalce exit by gpgconf_failure.
(gc_process_gpgconf_conf): Print a few warning status messages.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2017-12-18 17:46:05 +01:00
parent d74c40cef0
commit 482e000b8a
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 137 additions and 18 deletions

View File

@ -407,6 +407,14 @@ changing.
This means that the changes will take effect at run-time, as far as This means that the changes will take effect at run-time, as far as
this is possible. Otherwise, they will take effect at the next start this is possible. Otherwise, they will take effect at the next start
of the respective backend programs. of the respective backend programs.
@item --status-fd @var{n}
@opindex status-fd
Write special status strings to the file descriptor @var{n}. This
program returns the status messages SUCCESS or FAILURE which are
helpful when the caller uses a double fork approach and can't easily
get the return code of the process.
@manpause @manpause
@end table @end table

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# Apply defaults from /etc/gnupg/gpg.conf to all users -*- sh -*- # Apply defaults from /etc/gnupg/gpgconf.conf to all users -*- sh -*-
# #
# Copyright 2007 Free Software Foundation, Inc. # Copyright 2007 Free Software Foundation, Inc.
# #

View File

@ -48,6 +48,7 @@
#include "../common/i18n.h" #include "../common/i18n.h"
#include "../common/exechelp.h" #include "../common/exechelp.h"
#include "../common/sysutils.h" #include "../common/sysutils.h"
#include "../common/status.h"
#include "../common/gc-opt-flags.h" #include "../common/gc-opt-flags.h"
#include "gpgconf.h" #include "gpgconf.h"
@ -99,7 +100,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
{ {
log_printf (NULL); log_printf (NULL);
log_printf ("fatal error (exit status %i)\n", status); log_printf ("fatal error (exit status %i)\n", status);
exit (status); gpgconf_failure (gpg_error_from_errno (errnum));
} }
} }
@ -1310,7 +1311,7 @@ gc_component_launch (int component)
{ {
es_fputs (_("Component not suitable for launching"), es_stderr); es_fputs (_("Component not suitable for launching"), es_stderr);
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
exit (1); gpgconf_failure (0);
} }
pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT); pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
@ -3757,6 +3758,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{ {
gc_error (0, 0, "missing rule at '%s', line %d", fname, lineno); gc_error (0, 0, "missing rule at '%s', line %d", fname, lineno);
result = -1; result = -1;
gpgconf_write_status (STATUS_WARNING,
"gpgconf.conf %d file '%s' line %d "
"missing rule",
GPG_ERR_SYNTAX, fname, lineno);
continue; continue;
} }
*p++ = 0; *p++ = 0;
@ -3786,6 +3791,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{ {
gc_error (0, 0, "missing component at '%s', line %d", gc_error (0, 0, "missing component at '%s', line %d",
fname, lineno); fname, lineno);
gpgconf_write_status (STATUS_WARNING,
"gpgconf.conf %d file '%s' line %d "
" missing component",
GPG_ERR_NO_NAME, fname, lineno);
result = -1; result = -1;
continue; continue;
} }
@ -3797,6 +3806,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{ {
gc_error (0, 0, "unknown component at '%s', line %d", gc_error (0, 0, "unknown component at '%s', line %d",
fname, lineno); fname, lineno);
gpgconf_write_status (STATUS_WARNING,
"gpgconf.conf %d file '%s' line %d "
"unknown component",
GPG_ERR_UNKNOWN_NAME, fname, lineno);
result = -1; result = -1;
} }
@ -3809,6 +3822,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{ {
gc_error (0, 0, "missing option at '%s', line %d", gc_error (0, 0, "missing option at '%s', line %d",
fname, lineno); fname, lineno);
gpgconf_write_status (STATUS_WARNING,
"gpgconf.conf %d file '%s' line %d "
"missing option",
GPG_ERR_INV_NAME, fname, lineno);
result = -1; result = -1;
continue; continue;
} }
@ -3821,6 +3838,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{ {
gc_error (0, 0, "unknown option at '%s', line %d", gc_error (0, 0, "unknown option at '%s', line %d",
fname, lineno); fname, lineno);
gpgconf_write_status (STATUS_WARNING,
"gpgconf.conf %d file '%s' line %d "
"unknown option",
GPG_ERR_UNKNOWN_OPTION, fname, lineno);
result = -1; result = -1;
} }
} }
@ -3837,6 +3858,10 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
{ {
gc_error (0, 0, "syntax error in rule at '%s', line %d", gc_error (0, 0, "syntax error in rule at '%s', line %d",
fname, lineno); fname, lineno);
gpgconf_write_status (STATUS_WARNING,
"gpgconf.conf %d file '%s' line %d "
"syntax error in rule",
GPG_ERR_SYNTAX, fname, lineno);
result = -1; result = -1;
continue; continue;
} }

View File

@ -29,6 +29,7 @@
#include "../common/i18n.h" #include "../common/i18n.h"
#include "../common/sysutils.h" #include "../common/sysutils.h"
#include "../common/init.h" #include "../common/init.h"
#include "../common/status.h"
/* Constants to identify the commands and options. */ /* Constants to identify the commands and options. */
@ -45,6 +46,7 @@ enum cmd_and_opt_values
oNoVerbose = 500, oNoVerbose = 500,
oHomedir, oHomedir,
oBuilddir, oBuilddir,
oStatusFD,
aListComponents, aListComponents,
aCheckPrograms, aCheckPrograms,
@ -100,6 +102,7 @@ static ARGPARSE_OPTS opts[] =
{ oQuiet, "quiet", 0, N_("quiet") }, { oQuiet, "quiet", 0, N_("quiet") },
{ oDryRun, "dry-run", 0, N_("do not make any changes") }, { oDryRun, "dry-run", 0, N_("do not make any changes") },
{ oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") },
ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")),
/* hidden options */ /* hidden options */
{ oHomedir, "homedir", 2, "@" }, { oHomedir, "homedir", 2, "@" },
{ oBuilddir, "build-prefix", 2, "@" }, { oBuilddir, "build-prefix", 2, "@" },
@ -110,6 +113,11 @@ static ARGPARSE_OPTS opts[] =
}; };
/* The stream to output the status information. Status Output is disabled if
* this is NULL. */
static estream_t statusfp;
/* Print usage information and provide strings for help. */ /* Print usage information and provide strings for help. */
static const char * static const char *
my_strusage( int level ) my_strusage( int level )
@ -159,6 +167,60 @@ get_outfp (estream_t *fp)
} }
/* Set the status FD. */
static void
set_status_fd (int fd)
{
static int last_fd = -1;
if (fd != -1 && last_fd == fd)
return;
if (statusfp && statusfp != es_stdout && statusfp != es_stderr)
es_fclose (statusfp);
statusfp = NULL;
if (fd == -1)
return;
if (fd == 1)
statusfp = es_stdout;
else if (fd == 2)
statusfp = es_stderr;
else
statusfp = es_fdopen (fd, "w");
if (!statusfp)
{
log_fatal ("can't open fd %d for status output: %s\n",
fd, gpg_strerror (gpg_error_from_syserror ()));
}
last_fd = fd;
}
/* Write a status line with code NO followed by the output of the
* printf style FORMAT. The caller needs to make sure that LFs and
* CRs are not printed. */
void
gpgconf_write_status (int no, const char *format, ...)
{
va_list arg_ptr;
if (!statusfp)
return; /* Not enabled. */
es_fputs ("[GNUPG:] ", statusfp);
es_fputs (get_status_string (no), statusfp);
if (format)
{
es_putc (' ', statusfp);
va_start (arg_ptr, format);
es_vfprintf (statusfp, format, arg_ptr);
va_end (arg_ptr);
}
es_putc ('\n', statusfp);
}
static void static void
list_dirs (estream_t fp, char **names) list_dirs (estream_t fp, char **names)
{ {
@ -493,6 +555,9 @@ main (int argc, char **argv)
case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
case oBuilddir: gnupg_set_builddir (pargs.r.ret_str); break; case oBuilddir: gnupg_set_builddir (pargs.r.ret_str); break;
case oNull: opt.null = 1; break; case oNull: opt.null = 1; break;
case oStatusFD:
set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
break;
case aListDirs: case aListDirs:
case aListComponents: case aListComponents:
@ -518,7 +583,7 @@ main (int argc, char **argv)
} }
if (log_get_errorcount (0)) if (log_get_errorcount (0))
exit (2); gpgconf_failure (GPG_ERR_USER_2);
/* Print a warning if an argument looks like an option. */ /* Print a warning if an argument looks like an option. */
if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN)) if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
@ -554,7 +619,7 @@ main (int argc, char **argv)
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
es_fputs (_("Need one component argument"), es_stderr); es_fputs (_("Need one component argument"), es_stderr);
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
exit (2); gpgconf_failure (GPG_ERR_USER_2);
} }
else else
{ {
@ -563,7 +628,7 @@ main (int argc, char **argv)
{ {
es_fputs (_("Component not found"), es_stderr); es_fputs (_("Component not found"), es_stderr);
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
exit (1); gpgconf_failure (0);
} }
if (cmd == aCheckOptions) if (cmd == aCheckOptions)
gc_component_check_options (idx, get_outfp (&outfp), NULL); gc_component_check_options (idx, get_outfp (&outfp), NULL);
@ -571,7 +636,7 @@ main (int argc, char **argv)
{ {
gc_component_retrieve_options (idx); gc_component_retrieve_options (idx);
if (gc_process_gpgconf_conf (NULL, 1, 0, NULL)) if (gc_process_gpgconf_conf (NULL, 1, 0, NULL))
exit (1); gpgconf_failure (0);
if (cmd == aListOptions) if (cmd == aListOptions)
gc_component_list_options (idx, get_outfp (&outfp)); gc_component_list_options (idx, get_outfp (&outfp));
else if (cmd == aChangeOptions) else if (cmd == aChangeOptions)
@ -589,14 +654,14 @@ main (int argc, char **argv)
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
es_fputs (_("Need one component argument"), es_stderr); es_fputs (_("Need one component argument"), es_stderr);
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
exit (2); gpgconf_failure (GPG_ERR_USER_2);
} }
else if (!strcmp (fname, "all")) else if (!strcmp (fname, "all"))
{ {
if (cmd == aLaunch) if (cmd == aLaunch)
{ {
if (gc_component_launch (-1)) if (gc_component_launch (-1))
exit (1); gpgconf_failure (0);
} }
else else
{ {
@ -613,12 +678,12 @@ main (int argc, char **argv)
{ {
es_fputs (_("Component not found"), es_stderr); es_fputs (_("Component not found"), es_stderr);
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
exit (1); gpgconf_failure (0);
} }
else if (cmd == aLaunch) else if (cmd == aLaunch)
{ {
if (gc_component_launch (idx)) if (gc_component_launch (idx))
exit (1); gpgconf_failure (0);
} }
else else
{ {
@ -646,7 +711,7 @@ main (int argc, char **argv)
{ {
es_fputs (_("Component not found"), es_stderr); es_fputs (_("Component not found"), es_stderr);
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
exit (1); gpgconf_failure (0);
} }
else else
{ {
@ -657,12 +722,12 @@ main (int argc, char **argv)
case aListConfig: case aListConfig:
if (gc_process_gpgconf_conf (fname, 0, 0, get_outfp (&outfp))) if (gc_process_gpgconf_conf (fname, 0, 0, get_outfp (&outfp)))
exit (1); gpgconf_failure (0);
break; break;
case aCheckConfig: case aCheckConfig:
if (gc_process_gpgconf_conf (fname, 0, 0, NULL)) if (gc_process_gpgconf_conf (fname, 0, 0, NULL))
exit (1); gpgconf_failure (0);
break; break;
case aApplyDefaults: case aApplyDefaults:
@ -672,17 +737,17 @@ main (int argc, char **argv)
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
es_fputs (_("No argument allowed"), es_stderr); es_fputs (_("No argument allowed"), es_stderr);
es_putc ('\n', es_stderr); es_putc ('\n', es_stderr);
exit (2); gpgconf_failure (GPG_ERR_USER_2);
} }
gc_component_retrieve_options (-1); gc_component_retrieve_options (-1);
if (gc_process_gpgconf_conf (NULL, 1, 1, NULL)) if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
exit (1); gpgconf_failure (0);
break; break;
case aApplyProfile: case aApplyProfile:
gc_component_retrieve_options (-1); gc_component_retrieve_options (-1);
if (gc_apply_profile (fname)) if (gc_apply_profile (fname))
exit (1); gpgconf_failure (0);
break; break;
case aListDirs: case aListDirs:
@ -697,7 +762,7 @@ main (int argc, char **argv)
{ {
es_fprintf (es_stderr, "usage: %s --query-swdb NAME [VERSION]\n", es_fprintf (es_stderr, "usage: %s --query-swdb NAME [VERSION]\n",
GPGCONF_NAME); GPGCONF_NAME);
exit (2); gpgconf_failure (GPG_ERR_USER_2);
} }
get_outfp (&outfp); get_outfp (&outfp);
query_swdb (outfp, fname, argc > 1? argv[1] : NULL); query_swdb (outfp, fname, argc > 1? argv[1] : NULL);
@ -804,5 +869,22 @@ main (int argc, char **argv)
if (es_fclose (outfp)) if (es_fclose (outfp))
gc_error (1, errno, "error closing '%s'", opt.outfile); gc_error (1, errno, "error closing '%s'", opt.outfile);
if (log_get_errorcount (0))
gpgconf_failure (0);
else
gpgconf_write_status (STATUS_SUCCESS, NULL);
return 0; return 0;
} }
void
gpgconf_failure (gpg_error_t err)
{
if (!err)
err = gpg_error (GPG_ERR_GENERAL);
gpgconf_write_status
(STATUS_FAILURE, "- %u",
gpg_err_code (err) == GPG_ERR_USER_2? GPG_ERR_EINVAL : err);
exit (gpg_err_code (err) == GPG_ERR_USER_2? 2 : 1);
}

View File

@ -36,6 +36,10 @@ struct
} opt; } opt;
/*-- gpgconf.c --*/
void gpgconf_write_status (int no, const char *format,
...) GPGRT_ATTR_PRINTF(2,3);
void gpgconf_failure (gpg_error_t err) GPGRT_ATTR_NORETURN;
/*-- gpgconf-comp.c --*/ /*-- gpgconf-comp.c --*/