diff --git a/doc/tools.texi b/doc/tools.texi index 734d61918..2a1d38f3e 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -305,6 +305,14 @@ Reload all or the given component. This is basically the same as sending a SIGHUP to the component. Components which don't support reloading are ignored. +@item --launch [@var{component}] +@opindex launch +If the @var{component} is not already running, start it. +@command{component} must be a daemon. This is in general not required +because the system starts these daemons as needed. However, external +software making direct use of @command{gpg-agent} or @command{dirmngr} +may use this command to ensure that they are started. + @item --kill [@var{component}] @opindex kill Kill the given component. Components which support killing are diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 356b25126..65c116b7d 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1108,6 +1108,44 @@ scdaemon_runtime_change (int killflag) } +/* Launch the gpg-agent or the dirmngr if not already running. */ +void +gc_component_launch (int component) +{ + gpg_error_t err; + const char *pgmname; + const char *argv[3]; + int i; + pid_t pid; + + if (!(component == GC_COMPONENT_GPG_AGENT + || component == GC_COMPONENT_DIRMNGR)) + { + es_fputs (_("Component not suitable for launching"), es_stderr); + es_putc ('\n', es_stderr); + exit (1); + } + + pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT); + i = 0; + if (component == GC_COMPONENT_DIRMNGR) + argv[i++] = "--dirmngr"; + argv[i++] = "NOP"; + argv[i] = NULL; + + err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + if (!err) + err = gnupg_wait_process (pgmname, pid, 1, NULL); + if (err) + gc_error (0, 0, "error running '%s%s%s': %s", + pgmname, + component == GC_COMPONENT_DIRMNGR? " --dirmngr":"", + " NOP", + gpg_strerror (err)); + gnupg_release_process (pid); +} + + /* Unconditionally restart COMPONENT. */ void gc_component_kill (int component) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index fbce6d371..96313f617 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -51,6 +51,7 @@ enum cmd_and_opt_values aListConfig, aCheckConfig, aListDirs, + aLaunch, aKill, aReload }; @@ -75,6 +76,7 @@ static ARGPARSE_OPTS opts[] = { aCheckConfig, "check-config", 256, N_("check global configuration file") }, { aReload, "reload", 256, N_("reload all or a given component")}, + { aLaunch, "launch", 256, N_("launch a given component")}, { aKill, "kill", 256, N_("kill a given component")}, { 301, NULL, 0, N_("@\nOptions:\n ") }, @@ -184,6 +186,7 @@ main (int argc, char **argv) case aListConfig: case aCheckConfig: case aReload: + case aLaunch: case aKill: cmd = pargs.r_opt; break; @@ -255,6 +258,7 @@ main (int argc, char **argv) } break; + case aLaunch: case aKill: if (!fname) { @@ -266,7 +270,7 @@ main (int argc, char **argv) } else { - /* Kill a given component. */ + /* Launch/Kill a given component. */ int idx; idx = gc_component_find (fname); @@ -276,10 +280,10 @@ main (int argc, char **argv) es_putc ('\n', es_stderr); exit (1); } + else if (cmd == aLaunch) + gc_component_launch (idx); else - { - gc_component_kill (idx); - } + gc_component_kill (idx); } break; diff --git a/tools/gpgconf.h b/tools/gpgconf.h index 9caa0d490..0286c2737 100644 --- a/tools/gpgconf.h +++ b/tools/gpgconf.h @@ -44,6 +44,9 @@ char *gc_percent_escape (const char *src); void gc_error (int status, int errnum, const char *fmt, ...); +/* Launch given component. */ +void gc_component_launch (int component); + /* Kill given component. */ void gc_component_kill (int component);