tools/gpgtar: Handle '--directory' argument.
[gnupg.git] / tools / gpgconf-comp.c
index 74feadb..5e4bd58 100644 (file)
@@ -1,5 +1,6 @@
 /* gpgconf-comp.c - Configuration utility for GnuPG.
- * Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2007, 2008, 2009, 2010,
+ *               2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -43,7 +44,6 @@
 #endif
 
 /* For log_logv(), asctimestamp(), gnupg_get_time ().  */
-#define JNLIB_NEED_LOG_LOGV
 #include "util.h"
 #include "i18n.h"
 #include "exechelp.h"
@@ -57,7 +57,7 @@
 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
 #define GPGNAME "gpg2"
 #else
-#define GPGNAME "gpg"
+#define GPGNAME GPG_NAME
 #endif
 
 \f
@@ -86,7 +86,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
   va_list arg_ptr;
 
   va_start (arg_ptr, fmt);
-  log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr);
+  log_logv (GPGRT_LOG_ERROR, fmt, arg_ptr);
   va_end (arg_ptr);
 
   if (errnum)
@@ -104,8 +104,9 @@ gc_error (int status, int errnum, const char *fmt, ...)
 
 \f
 /* Forward declaration.  */
-static void gpg_agent_runtime_change (void);
-static void scdaemon_runtime_change (void);
+static void gpg_agent_runtime_change (int killflag);
+static void scdaemon_runtime_change (int killflag);
+static void dirmngr_runtime_change (int killflag);
 
 /* Backend configuration.  Backends are used to decide how the default
    and current value of an option can be determined, and how the
@@ -163,8 +164,9 @@ static struct
      available. */
   char module_name;
 
-  /* The runtime change callback.  */
-  void (*runtime_change) (void);
+  /* The runtime change callback.  If KILLFLAG is true the component
+     is killed and not just reloaded.  */
+  void (*runtime_change) (int killflag);
 
   /* The option name for the configuration filename of this backend.
      This must be an absolute filename.  It can be an option from a
@@ -178,20 +180,20 @@ static struct
 } gc_backend[GC_BACKEND_NR] =
   {
     { NULL },          /* GC_BACKEND_ANY dummy entry.  */
-    { "GnuPG", GPGNAME, GNUPG_MODULE_NAME_GPG,
-      NULL, "gpgconf-gpg.conf" },
-    { "GPGSM", "gpgsm", GNUPG_MODULE_NAME_GPGSM,
-      NULL, "gpgconf-gpgsm.conf" },
-    { "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT, 
-      gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
-    { "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON,
-      scdaemon_runtime_change, "gpgconf-scdaemon.conf" },
-    { "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR,
-      NULL, "gpgconf-dirmngr.conf" },
-    { "DirMngr LDAP Server List", NULL, 0, 
+    { GPG_DISP_NAME, GPGNAME, GNUPG_MODULE_NAME_GPG,
+      NULL, GPGCONF_NAME "-" GPG_NAME ".conf" },
+    { GPGSM_DISP_NAME, GPGSM_NAME, GNUPG_MODULE_NAME_GPGSM,
+      NULL, GPGCONF_NAME "-" GPGSM_NAME ".conf" },
+    { GPG_AGENT_DISP_NAME, GPG_AGENT_NAME, GNUPG_MODULE_NAME_AGENT,
+      gpg_agent_runtime_change, GPGCONF_NAME"-" GPG_AGENT_NAME ".conf" },
+    { SCDAEMON_DISP_NAME, SCDAEMON_NAME, GNUPG_MODULE_NAME_SCDAEMON,
+      scdaemon_runtime_change, GPGCONF_NAME"-" SCDAEMON_NAME ".conf" },
+    { DIRMNGR_DISP_NAME, DIRMNGR_NAME, GNUPG_MODULE_NAME_DIRMNGR,
+      dirmngr_runtime_change, GPGCONF_NAME "-" DIRMNGR_NAME ".conf" },
+    { DIRMNGR_DISP_NAME " LDAP Server List", NULL, 0,
       NULL, "ldapserverlist-file", "LDAP Server" },
     { "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
-      NULL, "gpgconf-pinentry.conf" },
+      NULL, GPGCONF_NAME "-pinentry.conf" },
   };
 
 \f
@@ -355,11 +357,6 @@ static struct
    several times.  A comma separated list of arguments is used as the
    argument value.  */
 #define GC_OPT_FLAG_LIST       (1UL << 2)
-/* The NO_CHANGE flag for an option indicates that the user should not
-   be allowed to change this option using the standard gpgconf method.
-   Frontends using gpgconf should grey out such options, so that only
-   the current value is displayed.  */
-#define GC_OPT_FLAG_NO_CHANGE   (1UL <<7)
 
 
 /* A human-readable description for each flag.  */
@@ -405,17 +402,17 @@ struct gc_option
   /* A gettext domain in which the following description can be found.
      If this is NULL, then DESC is not translated.  Valid for groups
      and options.
-     
+
      Note that we try to keep the description of groups within the
-     gnupg domain. 
-     
+     gnupg domain.
+
      IMPORTANT: If you add a new domain please make sure to add a code
      set switching call to the function my_dgettext further below.  */
   const char *desc_domain;
 
   /* A gettext description for this group or option.  If it starts
      with a '|', then the string up to the next '|' describes the
-     argument, and the description follows the second '|'. 
+     argument, and the description follows the second '|'.
 
      In general enclosing these description in N_() is not required
      because the description should be identical to the one in the
@@ -473,7 +470,8 @@ typedef struct gc_option gc_option_t;
 static gc_option_t gc_options_gpg_agent[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-" GPG_AGENT_NAME ".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
 
    { "Monitor",
@@ -490,7 +488,7 @@ static gc_option_t gc_options_gpg_agent[] =
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
 
    { "Configuration",
-     GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
+     GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
      "gnupg", N_("Options controlling the configuration") },
    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
      "gnupg", "|FILE|read options from FILE",
@@ -498,6 +496,12 @@ static gc_option_t gc_options_gpg_agent[] =
    { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
      "gnupg", "do not use the SCdaemon",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "enable-ssh-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
+     "gnupg", "enable ssh support",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "enable-putty-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
+     "gnupg", "enable putty support",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
 
    { "Debug",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
@@ -516,7 +520,7 @@ static gc_option_t gc_options_gpg_agent[] =
      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
      "gnupg", N_("Options controlling the security") },
    { "default-cache-ttl", GC_OPT_FLAG_RUNTIME,
-     GC_LEVEL_BASIC, "gnupg", 
+     GC_LEVEL_BASIC, "gnupg",
      "|N|expire cached PINs after N seconds",
      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
    { "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
@@ -528,14 +532,24 @@ static gc_option_t gc_options_gpg_agent[] =
      N_("|N|set maximum PIN cache lifetime to N seconds"),
      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
    { "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
-     GC_LEVEL_EXPERT, "gnupg", 
+     GC_LEVEL_EXPERT, "gnupg",
      N_("|N|set maximum SSH key lifetime to N seconds"),
      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
    { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
      GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
-   { "allow-mark-trusted", GC_OPT_FLAG_RUNTIME,
-     GC_LEVEL_ADVANCED, "gnupg", "allow clients to mark keys as \"trusted\"",
+   { "allow-emacs-pinentry", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_ADVANCED,
+     "gnupg", "allow passphrase to be prompted through Emacs",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "no-allow-external-cache", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_BASIC, "gnupg", "disallow the use of an external password cache",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "no-allow-mark-trusted", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_ADVANCED, "gnupg", "disallow clients to mark keys as \"trusted\"",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "allow-loopback-pinentry", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_EXPERT, "gnupg", "allow caller to override the pinentry",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
    { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
      "gnupg", "do not grab keyboard and mouse",
@@ -544,16 +558,16 @@ static gc_option_t gc_options_gpg_agent[] =
    { "Passphrase policy",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
      "gnupg", N_("Options enforcing a passphrase policy") },
-   { "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME, 
-     GC_LEVEL_EXPERT, "gnupg", 
+   { "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_EXPERT, "gnupg",
      N_("do not allow to bypass the passphrase policy"),
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
    { "min-passphrase-len", GC_OPT_FLAG_RUNTIME,
-     GC_LEVEL_ADVANCED, "gnupg", 
+     GC_LEVEL_ADVANCED, "gnupg",
      N_("|N|set minimal required length for new passphrases to N"),
      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
    { "min-passphrase-nonalpha", GC_OPT_FLAG_RUNTIME,
-     GC_LEVEL_EXPERT, "gnupg", 
+     GC_LEVEL_EXPERT, "gnupg",
      N_("|N|require at least N non-alpha characters for a new passphrase"),
      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
    { "check-passphrase-pattern", GC_OPT_FLAG_RUNTIME,
@@ -561,11 +575,11 @@ static gc_option_t gc_options_gpg_agent[] =
      "gnupg", N_("|FILE|check new passphrases against pattern in FILE"),
      GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
    { "max-passphrase-days", GC_OPT_FLAG_RUNTIME,
-     GC_LEVEL_EXPERT, "gnupg", 
+     GC_LEVEL_EXPERT, "gnupg",
      N_("|N|expire the passphrase after N days"),
      GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
-   { "enable-passphrase-history", GC_OPT_FLAG_RUNTIME, 
-     GC_LEVEL_EXPERT, "gnupg", 
+   { "enable-passphrase-history", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_EXPERT, "gnupg",
      N_("do not allow the reuse of old passphrases"),
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
 
@@ -581,7 +595,8 @@ static gc_option_t gc_options_gpg_agent[] =
 static gc_option_t gc_options_scdaemon[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"SCDAEMON_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
 
    { "Monitor",
@@ -615,8 +630,12 @@ static gc_option_t gc_options_scdaemon[] =
    { "disable-ccid", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
      "gnupg", "do not use the internal CCID driver",
      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
-   { "disable-keypad", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
-     "gnupg", "do not use a reader's keypad",
+   { "disable-pinpad", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
+     "gnupg", "do not use a reader's pinpad",
+     GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
+   { "enable-pinpad-varlen",
+     GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
+     "gnupg", "use variable length input for pinpad",
      GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
    { "card-timeout", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
      "gnupg", "|N|disconnect the card after N seconds of inactivity",
@@ -651,7 +670,8 @@ static gc_option_t gc_options_scdaemon[] =
 static gc_option_t gc_options_gpg[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"GPG_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
 
    { "Monitor",
@@ -686,7 +706,7 @@ static gc_option_t gc_options_gpg[] =
      (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
      NULL, NULL,
      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
-   
+
 
    { "Debug",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
@@ -704,8 +724,8 @@ static gc_option_t gc_options_gpg[] =
    { "Keyserver",
      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
      "gnupg", N_("Configuration for Keyservers") },
-   { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
-     "gnupg", N_("|URL|use keyserver at URL"),
+   { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
+     "gnupg", N_("|URL|use keyserver at URL"), /* Deprecated - use dirmngr */
      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
    { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
      "gnupg", N_("allow PKA lookups (DNS requests)"),
@@ -715,8 +735,6 @@ static gc_option_t gc_options_gpg[] =
      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
 
 
-
-
    GC_OPTION_NULL
  };
 #endif /*BUILD_WITH_GPG*/
@@ -729,7 +747,8 @@ static gc_option_t gc_options_gpg[] =
 static gc_option_t gc_options_gpgsm[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"GPGSM_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
 
    { "Monitor",
@@ -824,7 +843,8 @@ static gc_option_t gc_options_gpgsm[] =
 static gc_option_t gc_options_dirmngr[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"DIRMNGR_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
 
    { "Monitor",
@@ -849,7 +869,7 @@ static gc_option_t gc_options_dirmngr[] =
    { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
      "dirmngr", "csh-style command output",
      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
-   
+
    { "Configuration",
      GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
      "gnupg", N_("Options controlling the configuration") },
@@ -886,6 +906,20 @@ static gc_option_t gc_options_dirmngr[] =
      "dirmngr", "force loading of outdated CRLs",
      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
 
+   { "Tor",
+     GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
+     "gnupg", N_("Options controlling the use of Tor") },
+   { "use-tor", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+     "dirmngr", "route all network traffic via TOR",
+      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
+
+   { "Keyserver",
+     GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
+     "gnupg", N_("Configuration for Keyservers") },
+   { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
+     "gnupg", N_("|URL|use keyserver at URL"),
+     GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
+
    { "HTTP",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
      "gnupg", N_("Configuration for HTTP servers") },
@@ -966,7 +1000,8 @@ static gc_option_t gc_options_pinentry[] =
  {
    /* A dummy option to allow gc_component_list_components to find the
       pinentry backend.  Needs to be a conf file. */
-   { "gpgconf-pinentry.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-pinentry.conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_PINENTRY },
 
    GC_OPTION_NULL
@@ -1021,12 +1056,12 @@ static struct
   gc_option_t *options;
 } gc_component[] =
   {
-    { "gpg", NULL,   "GPG for OpenPGP", gc_options_gpg },
-    { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent },
-    { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon },
-    { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm },
-    { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr },
-    { "pinentry", NULL, "PIN and Passphrase Entry", gc_options_pinentry }
+    { "gpg",      "gnupg", N_("GPG for OpenPGP"), gc_options_gpg },
+    { "gpg-agent","gnupg", N_("GPG Agent"), gc_options_gpg_agent },
+    { "scdaemon", "gnupg", N_("Smartcard Daemon"), gc_options_scdaemon },
+    { "gpgsm",    "gnupg", N_("GPG for S/MIME"), gc_options_gpgsm },
+    { "dirmngr",  "gnupg", N_("Key Acquirer"), gc_options_dirmngr },
+    { "pinentry", "gnupg", N_("PIN and Passphrase Entry"), gc_options_pinentry }
   };
 
 
@@ -1047,35 +1082,38 @@ struct error_line_s
 \f
 /* Engine specific support.  */
 static void
-gpg_agent_runtime_change (void)
+gpg_agent_runtime_change (int killflag)
 {
   gpg_error_t err;
   const char *pgmname;
-  const char *argv[2];
+  const char *argv[3];
   pid_t pid;
-  
+
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
-  argv[0] = "reloadagent";
-  argv[1] = NULL;
-  
+  argv[0] = "--no-autostart";
+  argv[1] = killflag? "KILLAGENT" : "RELOADAGENT";
+  argv[2] = 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",
-              pgmname, " reloadagent", gpg_strerror (err));
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[1], gpg_strerror (err));
   gnupg_release_process (pid);
 }
 
 
 static void
-scdaemon_runtime_change (void)
+scdaemon_runtime_change (int killflag)
 {
   gpg_error_t err;
   const char *pgmname;
-  const char *argv[6];
+  const char *argv[7];
   pid_t pid;
-  
+
+  (void)killflag;  /* For scdaemon kill and reload are synonyms.  */
+
   /* We use "GETINFO app_running" to see whether the agent is already
      running and kill it only in this case.  This avoids an explicit
      starting of the agent in case it is not yet running.  There is
@@ -1083,22 +1121,115 @@ scdaemon_runtime_change (void)
 
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
   argv[0] = "-s";
-  argv[1] = "GETINFO scd_running";
-  argv[2] = "/if ${! $?}";
-  argv[3] = "scd killscd";
-  argv[4] = "/end";
-  argv[5] = NULL;
-  
+  argv[1] = "--no-autostart";
+  argv[2] = "GETINFO scd_running";
+  argv[3] = "/if ${! $?}";
+  argv[4] = "scd killscd";
+  argv[5] = "/end";
+  argv[6] = 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",
+              pgmname, argv[4], gpg_strerror (err));
+  gnupg_release_process (pid);
+}
+
+
+static void
+dirmngr_runtime_change (int killflag)
+{
+  gpg_error_t err;
+  const char *pgmname;
+  const char *argv[4];
+  pid_t pid;
+
+  pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
+  argv[0] = "--no-autostart";
+  argv[1] = "--dirmngr";
+  argv[2] = killflag? "KILLDIRMNGR" : "RELOADDIRMNGR";
+  argv[3] = 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",
-              pgmname, " scd killscd", gpg_strerror (err));
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[2], gpg_strerror (err));
   gnupg_release_process (pid);
 }
 
 
+/* Launch the gpg-agent or the dirmngr if not already running.  */
+gpg_error_t
+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);
+  return err;
+}
+
+
+/* Unconditionally restart COMPONENT.  */
+void
+gc_component_kill (int component)
+{
+  int runtime[GC_BACKEND_NR];
+  gc_option_t *option;
+  gc_backend_t backend;
+
+  /* Set a flag for the backends to be reloaded.  */
+  for (backend = 0; backend < GC_BACKEND_NR; backend++)
+    runtime[backend] = 0;
+
+  if (component >= 0)
+    {
+      assert (component < GC_COMPONENT_NR);
+      option = gc_component[component].options;
+      for (; option && option->name; option++)
+        runtime[option->backend] = 1;
+    }
+
+  /* Do the restart for the selected backends.  */
+  for (backend = 0; backend < GC_BACKEND_NR; backend++)
+    {
+      if (runtime[backend] && gc_backend[backend].runtime_change)
+        (*gc_backend[backend].runtime_change) (1);
+    }
+}
+
+
 /* Unconditionally reload COMPONENT or all components if COMPONENT is -1.  */
 void
 gc_component_reload (int component)
@@ -1110,7 +1241,7 @@ gc_component_reload (int component)
   /* Set a flag for the backends to be reloaded.  */
   for (backend = 0; backend < GC_BACKEND_NR; backend++)
     runtime[backend] = 0;
-  
+
   if (component == -1)
     {
       for (component = 0; component < GC_COMPONENT_NR; component++)
@@ -1129,10 +1260,10 @@ gc_component_reload (int component)
     }
 
   /* Do the reload for all selected backends.  */
-  for (backend = 0; backend < GC_BACKEND_NR; backend++)  
+  for (backend = 0; backend < GC_BACKEND_NR; backend++)
     {
       if (runtime[backend] && gc_backend[backend].runtime_change)
-        (*gc_backend[backend].runtime_change) ();
+        (*gc_backend[backend].runtime_change) (0);
     }
 }
 
@@ -1140,7 +1271,7 @@ gc_component_reload (int component)
 \f
 /* More or less Robust version of dgettext.  It has the side effect of
    switching the codeset to utf-8 because this is what we want to
-   output.  In theory it is posible to keep the orginal code set and
+   output.  In theory it is posible to keep the original code set and
    switch back for regular disgnostic output (redefine "_(" for that)
    but given the natur of this tool, being something invoked from
    other pograms, it does not make much sense.  */
@@ -1152,7 +1283,7 @@ my_dgettext (const char *domain, const char *msgid)
     {
       static int switched_codeset;
       char *text;
-      
+
       if (!switched_codeset)
         {
           switched_codeset = 1;
@@ -1167,20 +1298,22 @@ my_dgettext (const char *domain, const char *msgid)
       text = (char*)gettext (msgid);
       return text ? text : msgid;
     }
+  else
+    return msgid;
 #elif defined(ENABLE_NLS)
   if (domain)
     {
       static int switched_codeset;
       char *text;
-      
+
       if (!switched_codeset)
         {
           switched_codeset = 1;
           bind_textdomain_codeset (PACKAGE_GT, "utf-8");
 
-          bindtextdomain ("dirmngr", LOCALEDIR);
-          bind_textdomain_codeset ("dirmngr", "utf-8");
-   
+          bindtextdomain (DIRMNGR_NAME, LOCALEDIR);
+          bind_textdomain_codeset (DIRMNGR_NAME, "utf-8");
+
         }
 
       /* Note: This is a hack to actually use the gnupg2 domain as
@@ -1193,8 +1326,11 @@ my_dgettext (const char *domain, const char *msgid)
       return text ? text : msgid;
     }
   else
-#endif
     return msgid;
+#else
+  (void)domain;
+  return msgid;
+#endif
 }
 
 
@@ -1225,7 +1361,7 @@ gc_percent_escape (const char *src)
          *(dst++) = '%';
          *(dst++) = '2';
          *(dst++) = '5';
-       }         
+       }
       else if (*src == ':')
        {
          /* The colon is used as field separator.  */
@@ -1281,7 +1417,7 @@ percent_deescape (const char *src)
 
          *(dst++) = (char) val;
          src += 3;
-       }         
+       }
       else
        *(dst++) = *(src++);
     }
@@ -1374,7 +1510,7 @@ collect_error_output (estream_t fp, const char *tag)
           buffer[pos - (c == '\n')] = 0;
           if (cont_line)
             ; /*Ignore continuations of previous line. */
-          else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':') 
+          else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':')
             {
               /* "gpgsm: foo:4: bla" */
               /* Yep, we are interested in this line.  */
@@ -1424,7 +1560,7 @@ collect_error_output (estream_t fp, const char *tag)
           cont_line = (c != '\n');
         }
     }
-  
+
   /* We ignore error lines not terminated by a LF.  */
   return errlines;
 }
@@ -1483,16 +1619,16 @@ gc_component_check_options (int component, estream_t out, const char *conf_file)
   else
     argv[i++] = "--gpgconf-test";
   argv[i++] = NULL;
-  
+
   result = 0;
   errlines = NULL;
   err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT, NULL, 0,
                              NULL, NULL, &errfp, &pid);
   if (err)
     result |= 1; /* Program could not be run.  */
-  else 
+  else
     {
-      errlines = collect_error_output (errfp, 
+      errlines = collect_error_output (errfp,
                                       gc_component[component].name);
       if (gnupg_wait_process (pgmname, pid, 1, &exitcode))
        {
@@ -1504,12 +1640,12 @@ gc_component_check_options (int component, estream_t out, const char *conf_file)
       gnupg_release_process (pid);
       es_fclose (errfp);
     }
-  
+
   /* If the program could not be run, we can't tell whether
      the config file is good.  */
   if (result & 1)
-    result |= 2;  
-  
+    result |= 2;
+
   if (out)
     {
       const char *desc;
@@ -1617,7 +1753,7 @@ list_one_option (const gc_option_t *option, estream_t out)
   if (opt.verbose)
     {
       es_putc (' ', out);
-         
+
       if (!option->flags)
        es_fprintf (out, "none");
       else
@@ -1649,7 +1785,7 @@ list_one_option (const gc_option_t *option, estream_t out)
 
   /* The description field.  */
   es_fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
-  
+
   /* The type field.  */
   es_fprintf (out, ":%u", option->arg_type);
   if (opt.verbose)
@@ -1690,7 +1826,7 @@ list_one_option (const gc_option_t *option, estream_t out)
 /* List all options of the component COMPONENT.  */
 void
 gc_component_list_options (int component, estream_t out)
-{  
+{
   const gc_option_t *option = gc_component[component].options;
 
   while (option && option->name)
@@ -1713,7 +1849,7 @@ gc_component_list_options (int component, estream_t out)
             different active options, and because it is hard to
             maintain manually, we calculate it here.  The value in
             the global static table is ignored.  */
-         
+
          while (group_option->name)
            {
              if (group_option->flags & GC_OPT_FLAG_GROUP)
@@ -1788,7 +1924,7 @@ get_config_filename (gc_component_t component, gc_backend_t backend)
 #if HAVE_W32CE_SYSTEM
   if (!(filename[0] == '/' || filename[0] == '\\'))
 #elif defined(HAVE_DOSISH_SYSTEM)
-  if (!(filename[0] 
+  if (!(filename[0]
         && filename[1] == ':'
         && (filename[2] == '/' || filename[2] == '\\')))
 #else
@@ -1819,8 +1955,8 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
   estream_t config;
   char *config_filename;
 
-  pgmname = (gc_backend[backend].module_name 
-             ? gnupg_module_name (gc_backend[backend].module_name) 
+  pgmname = (gc_backend[backend].module_name
+             ? gnupg_module_name (gc_backend[backend].module_name)
              : gc_backend[backend].program );
   argv[0] = "--gpgconf-list";
   argv[1] = NULL;
@@ -1829,7 +1965,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
                              NULL, &outfp, NULL, &pid);
   if (err)
     {
-      gc_error (1, 0, "could not gather active options from `%s': %s",
+      gc_error (1, 0, "could not gather active options from '%s': %s",
                 pgmname, gpg_strerror (err));
     }
 
@@ -1839,7 +1975,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
       char *linep;
       unsigned long flags = 0;
       char *default_value = NULL;
-      
+
       /* Strip newline and carriage return, if present.  */
       while (length > 0
             && (line[length - 1] == '\n' || line[length - 1] == '\r'))
@@ -1848,7 +1984,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
       linep = strchr (line, ':');
       if (linep)
        *(linep++) = '\0';
-      
+
       /* Extract additional flags.  Default to none.  */
       if (linep)
        {
@@ -1928,7 +2064,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
          char *name;
          char *value;
          gc_option_t *option;
-         
+
          name = line;
          while (*name == ' ' || *name == '\t')
            name++;
@@ -2015,7 +2151,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
 
 
 /* Retrieve the options for the component COMPONENT from backend
-   BACKEND, which we already know is of type file list.  */ 
+   BACKEND, which we already know is of type file list.  */
 static void
 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
 {
@@ -2115,7 +2251,7 @@ gc_component_retrieve_options (int component)
       component = 0;
       assert (component < GC_COMPONENT_NR);
     }
-      
+
   do
     {
       option = gc_component[component].options;
@@ -2125,16 +2261,16 @@ gc_component_retrieve_options (int component)
           if (!(option->flags & GC_OPT_FLAG_GROUP))
             {
               backend = option->backend;
-              
+
               if (backend_seen[backend])
                 {
                   option++;
                   continue;
                 }
               backend_seen[backend] = 1;
-              
+
               assert (backend != GC_BACKEND_ANY);
-              
+
               if (gc_backend[backend].program)
                 retrieve_options_from_program (component, backend);
               else
@@ -2161,7 +2297,7 @@ option_check_validity (gc_option_t *option, unsigned long flags,
   if (!option->active)
     gc_error (1, 0, "option %s not supported by backend %s",
               option->name, gc_backend[option->backend].name);
-      
+
   if (option->new_flags || option->new_value)
     gc_error (1, 0, "option %s already changed", option->name);
 
@@ -2247,7 +2383,7 @@ option_check_validity (gc_option_t *option, unsigned long flags,
            gc_error (1, 0, "garbage after argument for option %s",
                      option->name);
        }
-      else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
+      else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32)
        {
          unsigned long res;
 
@@ -2333,7 +2469,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
                     char **src_filenamep, char **dest_filenamep,
                     char **orig_filenamep)
 {
-  static const char marker[] = "###+++--- GPGConf ---+++###";
+  static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
   /* True if we are within the marker in the config file.  */
   int in_marker = 0;
   gc_option_t *option;
@@ -2360,8 +2496,10 @@ change_options_file (gc_component_t component, gc_backend_t backend,
   /* Note that get_config_filename() calls percent_deescape(), so we
      call this before processing the arguments.  */
   dest_filename = xstrdup (get_config_filename (component, backend));
-  src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, (int)getpid ());
-  orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename,(int)getpid ());
+  src_filename = xasprintf ("%s.%s.%i.new",
+                            dest_filename, GPGCONF_NAME, (int)getpid ());
+  orig_filename = xasprintf ("%s.%s.%i.bak",
+                             dest_filename, GPGCONF_NAME, (int)getpid ());
 
   arg = option->new_value;
   if (arg && arg[0] == '\0')
@@ -2391,7 +2529,10 @@ change_options_file (gc_component_t component, gc_backend_t backend,
   res = link (dest_filename, orig_filename);
 #endif
   if (res < 0 && errno != ENOENT)
-    return -1;
+    {
+      xfree (dest_filename);
+      return -1;
+    }
   if (res < 0)
     {
       xfree (orig_filename);
@@ -2498,8 +2639,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
              if (!in_marker)
                {
                  fprintf (src_file,
-                          "# GPGConf disabled this option here at %s\n",
-                          asctimestamp (gnupg_get_time ()));
+                          "# %s disabled this option here at %s\n",
+                          GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
                  if (ferror (src_file))
                    goto change_file_one_err;
                  fprintf (src_file, "# %s", line);
@@ -2567,7 +2708,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
 
   if (!in_marker)
     {
-      fprintf (src_file, "# GPGConf edited this configuration file.\n");
+      fprintf (src_file, "# %s edited this configuration file.\n",
+               GPGCONF_DISP_NAME);
       if (ferror (src_file))
        goto change_file_one_err;
       fprintf (src_file, "# It will disable options before this marked "
@@ -2633,7 +2775,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
                        char **src_filenamep, char **dest_filenamep,
                        char **orig_filenamep)
 {
-  static const char marker[] = "###+++--- GPGConf ---+++###";
+  static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
   /* True if we are within the marker in the config file.  */
   int in_marker = 0;
   gc_option_t *option;
@@ -2652,8 +2794,10 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 
   /* FIXME.  Throughout the function, do better error reporting.  */
   dest_filename = xstrdup (get_config_filename (component, backend));
-  src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, (int)getpid ());
-  orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename,(int)getpid ());
+  src_filename = xasprintf ("%s.%s.%i.new",
+                            dest_filename, GPGCONF_NAME, (int)getpid ());
+  orig_filename = xasprintf ("%s.%s.%i.bak",
+                             dest_filename, GPGCONF_NAME, (int)getpid ());
 
 #ifdef HAVE_W32_SYSTEM
   res = copy_file (dest_filename, orig_filename);
@@ -2744,8 +2888,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
              if (!in_marker)
                {
                  fprintf (src_file,
-                          "# GPGConf disabled this option here at %s\n",
-                          asctimestamp (gnupg_get_time ()));
+                          "# %s disabled this option here at %s\n",
+                          GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
                  if (ferror (src_file))
                    goto change_one_err;
                  fprintf (src_file, "# %s", line);
@@ -2816,10 +2960,10 @@ change_options_program (gc_component_t component, gc_backend_t backend,
                       == GC_ARG_TYPE_STRING)
                {
                  char *end;
-                 
+
                  assert (*arg == '"');
                  arg++;
-                 
+
                  end = strchr (arg, ',');
                  if (end)
                    *end = '\0';
@@ -2865,7 +3009,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 
   if (!in_marker)
     {
-      fprintf (src_file, "# GPGConf edited this configuration file.\n");
+      fprintf (src_file, "# %s edited this configuration file.\n",
+               GPGCONF_DISP_NAME);
       if (ferror (src_file))
        goto change_one_err;
       fprintf (src_file, "# It will disable options before this marked "
@@ -3000,16 +3145,16 @@ gc_component_change_options (int component, estream_t in, estream_t out)
           char *linep;
           unsigned long flags = 0;
           char *new_value = "";
-          
+
           /* Strip newline and carriage return, if present.  */
           while (length > 0
                  && (line[length - 1] == '\n' || line[length - 1] == '\r'))
             line[--length] = '\0';
-          
+
           linep = strchr (line, ':');
           if (linep)
             *(linep++) = '\0';
-          
+
           /* Extract additional flags.  Default to none.  */
           if (linep)
             {
@@ -3019,20 +3164,20 @@ gc_component_change_options (int component, estream_t in, estream_t out)
               end = strchr (linep, ':');
               if (end)
                 *(end++) = '\0';
-              
+
               gpg_err_set_errno (0);
               flags = strtoul (linep, &tail, 0);
               if (errno)
                 gc_error (1, errno, "malformed flags in option %s", line);
               if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
                 gc_error (1, 0, "garbage after flags in option %s", line);
-              
+
               linep = end;
             }
 
           /* Don't allow setting of the no change flag.  */
           flags &= ~GC_OPT_FLAG_NO_CHANGE;
-          
+
           /* Extract default value, if present.  Default to empty if not.  */
           if (linep)
             {
@@ -3043,18 +3188,18 @@ gc_component_change_options (int component, estream_t in, estream_t out)
               new_value = linep;
               linep = end;
             }
-          
+
           option = find_option (component, line, GC_BACKEND_ANY);
           if (!option)
             gc_error (1, 0, "unknown option %s", line);
-          
+
           if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
             {
               gc_error (0, 0, "ignoring new value for option %s",
                         option->name);
               continue;
             }
-          
+
           change_one_value (option, runtime, flags, new_value);
         }
     }
@@ -3100,10 +3245,10 @@ gc_component_change_options (int component, estream_t in, estream_t out)
                                   &src_filename[option->backend],
                                   &dest_filename[option->backend],
                                   &orig_filename[option->backend]);
-       
+
       if (err)
        break;
-         
+
       option++;
     }
 
@@ -3155,7 +3300,7 @@ gc_component_change_options (int component, estream_t in, estream_t out)
       int i;
       int saved_errno = errno;
 
-      /* An error occured or a dry-run is requested.  */
+      /* An error occurred or a dry-run is requested.  */
       for (i = 0; i < GC_BACKEND_NR; i++)
        {
          if (src_filename[i])
@@ -3192,21 +3337,22 @@ gc_component_change_options (int component, estream_t in, estream_t out)
 
   /* If it all worked, notify the daemons of the changes.  */
   if (opt.runtime)
-    for (backend = 0; backend < GC_BACKEND_NR; backend++)  
+    for (backend = 0; backend < GC_BACKEND_NR; backend++)
       {
        if (runtime[backend] && gc_backend[backend].runtime_change)
-         (*gc_backend[backend].runtime_change) ();
+         (*gc_backend[backend].runtime_change) (0);
       }
 
   /* Move the per-process backup file into its place.  */
-  for (backend = 0; backend < GC_BACKEND_NR; backend++)  
+  for (backend = 0; backend < GC_BACKEND_NR; backend++)
     if (orig_filename[backend])
       {
        char *backup_filename;
 
        assert (dest_filename[backend]);
 
-       backup_filename = xasprintf ("%s.gpgconf.bak", dest_filename[backend]);
+       backup_filename = xasprintf ("%s.%s.bak",
+                                     dest_filename[backend], GPGCONF_NAME);
 
 #ifdef HAVE_W32_SYSTEM
        /* There is no atomic update on W32.  */
@@ -3236,7 +3382,7 @@ key_matches_user_or_group (char *user)
     *group++ = 0;
 
 #ifdef HAVE_W32_SYSTEM
-  /* Under Windows we don't support groups. */   
+  /* Under Windows we don't support groups. */
   if (group && *group)
     gc_error (0, 0, _("Note that group specifications are ignored\n"));
 #ifndef HAVE_W32CE_SYSTEM
@@ -3349,19 +3495,17 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
   int in_rule = 0;
   int got_match = 0;
   int runtime[GC_BACKEND_NR];
-  int used_components[GC_COMPONENT_NR];
   int backend_id, component_id;
   char *fname;
 
   if (fname_arg)
     fname = xstrdup (fname_arg);
   else
-    fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
+    fname = make_filename (gnupg_sysconfdir (), GPGCONF_NAME EXTSEP_S "conf",
+                           NULL);
 
   for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
     runtime[backend_id] = 0;
-  for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
-    used_components[component_id] = 0;
 
   config = fopen (fname, "r");
   if (!config)
@@ -3370,7 +3514,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
          when running in syntax check mode.  */
       if (errno != ENOENT || !update)
         {
-          gc_error (0, errno, "can not open global config file `%s'", fname);
+          gc_error (0, errno, "can not open global config file '%s'", fname);
           result = -1;
         }
       xfree (fname);
@@ -3384,7 +3528,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
       gc_option_t *option_info = NULL;
       char *p;
       int is_continuation;
-      
+
       lineno++;
       key = line;
       while (*key == ' ' || *key == '\t')
@@ -3404,7 +3548,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
             ;
           if (!*p)
             {
-              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;
               continue;
             }
@@ -3413,7 +3557,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         }
       else if (!in_rule)
         {
-          gc_error (0, 0, "continuation but no rule at `%s', line %d",
+          gc_error (0, 0, "continuation but no rule at '%s', line %d",
                     fname, lineno);
           result = -1;
           continue;
@@ -3433,7 +3577,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         ;
       if (p == component)
         {
-          gc_error (0, 0, "missing component at `%s', line %d",
+          gc_error (0, 0, "missing component at '%s', line %d",
                     fname, lineno);
           result = -1;
           continue;
@@ -3444,7 +3588,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
       component_id = gc_component_find (component);
       if (component_id < 0)
         {
-          gc_error (0, 0, "unknown component at `%s', line %d",
+          gc_error (0, 0, "unknown component at '%s', line %d",
                     fname, lineno);
           result = -1;
         }
@@ -3456,7 +3600,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         ;
       if (p == option)
         {
-          gc_error (0, 0, "missing option at `%s', line %d",
+          gc_error (0, 0, "missing option at '%s', line %d",
                     fname, lineno);
           result = -1;
           continue;
@@ -3468,7 +3612,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
           option_info = find_option (component_id, option, GC_BACKEND_ANY);
           if (!option_info)
             {
-              gc_error (0, 0, "unknown option at `%s', line %d",
+              gc_error (0, 0, "unknown option at '%s', line %d",
                         fname, lineno);
               result = -1;
             }
@@ -3484,7 +3628,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
           p = strchr (flags, ']');
           if (!p)
             {
-              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);
               result = -1;
               continue;
@@ -3521,7 +3665,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
           if (*value)
             {
               gc_error (0, 0, "flag \"default\" may not be combined "
-                        "with a value at `%s', line %d",
+                        "with a value at '%s', line %d",
                         fname, lineno);
               result = -1;
             }
@@ -3532,7 +3676,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
         ;
       else
         {
-          gc_error (0, 0, "unknown flag at `%s', line %d",
+          gc_error (0, 0, "unknown flag at '%s', line %d",
                     fname, lineno);
           result = -1;
         }
@@ -3549,26 +3693,26 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
                   *group++ = 0;
                   if ((p = strchr (group, ':')))
                     *p = 0; /* We better strip any extra stuff. */
-                }                    
-              
+                }
+
               es_fprintf (listfp, "k:%s:", gc_percent_escape (key));
               es_fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
             }
 
           /* All other lines are rule records.  */
           es_fprintf (listfp, "r:::%s:%s:%s:",
-                      gc_component[component_id].name,                     
+                      gc_component[component_id].name,
                       option_info->name? option_info->name : "",
                       flags? flags : "");
           if (value != empty)
             es_fprintf (listfp, "\"%s", gc_percent_escape (value));
-          
+
           es_putc ('\n', listfp);
         }
 
       /* Check whether the key matches but do this only if we are not
          running in syntax check mode. */
-      if ( update 
+      if ( update
            && !result && !listfp
            && (got_match || (key && key_matches_user_or_group (key))) )
         {
@@ -3588,9 +3732,6 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
 
           if (defaults)
             {
-              assert (component_id >= 0 && component_id < GC_COMPONENT_NR);
-              used_components[component_id] = 1;
-
               /* Here we explicitly allow to update the value again.  */
               if (newflags)
                 {
@@ -3608,11 +3749,11 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
 
   if (length < 0 || ferror (config))
     {
-      gc_error (0, errno, "error reading from `%s'", fname);
+      gc_error (0, errno, "error reading from '%s'", fname);
       result = -1;
     }
   if (fclose (config))
-    gc_error (0, errno, "error closing `%s'", fname);
+    gc_error (0, errno, "error closing '%s'", fname);
 
   xfree (line);
 
@@ -3632,9 +3773,9 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
 
       if (opt.runtime)
         {
-          for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)  
+          for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
             if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
-              (*gc_backend[backend_id].runtime_change) ();
+              (*gc_backend[backend_id].runtime_change) (0);
         }
     }