diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 2c4d313f5..46fb840bb 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -1,3283 +1,3295 @@
 /* gpg-agent.c  -  The GnuPG Agent
  * Copyright (C) 2000-2020 Free Software Foundation, Inc.
  * Copyright (C) 2000-2019 Werner Koch
  * Copyright (C) 2015-2020 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <stdarg.h>
 #include <string.h>
 #include <errno.h>
 #include <time.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #ifdef HAVE_W32_SYSTEM
 # ifndef WINVER
 #  define WINVER 0x0500  /* Same as in common/sysutils.c */
 # endif
 # ifdef HAVE_WINSOCK2_H
 #  include <winsock2.h>
 # endif
 # include <aclapi.h>
 # include <sddl.h>
 #else /*!HAVE_W32_SYSTEM*/
 # include <sys/socket.h>
 # include <sys/un.h>
 #endif /*!HAVE_W32_SYSTEM*/
 #include <unistd.h>
 #ifdef HAVE_SIGNAL_H
 # include <signal.h>
 #endif
 #include <npth.h>
 
 #define INCLUDED_BY_MAIN_MODULE 1
 #define GNUPG_COMMON_NEED_AFLOCAL
 #include "agent.h"
 #include <assuan.h> /* Malloc hooks  and socket wrappers. */
 
 #include "../common/i18n.h"
 #include "../common/sysutils.h"
 #include "../common/gc-opt-flags.h"
 #include "../common/exechelp.h"
 #include "../common/asshelp.h"
 #include "../common/comopt.h"
 #include "../common/init.h"
 
 
 enum cmd_and_opt_values
 { aNull = 0,
   oCsh		  = 'c',
   oQuiet	  = 'q',
   oSh		  = 's',
   oVerbose	  = 'v',
 
   oNoVerbose = 500,
   aGPGConfList,
   aGPGConfTest,
   aUseStandardSocketP,
   oOptions,
   oDebug,
   oDebugAll,
   oDebugLevel,
   oDebugWait,
   oDebugQuickRandom,
   oDebugPinentry,
   oNoOptions,
   oHomedir,
   oNoDetach,
   oGrab,
   oNoGrab,
   oLogFile,
   oServer,
   oDaemon,
   oSupervised,
   oBatch,
 
   oPinentryProgram,
   oPinentryTouchFile,
   oPinentryInvisibleChar,
   oPinentryTimeout,
   oPinentryFormattedPassphrase,
   oDisplay,
   oTTYname,
   oTTYtype,
   oLCctype,
   oLCmessages,
   oXauthority,
   oScdaemonProgram,
   oTpm2daemonProgram,
   oDefCacheTTL,
   oDefCacheTTLSSH,
   oMaxCacheTTL,
   oMaxCacheTTLSSH,
   oEnforcePassphraseConstraints,
   oMinPassphraseLen,
   oMinPassphraseNonalpha,
   oCheckPassphrasePattern,
   oCheckSymPassphrasePattern,
   oMaxPassphraseDays,
   oEnablePassphraseHistory,
   oDisableExtendedKeyFormat,
   oEnableExtendedKeyFormat,
+  oStealSocket,
   oUseStandardSocket,
   oNoUseStandardSocket,
   oExtraSocket,
   oBrowserSocket,
   oFakedSystemTime,
 
   oIgnoreCacheForSigning,
   oAllowMarkTrusted,
   oNoAllowMarkTrusted,
   oAllowPresetPassphrase,
   oAllowLoopbackPinentry,
   oNoAllowLoopbackPinentry,
   oNoAllowExternalCache,
   oAllowEmacsPinentry,
   oKeepTTY,
   oKeepDISPLAY,
   oSSHSupport,
   oSSHFingerprintDigest,
   oPuttySupport,
   oDisableScdaemon,
   oDisableCheckOwnSocket,
   oS2KCount,
   oS2KCalibration,
   oAutoExpandSecmem,
   oListenBacklog,
 
   oWriteEnvFile,
 
   oNoop
 };
 
 
 #ifndef ENAMETOOLONG
 # define ENAMETOOLONG EINVAL
 #endif
 
 static gpgrt_opt_t opts[] = {
 
   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
   ARGPARSE_c (aUseStandardSocketP, "use-standard-socket-p", "@"),
 
 
   ARGPARSE_header (NULL, N_("Options used for startup")),
 
   ARGPARSE_s_n (oDaemon,  "daemon", N_("run in daemon mode (background)")),
   ARGPARSE_s_n (oServer,  "server", N_("run in server mode (foreground)")),
 #ifndef HAVE_W32_SYSTEM
   ARGPARSE_s_n (oSupervised,  "supervised", N_("run in supervised mode")),
 #endif
   ARGPARSE_s_n (oNoDetach,  "no-detach", N_("do not detach from the console")),
   ARGPARSE_s_n (oSh,	  "sh",        N_("sh-style command output")),
   ARGPARSE_s_n (oCsh,	  "csh",       N_("csh-style command output")),
+  ARGPARSE_s_n (oStealSocket, "steal-socket", "@"),
   ARGPARSE_s_s (oDisplay,    "display",     "@"),
   ARGPARSE_s_s (oTTYname,    "ttyname",     "@"),
   ARGPARSE_s_s (oTTYtype,    "ttytype",     "@"),
   ARGPARSE_s_s (oLCctype,    "lc-ctype",    "@"),
   ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
   ARGPARSE_s_s (oXauthority, "xauthority",  "@"),
   ARGPARSE_s_s (oHomedir,    "homedir",      "@"),
   ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")),
   ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
 
 
   ARGPARSE_header ("Monitor", N_("Options controlling the diagnostic output")),
 
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet,	  "quiet",     N_("be somewhat more quiet")),
   ARGPARSE_s_s (oDebug,	     "debug",       "@"),
   ARGPARSE_s_n (oDebugAll,   "debug-all",   "@"),
   ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
   ARGPARSE_s_i (oDebugWait,  "debug-wait",  "@"),
   ARGPARSE_s_n (oDebugQuickRandom, "debug-quick-random", "@"),
   ARGPARSE_s_n (oDebugPinentry, "debug-pinentry", "@"),
   ARGPARSE_s_s (oLogFile,   "log-file",
                 /* */       N_("|FILE|write server mode logs to FILE")),
 
 
   ARGPARSE_header ("Configuration",
                    N_("Options controlling the configuration")),
 
   ARGPARSE_s_n (oDisableScdaemon, "disable-scdaemon",
                 /* */             N_("do not use the SCdaemon") ),
   ARGPARSE_s_s (oScdaemonProgram, "scdaemon-program",
                 /* */             N_("|PGM|use PGM as the SCdaemon program") ),
   ARGPARSE_s_s (oTpm2daemonProgram, "tpm2daemon-program",
 		/* */             N_("|PGM|use PGM as the tpm2daemon program") ),
   ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
 
   ARGPARSE_s_s (oExtraSocket, "extra-socket",
                 /* */       N_("|NAME|accept some commands via NAME")),
 
   ARGPARSE_s_s (oBrowserSocket, "browser-socket", "@"),
   ARGPARSE_s_n (oKeepTTY,    "keep-tty",
                 /* */        N_("ignore requests to change the TTY")),
   ARGPARSE_s_n (oKeepDISPLAY, "keep-display",
                 /* */        N_("ignore requests to change the X display")),
   ARGPARSE_s_n (oSSHSupport,   "enable-ssh-support", N_("enable ssh support")),
   ARGPARSE_s_s (oSSHFingerprintDigest, "ssh-fingerprint-digest",
                 N_("|ALGO|use ALGO to show ssh fingerprints")),
   ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
 #ifdef HAVE_W32_SYSTEM
                 /* */           N_("enable putty support")
 #else
                 /* */           "@"
 #endif
                 ),
   ARGPARSE_s_n (oDisableExtendedKeyFormat, "disable-extended-key-format", "@"),
   ARGPARSE_s_n (oEnableExtendedKeyFormat, "enable-extended-key-format", "@"),
   ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
   ARGPARSE_op_u (oAutoExpandSecmem, "auto-expand-secmem", "@"),
   ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
 
 
   ARGPARSE_header ("Security", N_("Options controlling the security")),
 
   ARGPARSE_s_u (oDefCacheTTL,    "default-cache-ttl",
                                  N_("|N|expire cached PINs after N seconds")),
   ARGPARSE_s_u (oDefCacheTTLSSH, "default-cache-ttl-ssh",
                 /* */            N_("|N|expire SSH keys after N seconds")),
   ARGPARSE_s_u (oMaxCacheTTL,    "max-cache-ttl",
                 /* */     N_("|N|set maximum PIN cache lifetime to N seconds")),
   ARGPARSE_s_u (oMaxCacheTTLSSH, "max-cache-ttl-ssh",
                 /* */     N_("|N|set maximum SSH key lifetime to N seconds")),
   ARGPARSE_s_n (oIgnoreCacheForSigning, "ignore-cache-for-signing",
                 /* */    N_("do not use the PIN cache when signing")),
   ARGPARSE_s_n (oNoAllowExternalCache,  "no-allow-external-cache",
                 /* */    N_("disallow the use of an external password cache")),
   ARGPARSE_s_n (oNoAllowMarkTrusted, "no-allow-mark-trusted",
                 /* */    N_("disallow clients to mark keys as \"trusted\"")),
   ARGPARSE_s_n (oAllowMarkTrusted,   "allow-mark-trusted", "@"),
   ARGPARSE_s_n (oAllowPresetPassphrase, "allow-preset-passphrase",
                 /* */                    N_("allow presetting passphrase")),
   ARGPARSE_s_u (oS2KCount, "s2k-count", "@"),
   ARGPARSE_s_u (oS2KCalibration, "s2k-calibration", "@"),
 
   ARGPARSE_header ("Passphrase policy",
                    N_("Options enforcing a passphrase policy")),
 
   ARGPARSE_s_n (oEnforcePassphraseConstraints, "enforce-passphrase-constraints",
                 N_("do not allow bypassing the passphrase policy")),
   ARGPARSE_s_u (oMinPassphraseLen,        "min-passphrase-len",
                 N_("|N|set minimal required length for new passphrases to N")),
   ARGPARSE_s_u (oMinPassphraseNonalpha,   "min-passphrase-nonalpha",
                 N_("|N|require at least N non-alpha"
                    " characters for a new passphrase")),
   ARGPARSE_s_s (oCheckPassphrasePattern,  "check-passphrase-pattern",
                 N_("|FILE|check new passphrases against pattern in FILE")),
   ARGPARSE_s_s (oCheckSymPassphrasePattern,  "check-sym-passphrase-pattern",
                 "@"),
   ARGPARSE_s_u (oMaxPassphraseDays,       "max-passphrase-days",
                 N_("|N|expire the passphrase after N days")),
   ARGPARSE_s_n (oEnablePassphraseHistory, "enable-passphrase-history",
                 N_("do not allow the reuse of old passphrases")),
 
 
   ARGPARSE_header ("Pinentry", N_("Options controlling the PIN-Entry")),
 
   ARGPARSE_s_n (oBatch,  "batch",  N_("never use the PIN-entry")),
   ARGPARSE_s_n (oNoAllowLoopbackPinentry, "no-allow-loopback-pinentry",
                 N_("disallow caller to override the pinentry")),
   ARGPARSE_s_n (oAllowLoopbackPinentry, "allow-loopback-pinentry", "@"),
   ARGPARSE_s_n (oGrab,   "grab",   N_("let PIN-Entry grab keyboard and mouse")),
   ARGPARSE_s_n (oNoGrab, "no-grab",   "@"),
   ARGPARSE_s_s (oPinentryProgram, "pinentry-program",
                 N_("|PGM|use PGM as the PIN-Entry program")),
   ARGPARSE_s_s (oPinentryTouchFile, "pinentry-touch-file", "@"),
   ARGPARSE_s_s (oPinentryInvisibleChar, "pinentry-invisible-char", "@"),
   ARGPARSE_s_u (oPinentryTimeout, "pinentry-timeout",
                 N_("|N|set the Pinentry timeout to N seconds")),
   ARGPARSE_s_n (oPinentryFormattedPassphrase, "pinentry-formatted-passphrase",
                 "@"),
   ARGPARSE_s_n (oAllowEmacsPinentry,  "allow-emacs-pinentry",
                 N_("allow passphrase to be prompted through Emacs")),
 
 
   /* Dummy options for backward compatibility.  */
   ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
   ARGPARSE_s_n (oUseStandardSocket, "use-standard-socket", "@"),
   ARGPARSE_s_n (oNoUseStandardSocket, "no-use-standard-socket", "@"),
 
   /* Dummy options.  */
 
 
   ARGPARSE_end () /* End of list */
 };
 
 
 /* The list of supported debug flags.  */
 static struct debug_flags_s debug_flags [] =
   {
     { DBG_MPI_VALUE    , "mpi"     },
     { DBG_CRYPTO_VALUE , "crypto"  },
     { DBG_MEMORY_VALUE , "memory"  },
     { DBG_CACHE_VALUE  , "cache"   },
     { DBG_MEMSTAT_VALUE, "memstat" },
     { DBG_HASHING_VALUE, "hashing" },
     { DBG_IPC_VALUE    , "ipc"     },
     { 77, NULL } /* 77 := Do not exit on "help" or "?".  */
   };
 
 
 
 #define DEFAULT_CACHE_TTL     (10*60)  /* 10 minutes */
 #define DEFAULT_CACHE_TTL_SSH (30*60)  /* 30 minutes */
 #define MAX_CACHE_TTL         (120*60) /* 2 hours */
 #define MAX_CACHE_TTL_SSH     (120*60) /* 2 hours */
 #define MIN_PASSPHRASE_LEN    (8)
 #define MIN_PASSPHRASE_NONALPHA (1)
 #define MAX_PASSPHRASE_DAYS   (0)
 
 /* The timer tick used for housekeeping stuff.  Note that on Windows
  * we use a SetWaitableTimer seems to signal earlier than about 2
  * seconds.  Thus we use 4 seconds on all platforms except for
  * Windowsce.  CHECK_OWN_SOCKET_INTERVAL defines how often we check
  * our own socket in standard socket mode.  If that value is 0 we
  * don't check at all.  All values are in seconds. */
 #if defined(HAVE_W32CE_SYSTEM)
 # define TIMERTICK_INTERVAL         (60)
 # define CHECK_OWN_SOCKET_INTERVAL   (0)  /* Never */
 #else
 # define TIMERTICK_INTERVAL          (4)
 # define CHECK_OWN_SOCKET_INTERVAL  (60)
 #endif
 
 
 /* Flag indicating that the ssh-agent subsystem has been enabled.  */
 static int ssh_support;
 
 #ifdef HAVE_W32_SYSTEM
 /* Flag indicating that support for Putty has been enabled.  */
 static int putty_support;
 /* A magic value used with WM_COPYDATA.  */
 #define PUTTY_IPC_MAGIC 0x804e50ba
 /* To avoid surprises we limit the size of the mapped IPC file to this
    value.  Putty currently (0.62) uses 8k, thus 16k should be enough
    for the foreseeable future.  */
 #define PUTTY_IPC_MAXLEN 16384
 #endif /*HAVE_W32_SYSTEM*/
 
 /* The list of open file descriptors at startup.  Note that this list
  * has been allocated using the standard malloc.  */
 #ifndef HAVE_W32_SYSTEM
 static int *startup_fd_list;
 #endif
 
 /* The signal mask at startup and a flag telling whether it is valid.  */
 #ifdef HAVE_SIGPROCMASK
 static sigset_t startup_signal_mask;
 static int startup_signal_mask_valid;
 #endif
 
 /* Flag to indicate that a shutdown was requested.  */
 static int shutdown_pending;
 
 /* Counter for the currently running own socket checks.  */
 static int check_own_socket_running;
 
 /* Flags to indicate that check_own_socket shall not be called.  */
 static int disable_check_own_socket;
 
 /* Flag indicating that we are in supervised mode.  */
 static int is_supervised;
 
+/* Flag indicating to start the daemon even if one already runs.  */
+static int steal_socket;
+
 /* Flag to inhibit socket removal in cleanup.  */
 static int inhibit_socket_removal;
 
 /* It is possible that we are currently running under setuid permissions */
 static int maybe_setuid = 1;
 
 /* Name of the communication socket used for native gpg-agent
    requests. The second variable is either NULL or a malloced string
    with the real socket name in case it has been redirected.  */
 static char *socket_name;
 static char *redir_socket_name;
 
 /* Name of the optional extra socket used for native gpg-agent requests.  */
 static char *socket_name_extra;
 static char *redir_socket_name_extra;
 
 /* Name of the optional browser socket used for native gpg-agent requests.  */
 static char *socket_name_browser;
 static char *redir_socket_name_browser;
 
 /* Name of the communication socket used for ssh-agent protocol.  */
 static char *socket_name_ssh;
 static char *redir_socket_name_ssh;
 
 /* We need to keep track of the server's nonces (these are dummies for
    POSIX systems). */
 static assuan_sock_nonce_t socket_nonce;
 static assuan_sock_nonce_t socket_nonce_extra;
 static assuan_sock_nonce_t socket_nonce_browser;
 static assuan_sock_nonce_t socket_nonce_ssh;
 
 /* Value for the listen() backlog argument.  We use the same value for
  * all sockets - 64 is on current Linux half of the default maximum.
  * Let's try this as default.  Change at runtime with --listen-backlog.  */
 static int listen_backlog = 64;
 
 /* Default values for options passed to the pinentry. */
 static char *default_display;
 static char *default_ttyname;
 static char *default_ttytype;
 static char *default_lc_ctype;
 static char *default_lc_messages;
 static char *default_xauthority;
 
 /* Name of a config file which was last read on startup or if missing
  * the name of the standard config file.  Any value here enabled the
  * rereading of the standard config files on SIGHUP. */
 static char *config_filename;
 
 /* Helper to implement --debug-level */
 static const char *debug_level;
 
 /* Keep track of the current log file so that we can avoid updating
    the log file after a SIGHUP if it didn't changed. Malloced. */
 static char *current_logfile;
 
 /* The handle_tick() function may test whether a parent is still
  * running.  We record the PID of the parent here or -1 if it should
  * be watched.  */
 static pid_t parent_pid = (pid_t)(-1);
 
 /* This flag is true if the inotify mechanism for detecting the
  * removal of the homedir is active.  This flag is used to disable the
  * alternative but portable stat based check.  */
 static int have_homedir_inotify;
 
 /* Depending on how gpg-agent was started, the homedir inotify watch
  * may not be reliable.  This flag is set if we assume that inotify
  * works reliable.  */
 static int reliable_homedir_inotify;
 
 /* Number of active connections.  */
 static int active_connections;
 
 /* This object is used to dispatch progress messages from Libgcrypt to
  * the right thread.  Given that we will have at max only a few dozen
  * connections at a time, using a linked list is the easiest way to
  * handle this. */
 struct progress_dispatch_s
 {
   struct progress_dispatch_s *next;
   /* The control object of the connection.  If this is NULL no
    * connection is associated with this item and it is free for reuse
    * by new connections.  */
   ctrl_t ctrl;
 
   /* The thread id of (npth_self) of the connection.  */
   npth_t tid;
 
   /* The callback set by the connection.  This is similar to the
    * Libgcrypt callback but with the control object passed as the
    * first argument.  */
   void (*cb)(ctrl_t ctrl,
              const char *what, int printchar,
              int current, int total);
 };
 struct progress_dispatch_s *progress_dispatch_list;
 
 
 
 
 /*
    Local prototypes.
  */
 
 static char *create_socket_name (char *standard_name, int with_homedir);
 static gnupg_fd_t create_server_socket (char *name, int primary, int cygwin,
                                         char **r_redir_name,
                                         assuan_sock_nonce_t *nonce);
 static void create_directories (void);
 
 static void agent_libgcrypt_progress_cb (void *data, const char *what,
                                          int printchar,
                                          int current, int total);
 static void agent_init_default_ctrl (ctrl_t ctrl);
 static void agent_deinit_default_ctrl (ctrl_t ctrl);
 
 static void handle_connections (gnupg_fd_t listen_fd,
                                 gnupg_fd_t listen_fd_extra,
                                 gnupg_fd_t listen_fd_browser,
                                 gnupg_fd_t listen_fd_ssh);
 static void check_own_socket (void);
 static int check_for_running_agent (int silent);
 
 /* Pth wrapper function definitions. */
 ASSUAN_SYSTEM_NPTH_IMPL;
 
 
 /*
    Functions.
  */
 
 /* Allocate a string describing a library version by calling a GETFNC.
    This function is expected to be called only once.  GETFNC is
    expected to have a semantic like gcry_check_version ().  */
 static char *
 make_libversion (const char *libname, const char *(*getfnc)(const char*))
 {
   const char *s;
   char *result;
 
   if (maybe_setuid)
     {
       gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
       maybe_setuid = 0;
     }
   s = getfnc (NULL);
   result = xmalloc (strlen (libname) + 1 + strlen (s) + 1);
   strcpy (stpcpy (stpcpy (result, libname), " "), s);
   return result;
 }
 
 /* Return strings describing this program.  The case values are
    described in common/argparse.c:strusage.  The values here override
    the default values given by strusage.  */
 static const char *
 my_strusage (int level)
 {
   static char *ver_gcry;
   const char *p;
 
   switch (level)
     {
     case  9: p = "GPL-3.0-or-later"; break;
     case 11: p = "@GPG_AGENT@ (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
     case 17: p = PRINTABLE_OS_NAME; break;
       /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug
          reporting address.  This is so that we can change the
          reporting address without breaking the translations.  */
     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
 
     case 20:
       if (!ver_gcry)
         ver_gcry = make_libversion ("libgcrypt", gcry_check_version);
       p = ver_gcry;
       break;
 
     case 1:
     case 40: p =  _("Usage: @GPG_AGENT@ [options] (-h for help)");
       break;
     case 41: p =  _("Syntax: @GPG_AGENT@ [options] [command [args]]\n"
                     "Secret key management for @GNUPG@\n");
     break;
 
     default: p = NULL;
     }
   return p;
 }
 
 
 
 /* Setup the debugging.  With the global variable DEBUG_LEVEL set to NULL
    only the active debug flags are propagated to the subsystems.  With
    DEBUG_LEVEL set, a specific set of debug flags is set; thus overriding
    all flags already set. Note that we don't fail here, because it is
    important to keep gpg-agent running even after re-reading the
    options due to a SIGHUP. */
 static void
 set_debug (void)
 {
   int numok = (debug_level && digitp (debug_level));
   int numlvl = numok? atoi (debug_level) : 0;
 
   if (!debug_level)
     ;
   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
     opt.debug = 0;
   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
     opt.debug = DBG_IPC_VALUE;
   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
     opt.debug = DBG_IPC_VALUE;
   else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
     opt.debug = (DBG_IPC_VALUE | DBG_CACHE_VALUE);
   else if (!strcmp (debug_level, "guru") || numok)
     {
       opt.debug = ~0;
       /* Unless the "guru" string has been used we don't want to allow
          hashing debugging.  The rationale is that people tend to
          select the highest debug value and would then clutter their
          disk with debug files which may reveal confidential data.  */
       if (numok)
         opt.debug &= ~(DBG_HASHING_VALUE);
     }
   else
     {
       log_error (_("invalid debug-level '%s' given\n"), debug_level);
       opt.debug = 0; /* Reset debugging, so that prior debug
                         statements won't have an undesired effect. */
     }
 
   if (opt.debug && !opt.verbose)
     opt.verbose = 1;
   if (opt.debug && opt.quiet)
     opt.quiet = 0;
 
   if (opt.debug & DBG_MPI_VALUE)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
   if (opt.debug & DBG_CRYPTO_VALUE )
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 
   if (opt.debug)
     parse_debug_flag (NULL, &opt.debug, debug_flags);
 }
 
 
 /* Helper for cleanup to remove one socket with NAME.  REDIR_NAME is
    the corresponding real name if the socket has been redirected.  */
 static void
 remove_socket (char *name, char *redir_name)
 {
   if (name && *name)
     {
       if (redir_name)
         name = redir_name;
 
       gnupg_remove (name);
       *name = 0;
     }
 }
 
 
 /* Discover which inherited file descriptors correspond to which
  * services/sockets offered by gpg-agent, using the LISTEN_FDS and
  * LISTEN_FDNAMES convention.  The understood labels are "ssh",
  * "extra", and "browser".  "std" or other labels will be interpreted
  * as the standard socket.
  *
  * This function is designed to log errors when the expected file
  * descriptors don't make sense, but to do its best to continue to
  * work even in the face of minor misconfigurations.
  *
  * For more information on the LISTEN_FDS convention, see
  * sd_listen_fds(3) on certain Linux distributions.
  */
 #ifndef HAVE_W32_SYSTEM
 static void
 map_supervised_sockets (gnupg_fd_t *r_fd,
                         gnupg_fd_t *r_fd_extra,
                         gnupg_fd_t *r_fd_browser,
                         gnupg_fd_t *r_fd_ssh)
 {
   struct {
     const char *label;
     int **fdaddr;
     char **nameaddr;
   } tbl[] = {
     { "ssh",     &r_fd_ssh,     &socket_name_ssh },
     { "browser", &r_fd_browser, &socket_name_browser },
     { "extra",   &r_fd_extra,   &socket_name_extra },
     { "std",     &r_fd,         &socket_name }  /* (Must be the last item.)  */
   };
   const char *envvar;
   char **fdnames;
   int nfdnames;
   int fd_count;
 
   *r_fd = *r_fd_extra = *r_fd_browser = *r_fd_ssh = -1;
 
   /* Print a warning if LISTEN_PID does not match outr pid.  */
   envvar = getenv ("LISTEN_PID");
   if (!envvar)
     log_error ("no LISTEN_PID environment variable found in "
                "--supervised mode (ignoring)\n");
   else if (strtoul (envvar, NULL, 10) != (unsigned long)getpid ())
     log_error ("environment variable LISTEN_PID (%lu) does not match"
                " our pid (%lu) in --supervised mode (ignoring)\n",
                (unsigned long)strtoul (envvar, NULL, 10),
                (unsigned long)getpid ());
 
   /* Parse LISTEN_FDNAMES into the array FDNAMES.  */
   envvar = getenv ("LISTEN_FDNAMES");
   if (envvar)
     {
       fdnames = strtokenize (envvar, ":");
       if (!fdnames)
         {
           log_error ("strtokenize failed: %s\n",
                      gpg_strerror (gpg_error_from_syserror ()));
           agent_exit (1);
         }
       for (nfdnames=0; fdnames[nfdnames]; nfdnames++)
         ;
     }
   else
     {
       fdnames = NULL;
       nfdnames = 0;
     }
 
   /* Parse LISTEN_FDS into fd_count or provide a replacement.  */
   envvar = getenv ("LISTEN_FDS");
   if (envvar)
     fd_count = atoi (envvar);
   else if (fdnames)
     {
       log_error ("no LISTEN_FDS environment variable found in --supervised"
                  " mode (relying on LISTEN_FDNAMES instead)\n");
       fd_count = nfdnames;
     }
   else
     {
       log_error ("no LISTEN_FDS or LISTEN_FDNAMES environment variables "
                 "found in --supervised mode"
                 " (assuming 1 active descriptor)\n");
       fd_count = 1;
     }
 
   if (fd_count < 1)
     {
       log_error ("--supervised mode expects at least one file descriptor"
                  " (was told %d, carrying on as though it were 1)\n",
                  fd_count);
       fd_count = 1;
     }
 
   /* Assign the descriptors to the return values.  */
   if (!fdnames)
     {
       struct stat statbuf;
 
       if (fd_count != 1)
         log_error ("no LISTEN_FDNAMES and LISTEN_FDS (%d) != 1"
                    " in --supervised mode."
                    " (ignoring all sockets but the first one)\n",
                    fd_count);
       if (fstat (3, &statbuf) == -1 && errno ==EBADF)
         log_fatal ("file descriptor 3 must be valid in --supervised mode"
                    " if LISTEN_FDNAMES is not set\n");
       *r_fd = 3;
       socket_name = gnupg_get_socket_name (3);
     }
   else if (fd_count != nfdnames)
     {
       log_fatal ("number of items in LISTEN_FDNAMES (%d) does not match "
                  "LISTEN_FDS (%d) in --supervised mode\n",
                  nfdnames, fd_count);
     }
   else
     {
       int i, j, fd;
       char *name;
 
       for (i = 0; i < nfdnames; i++)
         {
           for (j = 0; j < DIM (tbl); j++)
             {
               if (!strcmp (fdnames[i], tbl[j].label) || j == DIM(tbl)-1)
                 {
                   fd = 3 + i;
                   if (**tbl[j].fdaddr == -1)
                     {
                       name = gnupg_get_socket_name (fd);
                       if (name)
                         {
                           **tbl[j].fdaddr = fd;
                           *tbl[j].nameaddr = name;
                           log_info ("using fd %d for %s socket (%s)\n",
                                     fd, tbl[j].label, name);
                         }
                       else
                         {
                           log_error ("cannot listen on fd %d for %s socket\n",
                                      fd, tbl[j].label);
                           close (fd);
                         }
                     }
                   else
                     {
                       log_error ("cannot listen on more than one %s socket\n",
                                  tbl[j].label);
                       close (fd);
                     }
                   break;
                 }
             }
         }
     }
 
   xfree (fdnames);
 }
 #endif /*!HAVE_W32_SYSTEM*/
 
 
 /* Cleanup code for this program.  This is either called has an atexit
    handler or directly.  */
 static void
 cleanup (void)
 {
   static int done;
 
   if (done)
     return;
   done = 1;
   deinitialize_module_cache ();
   if (!is_supervised && !inhibit_socket_removal)
     {
       remove_socket (socket_name, redir_socket_name);
       if (opt.extra_socket > 1)
         remove_socket (socket_name_extra, redir_socket_name_extra);
       if (opt.browser_socket > 1)
         remove_socket (socket_name_browser, redir_socket_name_browser);
       remove_socket (socket_name_ssh, redir_socket_name_ssh);
     }
 }
 
 
 
 /* Handle options which are allowed to be reset after program start.
    Return true when the current option in PARGS could be handled and
    false if not.  As a special feature, passing a value of NULL for
    PARGS, resets the options to the default.  REREAD should be set
    true if it is not the initial option parsing. */
 static int
 parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
 {
   int i;
 
   if (!pargs)
     { /* reset mode */
       opt.quiet = 0;
       opt.verbose = 0;
       opt.debug = 0;
       opt.no_grab = 1;
       opt.debug_pinentry = 0;
       opt.pinentry_program = NULL;
       opt.pinentry_touch_file = NULL;
       xfree (opt.pinentry_invisible_char);
       opt.pinentry_invisible_char = NULL;
       opt.pinentry_timeout = 0;
       opt.pinentry_formatted_passphrase = 0;
       memset (opt.daemon_program, 0, sizeof opt.daemon_program);
       opt.def_cache_ttl = DEFAULT_CACHE_TTL;
       opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL_SSH;
       opt.max_cache_ttl = MAX_CACHE_TTL;
       opt.max_cache_ttl_ssh = MAX_CACHE_TTL_SSH;
       opt.enforce_passphrase_constraints = 0;
       opt.min_passphrase_len = MIN_PASSPHRASE_LEN;
       opt.min_passphrase_nonalpha = MIN_PASSPHRASE_NONALPHA;
       opt.check_passphrase_pattern = NULL;
       opt.check_sym_passphrase_pattern = NULL;
       opt.max_passphrase_days = MAX_PASSPHRASE_DAYS;
       opt.enable_passphrase_history = 0;
       opt.enable_extended_key_format = 1;
       opt.ignore_cache_for_signing = 0;
       opt.allow_mark_trusted = 1;
       opt.allow_external_cache = 1;
       opt.allow_loopback_pinentry = 1;
       opt.allow_emacs_pinentry = 0;
       memset (opt.disable_daemon, 0, sizeof opt.disable_daemon);
       disable_check_own_socket = 0;
       /* Note: When changing the next line, change also gpgconf_list.  */
       opt.ssh_fingerprint_digest = GCRY_MD_SHA256;
       opt.s2k_count = 0;
       set_s2k_calibration_time (0);  /* Set to default.  */
       return 1;
     }
 
   switch (pargs->r_opt)
     {
     case oQuiet: opt.quiet = 1; break;
     case oVerbose: opt.verbose++; break;
 
     case oDebug:
       parse_debug_flag (pargs->r.ret_str, &opt.debug, debug_flags);
       break;
     case oDebugAll: opt.debug = ~0; break;
     case oDebugLevel: debug_level = pargs->r.ret_str; break;
     case oDebugPinentry: opt.debug_pinentry = 1; break;
 
     case oLogFile:
       if (!reread)
         return 0; /* not handled */
       if (!current_logfile || !pargs->r.ret_str
           || strcmp (current_logfile, pargs->r.ret_str))
         {
           log_set_file (pargs->r.ret_str);
           xfree (current_logfile);
           current_logfile = xtrystrdup (pargs->r.ret_str);
         }
       break;
 
     case oNoGrab: opt.no_grab |= 1; break;
     case oGrab: opt.no_grab |= 2; break;
 
     case oPinentryProgram: opt.pinentry_program = pargs->r.ret_str; break;
     case oPinentryTouchFile: opt.pinentry_touch_file = pargs->r.ret_str; break;
     case oPinentryInvisibleChar:
       xfree (opt.pinentry_invisible_char);
       opt.pinentry_invisible_char = xtrystrdup (pargs->r.ret_str); break;
       break;
     case oPinentryTimeout: opt.pinentry_timeout = pargs->r.ret_ulong; break;
     case oPinentryFormattedPassphrase:
       opt.pinentry_formatted_passphrase = 1;
       break;
 
     case oTpm2daemonProgram:
       opt.daemon_program[DAEMON_TPM2D] = pargs->r.ret_str;
       break;
 
     case oScdaemonProgram:
       opt.daemon_program[DAEMON_SCD] = pargs->r.ret_str;
       break;
     case oDisableScdaemon: opt.disable_daemon[DAEMON_SCD] = 1; break;
     case oDisableCheckOwnSocket: disable_check_own_socket = 1; break;
 
     case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break;
     case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break;
     case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break;
     case oMaxCacheTTLSSH: opt.max_cache_ttl_ssh = pargs->r.ret_ulong; break;
 
     case oEnforcePassphraseConstraints:
       opt.enforce_passphrase_constraints=1;
       break;
     case oMinPassphraseLen: opt.min_passphrase_len = pargs->r.ret_ulong; break;
     case oMinPassphraseNonalpha:
       opt.min_passphrase_nonalpha = pargs->r.ret_ulong;
       break;
     case oCheckPassphrasePattern:
       opt.check_passphrase_pattern = pargs->r.ret_str;
       break;
     case oCheckSymPassphrasePattern:
       opt.check_sym_passphrase_pattern = pargs->r.ret_str;
       break;
     case oMaxPassphraseDays:
       opt.max_passphrase_days = pargs->r.ret_ulong;
       break;
     case oEnablePassphraseHistory:
       opt.enable_passphrase_history = 1;
       break;
 
     case oEnableExtendedKeyFormat:
       opt.enable_extended_key_format = 2;
       break;
     case oDisableExtendedKeyFormat:
       if (opt.enable_extended_key_format != 2)
         opt.enable_extended_key_format = 0;
       break;
 
     case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break;
 
     case oAllowMarkTrusted: opt.allow_mark_trusted = 1; break;
     case oNoAllowMarkTrusted: opt.allow_mark_trusted = 0; break;
 
     case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break;
 
     case oAllowLoopbackPinentry: opt.allow_loopback_pinentry = 1; break;
     case oNoAllowLoopbackPinentry: opt.allow_loopback_pinentry = 0; break;
 
     case oNoAllowExternalCache: opt.allow_external_cache = 0;
       break;
 
     case oAllowEmacsPinentry: opt.allow_emacs_pinentry = 1;
       break;
 
     case oSSHFingerprintDigest:
       i = gcry_md_map_name (pargs->r.ret_str);
       if (!i)
         log_error (_("selected digest algorithm is invalid\n"));
       else
         opt.ssh_fingerprint_digest = i;
       break;
 
     case oS2KCount:
       opt.s2k_count = pargs->r.ret_ulong;
       break;
 
     case oS2KCalibration:
       set_s2k_calibration_time (pargs->r.ret_ulong);
       break;
 
     case oNoop: break;
 
     default:
       return 0; /* not handled */
     }
 
   return 1; /* handled */
 }
 
 
 /* Fixup some options after all have been processed.  */
 static void
 finalize_rereadable_options (void)
 {
   /* Hack to allow --grab to override --no-grab.  */
   if ((opt.no_grab & 2))
     opt.no_grab = 0;
 }
 
 
 static void
 thread_init_once (void)
 {
   static int npth_initialized = 0;
 
   if (!npth_initialized)
     {
       npth_initialized++;
       npth_init ();
     }
   gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
   /* Now that we have set the syscall clamp we need to tell Libgcrypt
    * that it should get them from libgpg-error.  Note that Libgcrypt
    * has already been initialized but at that point nPth was not
    * initialized and thus Libgcrypt could not set its system call
    * clamp.  */
   gcry_control (GCRYCTL_REINIT_SYSCALL_CLAMP, 0, 0);
 }
 
 
 static void
 initialize_modules (void)
 {
   thread_init_once ();
   assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   initialize_module_cache ();
   initialize_module_call_pinentry ();
   initialize_module_daemon ();
   initialize_module_trustlist ();
 }
 
 
 /* The main entry point.  */
 int
 main (int argc, char **argv)
 {
   gpgrt_argparse_t pargs;
   int orig_argc;
   char **orig_argv;
   char *last_configname = NULL;
   const char *configname = NULL;
   int debug_argparser = 0;
   const char *shell;
   int pipe_server = 0;
   int is_daemon = 0;
   int nodetach = 0;
   int csh_style = 0;
   char *logfile = NULL;
   int debug_wait = 0;
   int gpgconf_list = 0;
   gpg_error_t err;
   struct assuan_malloc_hooks malloc_hooks;
 
   early_system_init ();
 
   /* Before we do anything else we save the list of currently open
      file descriptors and the signal mask.  This info is required to
      do the exec call properly.  We don't need it on Windows.  */
 #ifndef HAVE_W32_SYSTEM
   startup_fd_list = get_all_open_fds ();
 #endif /*!HAVE_W32_SYSTEM*/
 #ifdef HAVE_SIGPROCMASK
   if (!sigprocmask (SIG_UNBLOCK, NULL, &startup_signal_mask))
     startup_signal_mask_valid = 1;
 #endif /*HAVE_SIGPROCMASK*/
 
   /* Set program name etc.  */
   gpgrt_set_strusage (my_strusage);
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
   /* Please note that we may running SUID(ROOT), so be very CAREFUL
      when adding any stuff between here and the call to INIT_SECMEM()
      somewhere after the option parsing */
   log_set_prefix (GPG_AGENT_NAME, GPGRT_LOG_WITH_PREFIX|GPGRT_LOG_WITH_PID);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
   init_common_subsystems (&argc, &argv);
 
   malloc_hooks.malloc = gcry_malloc;
   malloc_hooks.realloc = gcry_realloc;
   malloc_hooks.free = gcry_free;
   assuan_set_malloc_hooks (&malloc_hooks);
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
   assuan_sock_init ();
   assuan_sock_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   setup_libassuan_logging (&opt.debug, NULL);
 
   setup_libgcrypt_logging ();
   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
   gcry_set_progress_handler (agent_libgcrypt_progress_cb, NULL);
 
   disable_core_dumps ();
 
   /* Set default options.  */
   parse_rereadable_options (NULL, 0); /* Reset them to default values. */
 
   shell = getenv ("SHELL");
   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
     csh_style = 1;
 
   /* Record some of the original environment strings. */
   {
     const char *s;
     int idx;
     static const char *names[] =
       { "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
 
     err = 0;
     opt.startup_env = session_env_new ();
     if (!opt.startup_env)
       err = gpg_error_from_syserror ();
     for (idx=0; !err && names[idx]; idx++)
       {
         s = getenv (names[idx]);
         if (s)
           err = session_env_setenv (opt.startup_env, names[idx], s);
       }
     if (!err)
       {
         s = gnupg_ttyname (0);
         if (s)
           err = session_env_setenv (opt.startup_env, "GPG_TTY", s);
       }
     if (err)
       log_fatal ("error recording startup environment: %s\n",
                  gpg_strerror (err));
 
     /* Fixme: Better use the locale function here.  */
     opt.startup_lc_ctype = getenv ("LC_CTYPE");
     if (opt.startup_lc_ctype)
       opt.startup_lc_ctype = xstrdup (opt.startup_lc_ctype);
     opt.startup_lc_messages = getenv ("LC_MESSAGES");
     if (opt.startup_lc_messages)
       opt.startup_lc_messages = xstrdup (opt.startup_lc_messages);
   }
 
   /* Check whether we have a config file on the commandline */
   orig_argc = argc;
   orig_argv = argv;
   pargs.argc = &argc;
   pargs.argv = &argv;
   pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
   while (gpgrt_argparse (NULL, &pargs, opts))
     {
       switch (pargs.r_opt)
         {
         case oDebug:
         case oDebugAll:
           debug_argparser++;
           break;
 
         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. */
   gcry_control (GCRYCTL_INIT_SECMEM, SECMEM_BUFFER_SIZE, 0);
   maybe_setuid = 0;
 
   /*
    *  Now we are now working under our real uid
    */
 
   /* The configuraton directories for use by gpgrt_argparser.  */
   gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ());
   gpgrt_set_confdir (GPGRT_CONFDIR_USER, gnupg_homedir ());
 
   argc = orig_argc;
   argv = orig_argv;
   pargs.argc = &argc;
   pargs.argv = &argv;
   /* 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);
 
   while (gpgrt_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))
         continue; /* Already handled */
       switch (pargs.r_opt)
         {
         case aGPGConfList: gpgconf_list = 1; break;
         case aGPGConfTest: gpgconf_list = 2; break;
         case aUseStandardSocketP: gpgconf_list = 3; break;
         case oBatch: opt.batch=1; break;
 
         case oDebugWait: debug_wait = pargs.r.ret_int; break;
 
         case oNoVerbose: opt.verbose = 0; break;
         case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
         case oNoDetach: nodetach = 1; break;
         case oLogFile: logfile = pargs.r.ret_str; break;
         case oCsh: csh_style = 1; break;
         case oSh: csh_style = 0; break;
         case oServer: pipe_server = 1; break;
         case oDaemon: is_daemon = 1; break;
+        case oStealSocket: steal_socket = 1; break;
         case oSupervised: is_supervised = 1; break;
 
         case oDisplay: default_display = xstrdup (pargs.r.ret_str); break;
         case oTTYname: default_ttyname = xstrdup (pargs.r.ret_str); break;
         case oTTYtype: default_ttytype = xstrdup (pargs.r.ret_str); break;
         case oLCctype: default_lc_ctype = xstrdup (pargs.r.ret_str); break;
         case oLCmessages: default_lc_messages = xstrdup (pargs.r.ret_str);
           break;
         case oXauthority: default_xauthority = xstrdup (pargs.r.ret_str);
           break;
 
         case oUseStandardSocket:
         case oNoUseStandardSocket:
           obsolete_option (configname, pargs.lineno, "use-standard-socket");
           break;
 
         case oFakedSystemTime:
           {
             time_t faked_time = isotime2epoch (pargs.r.ret_str);
             if (faked_time == (time_t)(-1))
               faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
             gnupg_set_time (faked_time, 0);
           }
           break;
 
         case oKeepTTY: opt.keep_tty = 1; break;
         case oKeepDISPLAY: opt.keep_display = 1; break;
 
 	case oSSHSupport:
           ssh_support = 1;
           break;
 
         case oPuttySupport:
 #        ifdef HAVE_W32_SYSTEM
           putty_support = 1;
 #        endif
           break;
 
         case oExtraSocket:
           opt.extra_socket = 1;  /* (1 = points into argv)  */
           socket_name_extra = pargs.r.ret_str;
           break;
 
         case oBrowserSocket:
           opt.browser_socket = 1;  /* (1 = points into argv)  */
           socket_name_browser = pargs.r.ret_str;
           break;
 
         case oAutoExpandSecmem:
           /* Try to enable this option.  It will officially only be
            * supported by Libgcrypt 1.9 but 1.8.2 already supports it
            * on the quiet and thus we use the numeric value value.  */
           gcry_control (78 /*GCRYCTL_AUTO_EXPAND_SECMEM*/,
                         (unsigned int)pargs.r.ret_ulong,  0);
           break;
 
         case oListenBacklog:
           listen_backlog = pargs.r.ret_int;
           break;
 
         case oDebugQuickRandom:
           /* Only used by the first stage command line parser.  */
           break;
 
         case oWriteEnvFile:
           obsolete_option (configname, pargs.lineno, "write-env-file");
           break;
 
         default:
           if (configname)
             pargs.err = ARGPARSE_PRINT_WARNING;
           else
             pargs.err = ARGPARSE_PRINT_ERROR;
           break;
 	}
     }
 
   gpgrt_argparse (NULL, &pargs, NULL);  /* Release internal state.  */
 
   if (!last_configname)
     config_filename = gpgrt_fnameconcat (gnupg_homedir (),
                                          GPG_AGENT_NAME EXTSEP_S "conf",
                                          NULL);
   else
     {
       config_filename = last_configname;
       last_configname = NULL;
     }
 
   if (log_get_errorcount(0))
     exit(2);
 
   finalize_rereadable_options ();
 
   /* Get a default log file from common.conf.  */
   if (!logfile && !parse_comopt (GNUPG_MODULE_NAME_AGENT, debug_argparser))
     {
       logfile = comopt.logfile;
       comopt.logfile = NULL;
     }
 
   /* Print a warning if an argument looks like an option.  */
   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
     {
       int i;
 
       for (i=0; i < argc; i++)
         if (argv[i][0] == '-' && argv[i][1] == '-')
           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
     }
 
 #ifdef ENABLE_NLS
   /* gpg-agent usually does not output any messages because it runs in
      the background.  For log files it is acceptable to have messages
      always encoded in utf-8.  We switch here to utf-8, so that
      commands like --help still give native messages.  It is far
      easier to switch only once instead of for every message and it
      actually helps when more then one thread is active (avoids an
      extra copy step). */
     bind_textdomain_codeset (PACKAGE_GT, "UTF-8");
 #endif
 
   if (!pipe_server && !is_daemon && !gpgconf_list && !is_supervised)
     {
      /* We have been called without any command and thus we merely
         check whether an agent is already running.  We do this right
         here so that we don't clobber a logfile with this check but
         print the status directly to stderr. */
       opt.debug = 0;
       set_debug ();
       check_for_running_agent (0);
       agent_exit (0);
     }
 
   if (is_supervised)
     ;
   else if (!opt.extra_socket)
     opt.extra_socket = 1;
   else if (socket_name_extra
            && (!strcmp (socket_name_extra, "none")
                || !strcmp (socket_name_extra, "/dev/null")))
     {
       /* User requested not to create this socket.  */
       opt.extra_socket = 0;
       socket_name_extra = NULL;
     }
 
   if (is_supervised)
     ;
   else if (!opt.browser_socket)
     opt.browser_socket = 1;
   else if (socket_name_browser
            && (!strcmp (socket_name_browser, "none")
                || !strcmp (socket_name_browser, "/dev/null")))
     {
       /* User requested not to create this socket.  */
       opt.browser_socket = 0;
       socket_name_browser = NULL;
     }
 
   set_debug ();
 
   if (atexit (cleanup))
     {
       log_error ("atexit failed\n");
       cleanup ();
       exit (1);
     }
 
   /* Try to create missing directories. */
   if (!gpgconf_list)
     create_directories ();
 
   if (debug_wait && pipe_server)
     {
       thread_init_once ();
       log_debug ("waiting for debugger - my pid is %u .....\n",
                  (unsigned int)getpid());
       gnupg_sleep (debug_wait);
       log_debug ("... okay\n");
     }
 
   if (gpgconf_list == 3)
     {
       /* We now use the standard socket always - return true for
          backward compatibility.  */
       agent_exit (0);
     }
   else if (gpgconf_list == 2)
     agent_exit (0);
   else if (gpgconf_list)
     {
       /* Note: If an option is runtime changeable, please set the
        * respective flag in the gpgconf-comp.c table.  */
       es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
       es_printf ("default-cache-ttl:%lu:%d:\n",
                  GC_OPT_FLAG_DEFAULT, DEFAULT_CACHE_TTL );
       es_printf ("default-cache-ttl-ssh:%lu:%d:\n",
                  GC_OPT_FLAG_DEFAULT, DEFAULT_CACHE_TTL_SSH );
       es_printf ("max-cache-ttl:%lu:%d:\n",
                  GC_OPT_FLAG_DEFAULT, MAX_CACHE_TTL );
       es_printf ("max-cache-ttl-ssh:%lu:%d:\n",
                  GC_OPT_FLAG_DEFAULT, MAX_CACHE_TTL_SSH );
       es_printf ("min-passphrase-len:%lu:%d:\n",
                  GC_OPT_FLAG_DEFAULT, MIN_PASSPHRASE_LEN );
       es_printf ("min-passphrase-nonalpha:%lu:%d:\n",
                  GC_OPT_FLAG_DEFAULT, MIN_PASSPHRASE_NONALPHA);
       es_printf ("check-passphrase-pattern:%lu:\n",
                  GC_OPT_FLAG_DEFAULT);
       es_printf ("check-sym-passphrase-pattern:%lu:\n",
                  GC_OPT_FLAG_DEFAULT);
       es_printf ("max-passphrase-days:%lu:%d:\n",
                  GC_OPT_FLAG_DEFAULT, MAX_PASSPHRASE_DAYS);
       es_printf ("ssh-fingerprint-digest:%lu:\"%s:\n",
                  GC_OPT_FLAG_DEFAULT, "sha256");
 
       agent_exit (0);
     }
 
   /* Now start with logging to a file if this is desired. */
   if (logfile)
     {
       log_set_file (logfile);
       log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
                              | GPGRT_LOG_WITH_TIME
                              | GPGRT_LOG_WITH_PID));
       current_logfile = xstrdup (logfile);
     }
 
   /* Make sure that we have a default ttyname. */
   if (!default_ttyname && gnupg_ttyname (1))
     default_ttyname = xstrdup (gnupg_ttyname (1));
   if (!default_ttytype && getenv ("TERM"))
     default_ttytype = xstrdup (getenv ("TERM"));
 
 
   if (pipe_server)
     {
       /* This is the simple pipe based server */
       ctrl_t ctrl;
 
       initialize_modules ();
 
       ctrl = xtrycalloc (1, sizeof *ctrl);
       if (!ctrl)
         {
           log_error ("error allocating connection control data: %s\n",
                      strerror (errno) );
           agent_exit (1);
         }
       ctrl->session_env = session_env_new ();
       if (!ctrl->session_env)
         {
           log_error ("error allocating session environment block: %s\n",
                      strerror (errno) );
           xfree (ctrl);
           agent_exit (1);
         }
       agent_init_default_ctrl (ctrl);
       start_command_handler (ctrl, GNUPG_INVALID_FD, GNUPG_INVALID_FD);
       agent_deinit_default_ctrl (ctrl);
       xfree (ctrl);
     }
   else if (is_supervised)
     {
 #ifndef HAVE_W32_SYSTEM
       gnupg_fd_t fd, fd_extra, fd_browser, fd_ssh;
 
       initialize_modules ();
 
       /* when supervised and sending logs to stderr, the process
          supervisor should handle log entry metadata (pid, name,
          timestamp) */
       if (!logfile)
         log_set_prefix (NULL, 0);
 
       log_info ("%s %s starting in supervised mode.\n",
                 gpgrt_strusage(11), gpgrt_strusage(13) );
 
       /* See below in "regular server mode" on why we remove certain
        * envvars.  */
       if (!opt.keep_display)
         gnupg_unsetenv ("DISPLAY");
       gnupg_unsetenv ("INSIDE_EMACS");
 
       /* Virtually create the sockets.  Note that we use -1 here
        * because the whole thing works only on Unix. */
       map_supervised_sockets (&fd, &fd_extra, &fd_browser, &fd_ssh);
       if (fd == -1)
         log_fatal ("no standard socket provided\n");
 
 #ifdef HAVE_SIGPROCMASK
       if (startup_signal_mask_valid)
         {
           if (sigprocmask (SIG_SETMASK, &startup_signal_mask, NULL))
             log_error ("error restoring signal mask: %s\n",
                        strerror (errno));
         }
       else
         log_info ("no saved signal mask\n");
 #endif /*HAVE_SIGPROCMASK*/
 
       log_info ("listening on: std=%d extra=%d browser=%d ssh=%d\n",
                 fd, fd_extra, fd_browser, fd_ssh);
       handle_connections (fd, fd_extra, fd_browser, fd_ssh);
 #endif /*!HAVE_W32_SYSTEM*/
     }
   else if (!is_daemon)
     ; /* NOTREACHED */
   else
     { /* Regular server mode */
       gnupg_fd_t fd;
       gnupg_fd_t fd_extra = GNUPG_INVALID_FD;
       gnupg_fd_t fd_browser = GNUPG_INVALID_FD;
       gnupg_fd_t fd_ssh = GNUPG_INVALID_FD;
 #ifndef HAVE_W32_SYSTEM
       pid_t pid;
 #endif
 
       /* Remove the DISPLAY variable so that a pinentry does not
          default to a specific display.  There is still a default
          display when gpg-agent was started using --display or a
          client requested this using an OPTION command.  Note, that we
          don't do this when running in reverse daemon mode (i.e. when
          exec the program given as arguments). */
 #ifndef HAVE_W32_SYSTEM
       if (!opt.keep_display && !argc)
         gnupg_unsetenv ("DISPLAY");
 #endif
 
       /* Remove the INSIDE_EMACS variable so that a pinentry does not
          always try to interact with Emacs.  The variable is set when
          a client requested this using an OPTION command.  */
       gnupg_unsetenv ("INSIDE_EMACS");
 
       /* Create the sockets.  */
       socket_name = create_socket_name (GPG_AGENT_SOCK_NAME, 1);
       fd = create_server_socket (socket_name, 1, 0,
                                  &redir_socket_name, &socket_nonce);
 
       if (opt.extra_socket)
         {
           if (socket_name_extra)
             socket_name_extra = create_socket_name (socket_name_extra, 0);
           else
             socket_name_extra = create_socket_name
               /**/                (GPG_AGENT_EXTRA_SOCK_NAME, 1);
           opt.extra_socket = 2; /* Indicate that it has been malloced.  */
           fd_extra = create_server_socket (socket_name_extra, 0, 0,
                                            &redir_socket_name_extra,
                                            &socket_nonce_extra);
         }
 
       if (opt.browser_socket)
         {
           if (socket_name_browser)
             socket_name_browser = create_socket_name (socket_name_browser, 0);
           else
             socket_name_browser= create_socket_name
               /**/                 (GPG_AGENT_BROWSER_SOCK_NAME, 1);
           opt.browser_socket = 2; /* Indicate that it has been malloced.  */
           fd_browser = create_server_socket (socket_name_browser, 0, 0,
                                              &redir_socket_name_browser,
                                              &socket_nonce_browser);
         }
 
       socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
       fd_ssh = create_server_socket (socket_name_ssh, 0, 1,
                                      &redir_socket_name_ssh,
                                      &socket_nonce_ssh);
 
       /* If we are going to exec a program in the parent, we record
          the PID, so that the child may check whether the program is
          still alive. */
       if (argc)
         parent_pid = getpid ();
 
       fflush (NULL);
 
 #ifdef HAVE_W32_SYSTEM
 
       (void)csh_style;
       (void)nodetach;
       initialize_modules ();
 
 #else /*!HAVE_W32_SYSTEM*/
 
       pid = fork ();
       if (pid == (pid_t)-1)
         {
           log_fatal ("fork failed: %s\n", strerror (errno) );
           exit (1);
         }
       else if (pid)
         { /* We are the parent */
           char *infostr_ssh_sock, *infostr_ssh_valid;
 
           /* Close the socket FD. */
           close (fd);
 
           /* The signal mask might not be correct right now and thus
              we restore it.  That is not strictly necessary but some
              programs falsely assume a cleared signal mask.  */
 
 #ifdef HAVE_SIGPROCMASK
           if (startup_signal_mask_valid)
             {
               if (sigprocmask (SIG_SETMASK, &startup_signal_mask, NULL))
                 log_error ("error restoring signal mask: %s\n",
                            strerror (errno));
             }
           else
             log_info ("no saved signal mask\n");
 #endif /*HAVE_SIGPROCMASK*/
 
           /* Create the SSH info string if enabled. */
 	  if (ssh_support)
 	    {
 	      if (asprintf (&infostr_ssh_sock, "SSH_AUTH_SOCK=%s",
 			    socket_name_ssh) < 0)
 		{
 		  log_error ("out of core\n");
 		  kill (pid, SIGTERM);
 		  exit (1);
 		}
 	      if (asprintf (&infostr_ssh_valid, "gnupg_SSH_AUTH_SOCK_by=%lu",
 			    (unsigned long)getpid()) < 0)
 		{
 		  log_error ("out of core\n");
 		  kill (pid, SIGTERM);
 		  exit (1);
 		}
 	    }
 
           *socket_name = 0; /* Don't let cleanup() remove the socket -
                                the child should do this from now on */
 	  if (opt.extra_socket)
 	    *socket_name_extra = 0;
 	  if (opt.browser_socket)
 	    *socket_name_browser = 0;
           *socket_name_ssh = 0;
 
           if (argc)
             { /* Run the program given on the commandline.  */
               if (ssh_support && (putenv (infostr_ssh_sock)
                                   || putenv (infostr_ssh_valid)))
                 {
                   log_error ("failed to set environment: %s\n",
                              strerror (errno) );
                   kill (pid, SIGTERM );
                   exit (1);
                 }
 
               /* Close all the file descriptors except the standard
                  ones and those open at startup.  We explicitly don't
                  close 0,1,2 in case something went wrong collecting
                  them at startup.  */
               close_all_fds (3, startup_fd_list);
 
               /* Run the command.  */
               execvp (argv[0], argv);
               log_error ("failed to run the command: %s\n", strerror (errno));
               kill (pid, SIGTERM);
               exit (1);
             }
           else
             {
               /* Print the environment string, so that the caller can use
                  shell's eval to set it */
               if (csh_style)
                 {
 		  if (ssh_support)
 		    {
 		      *strchr (infostr_ssh_sock, '=') = ' ';
 		      es_printf ("setenv %s;\n", infostr_ssh_sock);
 		    }
                 }
               else
                 {
 		  if (ssh_support)
 		    {
 		      es_printf ("%s; export SSH_AUTH_SOCK;\n",
                                  infostr_ssh_sock);
 		    }
                 }
 	      if (ssh_support)
 		{
 		  xfree (infostr_ssh_sock);
 		  xfree (infostr_ssh_valid);
 		}
               exit (0);
             }
           /*NOTREACHED*/
         } /* End parent */
 
       /*
          This is the child
        */
 
       initialize_modules ();
 
       /* Detach from tty and put process into a new session */
       if (!nodetach )
         {
           int i;
           unsigned int oldflags;
 
           /* Close stdin, stdout and stderr unless it is the log stream */
           for (i=0; i <= 2; i++)
             {
               if (!log_test_fd (i) && i != fd )
                 {
                   if ( ! close (i)
                        && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1)
                     {
                       log_error ("failed to open '%s': %s\n",
                                  "/dev/null", strerror (errno));
                       cleanup ();
                       exit (1);
                     }
                 }
             }
           if (setsid() == -1)
             {
               log_error ("setsid() failed: %s\n", strerror(errno) );
               cleanup ();
               exit (1);
             }
 
           log_get_prefix (&oldflags);
           log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED);
           opt.running_detached = 1;
 
           /* Unless we are running with a program given on the command
            * line we can assume that the inotify things works and thus
            * we can avoid the regular stat calls.  */
           if (!argc)
             reliable_homedir_inotify = 1;
         }
 
       {
         struct sigaction sa;
 
         sa.sa_handler = SIG_IGN;
         sigemptyset (&sa.sa_mask);
         sa.sa_flags = 0;
         sigaction (SIGPIPE, &sa, NULL);
       }
 #endif /*!HAVE_W32_SYSTEM*/
 
       if (gnupg_chdir (gnupg_daemon_rootdir ()))
         {
           log_error ("chdir to '%s' failed: %s\n",
                      gnupg_daemon_rootdir (), strerror (errno));
           exit (1);
         }
 
       log_info ("%s %s started\n", gpgrt_strusage(11), gpgrt_strusage(13) );
       handle_connections (fd, fd_extra, fd_browser, fd_ssh);
       assuan_sock_close (fd);
     }
 
   return 0;
 }
 
 
 /* Exit entry point.  This function should be called instead of a
    plain exit.  */
 void
 agent_exit (int rc)
 {
   /*FIXME: update_random_seed_file();*/
 
   /* We run our cleanup handler because that may close cipher contexts
      stored in secure memory and thus this needs to be done before we
      explicitly terminate secure memory.  */
   cleanup ();
 
 #if 1
   /* at this time a bit annoying */
   if (opt.debug & DBG_MEMSTAT_VALUE)
     {
       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
     }
   if (opt.debug)
     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
 #endif
   gcry_control (GCRYCTL_TERM_SECMEM );
   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
   exit (rc);
 }
 
 
 /* This is our callback function for gcrypt progress messages.  It is
    set once at startup and dispatches progress messages to the
    corresponding threads of the agent.  */
 static void
 agent_libgcrypt_progress_cb (void *data, const char *what, int printchar,
                              int current, int total)
 {
   struct progress_dispatch_s *dispatch;
   npth_t mytid = npth_self ();
 
   (void)data;
 
   for (dispatch = progress_dispatch_list; dispatch; dispatch = dispatch->next)
     if (dispatch->ctrl && dispatch->tid == mytid)
       break;
   if (dispatch && dispatch->cb)
     dispatch->cb (dispatch->ctrl, what, printchar, current, total);
 }
 
 
 /* If a progress dispatcher callback has been associated with the
  * current connection unregister it.  */
 static void
 unregister_progress_cb (void)
 {
   struct progress_dispatch_s *dispatch;
   npth_t mytid = npth_self ();
 
   for (dispatch = progress_dispatch_list; dispatch; dispatch = dispatch->next)
     if (dispatch->ctrl && dispatch->tid == mytid)
       break;
   if (dispatch)
     {
       dispatch->ctrl = NULL;
       dispatch->cb = NULL;
     }
 }
 
 
 /* Setup a progress callback CB for the current connection.  Using a
  * CB of NULL disables the callback.  */
 void
 agent_set_progress_cb (void (*cb)(ctrl_t ctrl, const char *what,
                                   int printchar, int current, int total),
                        ctrl_t ctrl)
 {
   struct progress_dispatch_s *dispatch, *firstfree;
   npth_t mytid = npth_self ();
 
   firstfree = NULL;
   for (dispatch = progress_dispatch_list; dispatch; dispatch = dispatch->next)
     {
       if (dispatch->ctrl && dispatch->tid == mytid)
         break;
       if (!dispatch->ctrl && !firstfree)
         firstfree = dispatch;
     }
   if (!dispatch) /* None allocated: Reuse or allocate a new one.  */
     {
       if (firstfree)
         {
           dispatch = firstfree;
         }
       else if ((dispatch = xtrycalloc (1, sizeof *dispatch)))
         {
           dispatch->next = progress_dispatch_list;
           progress_dispatch_list = dispatch;
         }
       else
         {
           log_error ("error allocating new progress dispatcher slot: %s\n",
                      gpg_strerror (gpg_error_from_syserror ()));
           return;
         }
       dispatch->ctrl = ctrl;
       dispatch->tid = mytid;
     }
 
   dispatch->cb = cb;
 }
 
 
 /* Each thread has its own local variables conveyed by a control
    structure usually identified by an argument named CTRL.  This
    function is called immediately after allocating the control
    structure.  Its purpose is to setup the default values for that
    structure.  Note that some values may have already been set.  */
 static void
 agent_init_default_ctrl (ctrl_t ctrl)
 {
   log_assert (ctrl->session_env);
 
   /* Note we ignore malloc errors because we can't do much about it
      and the request will fail anyway shortly after this
      initialization. */
   session_env_setenv (ctrl->session_env, "DISPLAY", default_display);
   session_env_setenv (ctrl->session_env, "GPG_TTY", default_ttyname);
   session_env_setenv (ctrl->session_env, "TERM", default_ttytype);
   session_env_setenv (ctrl->session_env, "XAUTHORITY", default_xauthority);
   session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", NULL);
 
   if (ctrl->lc_ctype)
     xfree (ctrl->lc_ctype);
   ctrl->lc_ctype = default_lc_ctype? xtrystrdup (default_lc_ctype) : NULL;
 
   if (ctrl->lc_messages)
     xfree (ctrl->lc_messages);
   ctrl->lc_messages = default_lc_messages? xtrystrdup (default_lc_messages)
                                     /**/ : NULL;
   ctrl->cache_ttl_opt_preset = CACHE_TTL_OPT_PRESET;
 }
 
 
 /* Release all resources allocated by default in the control
    structure.  This is the counterpart to agent_init_default_ctrl.  */
 static void
 agent_deinit_default_ctrl (ctrl_t ctrl)
 {
   unregister_progress_cb ();
   session_env_release (ctrl->session_env);
 
   xfree (ctrl->digest.data);
   ctrl->digest.data = NULL;
   if (ctrl->lc_ctype)
     xfree (ctrl->lc_ctype);
   if (ctrl->lc_messages)
     xfree (ctrl->lc_messages);
 }
 
 
 /* Because the ssh protocol does not send us information about the
    current TTY setting, we use this function to use those from startup
    or those explicitly set.  This is also used for the restricted mode
    where we ignore requests to change the environment.  */
 gpg_error_t
 agent_copy_startup_env (ctrl_t ctrl)
 {
   gpg_error_t err = 0;
   int iterator = 0;
   const char *name, *value;
 
   while (!err && (name = session_env_list_stdenvnames (&iterator, NULL)))
     {
       if ((value = session_env_getenv (opt.startup_env, name)))
         err = session_env_setenv (ctrl->session_env, name, value);
     }
 
   if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
     if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
       err = gpg_error_from_syserror ();
 
   if (!err && !ctrl->lc_messages && opt.startup_lc_messages)
     if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages)))
       err = gpg_error_from_syserror ();
 
   if (err)
     log_error ("error setting default session environment: %s\n",
                gpg_strerror (err));
 
   return err;
 }
 
 
 /* Reread parts of the configuration.  Note, that this function is
    obviously not thread-safe and should only be called from the PTH
    signal handler.
 
    Fixme: Due to the way the argument parsing works, we create a
    memory leak here for all string type arguments.  There is currently
    no clean way to tell whether the memory for the argument has been
    allocated or points into the process's original arguments.  Unless
    we have a mechanism to tell this, we need to live on with this. */
 static void
 reread_configuration (void)
 {
   gpgrt_argparse_t pargs;
   char *twopart;
   int dummy;
   int logfile_seen = 0;
 
   if (!config_filename)
     return; /* No config file. */
 
   twopart = strconcat (GPG_AGENT_NAME EXTSEP_S "conf" PATHSEP_S,
                        config_filename, NULL);
   if (!twopart)
     return;  /* Out of core.  */
 
   parse_rereadable_options (NULL, 1); /* Start from the default values. */
 
   memset (&pargs, 0, sizeof pargs);
   dummy = 0;
   pargs.argc = &dummy;
   pargs.flags = (ARGPARSE_FLAG_KEEP
                  |ARGPARSE_FLAG_SYS
                  |ARGPARSE_FLAG_USER);
   while (gpgrt_argparser (&pargs, opts, twopart) )
     {
       if (pargs.r_opt == ARGPARSE_CONFFILE)
         {
           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. */
         {
           if (pargs.r_opt == oLogFile)
             logfile_seen = 1;
           parse_rereadable_options (&pargs, 1);
         }
     }
   gpgrt_argparse (NULL, &pargs, NULL);  /* Release internal state.  */
   xfree (twopart);
 
   finalize_rereadable_options ();
   set_debug ();
 
   /* Get a default log file from common.conf.  */
   if (!logfile_seen && !parse_comopt (GNUPG_MODULE_NAME_AGENT, !!opt.debug))
     {
       if (!current_logfile || !comopt.logfile
           || strcmp (current_logfile, comopt.logfile))
         {
           log_set_file (comopt.logfile);
           xfree (current_logfile);
           current_logfile = comopt.logfile? xtrystrdup (comopt.logfile) : NULL;
         }
     }
 }
 
 
 /* Return the file name of the socket we are using for native
    requests.  */
 const char *
 get_agent_socket_name (void)
 {
   const char *s = socket_name;
 
   return (s && *s)? s : NULL;
 }
 
 /* Return the file name of the socket we are using for SSH
    requests.  */
 const char *
 get_agent_ssh_socket_name (void)
 {
   const char *s = socket_name_ssh;
 
   return (s && *s)? s : NULL;
 }
 
 
 /* Return the number of active connections. */
 int
 get_agent_active_connection_count (void)
 {
   return active_connections;
 }
 
 
 /* Under W32, this function returns the handle of the scdaemon
    notification event.  Calling it the first time creates that
    event.  */
 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
 void *
 get_agent_daemon_notify_event (void)
 {
   static HANDLE the_event = INVALID_HANDLE_VALUE;
 
   if (the_event == INVALID_HANDLE_VALUE)
     {
       HANDLE h, h2;
       SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
 
       /* We need to use a manual reset event object due to the way our
          w32-pth wait function works: If we would use an automatic
          reset event we are not able to figure out which handle has
          been signaled because at the time we single out the signaled
          handles using WFSO the event has already been reset due to
          the WFMO.  */
       h = CreateEvent (&sa, TRUE, FALSE, NULL);
       if (!h)
         log_error ("can't create scd notify event: %s\n", w32_strerror (-1) );
       else if (!DuplicateHandle (GetCurrentProcess(), h,
                                  GetCurrentProcess(), &h2,
                                  EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0))
         {
           log_error ("setting synchronize for scd notify event failed: %s\n",
                      w32_strerror (-1) );
           CloseHandle (h);
         }
       else
         {
           CloseHandle (h);
           the_event = h2;
         }
     }
 
   return the_event;
 }
 #endif /*HAVE_W32_SYSTEM && !HAVE_W32CE_SYSTEM*/
 
 
 
 /* Create a name for the socket in the home directory as using
    STANDARD_NAME.  We also check for valid characters as well as
    against a maximum allowed length for a unix domain socket is done.
    The function terminates the process in case of an error.  Returns:
    Pointer to an allocated string with the absolute name of the socket
    used.  */
 static char *
 create_socket_name (char *standard_name, int with_homedir)
 {
   char *name;
 
   if (with_homedir)
     name = make_filename (gnupg_socketdir (), standard_name, NULL);
   else
     name = make_filename (standard_name, NULL);
   if (strchr (name, PATHSEP_C))
     {
       log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
       agent_exit (2);
     }
   return name;
 }
 
 
 
 /* Create a Unix domain socket with NAME.  Returns the file descriptor
    or terminates the process in case of an error.  Note that this
    function needs to be used for the regular socket first (indicated
    by PRIMARY) and only then for the extra and the ssh sockets.  If
    the socket has been redirected the name of the real socket is
    stored as a malloced string at R_REDIR_NAME.  If CYGWIN is set a
    Cygwin compatible socket is created (Windows only). */
 static gnupg_fd_t
 create_server_socket (char *name, int primary, int cygwin,
                       char **r_redir_name, assuan_sock_nonce_t *nonce)
 {
   struct sockaddr *addr;
   struct sockaddr_un *unaddr;
   socklen_t len;
   gnupg_fd_t fd;
   int rc;
 
   xfree (*r_redir_name);
   *r_redir_name = NULL;
 
   fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
   if (fd == ASSUAN_INVALID_FD)
     {
       log_error (_("can't create socket: %s\n"), strerror (errno));
       *name = 0; /* Inhibit removal of the socket by cleanup(). */
       agent_exit (2);
     }
 
   if (cygwin)
     assuan_sock_set_flag (fd, "cygwin", 1);
 
   unaddr = xmalloc (sizeof *unaddr);
   addr = (struct sockaddr*)unaddr;
 
   {
     int redirected;
 
     if (assuan_sock_set_sockaddr_un (name, addr, &redirected))
       {
         if (errno == ENAMETOOLONG)
           log_error (_("socket name '%s' is too long\n"), name);
         else
           log_error ("error preparing socket '%s': %s\n",
                      name, gpg_strerror (gpg_error_from_syserror ()));
         *name = 0; /* Inhibit removal of the socket by cleanup(). */
         xfree (unaddr);
         agent_exit (2);
       }
     if (redirected)
       {
         *r_redir_name = xstrdup (unaddr->sun_path);
         if (opt.verbose)
           log_info ("redirecting socket '%s' to '%s'\n", name, *r_redir_name);
       }
   }
 
   len = SUN_LEN (unaddr);
   rc = assuan_sock_bind (fd, addr, len);
 
   /* Our error code mapping on W32CE returns EEXIST thus we also test
      for this. */
   if (rc == -1
       && (errno == EADDRINUSE
 #ifdef HAVE_W32_SYSTEM
           || errno == EEXIST
 #endif
           ))
     {
       /* Check whether a gpg-agent is already running.  We do this
          test only if this is the primary socket.  For secondary
          sockets we assume that a test for gpg-agent has already been
          done and reuse the requested socket.  Testing the ssh-socket
          is not possible because at this point, though we know the new
          Assuan socket, the Assuan server and thus the ssh-agent
          server is not yet operational; this would lead to a hang.  */
       if (primary && !check_for_running_agent (1))
         {
-          log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX);
-          log_set_file (NULL);
-          log_error (_("a gpg-agent is already running - "
-                       "not starting a new one\n"));
-          *name = 0; /* Inhibit removal of the socket by cleanup(). */
-          assuan_sock_close (fd);
-          xfree (unaddr);
-          agent_exit (2);
+          if (steal_socket)
+            log_info (N_("trying to steal socket from running %s\n"),
+                      "gpg-agent");
+          else
+            {
+              log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX);
+              log_set_file (NULL);
+              log_error (_("a gpg-agent is already running - "
+                           "not starting a new one\n"));
+              *name = 0; /* Inhibit removal of the socket by cleanup(). */
+              assuan_sock_close (fd);
+              xfree (unaddr);
+              agent_exit (2);
+            }
         }
       gnupg_remove (unaddr->sun_path);
       rc = assuan_sock_bind (fd, addr, len);
     }
   if (rc != -1 && (rc=assuan_sock_get_nonce (addr, len, nonce)))
     log_error (_("error getting nonce for the socket\n"));
   if (rc == -1)
     {
       /* We use gpg_strerror here because it allows us to get strings
          for some W32 socket error codes.  */
       log_error (_("error binding socket to '%s': %s\n"),
                  unaddr->sun_path,
                  gpg_strerror (gpg_error_from_syserror ()));
 
       assuan_sock_close (fd);
       *name = 0; /* Inhibit removal of the socket by cleanup(). */
       xfree (unaddr);
       agent_exit (2);
     }
 
   if (gnupg_chmod (unaddr->sun_path, "-rwx"))
     log_error (_("can't set permissions of '%s': %s\n"),
                unaddr->sun_path, strerror (errno));
 
   if (listen (FD2INT(fd), listen_backlog ) == -1)
     {
       log_error ("listen(fd,%d) failed: %s\n",
                  listen_backlog, strerror (errno));
       *name = 0; /* Inhibit removal of the socket by cleanup(). */
       assuan_sock_close (fd);
       xfree (unaddr);
       agent_exit (2);
     }
 
   if (opt.verbose)
     log_info (_("listening on socket '%s'\n"), unaddr->sun_path);
 
   xfree (unaddr);
   return fd;
 }
 
 
 /* Check that the directory for storing the private keys exists and
    create it if not.  This function won't fail as it is only a
    convenience function and not strictly necessary.  */
 static void
 create_private_keys_directory (const char *home)
 {
   char *fname;
   struct stat statbuf;
 
   fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL);
   if (gnupg_stat (fname, &statbuf) && errno == ENOENT)
     {
       if (gnupg_mkdir (fname, "-rwx"))
         log_error (_("can't create directory '%s': %s\n"),
                    fname, strerror (errno) );
       else if (!opt.quiet)
         log_info (_("directory '%s' created\n"), fname);
 
       if (gnupg_chmod (fname, "-rwx"))
         log_error (_("can't set permissions of '%s': %s\n"),
                    fname, strerror (errno));
     }
   else
     {
       /* The file exists or another error.  Make sure we have sensible
        * permissions.  We enforce rwx for user but keep existing group
        * permissions.  Permissions for other are always cleared.  */
       if (gnupg_chmod (fname, "-rwx...---"))
         log_error (_("can't set permissions of '%s': %s\n"),
                    fname, strerror (errno));
     }
   xfree (fname);
 }
 
 
 /* Create the directory only if the supplied directory name is the
    same as the default one.  This way we avoid to create arbitrary
    directories when a non-default home directory is used.  To cope
    with HOME, we compare only the suffix if we see that the default
    homedir does start with a tilde.  We don't stop here in case of
    problems because other functions will throw an error anyway.*/
 static void
 create_directories (void)
 {
   struct stat statbuf;
   const char *defhome = standard_homedir ();
   char *home;
 
   home = make_filename (gnupg_homedir (), NULL);
   if (gnupg_stat (home, &statbuf))
     {
       if (errno == ENOENT)
         {
           if (
 #ifdef HAVE_W32_SYSTEM
               ( !compare_filenames (home, defhome) )
 #else
               (*defhome == '~'
                 && (strlen (home) >= strlen (defhome+1)
                     && !strcmp (home + strlen(home)
                                 - strlen (defhome+1), defhome+1)))
                || (*defhome != '~' && !strcmp (home, defhome) )
 #endif
                )
             {
               if (gnupg_mkdir (home, "-rwx"))
                 log_error (_("can't create directory '%s': %s\n"),
                            home, strerror (errno) );
               else
                 {
                   if (!opt.quiet)
                     log_info (_("directory '%s' created\n"), home);
                   create_private_keys_directory (home);
                 }
             }
         }
       else
         log_error (_("stat() failed for '%s': %s\n"), home, strerror (errno));
     }
   else if ( !S_ISDIR(statbuf.st_mode))
     {
       log_error (_("can't use '%s' as home directory\n"), home);
     }
   else /* exists and is a directory. */
     {
       create_private_keys_directory (home);
     }
   xfree (home);
 }
 
 
 
 /* This is the worker for the ticker.  It is called every few seconds
    and may only do fast operations. */
 static void
 handle_tick (void)
 {
   static time_t last_minute;
   struct stat statbuf;
 
   if (!last_minute)
     last_minute = time (NULL);
 
   /* If we are running as a child of another process, check whether
      the parent is still alive and shutdown if not. */
 #ifndef HAVE_W32_SYSTEM
   if (parent_pid != (pid_t)(-1))
     {
       if (kill (parent_pid, 0))
         {
           shutdown_pending = 2;
           log_info ("parent process died - shutting down\n");
           log_info ("%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13));
           cleanup ();
           agent_exit (0);
         }
     }
 #endif /*HAVE_W32_SYSTEM*/
 
   /* Code to be run from time to time.  */
 #if CHECK_OWN_SOCKET_INTERVAL > 0
   if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL))
     {
       check_own_socket ();
       last_minute = time (NULL);
     }
 #endif
 
   /* Need to check for expired cache entries.  */
   agent_cache_housekeeping ();
 
   /* Check whether the homedir is still available.  */
   if (!shutdown_pending
       && (!have_homedir_inotify || !reliable_homedir_inotify)
       && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT)
     {
       shutdown_pending = 1;
       log_info ("homedir has been removed - shutting down\n");
     }
 }
 
 
 /* A global function which allows us to call the reload stuff from
    other places too.  This is only used when build for W32.  */
 void
 agent_sighup_action (void)
 {
   log_info ("SIGHUP received - "
             "re-reading configuration and flushing cache\n");
 
   agent_flush_cache (0);
   reread_configuration ();
   agent_reload_trustlist ();
   /* We flush the module name cache so that after installing a
      "pinentry" binary that one can be used in case the
      "pinentry-basic" fallback was in use.  */
   gnupg_module_name_flush_some ();
 
   if (opt.disable_daemon[DAEMON_SCD])
     agent_kill_daemon (DAEMON_SCD);
 }
 
 
 /* A helper function to handle SIGUSR2.  */
 static void
 agent_sigusr2_action (void)
 {
   if (opt.verbose)
     log_info ("SIGUSR2 received - updating card event counter\n");
   /* Nothing to check right now.  We only increment a counter.  */
   bump_card_eventcounter ();
 }
 
 
 #ifndef HAVE_W32_SYSTEM
 /* The signal handler for this program.  It is expected to be run in
    its own thread and not in the context of a signal handler.  */
 static void
 handle_signal (int signo)
 {
   switch (signo)
     {
 #ifndef HAVE_W32_SYSTEM
     case SIGHUP:
       agent_sighup_action ();
       break;
 
     case SIGUSR1:
       log_info ("SIGUSR1 received - printing internal information:\n");
       /* Fixme: We need to see how to integrate pth dumping into our
          logging system.  */
       /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
       agent_query_dump_state ();
       agent_daemon_dump_state ();
       break;
 
     case SIGUSR2:
       agent_sigusr2_action ();
       break;
 
     case SIGTERM:
       if (!shutdown_pending)
         log_info ("SIGTERM received - shutting down ...\n");
       else
         log_info ("SIGTERM received - still %i open connections\n",
 		  active_connections);
       shutdown_pending++;
       if (shutdown_pending > 2)
         {
           log_info ("shutdown forced\n");
           log_info ("%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13));
           cleanup ();
           agent_exit (0);
 	}
       break;
 
     case SIGINT:
       log_info ("SIGINT received - immediate shutdown\n");
       log_info( "%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13));
       cleanup ();
       agent_exit (0);
       break;
 #endif
     default:
       log_info ("signal %d received - no action defined\n", signo);
     }
 }
 #endif
 
 /* Check the nonce on a new connection.  This is a NOP unless we
    are using our Unix domain socket emulation under Windows.  */
 static int
 check_nonce (ctrl_t ctrl, assuan_sock_nonce_t *nonce)
 {
   if (assuan_sock_check_nonce (ctrl->thread_startup.fd, nonce))
     {
       log_info (_("error reading nonce on fd %d: %s\n"),
                 FD2INT(ctrl->thread_startup.fd), strerror (errno));
       assuan_sock_close (ctrl->thread_startup.fd);
       xfree (ctrl);
       return -1;
     }
   else
     return 0;
 }
 
 
 #ifdef HAVE_W32_SYSTEM
 /* The window message processing function for Putty.  Warning: This
    code runs as a native Windows thread.  Use of our own functions
    needs to be bracket with pth_leave/pth_enter. */
 static LRESULT CALLBACK
 putty_message_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
 {
   int ret = 0;
   int w32rc;
   COPYDATASTRUCT *cds;
   const char *mapfile;
   HANDLE maphd;
   PSID mysid = NULL;
   PSID mapsid = NULL;
   void *data = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   ctrl_t ctrl = NULL;
 
   if (msg != WM_COPYDATA)
     {
       return DefWindowProc (hwnd, msg, wparam, lparam);
     }
 
   cds = (COPYDATASTRUCT*)lparam;
   if (cds->dwData != PUTTY_IPC_MAGIC)
     return 0;  /* Ignore data with the wrong magic.  */
   mapfile = cds->lpData;
   if (!cds->cbData || mapfile[cds->cbData - 1])
     return 0;  /* Ignore empty and non-properly terminated strings.  */
 
   if (DBG_IPC)
     {
       npth_protect ();
       log_debug ("ssh map file '%s'", mapfile);
       npth_unprotect ();
     }
 
   maphd = OpenFileMapping (FILE_MAP_ALL_ACCESS, FALSE, mapfile);
   if (DBG_IPC)
     {
       npth_protect ();
       log_debug ("ssh map handle %p\n", maphd);
       npth_unprotect ();
     }
 
   if (!maphd || maphd == INVALID_HANDLE_VALUE)
     return 0;
 
   npth_protect ();
 
   mysid = w32_get_user_sid ();
   if (!mysid)
     {
       log_error ("error getting my sid\n");
       goto leave;
     }
 
   w32rc = GetSecurityInfo (maphd, SE_KERNEL_OBJECT,
                            OWNER_SECURITY_INFORMATION,
                            &mapsid, NULL, NULL, NULL,
                            &psd);
   if (w32rc)
     {
       log_error ("error getting sid of ssh map file: rc=%d", w32rc);
       goto leave;
     }
 
   if (DBG_IPC)
     {
       char *sidstr;
 
       if (!ConvertSidToStringSid (mysid, &sidstr))
         sidstr = NULL;
       log_debug ("          my sid: '%s'", sidstr? sidstr: "[error]");
       LocalFree (sidstr);
       if (!ConvertSidToStringSid (mapsid, &sidstr))
         sidstr = NULL;
       log_debug ("ssh map file sid: '%s'", sidstr? sidstr: "[error]");
       LocalFree (sidstr);
     }
 
   if (!EqualSid (mysid, mapsid))
     {
       log_error ("ssh map file has a non-matching sid\n");
       goto leave;
     }
 
   data = MapViewOfFile (maphd, FILE_MAP_ALL_ACCESS, 0, 0, 0);
   if (DBG_IPC)
     log_debug ("ssh IPC buffer at %p\n", data);
   if (!data)
     goto leave;
 
   /* log_printhex ("request:", data, 20); */
 
   ctrl = xtrycalloc (1, sizeof *ctrl);
   if (!ctrl)
     {
       log_error ("error allocating connection control data: %s\n",
                  strerror (errno) );
       goto leave;
     }
   ctrl->session_env = session_env_new ();
   if (!ctrl->session_env)
     {
       log_error ("error allocating session environment block: %s\n",
                  strerror (errno) );
       goto leave;
     }
 
   agent_init_default_ctrl (ctrl);
   if (!serve_mmapped_ssh_request (ctrl, data, PUTTY_IPC_MAXLEN))
     ret = 1; /* Valid ssh message has been constructed.  */
   agent_deinit_default_ctrl (ctrl);
   /* log_printhex ("  reply:", data, 20); */
 
  leave:
   xfree (ctrl);
   if (data)
     UnmapViewOfFile (data);
   xfree (mapsid);
   if (psd)
     LocalFree (psd);
   xfree (mysid);
   CloseHandle (maphd);
 
   npth_unprotect ();
 
   return ret;
 }
 #endif /*HAVE_W32_SYSTEM*/
 
 
 #ifdef HAVE_W32_SYSTEM
 /* The thread handling Putty's IPC requests.  */
 static void *
 putty_message_thread (void *arg)
 {
   WNDCLASS wndwclass = {0, putty_message_proc, 0, 0,
                         NULL, NULL, NULL, NULL, NULL, "Pageant"};
   HWND hwnd;
   MSG msg;
 
   (void)arg;
 
   if (opt.verbose)
     log_info ("putty message loop thread started\n");
 
   /* The message loop runs as thread independent from our nPth system.
      This also means that we need to make sure that we switch back to
      our system before calling any no-windows function.  */
   npth_unprotect ();
 
   /* First create a window to make sure that a message queue exists
      for this thread.  */
   if (!RegisterClass (&wndwclass))
     {
       npth_protect ();
       log_error ("error registering Pageant window class");
       return NULL;
     }
   hwnd = CreateWindowEx (0, "Pageant", "Pageant", 0,
                          0, 0, 0, 0,
                          HWND_MESSAGE,  /* hWndParent */
                          NULL,          /* hWndMenu   */
                          NULL,          /* hInstance  */
                          NULL);         /* lpParm     */
   if (!hwnd)
     {
       npth_protect ();
       log_error ("error creating Pageant window");
       return NULL;
     }
 
   while (GetMessage(&msg, NULL, 0, 0))
     {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
     }
 
   /* Back to nPth.  */
   npth_protect ();
 
   if (opt.verbose)
     log_info ("putty message loop thread stopped\n");
   return NULL;
 }
 #endif /*HAVE_W32_SYSTEM*/
 
 
 static void *
 do_start_connection_thread (ctrl_t ctrl)
 {
   active_connections++;
   agent_init_default_ctrl (ctrl);
   if (opt.verbose > 1 && !DBG_IPC)
     log_info (_("handler 0x%lx for fd %d started\n"),
               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   start_command_handler (ctrl, GNUPG_INVALID_FD, ctrl->thread_startup.fd);
   if (opt.verbose > 1 && !DBG_IPC)
     log_info (_("handler 0x%lx for fd %d terminated\n"),
               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   agent_deinit_default_ctrl (ctrl);
   xfree (ctrl);
   active_connections--;
   return NULL;
 }
 
 
 /* This is the standard connection thread's main function.  */
 static void *
 start_connection_thread_std (void *arg)
 {
   ctrl_t ctrl = arg;
 
   if (check_nonce (ctrl, &socket_nonce))
     {
       log_error ("handler 0x%lx nonce check FAILED\n",
                  (unsigned long) npth_self());
       return NULL;
     }
 
   return do_start_connection_thread (ctrl);
 }
 
 
 /* This is the extra socket connection thread's main function.  */
 static void *
 start_connection_thread_extra (void *arg)
 {
   ctrl_t ctrl = arg;
 
   if (check_nonce (ctrl, &socket_nonce_extra))
     {
       log_error ("handler 0x%lx nonce check FAILED\n",
                  (unsigned long) npth_self());
       return NULL;
     }
 
   ctrl->restricted = 1;
   return do_start_connection_thread (ctrl);
 }
 
 
 /* This is the browser socket connection thread's main function.  */
 static void *
 start_connection_thread_browser (void *arg)
 {
   ctrl_t ctrl = arg;
 
   if (check_nonce (ctrl, &socket_nonce_browser))
     {
       log_error ("handler 0x%lx nonce check FAILED\n",
                  (unsigned long) npth_self());
       return NULL;
     }
 
   ctrl->restricted = 2;
   return do_start_connection_thread (ctrl);
 }
 
 
 /* This is the ssh connection thread's main function.  */
 static void *
 start_connection_thread_ssh (void *arg)
 {
   ctrl_t ctrl = arg;
 
   if (check_nonce (ctrl, &socket_nonce_ssh))
     return NULL;
 
   active_connections++;
   agent_init_default_ctrl (ctrl);
   if (opt.verbose)
     log_info (_("ssh handler 0x%lx for fd %d started\n"),
               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   start_command_handler_ssh (ctrl, ctrl->thread_startup.fd);
   if (opt.verbose)
     log_info (_("ssh handler 0x%lx for fd %d terminated\n"),
               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
 
   agent_deinit_default_ctrl (ctrl);
   xfree (ctrl);
   active_connections--;
   return NULL;
 }
 
 
 /* Connection handler loop.  Wait for connection requests and spawn a
    thread after accepting a connection.  */
 static void
 handle_connections (gnupg_fd_t listen_fd,
                     gnupg_fd_t listen_fd_extra,
                     gnupg_fd_t listen_fd_browser,
                     gnupg_fd_t listen_fd_ssh)
 {
   gpg_error_t err;
   npth_attr_t tattr;
   struct sockaddr_un paddr;
   socklen_t plen;
   fd_set fdset, read_fdset;
   int ret;
   gnupg_fd_t fd;
   int nfd;
   int saved_errno;
   struct timespec abstime;
   struct timespec curtime;
   struct timespec timeout;
 #ifdef HAVE_W32_SYSTEM
   HANDLE events[2];
   unsigned int events_set;
 #endif
   int sock_inotify_fd = -1;
   int home_inotify_fd = -1;
   struct {
     const char *name;
     void *(*func) (void *arg);
     gnupg_fd_t l_fd;
   } listentbl[] = {
     { "std",     start_connection_thread_std   },
     { "extra",   start_connection_thread_extra },
     { "browser", start_connection_thread_browser },
     { "ssh",    start_connection_thread_ssh   }
   };
 
 
   ret = npth_attr_init(&tattr);
   if (ret)
     log_fatal ("error allocating thread attributes: %s\n",
 	       strerror (ret));
   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
 
 #ifndef HAVE_W32_SYSTEM
   npth_sigev_init ();
   npth_sigev_add (SIGHUP);
   npth_sigev_add (SIGUSR1);
   npth_sigev_add (SIGUSR2);
   npth_sigev_add (SIGINT);
   npth_sigev_add (SIGTERM);
   npth_sigev_fini ();
 #else
 # ifdef HAVE_W32CE_SYSTEM
   /* Use a dummy event. */
   sigs = 0;
   ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
 # else
   events[0] = get_agent_daemon_notify_event ();
   events[1] = INVALID_HANDLE_VALUE;
 # endif
 #endif
 
   if (disable_check_own_socket)
     sock_inotify_fd = -1;
   else if ((err = gnupg_inotify_watch_socket (&sock_inotify_fd, socket_name)))
     {
       if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
         log_info ("error enabling daemon termination by socket removal: %s\n",
                   gpg_strerror (err));
     }
 
   if (disable_check_own_socket)
     home_inotify_fd = -1;
   else if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd,
                                                    gnupg_homedir ())))
     {
       if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
         log_info ("error enabling daemon termination by homedir removal: %s\n",
                   gpg_strerror (err));
     }
   else
     have_homedir_inotify = 1;
 
   /* On Windows we need to fire up a separate thread to listen for
      requests from Putty (an SSH client), so we can replace Putty's
      Pageant (its ssh-agent implementation). */
 #ifdef HAVE_W32_SYSTEM
   if (putty_support)
     {
       npth_t thread;
 
       ret = npth_create (&thread, &tattr, putty_message_thread, NULL);
       if (ret)
         {
           log_error ("error spawning putty message loop: %s\n", strerror (ret));
         }
     }
 #endif /*HAVE_W32_SYSTEM*/
 
   /* Set a flag to tell call-scd.c that it may enable event
      notifications.  */
   opt.sigusr2_enabled = 1;
 
   FD_ZERO (&fdset);
   FD_SET (FD2INT (listen_fd), &fdset);
   nfd = FD2INT (listen_fd);
   if (listen_fd_extra != GNUPG_INVALID_FD)
     {
       FD_SET ( FD2INT(listen_fd_extra), &fdset);
       if (FD2INT (listen_fd_extra) > nfd)
         nfd = FD2INT (listen_fd_extra);
     }
   if (listen_fd_browser != GNUPG_INVALID_FD)
     {
       FD_SET ( FD2INT(listen_fd_browser), &fdset);
       if (FD2INT (listen_fd_browser) > nfd)
         nfd = FD2INT (listen_fd_browser);
     }
   if (listen_fd_ssh != GNUPG_INVALID_FD)
     {
       FD_SET ( FD2INT(listen_fd_ssh), &fdset);
       if (FD2INT (listen_fd_ssh) > nfd)
         nfd = FD2INT (listen_fd_ssh);
     }
   if (sock_inotify_fd != -1)
     {
       FD_SET (sock_inotify_fd, &fdset);
       if (sock_inotify_fd > nfd)
         nfd = sock_inotify_fd;
     }
   if (home_inotify_fd != -1)
     {
       FD_SET (home_inotify_fd, &fdset);
       if (home_inotify_fd > nfd)
         nfd = home_inotify_fd;
     }
 
   listentbl[0].l_fd = listen_fd;
   listentbl[1].l_fd = listen_fd_extra;
   listentbl[2].l_fd = listen_fd_browser;
   listentbl[3].l_fd = listen_fd_ssh;
 
   npth_clock_gettime (&abstime);
   abstime.tv_sec += TIMERTICK_INTERVAL;
 
   for (;;)
     {
       /* Shutdown test.  */
       if (shutdown_pending)
         {
           if (active_connections == 0)
             break; /* ready */
 
           /* Do not accept new connections but keep on running the
            * loop to cope with the timer events.
            *
            * Note that we do not close the listening socket because a
            * client trying to connect to that socket would instead
            * restart a new dirmngr instance - which is unlikely the
            * intention of a shutdown. */
           FD_ZERO (&fdset);
           nfd = -1;
           if (sock_inotify_fd != -1)
             {
               FD_SET (sock_inotify_fd, &fdset);
               nfd = sock_inotify_fd;
             }
           if (home_inotify_fd != -1)
             {
               FD_SET (home_inotify_fd, &fdset);
               if (home_inotify_fd > nfd)
                 nfd = home_inotify_fd;
             }
 	}
 
       /* POSIX says that fd_set should be implemented as a structure,
          thus a simple assignment is fine to copy the entire set.  */
       read_fdset = fdset;
 
       npth_clock_gettime (&curtime);
       if (!(npth_timercmp (&curtime, &abstime, <)))
 	{
 	  /* Timeout.  */
 	  handle_tick ();
 	  npth_clock_gettime (&abstime);
 	  abstime.tv_sec += TIMERTICK_INTERVAL;
 	}
       npth_timersub (&abstime, &curtime, &timeout);
 
 #ifndef HAVE_W32_SYSTEM
       ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
                           npth_sigev_sigmask ());
       saved_errno = errno;
 
       {
         int signo;
         while (npth_sigev_get_pending (&signo))
           handle_signal (signo);
       }
 #else
       ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
                           events, &events_set);
       saved_errno = errno;
 
       /* This is valid even if npth_eselect returns an error.  */
       if (events_set & 1)
 	agent_sigusr2_action ();
 #endif
 
       if (ret == -1 && saved_errno != EINTR)
 	{
           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
                      strerror (saved_errno));
           gnupg_sleep (1);
           continue;
 	}
       if (ret <= 0)
 	/* Interrupt or timeout.  Will be handled when calculating the
 	   next timeout.  */
 	continue;
 
       /* The inotify fds are set even when a shutdown is pending (see
        * above).  So we must handle them in any case.  To avoid that
        * they trigger a second time we close them immediately.  */
       if (sock_inotify_fd != -1
           && FD_ISSET (sock_inotify_fd, &read_fdset)
           && gnupg_inotify_has_name (sock_inotify_fd, GPG_AGENT_SOCK_NAME))
         {
           shutdown_pending = 1;
           close (sock_inotify_fd);
           sock_inotify_fd = -1;
           log_info ("socket file has been removed - shutting down\n");
         }
 
       if (home_inotify_fd != -1
           && FD_ISSET (home_inotify_fd, &read_fdset))
         {
           shutdown_pending = 1;
           close (home_inotify_fd);
           home_inotify_fd = -1;
           log_info ("homedir has been removed - shutting down\n");
         }
 
       if (!shutdown_pending)
         {
           int idx;
           ctrl_t ctrl;
           npth_t thread;
 
           for (idx=0; idx < DIM(listentbl); idx++)
             {
               if (listentbl[idx].l_fd == GNUPG_INVALID_FD)
                 continue;
               if (!FD_ISSET (FD2INT (listentbl[idx].l_fd), &read_fdset))
                 continue;
 
               plen = sizeof paddr;
               fd = INT2FD (npth_accept (FD2INT(listentbl[idx].l_fd),
                                         (struct sockaddr *)&paddr, &plen));
               if (fd == GNUPG_INVALID_FD)
                 {
                   log_error ("accept failed for %s: %s\n",
                              listentbl[idx].name, strerror (errno));
                 }
               else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)))
                 {
                   log_error ("error allocating connection data for %s: %s\n",
                              listentbl[idx].name, strerror (errno) );
                   assuan_sock_close (fd);
                 }
               else if ( !(ctrl->session_env = session_env_new ()))
                 {
                   log_error ("error allocating session env block for %s: %s\n",
                              listentbl[idx].name, strerror (errno) );
                   xfree (ctrl);
                   assuan_sock_close (fd);
                 }
               else
                 {
                   ctrl->thread_startup.fd = fd;
                   ret = npth_create (&thread, &tattr,
                                      listentbl[idx].func, ctrl);
                   if (ret)
                     {
                       log_error ("error spawning connection handler for %s:"
                                  " %s\n", listentbl[idx].name, strerror (ret));
                       assuan_sock_close (fd);
                       xfree (ctrl);
                     }
                 }
             }
         }
     }
 
   if (sock_inotify_fd != -1)
     close (sock_inotify_fd);
   if (home_inotify_fd != -1)
     close (home_inotify_fd);
   cleanup ();
   log_info (_("%s %s stopped\n"), gpgrt_strusage(11), gpgrt_strusage(13));
   npth_attr_destroy (&tattr);
 }
 
 
 
 /* Helper for check_own_socket.  */
 static gpg_error_t
 check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length)
 {
   membuf_t *mb = opaque;
   put_membuf (mb, buffer, length);
   return 0;
 }
 
 
 /* The thread running the actual check.  We need to run this in a
    separate thread so that check_own_thread can be called from the
    timer tick.  */
 static void *
 check_own_socket_thread (void *arg)
 {
   int rc;
   char *sockname = arg;
   assuan_context_t ctx = NULL;
   membuf_t mb;
   char *buffer;
 
   check_own_socket_running++;
 
   rc = assuan_new (&ctx);
   if (rc)
     {
       log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
       goto leave;
     }
   assuan_set_flag (ctx, ASSUAN_NO_LOGGING, 1);
 
   rc = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0);
   if (rc)
     {
       log_error ("can't connect my own socket: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
   init_membuf (&mb, 100);
   rc = assuan_transact (ctx, "GETINFO pid", check_own_socket_pid_cb, &mb,
                         NULL, NULL, NULL, NULL);
   put_membuf (&mb, "", 1);
   buffer = get_membuf (&mb, NULL);
   if (rc || !buffer)
     {
       log_error ("sending command \"%s\" to my own socket failed: %s\n",
                  "GETINFO pid", gpg_strerror (rc));
       rc = 1;
     }
   else if ( (pid_t)strtoul (buffer, NULL, 10) != getpid ())
     {
       log_error ("socket is now serviced by another server\n");
       rc = 1;
     }
   else if (opt.verbose > 1)
     log_error ("socket is still served by this server\n");
 
   xfree (buffer);
 
  leave:
   xfree (sockname);
   if (ctx)
     assuan_release (ctx);
   if (rc)
     {
       /* We may not remove the socket as it is now in use by another
          server. */
       inhibit_socket_removal = 1;
       shutdown_pending = 2;
       log_info ("this process is useless - shutting down\n");
     }
   check_own_socket_running--;
   return NULL;
 }
 
 
 /* Check whether we are still listening on our own socket.  In case
    another gpg-agent process started after us has taken ownership of
    our socket, we would linger around without any real task.  Thus we
    better check once in a while whether we are really needed.  */
 static void
 check_own_socket (void)
 {
   char *sockname;
   npth_t thread;
   npth_attr_t tattr;
   int err;
 
   if (disable_check_own_socket)
     return;
 
   if (check_own_socket_running || shutdown_pending)
     return;  /* Still running or already shutting down.  */
 
   sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
   if (!sockname)
     return; /* Out of memory.  */
 
   err = npth_attr_init (&tattr);
   if (err)
     {
       xfree (sockname);
       return;
     }
   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
   err = npth_create (&thread, &tattr, check_own_socket_thread, sockname);
   if (err)
     log_error ("error spawning check_own_socket_thread: %s\n", strerror (err));
   npth_attr_destroy (&tattr);
 }
 
 
 
 /* Figure out whether an agent is available and running. Prints an
    error if not.  If SILENT is true, no messages are printed.
    Returns 0 if the agent is running. */
 static int
 check_for_running_agent (int silent)
 {
   gpg_error_t err;
   char *sockname;
   assuan_context_t ctx = NULL;
 
   sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
   if (!sockname)
     return gpg_error_from_syserror ();
 
   err = assuan_new (&ctx);
   if (!err)
     err = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0);
   xfree (sockname);
   if (err)
     {
       if (!silent)
         log_error (_("no gpg-agent running in this session\n"));
 
       if (ctx)
 	assuan_release (ctx);
       return -1;
     }
 
   if (!opt.quiet && !silent)
     log_info ("gpg-agent running and available\n");
 
   assuan_release (ctx);
   return 0;
 }
diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
index 51a586e20..78ca4b215 100644
--- a/dirmngr/dirmngr.c
+++ b/dirmngr/dirmngr.c
@@ -1,2507 +1,2518 @@
 /* dirmngr.c - Keyserver and X.509 LDAP access
  * Copyright (C) 2002 Klarälvdalens Datakonsult AB
  * Copyright (C) 2003-2004, 2006-2007, 2008, 2010-2011, 2020 g10 Code GmbH
  * Copyright (C) 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
 #include <config.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <stdarg.h>
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
 #include <time.h>
 #include <fcntl.h>
 #ifndef HAVE_W32_SYSTEM
 #include <sys/socket.h>
 #include <sys/un.h>
 #endif
 #include <sys/stat.h>
 #include <unistd.h>
 #ifdef HAVE_SIGNAL_H
 # include <signal.h>
 #endif
 #ifdef HAVE_INOTIFY_INIT
 # include <sys/inotify.h>
 #endif /*HAVE_INOTIFY_INIT*/
 #include <npth.h>
 
 #include "dirmngr-err.h"
 
 #if  HTTP_USE_NTBTLS
 # include <ntbtls.h>
 #elif HTTP_USE_GNUTLS
 # include <gnutls/gnutls.h>
 #endif /*HTTP_USE_GNUTLS*/
 
 
 #define INCLUDED_BY_MAIN_MODULE 1
 #define GNUPG_COMMON_NEED_AFLOCAL
 #include "dirmngr.h"
 
 #include <assuan.h>
 
 #include "certcache.h"
 #include "crlcache.h"
 #include "crlfetch.h"
 #include "misc.h"
 #if USE_LDAP
 # include "ldapserver.h"
 #endif
 #include "../common/asshelp.h"
 #if USE_LDAP
 # include "ldap-wrapper.h"
 #endif
 #include "../common/comopt.h"
 #include "../common/init.h"
 #include "../common/gc-opt-flags.h"
 #include "dns-stuff.h"
 #include "http-common.h"
 
 #ifndef ENAMETOOLONG
 # define ENAMETOOLONG EINVAL
 #endif
 
 
 enum cmd_and_opt_values {
   aNull = 0,
   oCsh		  = 'c',
   oQuiet	  = 'q',
   oSh		  = 's',
   oVerbose	  = 'v',
   oNoVerbose = 500,
 
   aServer,
   aDaemon,
   aSupervised,
   aListCRLs,
   aLoadCRL,
   aFetchCRL,
   aShutdown,
   aFlush,
   aGPGConfList,
   aGPGConfTest,
   aGPGConfVersions,
 
   oOptions,
   oDebug,
   oDebugAll,
   oDebugWait,
   oDebugLevel,
   oGnutlsDebug,
   oNoGreeting,
   oNoOptions,
   oHomedir,
   oNoDetach,
   oLogFile,
   oBatch,
   oDisableHTTP,
   oDisableLDAP,
   oDisableIPv4,
   oDisableIPv6,
   oIgnoreLDAPDP,
   oIgnoreHTTPDP,
   oIgnoreOCSPSvcUrl,
   oHonorHTTPProxy,
   oHTTPProxy,
   oLDAPProxy,
   oOnlyLDAPProxy,
   oLDAPServer,
   oLDAPFile,
   oLDAPTimeout,
   oLDAPAddServers,
   oOCSPResponder,
   oOCSPSigner,
   oOCSPMaxClockSkew,
   oOCSPMaxPeriod,
   oOCSPCurrentPeriod,
   oMaxReplies,
   oHkpCaCert,
   oFakedSystemTime,
   oForce,
   oAllowOCSP,
   oAllowVersionCheck,
+  oStealSocket,
   oSocketName,
   oLDAPWrapperProgram,
   oHTTPWrapperProgram,
   oIgnoreCert,
   oIgnoreCertExtension,
   oUseTor,
   oNoUseTor,
   oKeyServer,
   oNameServer,
   oDisableCheckOwnSocket,
   oStandardResolver,
   oRecursiveResolver,
   oResolverTimeout,
   oConnectTimeout,
   oConnectQuickTimeout,
   oListenBacklog,
   aTest
 };
 
 
 
 static gpgrt_opt_t opts[] = {
 
   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
   ARGPARSE_c (aGPGConfVersions, "gpgconf-versions", "@"),
 
   ARGPARSE_group (300, N_("@Commands:\n ")),
 
   ARGPARSE_c (aServer,   "server",  N_("run in server mode (foreground)") ),
   ARGPARSE_c (aDaemon,   "daemon",  N_("run in daemon mode (background)") ),
 #ifndef HAVE_W32_SYSTEM
   ARGPARSE_c (aSupervised,  "supervised", N_("run in supervised mode")),
 #endif
   ARGPARSE_c (aListCRLs, "list-crls", N_("list the contents of the CRL cache")),
   ARGPARSE_c (aLoadCRL,  "load-crl", N_("|FILE|load CRL from FILE into cache")),
   ARGPARSE_c (aFetchCRL, "fetch-crl", N_("|URL|fetch a CRL from URL")),
   ARGPARSE_c (aShutdown, "shutdown",  N_("shutdown the dirmngr")),
   ARGPARSE_c (aFlush,    "flush",     N_("flush the cache")),
 
 
   ARGPARSE_header (NULL, N_("Options used for startup")),
 
   ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
   ARGPARSE_s_n (oSh,       "sh",        N_("sh-style command output")),
   ARGPARSE_s_n (oCsh,      "csh",       N_("csh-style command output")),
+  ARGPARSE_s_n (oStealSocket, "steal-socket", "@"),
   ARGPARSE_s_s (oHomedir, "homedir", "@"),
   ARGPARSE_conffile (oOptions,  "options", N_("|FILE|read options from FILE")),
   ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
 
 
   ARGPARSE_header ("Monitor", N_("Options controlling the diagnostic output")),
 
   ARGPARSE_s_n (oVerbose,  "verbose",   N_("verbose")),
   ARGPARSE_s_n (oQuiet,    "quiet",     N_("be somewhat more quiet")),
   ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
   ARGPARSE_s_s (oDebugLevel, "debug-level",
                 N_("|LEVEL|set the debugging level to LEVEL")),
   ARGPARSE_s_s (oDebug,    "debug", "@"),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
   ARGPARSE_s_i (oGnutlsDebug, "gnutls-debug", "@"),
   ARGPARSE_s_i (oGnutlsDebug, "tls-debug", "@"),
   ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
   ARGPARSE_s_s (oLogFile,  "log-file",
                 N_("|FILE|write server mode logs to FILE")),
 
 
   ARGPARSE_header ("Configuration",
                    N_("Options controlling the configuration")),
 
   ARGPARSE_s_n (oAllowVersionCheck, "allow-version-check",
                 N_("allow online software version check")),
   ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
   ARGPARSE_s_i (oMaxReplies, "max-replies",
                 N_("|N|do not return more than N items in one query")),
   ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
   ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
   ARGPARSE_s_s (oIgnoreCert,"ignore-cert", "@"),
   ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"),
 
 
   ARGPARSE_header ("Network", N_("Network related options")),
 
   ARGPARSE_s_n (oUseTor, "use-tor", N_("route all network traffic via Tor")),
   ARGPARSE_s_n (oNoUseTor, "no-use-tor", "@"),
   ARGPARSE_s_n (oDisableIPv4, "disable-ipv4", "@"),
   ARGPARSE_s_n (oDisableIPv6, "disable-ipv6", "@"),
   ARGPARSE_s_n (oStandardResolver, "standard-resolver", "@"),
   ARGPARSE_s_n (oRecursiveResolver, "recursive-resolver", "@"),
   ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"),
   ARGPARSE_s_s (oNameServer, "nameserver", "@"),
   ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"),
   ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"),
 
 
   ARGPARSE_header ("Keyserver", N_("Configuration for Keyservers")),
 
   ARGPARSE_s_s (oKeyServer, "keyserver",
                 N_("|URL|use keyserver at URL")),
   ARGPARSE_s_s (oHkpCaCert, "hkp-cacert",
                 N_("|FILE|use the CA certificates in FILE for HKP over TLS")),
 
   ARGPARSE_header ("HTTP", N_("Configuration for HTTP servers")),
 
   ARGPARSE_s_n (oDisableHTTP, "disable-http", N_("inhibit the use of HTTP")),
   ARGPARSE_s_n (oIgnoreHTTPDP,"ignore-http-dp",
                 N_("ignore HTTP CRL distribution points")),
   ARGPARSE_s_s (oHTTPProxy,  "http-proxy",
                 N_("|URL|redirect all HTTP requests to URL")),
   ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy",
                 N_("use system's HTTP proxy setting")),
   ARGPARSE_s_s (oLDAPWrapperProgram, "ldap-wrapper-program", "@"),
 
 
   ARGPARSE_header ("LDAP", N_("Configuration of LDAP servers to use")),
 
   ARGPARSE_s_n (oDisableLDAP, "disable-ldap", N_("inhibit the use of LDAP")),
   ARGPARSE_s_n (oIgnoreLDAPDP,"ignore-ldap-dp",
                 N_("ignore LDAP CRL distribution points")),
   ARGPARSE_s_s (oLDAPProxy,  "ldap-proxy",
                 N_("|HOST|use HOST for LDAP queries")),
   ARGPARSE_s_n (oOnlyLDAPProxy, "only-ldap-proxy",
                 N_("do not use fallback hosts with --ldap-proxy")),
   ARGPARSE_s_s (oLDAPServer, "ldapserver",
                 N_("|SPEC|use this keyserver to lookup keys")),
   ARGPARSE_s_s (oLDAPFile, "ldapserverlist-file",
                 N_("|FILE|read LDAP server list from FILE")),
   ARGPARSE_s_n (oLDAPAddServers, "add-servers",
                 N_("add new servers discovered in CRL distribution"
                    " points to serverlist")),
   ARGPARSE_s_i (oLDAPTimeout, "ldaptimeout",
                 N_("|N|set LDAP timeout to N seconds")),
 
 
   ARGPARSE_header ("OCSP", N_("Configuration for OCSP")),
 
   ARGPARSE_s_n (oAllowOCSP, "allow-ocsp", N_("allow sending OCSP requests")),
   ARGPARSE_s_n (oIgnoreOCSPSvcUrl, "ignore-ocsp-service-url",
                 N_("ignore certificate contained OCSP service URLs")),
   ARGPARSE_s_s (oOCSPResponder, "ocsp-responder",
                 N_("|URL|use OCSP responder at URL")),
   ARGPARSE_s_s (oOCSPSigner, "ocsp-signer",
                 N_("|FPR|OCSP response signed by FPR")),
   ARGPARSE_s_i (oOCSPMaxClockSkew, "ocsp-max-clock-skew", "@"),
   ARGPARSE_s_i (oOCSPMaxPeriod,    "ocsp-max-period", "@"),
   ARGPARSE_s_i (oOCSPCurrentPeriod, "ocsp-current-period", "@"),
 
 
   ARGPARSE_header (NULL, N_("Other options")),
 
   ARGPARSE_s_n (oForce,    "force",    N_("force loading of outdated CRLs")),
   ARGPARSE_s_s (oSocketName, "socket-name", "@"),  /* Only for debugging.  */
 
 
   ARGPARSE_header (NULL, ""),  /* Stop the header group.  */
 
   /* Not yet used options.  */
   ARGPARSE_s_n (oBatch,    "batch",       "@"),
   ARGPARSE_s_s (oHTTPWrapperProgram, "http-wrapper-program", "@"),
 
 
   ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
                          "of all commands and options)\n")),
 
   ARGPARSE_end ()
 };
 
 /* The list of supported debug flags.  */
 static struct debug_flags_s debug_flags [] =
   {
     { DBG_X509_VALUE   , "x509"    },
     { DBG_CRYPTO_VALUE , "crypto"  },
     { DBG_MEMORY_VALUE , "memory"  },
     { DBG_CACHE_VALUE  , "cache"   },
     { DBG_MEMSTAT_VALUE, "memstat" },
     { DBG_HASHING_VALUE, "hashing" },
     { DBG_IPC_VALUE    , "ipc"     },
     { DBG_DNS_VALUE    , "dns"     },
     { DBG_NETWORK_VALUE, "network" },
     { DBG_LOOKUP_VALUE , "lookup"  },
     { DBG_EXTPROG_VALUE, "extprog" },
     { 77, NULL } /* 77 := Do not exit on "help" or "?".  */
   };
 
 #define DEFAULT_MAX_REPLIES 10
 #define DEFAULT_LDAP_TIMEOUT 15  /* seconds */
 
 #define DEFAULT_CONNECT_TIMEOUT       (15*1000)  /* 15 seconds */
 #define DEFAULT_CONNECT_QUICK_TIMEOUT ( 2*1000)  /*  2 seconds */
 
 /* For the cleanup handler we need to keep track of the socket's name.  */
 static const char *socket_name;
 /* If the socket has been redirected, this is the name of the
    redirected socket..  */
 static const char *redir_socket_name;
 
 /* We need to keep track of the server's nonces (these are dummies for
    POSIX systems). */
 static assuan_sock_nonce_t socket_nonce;
 
 /* Value for the listen() backlog argument.
  * Change at runtime with --listen-backlog.  */
 static int listen_backlog = 64;
 
 /* Only if this flag has been set will we remove the socket file.  */
 static int cleanup_socket;
 
 /* Keep track of the current log file so that we can avoid updating
    the log file after a SIGHUP if it didn't changed. Malloced. */
 static char *current_logfile;
 
 /* Helper to implement --debug-level. */
 static const char *debug_level;
 
 /* Helper to set the NTBTLS or GNUTLS log level.  */
 static int opt_gnutls_debug = -1;
 
 /* Flag indicating that a shutdown has been requested.  */
 static volatile int shutdown_pending;
 
 /* Flags to indicate that we shall not watch our own socket. */
 static int disable_check_own_socket;
 
+/* Flag indicating to start the daemon even if one already runs.  */
+static int steal_socket;
+
+
 /* Flag to control the Tor mode.  */
 static enum
   { TOR_MODE_AUTO = 0,  /* Switch to NO or YES         */
     TOR_MODE_NEVER,     /* Never use Tor.              */
     TOR_MODE_NO,        /* Do not use Tor              */
     TOR_MODE_YES,       /* Use Tor                     */
     TOR_MODE_FORCE      /* Force using Tor             */
   } tor_mode;
 
 
 /* Counter for the active connections.  */
 static int active_connections;
 
 /* This flag is set by any network access and used by the housekeeping
  * thread to run background network tasks.  */
 static int network_activity_seen;
 
 /* A list of filenames registered with --hkp-cacert.  */
 static strlist_t hkp_cacert_filenames;
 
 /* A flag used to clear the list of ldapservers iff --ldapserver is
  * given on the command line or one of the conf files. In this case we
  * want to clear all old specifications through the legacy
  * dirmngr_ldapservers.conf. */
 static int ldapserver_list_needs_reset;
 
 /* The timer tick used for housekeeping stuff.  The second constant is used when a shutdown is pending.  */
 #define TIMERTICK_INTERVAL           (60)
 #define TIMERTICK_INTERVAL_SHUTDOWN  (4)
 
 /* How oft to run the housekeeping.  */
 #define HOUSEKEEPING_INTERVAL      (600)
 
 
 /* This union is used to avoid compiler warnings in case a pointer is
    64 bit and an int 32 bit.  We store an integer in a pointer and get
    it back later (npth_getspecific et al.).  */
 union int_and_ptr_u
 {
   int  aint;
   assuan_fd_t afd;
   void *aptr;
 };
 
 
 
 /* The key used to store the current file descriptor in the thread
    local storage.  We use this in conjunction with the
    log_set_pid_suffix_cb feature.  */
 #ifndef HAVE_W32_SYSTEM
 static npth_key_t my_tlskey_current_fd;
 #endif
 
 /* Prototypes. */
 static void cleanup (void);
 #if USE_LDAP
 static ldap_server_t parse_ldapserver_file (const char* filename, int ienoent);
 #endif /*USE_LDAP*/
 static fingerprint_list_t parse_fingerprint_item (const char *string,
                                                   const  char *optionname,
                                                   int want_binary);
 static void netactivity_action (void);
 static void handle_connections (assuan_fd_t listen_fd);
 static void gpgconf_versions (void);
 
 
 /* NPth wrapper function definitions. */
 ASSUAN_SYSTEM_NPTH_IMPL;
 
 static const char *
 my_strusage( int level )
 {
   const char *p;
   switch ( level )
     {
     case  9: p = "GPL-3.0-or-later"; break;
     case 11: p = "@DIRMNGR@ (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
     case 17: p = PRINTABLE_OS_NAME; break;
       /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug
          reporting address.  This is so that we can change the
          reporting address without breaking the translations.  */
     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
     case 49: p = PACKAGE_BUGREPORT; break;
     case 1:
     case 40: p = _("Usage: @DIRMNGR@ [options] (-h for help)");
       break;
     case 41: p = _("Syntax: @DIRMNGR@ [options] [command [args]]\n"
                    "Keyserver, CRL, and OCSP access for @GNUPG@\n");
       break;
 
     default: p = NULL;
     }
   return p;
 }
 
 
 /* Callback from libksba to hash a provided buffer.  Our current
    implementation does only allow SHA-1 for hashing. This may be
    extended by mapping the name, testing for algorithm availability
    and adjust the length checks accordingly. */
 static gpg_error_t
 my_ksba_hash_buffer (void *arg, const char *oid,
                      const void *buffer, size_t length, size_t resultsize,
                      unsigned char *result, size_t *resultlen)
 {
   (void)arg;
 
   if (oid && strcmp (oid, "1.3.14.3.2.26"))
     return gpg_error (GPG_ERR_NOT_SUPPORTED);
   if (resultsize < 20)
     return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
   gcry_md_hash_buffer (2, result, buffer, length);
   *resultlen = 20;
   return 0;
 }
 
 
 /* GNUTLS log function callback.  */
 #ifdef HTTP_USE_GNUTLS
 static void
 my_gnutls_log (int level, const char *text)
 {
   int n;
 
   n = strlen (text);
   while (n && text[n-1] == '\n')
     n--;
 
   log_debug ("gnutls:L%d: %.*s\n", level, n, text);
 }
 #endif /*HTTP_USE_GNUTLS*/
 
 /* Setup the debugging.  With a LEVEL of NULL only the active debug
    flags are propagated to the subsystems.  With LEVEL set, a specific
    set of debug flags is set; thus overriding all flags already
    set. */
 static void
 set_debug (void)
 {
   int numok = (debug_level && digitp (debug_level));
   int numlvl = numok? atoi (debug_level) : 0;
 
   if (!debug_level)
     ;
   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
     opt.debug = 0;
   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
     opt.debug = DBG_IPC_VALUE;
   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
     opt.debug = (DBG_IPC_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE);
   else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
     opt.debug = (DBG_IPC_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE
                  |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE);
   else if (!strcmp (debug_level, "guru") || numok)
     {
       opt.debug = ~0;
       /* Unless the "guru" string has been used we don't want to allow
          hashing debugging.  The rationale is that people tend to
          select the highest debug value and would then clutter their
          disk with debug files which may reveal confidential data.  */
       if (numok)
         opt.debug &= ~(DBG_HASHING_VALUE);
     }
   else
     {
       log_error (_("invalid debug-level '%s' given\n"), debug_level);
       log_info (_("valid debug levels are: %s\n"),
                 "none, basic, advanced, expert, guru");
       opt.debug = 0; /* Reset debugging, so that prior debug
                         statements won't have an undesired effect. */
     }
 
 
   if (opt.debug && !opt.verbose)
     {
       opt.verbose = 1;
       gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
     }
   if (opt.debug && opt.quiet)
     opt.quiet = 0;
 
   if (opt.debug & DBG_CRYPTO_VALUE )
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
 
 #if HTTP_USE_NTBTLS
   if (opt_gnutls_debug >= 0)
     {
       ntbtls_set_debug (opt_gnutls_debug, NULL, NULL);
     }
 #elif HTTP_USE_GNUTLS
   if (opt_gnutls_debug >= 0)
     {
       gnutls_global_set_log_function (my_gnutls_log);
       gnutls_global_set_log_level (opt_gnutls_debug);
     }
 #endif /*HTTP_USE_GNUTLS*/
 
   if (opt.debug)
     parse_debug_flag (NULL, &opt.debug, debug_flags);
 }
 
 
 static void
 set_tor_mode (void)
 {
   if (dirmngr_use_tor ())
     {
       /* Enable Tor mode and when called again force a new circuit
        * (e.g. on SIGHUP).  */
       enable_dns_tormode (1);
       if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
         {
           log_error ("error enabling Tor mode: %s\n", strerror (errno));
           log_info ("(is your Libassuan recent enough?)\n");
         }
     }
   else
     disable_dns_tormode ();
 }
 
 
 /* Return true if Tor shall be used.  */
 int
 dirmngr_use_tor (void)
 {
   if (tor_mode == TOR_MODE_AUTO)
     {
       /* Figure out whether Tor is running.  */
       assuan_fd_t sock;
 
       sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
       if (sock == ASSUAN_INVALID_FD)
         tor_mode = TOR_MODE_NO;
       else
         {
           tor_mode = TOR_MODE_YES;
           assuan_sock_close (sock);
         }
     }
 
   if (tor_mode == TOR_MODE_FORCE)
     return 2; /* Use Tor (using 2 to indicate force mode) */
   else if (tor_mode == TOR_MODE_YES)
     return 1; /* Use Tor */
   else
     return 0; /* Do not use Tor.  */
 }
 
 
 static void
 wrong_args (const char *text)
 {
   es_fprintf (es_stderr, _("usage: %s [options] "), DIRMNGR_NAME);
   es_fputs (text, es_stderr);
   es_putc ('\n', es_stderr);
   dirmngr_exit (2);
 }
 
 
 /* Helper to stop the reaper thread for the ldap wrapper.  */
 static void
 shutdown_reaper (void)
 {
 #if USE_LDAP
   ldap_wrapper_wait_connections ();
 #endif
 }
 
 
 /* Handle options which are allowed to be reset after program start.
    Return true if the current option in PARGS could be handled and
    false if not.  As a special feature, passing a value of NULL for
    PARGS, resets the options to the default.  REREAD should be set
    true if it is not the initial option parsing. */
 static int
 parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
 {
   if (!pargs)
     { /* Reset mode. */
       opt.quiet = 0;
       opt.verbose = 0;
       opt.debug = 0;
       opt.ldap_wrapper_program = NULL;
       opt.disable_http = 0;
       opt.disable_ldap = 0;
       opt.honor_http_proxy = 0;
       opt.http_proxy = NULL;
       opt.ldap_proxy = NULL;
       opt.only_ldap_proxy = 0;
       opt.ignore_http_dp = 0;
       opt.ignore_ldap_dp = 0;
       opt.ignore_ocsp_service_url = 0;
       opt.allow_ocsp = 0;
       opt.allow_version_check = 0;
       opt.ocsp_responder = NULL;
       opt.ocsp_max_clock_skew = 10 * 60;      /* 10 minutes.  */
       opt.ocsp_max_period = 90 * 86400;       /* 90 days.  */
       opt.ocsp_current_period = 3 * 60 * 60;  /* 3 hours. */
       opt.max_replies = DEFAULT_MAX_REPLIES;
       while (opt.ocsp_signer)
         {
           fingerprint_list_t tmp = opt.ocsp_signer->next;
           xfree (opt.ocsp_signer);
           opt.ocsp_signer = tmp;
         }
       while (opt.ignored_certs)
         {
           fingerprint_list_t tmp = opt.ignored_certs->next;
           xfree (opt.ignored_certs);
           opt.ignored_certs = tmp;
         }
       FREE_STRLIST (opt.ignored_cert_extensions);
       http_register_tls_ca (NULL);
       FREE_STRLIST (hkp_cacert_filenames);
       FREE_STRLIST (opt.keyserver);
       /* Note: We do not allow resetting of TOR_MODE_FORCE at runtime.  */
       if (tor_mode != TOR_MODE_FORCE)
         tor_mode = TOR_MODE_AUTO;
       disable_check_own_socket = 0;
       enable_standard_resolver (0);
       set_dns_timeout (0);
       opt.connect_timeout = 0;
       opt.connect_quick_timeout = 0;
       opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT;
       ldapserver_list_needs_reset = 1;
       return 1;
     }
 
   switch (pargs->r_opt)
     {
     case oQuiet:   opt.quiet = 1; break;
     case oVerbose: opt.verbose++; break;
     case oDebug:
       parse_debug_flag (pargs->r.ret_str, &opt.debug, debug_flags);
       break;
     case oDebugAll: opt.debug = ~0; break;
     case oDebugLevel: debug_level = pargs->r.ret_str; break;
     case oGnutlsDebug: opt_gnutls_debug = pargs->r.ret_int; break;
 
     case oLogFile:
       if (!reread)
         return 0; /* Not handled. */
       if (!current_logfile || !pargs->r.ret_str
           || strcmp (current_logfile, pargs->r.ret_str))
         {
           log_set_file (pargs->r.ret_str);
           xfree (current_logfile);
           current_logfile = xtrystrdup (pargs->r.ret_str);
         }
       break;
 
     case oDisableCheckOwnSocket: disable_check_own_socket = 1; break;
 
     case oLDAPWrapperProgram:
       opt.ldap_wrapper_program = pargs->r.ret_str;
       break;
     case oHTTPWrapperProgram:
       opt.http_wrapper_program = pargs->r.ret_str;
       break;
 
     case oDisableHTTP: opt.disable_http = 1; break;
     case oDisableLDAP: opt.disable_ldap = 1; break;
     case oDisableIPv4: opt.disable_ipv4 = 1; break;
     case oDisableIPv6: opt.disable_ipv6 = 1; break;
     case oHonorHTTPProxy: opt.honor_http_proxy = 1; break;
     case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break;
     case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break;
     case oOnlyLDAPProxy: opt.only_ldap_proxy = 1; break;
     case oIgnoreHTTPDP: opt.ignore_http_dp = 1; break;
     case oIgnoreLDAPDP: opt.ignore_ldap_dp = 1; break;
     case oIgnoreOCSPSvcUrl: opt.ignore_ocsp_service_url = 1; break;
 
     case oAllowOCSP: opt.allow_ocsp = 1; break;
     case oAllowVersionCheck: opt.allow_version_check = 1; break;
     case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
     case oOCSPSigner:
       opt.ocsp_signer = parse_fingerprint_item (pargs->r.ret_str,
                                                 "--ocsp-signer", 0);
       break;
     case oOCSPMaxClockSkew: opt.ocsp_max_clock_skew = pargs->r.ret_int; break;
     case oOCSPMaxPeriod: opt.ocsp_max_period = pargs->r.ret_int; break;
     case oOCSPCurrentPeriod: opt.ocsp_current_period = pargs->r.ret_int; break;
 
     case oMaxReplies: opt.max_replies = pargs->r.ret_int; break;
 
     case oHkpCaCert:
       {
         /* We need to register the filenames with gnutls (http.c) and
          * also for our own cert cache.  */
         char *tmpname;
 
         /* Do tilde expansion and make path absolute.  */
         tmpname = make_absfilename (pargs->r.ret_str, NULL);
         http_register_tls_ca (tmpname);
         add_to_strlist (&hkp_cacert_filenames, pargs->r.ret_str);
         xfree (tmpname);
       }
       break;
 
     case oIgnoreCert:
       {
         fingerprint_list_t item, r;
         item = parse_fingerprint_item (pargs->r.ret_str, "--ignore-cert", 20);
         if (item)
           {  /* Append  */
             if (!opt.ignored_certs)
               opt.ignored_certs = item;
             else
               {
                 for (r = opt.ignored_certs; r->next; r = r->next)
                   ;
                 r->next = item;
               }
           }
       }
       break;
 
     case oIgnoreCertExtension:
       add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
       break;
 
     case oUseTor:
       tor_mode = TOR_MODE_FORCE;
       break;
     case oNoUseTor:
       if (tor_mode != TOR_MODE_FORCE)
         tor_mode = TOR_MODE_NEVER;
       break;
 
     case oStandardResolver: enable_standard_resolver (1); break;
     case oRecursiveResolver: enable_recursive_resolver (1); break;
 
     case oLDAPServer:
 #if USE_LDAP
       {
         ldap_server_t server;
         char *p;
 
         p = pargs->r.ret_str;
         if (!strncmp (p, "ldap:", 5) && !(p[5] == '/' && p[6] == '/'))
           p += 5;
 
         server = ldapserver_parse_one (p, NULL, 0);
         if (server)
           {
             if (ldapserver_list_needs_reset)
               {
                 ldapserver_list_needs_reset = 0;
                 ldapserver_list_free (opt.ldapservers);
                 opt.ldapservers = NULL;
               }
             server->next = opt.ldapservers;
             opt.ldapservers = server;
           }
       }
 #endif
       break;
 
     case oKeyServer:
       if (*pargs->r.ret_str)
         add_to_strlist (&opt.keyserver, pargs->r.ret_str);
       break;
 
     case oNameServer:
       set_dns_nameserver (pargs->r.ret_str);
       break;
 
     case oResolverTimeout:
       set_dns_timeout (pargs->r.ret_int);
       break;
 
     case oConnectTimeout:
       opt.connect_timeout = pargs->r.ret_ulong * 1000;
       break;
 
     case oConnectQuickTimeout:
       opt.connect_quick_timeout = pargs->r.ret_ulong * 1000;
       break;
 
     case oLDAPTimeout:
       opt.ldaptimeout = pargs->r.ret_int;
       break;
 
     default:
       return 0; /* Not handled. */
     }
 
   set_dns_verbose (opt.verbose, !!DBG_DNS);
   http_set_verbose (opt.verbose, !!DBG_NETWORK);
   set_dns_disable_ipv4 (opt.disable_ipv4);
   set_dns_disable_ipv6 (opt.disable_ipv6);
 
   return 1; /* Handled. */
 }
 
 
 /* This function is called after option parsing to adjust some values
  * and call option setup functions.  */
 static void
 post_option_parsing (void)
 {
   /* It would be too surpirsing if the quick timeout is larger than
    * the standard value.  */
   if (opt.connect_quick_timeout > opt.connect_timeout)
     opt.connect_quick_timeout = opt.connect_timeout;
 
   set_debug ();
 }
 
 
 #ifndef HAVE_W32_SYSTEM
 static int
 pid_suffix_callback (unsigned long *r_suffix)
 {
   union int_and_ptr_u value;
 
   memset (&value, 0, sizeof value);
   value.aptr = npth_getspecific (my_tlskey_current_fd);
   *r_suffix = value.aint;
   return (*r_suffix != -1);  /* Use decimal representation.  */
 }
 #endif /*!HAVE_W32_SYSTEM*/
 
 #if HTTP_USE_NTBTLS
 static void
 my_ntbtls_log_handler (void *opaque, int level, const char *fmt, va_list argv)
 {
   (void)opaque;
 
   if (level == -1)
     log_logv_prefix (GPGRT_LOGLVL_INFO, "ntbtls: ", fmt, argv);
   else
     {
       char prefix[10+20];
       snprintf (prefix, sizeof prefix, "ntbtls(%d): ", level);
       log_logv_prefix (GPGRT_LOGLVL_DEBUG, prefix, fmt, argv);
     }
 }
 #endif
 
 
 static void
 thread_init (void)
 {
   npth_init ();
   assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
 
   /* Now with NPth running we can set the logging callback.  Our
      windows implementation does not yet feature the NPth TLS
      functions.  */
 #ifndef HAVE_W32_SYSTEM
   if (npth_key_create (&my_tlskey_current_fd, NULL) == 0)
     if (npth_setspecific (my_tlskey_current_fd, NULL) == 0)
       log_set_pid_suffix_cb (pid_suffix_callback);
 #endif /*!HAVE_W32_SYSTEM*/
 }
 
 
 int
 main (int argc, char **argv)
 {
   enum cmd_and_opt_values cmd = 0;
   gpgrt_argparse_t pargs;
   int orig_argc;
   char **orig_argv;
   char *last_configname = NULL;
   const char *configname = NULL;
   const char *shell;
   int debug_argparser = 0;
   int greeting = 0;
   int nogreeting = 0;
   int nodetach = 0;
   int csh_style = 0;
   char *logfile = NULL;
 #if USE_LDAP
   char *ldapfile = NULL;
 #endif /*USE_LDAP*/
   int debug_wait = 0;
   int rc;
   struct assuan_malloc_hooks malloc_hooks;
 
   early_system_init ();
   gpgrt_set_strusage (my_strusage);
   log_set_prefix (DIRMNGR_NAME, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID);
 
   /* Make sure that our subsystems are ready.  */
   i18n_init ();
   init_common_subsystems (&argc, &argv);
 
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
 
  /* Check that the libraries are suitable.  Do it here because
     the option parsing may need services of the libraries. */
   if (!ksba_check_version (NEED_KSBA_VERSION) )
     log_fatal( _("%s is too old (need %s, have %s)\n"), "libksba",
                NEED_KSBA_VERSION, ksba_check_version (NULL) );
 
   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
   ksba_set_hash_buffer_function (my_ksba_hash_buffer, NULL);
 
   /* Init TLS library.  */
 #if HTTP_USE_NTBTLS
   if (!ntbtls_check_version (NEED_NTBTLS_VERSION) )
     log_fatal( _("%s is too old (need %s, have %s)\n"), "ntbtls",
                NEED_NTBTLS_VERSION, ntbtls_check_version (NULL) );
 #elif HTTP_USE_GNUTLS
   rc = gnutls_global_init ();
   if (rc)
     log_fatal ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));
 #endif /*HTTP_USE_GNUTLS*/
 
   /* Init Assuan. */
   malloc_hooks.malloc = gcry_malloc;
   malloc_hooks.realloc = gcry_realloc;
   malloc_hooks.free = gcry_free;
   assuan_set_malloc_hooks (&malloc_hooks);
   assuan_set_assuan_log_prefix (log_get_prefix (NULL));
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
   assuan_sock_init ();
   setup_libassuan_logging (&opt.debug, dirmngr_assuan_log_monitor);
 
   setup_libgcrypt_logging ();
 
 #if HTTP_USE_NTBTLS
   ntbtls_set_log_handler (my_ntbtls_log_handler, NULL);
 #endif
 
   /* Setup defaults. */
   shell = getenv ("SHELL");
   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
     csh_style = 1;
 
   /* Reset rereadable options to default values. */
   parse_rereadable_options (NULL, 0);
 
   /* Default TCP timeouts.  */
   opt.connect_timeout = DEFAULT_CONNECT_TIMEOUT;
   opt.connect_quick_timeout = DEFAULT_CONNECT_QUICK_TIMEOUT;
 
   /* LDAP defaults.  */
   opt.add_new_ldapservers = 0;
   opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT;
 
   /* Other defaults.  */
 
   /* Check whether we have a config file given on the commandline */
   orig_argc = argc;
   orig_argv = argv;
   pargs.argc = &argc;
   pargs.argv = &argv;
   pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
   while (gpgrt_argparse (NULL, &pargs, opts))
     {
       switch (pargs.r_opt)
         {
         case oDebug:
         case oDebugAll:
           debug_argparser++;
           break;
         case oHomedir:
           gnupg_set_homedir (pargs.r.ret_str);
           break;
         }
     }
   /* Reset the flags.  */
   pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
 
   socket_name = dirmngr_socket_name ();
 
   /* The configuraton directories for use by gpgrt_argparser.  */
   gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ());
   gpgrt_set_confdir (GPGRT_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;
   argv = orig_argv;
   pargs.argc = &argc;
   pargs.argv = &argv;
   pargs.flags |=  (ARGPARSE_FLAG_RESET
                    | ARGPARSE_FLAG_KEEP
                    | ARGPARSE_FLAG_SYS
                    | ARGPARSE_FLAG_USER);
   while (gpgrt_argparser (&pargs, opts, DIRMNGR_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))
         continue; /* Already handled */
       switch (pargs.r_opt)
         {
         case aServer:
         case aDaemon:
         case aSupervised:
         case aShutdown:
         case aFlush:
 	case aListCRLs:
 	case aLoadCRL:
         case aFetchCRL:
 	case aGPGConfList:
 	case aGPGConfTest:
 	case aGPGConfVersions:
           cmd = pargs.r_opt;
           break;
 
         case oQuiet: opt.quiet = 1; break;
         case oVerbose: opt.verbose++; break;
         case oBatch: opt.batch=1; break;
 
         case oDebugWait: debug_wait = pargs.r.ret_int; break;
 
         case oNoGreeting: nogreeting = 1; break;
         case oNoVerbose: opt.verbose = 0; break;
         case oHomedir: /* Ignore this option here. */; break;
         case oNoDetach: nodetach = 1; break;
+        case oStealSocket: steal_socket = 1; break;
         case oLogFile: logfile = pargs.r.ret_str; break;
         case oCsh: csh_style = 1; break;
         case oSh: csh_style = 0; break;
 	case oLDAPFile:
 #        if USE_LDAP
           ldapfile = pargs.r.ret_str;
 #        endif /*USE_LDAP*/
           break;
 	case oLDAPAddServers: opt.add_new_ldapservers = 1; break;
 
         case oFakedSystemTime:
           gnupg_set_time ((time_t)pargs.r.ret_ulong, 0);
           break;
 
         case oForce: opt.force = 1; break;
 
         case oSocketName: socket_name = pargs.r.ret_str; break;
 
         case oListenBacklog:
           listen_backlog = pargs.r.ret_int;
           break;
 
         default:
           if (configname)
             pargs.err = ARGPARSE_PRINT_WARNING;
           else
             pargs.err = ARGPARSE_PRINT_ERROR;
           break;
 	}
     }
   gpgrt_argparse (NULL, &pargs, NULL);  /* Release internal state.  */
 
   if (!last_configname)
     opt.config_filename = gpgrt_fnameconcat (gnupg_homedir (),
                                              DIRMNGR_NAME EXTSEP_S "conf",
                                              NULL);
   else
     {
       opt.config_filename = last_configname;
       last_configname = NULL;
     }
 
   if (log_get_errorcount(0))
     exit(2);
 
   /* Get a default log file from common.conf.  */
   if (!logfile && !parse_comopt (GNUPG_MODULE_NAME_DIRMNGR, debug_argparser))
     {
       logfile = comopt.logfile;
       comopt.logfile = NULL;
     }
 
   if (nogreeting )
     greeting = 0;
 
   if (!opt.homedir_cache)
     opt.homedir_cache = xstrdup (gnupg_homedir ());
 
   if (greeting)
     {
       es_fprintf (es_stderr, "%s %s; %s\n",
                   gpgrt_strusage(11), gpgrt_strusage(13), gpgrt_strusage(14));
       es_fprintf (es_stderr, "%s\n", gpgrt_strusage(15));
     }
 
 #ifdef IS_DEVELOPMENT_VERSION
   log_info ("NOTE: this is a development version!\n");
 #endif
 
   /* Print a warning if an argument looks like an option.  */
   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
     {
       int i;
 
       for (i=0; i < argc; i++)
         if (argv[i][0] == '-' && argv[i][1] == '-')
           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
     }
 
   if (!gnupg_access ("/etc/"DIRMNGR_NAME, F_OK)
       && !strncmp (gnupg_homedir (), "/etc/", 5))
     log_info
       ("NOTE: DirMngr is now a proper part of %s.  The configuration and"
        " other directory names changed.  Please check that no other version"
        " of dirmngr is still installed.  To disable this warning, remove the"
        " directory '/etc/dirmngr'.\n", GNUPG_NAME);
 
   if (gnupg_faked_time_p ())
     {
       gnupg_isotime_t tbuf;
 
       log_info (_("WARNING: running with faked system time: "));
       gnupg_get_isotime (tbuf);
       dump_isotime (tbuf);
       log_printf ("\n");
     }
 
   /* Note that we do not run set_tor_mode in --gpgconf-list mode
    * because it will attempt to connect to the tor client and that can
    * be time consuming.  */
   post_option_parsing ();
   if (cmd != aGPGConfTest && cmd != aGPGConfList && cmd != aGPGConfVersions)
     set_tor_mode ();
 
   /* Get LDAP server list from file unless --ldapserver has been used.  */
 #if USE_LDAP
   if (opt.ldapservers)
     ;
   else if (!ldapfile)
     {
       ldapfile = make_filename (gnupg_homedir (),
                                 "dirmngr_ldapservers.conf",
                                 NULL);
       opt.ldapservers = parse_ldapserver_file (ldapfile, 1);
       xfree (ldapfile);
     }
   else
     opt.ldapservers = parse_ldapserver_file (ldapfile, 0);
 #endif /*USE_LDAP*/
 
 #ifndef HAVE_W32_SYSTEM
   /* We need to ignore the PIPE signal because the we might log to a
      socket and that code handles EPIPE properly.  The ldap wrapper
      also requires us to ignore this silly signal. Assuan would set
      this signal to ignore anyway.*/
   signal (SIGPIPE, SIG_IGN);
 #endif
 
   /* Ready.  Now to our duties. */
   if (!cmd)
     cmd = aServer;
   rc = 0;
 
   if (cmd == aServer)
     {
       /* Note that this server mode is mainly useful for debugging.  */
       if (argc)
         wrong_args ("--server");
 
       if (logfile)
         {
           log_set_file (logfile);
           log_set_prefix (NULL, GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID);
         }
 
       if (debug_wait)
         {
           log_debug ("waiting for debugger - my pid is %u .....\n",
                      (unsigned int)getpid());
           gnupg_sleep (debug_wait);
           log_debug ("... okay\n");
         }
 
 
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       ks_hkp_init ();
       http_register_netactivity_cb (netactivity_action);
       start_command_handler (ASSUAN_INVALID_FD, 0);
       shutdown_reaper ();
     }
 #ifndef HAVE_W32_SYSTEM
   else if (cmd == aSupervised)
     {
       /* In supervised mode, we expect file descriptor 3 to be an
          already opened, listening socket.
 
          We will also not detach from the controlling process or close
          stderr; the supervisor should handle all of that.  */
       struct stat statbuf;
       if (fstat (3, &statbuf) == -1 && errno == EBADF)
         {
           log_error ("file descriptor 3 must be validin --supervised mode\n");
           dirmngr_exit (1);
         }
       socket_name = gnupg_get_socket_name (3);
 
       /* Now start with logging to a file if this is desired. */
       if (logfile)
         {
           log_set_file (logfile);
           log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
                                  |GPGRT_LOG_WITH_TIME
                                  |GPGRT_LOG_WITH_PID));
           current_logfile = xstrdup (logfile);
         }
       else
         log_set_prefix (NULL, 0);
 
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       ks_hkp_init ();
       http_register_netactivity_cb (netactivity_action);
       handle_connections (3);
       shutdown_reaper ();
     }
 #endif /*HAVE_W32_SYSTEM*/
   else if (cmd == aDaemon)
     {
       assuan_fd_t fd;
       pid_t pid;
       int len;
       struct sockaddr_un serv_addr;
 
       if (argc)
         wrong_args ("--daemon");
 
       /* Now start with logging to a file if this is desired. */
       if (logfile)
         {
           log_set_file (logfile);
           log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
                                  |GPGRT_LOG_WITH_TIME
                                  |GPGRT_LOG_WITH_PID));
           current_logfile = xstrdup (logfile);
         }
 
       if (debug_wait)
         {
           log_debug ("waiting for debugger - my pid is %u .....\n",
                      (unsigned int)getpid());
           gnupg_sleep (debug_wait);
           log_debug ("... okay\n");
         }
 
 #ifndef HAVE_W32_SYSTEM
       if (strchr (socket_name, ':'))
         {
           log_error (_("colons are not allowed in the socket name\n"));
           dirmngr_exit (1);
         }
 #endif
       fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
       if (fd == ASSUAN_INVALID_FD)
         {
           log_error (_("can't create socket: %s\n"), strerror (errno));
           cleanup ();
           dirmngr_exit (1);
         }
 
       {
         int redirected;
 
         if (assuan_sock_set_sockaddr_un (socket_name,
                                          (struct sockaddr*)&serv_addr,
                                          &redirected))
           {
             if (errno == ENAMETOOLONG)
               log_error (_("socket name '%s' is too long\n"), socket_name);
             else
               log_error ("error preparing socket '%s': %s\n",
                          socket_name,
                          gpg_strerror (gpg_error_from_syserror ()));
             dirmngr_exit (1);
           }
         if (redirected)
           {
             redir_socket_name = xstrdup (serv_addr.sun_path);
             if (opt.verbose)
               log_info ("redirecting socket '%s' to '%s'\n",
                         socket_name, redir_socket_name);
           }
       }
 
       len = SUN_LEN (&serv_addr);
 
       rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
       if (rc == -1
           && (errno == EADDRINUSE
 #ifdef HAVE_W32_SYSTEM
               || errno == EEXIST
 #endif
               ))
 	{
-          /* Fixme: We should test whether a dirmngr is already running. */
+          /* Fixme: We should actually test whether a dirmngr is
+           * already running.  For now the steal option is a dummy. */
+          /* if (steal_socket) */
+          /*   log_info (N_("trying to steal socket from running %s\n"), */
+          /*             "dirmngr"); */
 	  gnupg_remove (redir_socket_name? redir_socket_name : socket_name);
 	  rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
 	}
       if (rc != -1
 	  && (rc = assuan_sock_get_nonce ((struct sockaddr*) &serv_addr, len, &socket_nonce)))
 	log_error (_("error getting nonce for the socket\n"));
       if (rc == -1)
         {
           log_error (_("error binding socket to '%s': %s\n"),
                      serv_addr.sun_path,
                      gpg_strerror (gpg_error_from_syserror ()));
           assuan_sock_close (fd);
           dirmngr_exit (1);
         }
       cleanup_socket = 1;
 
       if (gnupg_chmod (serv_addr.sun_path, "-rwx"))
         log_error (_("can't set permissions of '%s': %s\n"),
                    serv_addr.sun_path, strerror (errno));
 
       if (listen (FD2INT (fd), listen_backlog) == -1)
         {
           log_error ("listen(fd,%d) failed: %s\n",
                      listen_backlog, strerror (errno));
           assuan_sock_close (fd);
           dirmngr_exit (1);
         }
 
       if (opt.verbose)
         log_info (_("listening on socket '%s'\n"), serv_addr.sun_path);
 
       es_fflush (NULL);
 
       /* Note: We keep the dirmngr_info output only for the sake of
          existing scripts which might use this to detect a successful
          start of the dirmngr.  */
 #ifdef HAVE_W32_SYSTEM
       (void)csh_style;
       (void)nodetach;
 
       pid = getpid ();
       es_printf ("set %s=%s;%lu;1\n",
                  DIRMNGR_INFO_NAME, socket_name, (ulong) pid);
 #else
       pid = fork();
       if (pid == (pid_t)-1)
         {
           log_fatal (_("error forking process: %s\n"), strerror (errno));
           dirmngr_exit (1);
         }
 
       if (pid)
         { /* We are the parent */
           char *infostr;
 
           /* Don't let cleanup() remove the socket - the child is
              responsible for doing that.  */
           cleanup_socket = 0;
 
           close (fd);
 
           /* Create the info string: <name>:<pid>:<protocol_version> */
           if (asprintf (&infostr, "%s=%s:%lu:1",
                         DIRMNGR_INFO_NAME, serv_addr.sun_path, (ulong)pid ) < 0)
             {
               log_error (_("out of core\n"));
               kill (pid, SIGTERM);
               dirmngr_exit (1);
             }
           /* Print the environment string, so that the caller can use
              shell's eval to set it.  But see above.  */
           if (csh_style)
             {
               *strchr (infostr, '=') = ' ';
               es_printf ( "setenv %s;\n", infostr);
             }
           else
             {
               es_printf ( "%s; export %s;\n", infostr, DIRMNGR_INFO_NAME);
             }
           free (infostr);
           exit (0);
           /*NEVER REACHED*/
         } /* end parent */
 
 
       /*
          This is the child
        */
 
       /* Detach from tty and put process into a new session */
       if (!nodetach )
         {
           int i;
           unsigned int oldflags;
 
           /* Close stdin, stdout and stderr unless it is the log stream */
           for (i=0; i <= 2; i++)
             {
               if (!log_test_fd (i) && i != fd )
                 {
                   if ( !close (i)
                        && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1)
                     {
                       log_error ("failed to open '%s': %s\n",
                                  "/dev/null", strerror (errno));
                       cleanup ();
                       dirmngr_exit (1);
                     }
                 }
             }
 
           if (setsid() == -1)
             {
               log_error ("setsid() failed: %s\n", strerror(errno) );
               dirmngr_exit (1);
             }
 
           log_get_prefix (&oldflags);
           log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED);
           opt.running_detached = 1;
 
         }
 #endif
 
       if (!nodetach )
         {
           if (gnupg_chdir (gnupg_daemon_rootdir ()))
             {
               log_error ("chdir to '%s' failed: %s\n",
                          gnupg_daemon_rootdir (), strerror (errno));
               dirmngr_exit (1);
             }
         }
 
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       ks_hkp_init ();
       http_register_netactivity_cb (netactivity_action);
       handle_connections (fd);
       shutdown_reaper ();
     }
   else if (cmd == aListCRLs)
     {
       /* Just list the CRL cache and exit. */
       if (argc)
         wrong_args ("--list-crls");
       crl_cache_init ();
       crl_cache_list (es_stdout);
     }
   else if (cmd == aLoadCRL)
     {
       struct server_control_s ctrlbuf;
 
       memset (&ctrlbuf, 0, sizeof ctrlbuf);
       dirmngr_init_default_ctrl (&ctrlbuf);
 
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       ks_hkp_init ();
       if (!argc)
         rc = crl_cache_load (&ctrlbuf, NULL);
       else
         {
           for (; !rc && argc; argc--, argv++)
             rc = crl_cache_load (&ctrlbuf, *argv);
         }
       dirmngr_deinit_default_ctrl (&ctrlbuf);
     }
   else if (cmd == aFetchCRL)
     {
       ksba_reader_t reader;
       struct server_control_s ctrlbuf;
 
       if (argc != 1)
         wrong_args ("--fetch-crl URL");
 
       memset (&ctrlbuf, 0, sizeof ctrlbuf);
       dirmngr_init_default_ctrl (&ctrlbuf);
 
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       ks_hkp_init ();
       rc = crl_fetch (&ctrlbuf, argv[0], &reader);
       if (rc)
         log_error (_("fetching CRL from '%s' failed: %s\n"),
                      argv[0], gpg_strerror (rc));
       else
         {
           rc = crl_cache_insert (&ctrlbuf, argv[0], reader);
           if (rc)
             log_error (_("processing CRL from '%s' failed: %s\n"),
                        argv[0], gpg_strerror (rc));
           crl_close_reader (reader);
         }
       dirmngr_deinit_default_ctrl (&ctrlbuf);
     }
   else if (cmd == aFlush)
     {
       /* Delete cache and exit. */
       if (argc)
         wrong_args ("--flush");
       rc = crl_cache_flush();
     }
   else if (cmd == aGPGConfTest)
     dirmngr_exit (0);
   else if (cmd == aGPGConfList)
     {
       unsigned long flags = 0;
       char *filename_esc;
 
       es_printf ("debug-level:%lu:\"none\n", flags | GC_OPT_FLAG_DEFAULT);
       es_printf ("ldaptimeout:%lu:%u\n",
                  flags | GC_OPT_FLAG_DEFAULT, DEFAULT_LDAP_TIMEOUT);
       es_printf ("max-replies:%lu:%u\n",
                  flags | GC_OPT_FLAG_DEFAULT, DEFAULT_MAX_REPLIES);
 
       filename_esc = percent_escape (get_default_keyserver (0), NULL);
       es_printf ("keyserver:%lu:\"%s:\n", flags | GC_OPT_FLAG_DEFAULT,
                  filename_esc);
       xfree (filename_esc);
 
       es_printf ("resolver-timeout:%lu:%u\n",
                  flags | GC_OPT_FLAG_DEFAULT, 0);
     }
   else if (cmd == aGPGConfVersions)
     gpgconf_versions ();
 
   cleanup ();
   return !!rc;
 }
 
 
 static void
 cleanup (void)
 {
   crl_cache_deinit ();
   cert_cache_deinit (1);
   reload_dns_stuff (1);
 
 #if USE_LDAP
   ldapserver_list_free (opt.ldapservers);
 #endif /*USE_LDAP*/
   opt.ldapservers = NULL;
 
   if (cleanup_socket)
     {
       cleanup_socket = 0;
       if (redir_socket_name)
         gnupg_remove (redir_socket_name);
       else if (socket_name && *socket_name)
         gnupg_remove (socket_name);
     }
 }
 
 
 void
 dirmngr_exit (int rc)
 {
   cleanup ();
   exit (rc);
 }
 
 
 void
 dirmngr_init_default_ctrl (ctrl_t ctrl)
 {
   ctrl->magic = SERVER_CONTROL_MAGIC;
   if (opt.http_proxy)
     ctrl->http_proxy = xstrdup (opt.http_proxy);
   ctrl->http_no_crl = 1;
   ctrl->timeout = opt.connect_timeout;
 }
 
 
 void
 dirmngr_deinit_default_ctrl (ctrl_t ctrl)
 {
   if (!ctrl)
     return;
   ctrl->magic = 0xdeadbeef;
 
   xfree (ctrl->http_proxy);
   ctrl->http_proxy = NULL;
 }
 
 
 /* Create a list of LDAP servers from the file FILENAME. Returns the
    list or NULL in case of errors.
 
    The format of such a file is line oriented where empty lines and
    lines starting with a hash mark are ignored.  All other lines are
    assumed to be colon seprated with these fields:
 
    1. field: Hostname
    2. field: Portnumber
    3. field: Username
    4. field: Password
    5. field: Base DN
 
 */
 #if USE_LDAP
 static ldap_server_t
 parse_ldapserver_file (const char* filename, int ignore_enoent)
 {
   char buffer[1024];
   char *p;
   ldap_server_t server, serverstart, *serverend;
   int c;
   unsigned int lineno = 0;
   estream_t fp;
 
   fp = es_fopen (filename, "r");
   if (!fp)
     {
       if (ignore_enoent && gpg_err_code_from_syserror () == GPG_ERR_ENOENT)
         ;
       else
         log_info ("failed to open '%s': %s\n", filename, strerror (errno));
       return NULL;
     }
 
   serverstart = NULL;
   serverend = &serverstart;
   while (es_fgets (buffer, sizeof buffer, fp))
     {
       lineno++;
       if (!*buffer || buffer[strlen(buffer)-1] != '\n')
         {
           if (*buffer && es_feof (fp))
             ; /* Last line not terminated - continue. */
           else
             {
               log_error (_("%s:%u: line too long - skipped\n"),
                          filename, lineno);
               while ( (c=es_fgetc (fp)) != EOF && c != '\n')
                 ; /* Skip until end of line. */
               continue;
             }
         }
       /* Skip empty and comment lines.*/
       for (p=buffer; spacep (p); p++)
         ;
       if (!*p || *p == '\n' || *p == '#')
         continue;
 
       /* Parse the colon separated fields. */
       server = ldapserver_parse_one (buffer, filename, lineno);
       if (server)
         {
           *serverend = server;
           serverend = &server->next;
         }
     }
 
   if (es_ferror (fp))
     log_error (_("error reading '%s': %s\n"), filename, strerror (errno));
   es_fclose (fp);
 
   return serverstart;
 }
 #endif /*USE_LDAP*/
 
 
 /* Parse a fingerprint entry as used by --ocsc-signer.  OPTIONNAME as
  * a description on the options used.  WANT_BINARY requests to store a
  * binary fingerprint.  Returns NULL on error and logs that error. */
 static fingerprint_list_t
 parse_fingerprint_item (const char *string,
                         const char *optionname, int want_binary)
 {
   gpg_error_t err;
   char *fname;
   estream_t fp;
   char line[256];
   char *p;
   fingerprint_list_t list, *list_tail, item;
   unsigned int lnr = 0;
   int c, i, j;
   int errflag = 0;
 
 
   /* Check whether this is not a filename and treat it as a direct
      fingerprint specification.  */
   if (!strpbrk (string, "/.~\\"))
     {
       item = xcalloc (1, sizeof *item);
       for (i=j=0; (string[i] == ':' || hexdigitp (string+i)) && j < 40; i++)
         if ( string[i] != ':' )
           item->hexfpr[j++] = string[i] >= 'a'? (string[i] & 0xdf): string[i];
       item->hexfpr[j] = 0;
       if (j != 40 || !(spacep (string+i) || !string[i]))
         {
           log_error (_("%s:%u: invalid fingerprint detected\n"),
                      optionname, 0);
           xfree (item);
           return NULL;
         }
       if (want_binary)
         {
           item->binlen = 20;
           hex2bin (item->hexfpr, item->hexfpr, 20);
         }
       return item;
     }
 
   /* Well, it is a filename.  */
   if (*string == '/' || (*string == '~' && string[1] == '/'))
     fname = make_filename (string, NULL);
   else
     {
       if (string[0] == '.' && string[1] == '/' )
         string += 2;
       fname = make_filename (gnupg_homedir (), string, NULL);
     }
 
   fp = es_fopen (fname, "r");
   if (!fp)
     {
       err = gpg_error_from_syserror ();
       log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err));
       xfree (fname);
       return NULL;
     }
 
   list = NULL;
   list_tail = &list;
   for (;;)
     {
       if (!es_fgets (line, DIM(line)-1, fp) )
         {
           if (!es_feof (fp))
             {
               err = gpg_error_from_syserror ();
               log_error (_("%s:%u: read error: %s\n"),
                          fname, lnr, gpg_strerror (err));
               errflag = 1;
             }
           es_fclose (fp);
           if (errflag)
             {
               while (list)
                 {
                   fingerprint_list_t tmp = list->next;
                   xfree (list);
                   list = tmp;
                 }
             }
           xfree (fname);
           return list; /* Ready.  */
         }
 
       lnr++;
       if (!*line || line[strlen(line)-1] != '\n')
         {
           /* Eat until end of line. */
           while ( (c=es_getc (fp)) != EOF && c != '\n')
             ;
           err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
                            /* */: GPG_ERR_INCOMPLETE_LINE);
           log_error (_("%s:%u: read error: %s\n"),
                      fname, lnr, gpg_strerror (err));
           errflag = 1;
           continue;
         }
 
       /* Allow for empty lines and spaces */
       for (p=line; spacep (p); p++)
         ;
       if (!*p || *p == '\n' || *p == '#')
         continue;
 
       item = xcalloc (1, sizeof *item);
       *list_tail = item;
       list_tail = &item->next;
 
       for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
         if ( p[i] != ':' )
           item->hexfpr[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
       item->hexfpr[j] = 0;
       if (j != 40 || !(spacep (p+i) || p[i] == '\n'))
         {
           log_error (_("%s:%u: invalid fingerprint detected\n"), fname, lnr);
           errflag = 1;
         }
       else if (want_binary)
         {
           item->binlen = 20;
           hex2bin (item->hexfpr, item->hexfpr, 20);
         }
 
       i++;
       while (spacep (p+i))
         i++;
       if (p[i] && p[i] != '\n')
         log_info (_("%s:%u: garbage at end of line ignored\n"), fname, lnr);
     }
   /*NOTREACHED*/
 }
 
 
 
 
 /*
    Stuff used in daemon mode.
  */
 
 
 
 /* Reread parts of the configuration.  Note, that this function is
    obviously not thread-safe and should only be called from the NPTH
    signal handler.
 
    Fixme: Due to the way the argument parsing works, we create a
    memory leak here for all string type arguments.  There is currently
    no clean way to tell whether the memory for the argument has been
    allocated or points into the process's original arguments.  Unless
    we have a mechanism to tell this, we need to live on with this. */
 static void
 reread_configuration (void)
 {
   gpgrt_argparse_t pargs;
   char *twopart;
   int dummy;
   int logfile_seen = 0;
 
   if (!opt.config_filename)
     goto finish; /* No config file. */
 
   twopart = strconcat (DIRMNGR_NAME EXTSEP_S "conf" PATHSEP_S,
                        opt.config_filename, NULL);
   if (!twopart)
     return;  /* Out of core.  */
 
   parse_rereadable_options (NULL, 1); /* Start from the default values. */
 
   memset (&pargs, 0, sizeof pargs);
   dummy = 0;
   pargs.argc = &dummy;
   pargs.flags = (ARGPARSE_FLAG_KEEP
                  |ARGPARSE_FLAG_SYS
                  |ARGPARSE_FLAG_USER);
   while (gpgrt_argparser (&pargs, opts, twopart))
     {
       if (pargs.r_opt == ARGPARSE_CONFFILE)
         {
           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. */
         {
           if (pargs.r_opt == oLogFile)
             logfile_seen = 1;
           parse_rereadable_options (&pargs, 1);
         }
     }
   gpgrt_argparse (NULL, &pargs, NULL);  /* Release internal state.  */
   xfree (twopart);
   post_option_parsing ();
 
  finish:
   /* Get a default log file from common.conf.  */
   if (!logfile_seen && !parse_comopt (GNUPG_MODULE_NAME_DIRMNGR, !!opt.debug))
     {
       if (!current_logfile || !comopt.logfile
           || strcmp (current_logfile, comopt.logfile))
         {
           log_set_file (comopt.logfile);
           xfree (current_logfile);
           current_logfile = comopt.logfile? xtrystrdup (comopt.logfile) : NULL;
         }
     }
 }
 
 
 /* A global function which allows us to trigger the reload stuff from
    other places.  */
 void
 dirmngr_sighup_action (void)
 {
   log_info (_("SIGHUP received - "
               "re-reading configuration and flushing caches\n"));
   reread_configuration ();
   set_tor_mode ();
   cert_cache_deinit (0);
   crl_cache_deinit ();
   cert_cache_init (hkp_cacert_filenames);
   crl_cache_init ();
   reload_dns_stuff (0);
   ks_hkp_reload ();
 }
 
 
 /* This function is called if some network activity was done.  At this
  * point we know the we have a network and we can decide whether to
  * run scheduled background tasks soon.  The function should return
  * quickly and only trigger actions for another thread. */
 static void
 netactivity_action (void)
 {
   network_activity_seen = 1;
 }
 
 
 /* The signal handler. */
 #ifndef HAVE_W32_SYSTEM
 static void
 handle_signal (int signo)
 {
   switch (signo)
     {
     case SIGHUP:
       dirmngr_sighup_action ();
       break;
 
     case SIGUSR1:
       cert_cache_print_stats ();
       domaininfo_print_stats ();
       break;
 
     case SIGUSR2:
       log_info (_("SIGUSR2 received - no action defined\n"));
       break;
 
     case SIGTERM:
       if (!shutdown_pending)
         log_info (_("SIGTERM received - shutting down ...\n"));
       else
         log_info (_("SIGTERM received - still %d active connections\n"),
                   active_connections);
       shutdown_pending++;
       if (shutdown_pending > 2)
         {
           log_info (_("shutdown forced\n"));
           log_info ("%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13));
           cleanup ();
           dirmngr_exit (0);
 	}
       break;
 
     case SIGINT:
       log_info (_("SIGINT received - immediate shutdown\n"));
       log_info( "%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13));
       cleanup ();
       dirmngr_exit (0);
       break;
 
     default:
       log_info (_("signal %d received - no action defined\n"), signo);
     }
 }
 #endif /*!HAVE_W32_SYSTEM*/
 
 
 /* Thread to do the housekeeping.  */
 static void *
 housekeeping_thread (void *arg)
 {
   static int sentinel;
   time_t curtime;
   struct server_control_s ctrlbuf;
 
   (void)arg;
 
   curtime = gnupg_get_time ();
   if (sentinel)
     {
       log_info ("housekeeping is already going on\n");
       return NULL;
     }
   sentinel++;
   if (opt.verbose > 1)
     log_info ("starting housekeeping\n");
 
   memset (&ctrlbuf, 0, sizeof ctrlbuf);
   dirmngr_init_default_ctrl (&ctrlbuf);
 
   dns_stuff_housekeeping ();
   ks_hkp_housekeeping (curtime);
   if (network_activity_seen)
     {
       network_activity_seen = 0;
       if (opt.allow_version_check)
         dirmngr_load_swdb (&ctrlbuf, 0);
       workqueue_run_global_tasks (&ctrlbuf, 1);
     }
   else
     workqueue_run_global_tasks (&ctrlbuf, 0);
 
   dirmngr_deinit_default_ctrl (&ctrlbuf);
 
   if (opt.verbose > 1)
     log_info ("ready with housekeeping\n");
   sentinel--;
   return NULL;
 
 }
 
 
 /* We try to enable correct overflow handling for signed int (commonly
  * used for time_t). With gcc 4.2 -fno-strict-overflow was introduced
  * and used here as a pragma.  Later gcc versions (gcc 6?) removed
  * this as a pragma and -fwrapv was then suggested as a replacement
  * for -fno-strict-overflow.  */
 #if GPGRT_HAVE_PRAGMA_GCC_PUSH
 # pragma GCC push_options
 # pragma GCC optimize ("wrapv")
 #endif
 static int
 time_for_housekeeping_p (time_t curtime)
 {
   static time_t last_housekeeping;
 
   if (!last_housekeeping)
     last_housekeeping = curtime;
 
   if (last_housekeeping + HOUSEKEEPING_INTERVAL <= curtime
       || last_housekeeping > curtime /*(be prepared for y2038)*/)
     {
       last_housekeeping = curtime;
       return 1;
     }
   return 0;
 }
 #if GPGRT_HAVE_PRAGMA_GCC_PUSH
 # pragma GCC pop_options
 #endif
 
 
 /* This is the worker for the ticker.  It is called every few seconds
    and may only do fast operations. */
 static void
 handle_tick (void)
 {
   struct stat statbuf;
 
   if (time_for_housekeeping_p (gnupg_get_time ()))
     {
       npth_t thread;
       npth_attr_t tattr;
       int err;
 
       err = npth_attr_init (&tattr);
       if (err)
         log_error ("error preparing housekeeping thread: %s\n", strerror (err));
       else
         {
           npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
           err = npth_create (&thread, &tattr, housekeeping_thread, NULL);
           if (err)
             log_error ("error spawning housekeeping thread: %s\n",
                        strerror (err));
           npth_attr_destroy (&tattr);
         }
     }
 
   /* Check whether the homedir is still available.  */
   if (!shutdown_pending
       && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT)
     {
       shutdown_pending = 1;
       log_info ("homedir has been removed - shutting down\n");
     }
 }
 
 
 /* Check the nonce on a new connection.  This is a NOP unless we are
    using our Unix domain socket emulation under Windows.  */
 static int
 check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
 {
   if (assuan_sock_check_nonce (fd, nonce))
     {
       log_info (_("error reading nonce on fd %d: %s\n"),
                 FD2INT (fd), strerror (errno));
       assuan_sock_close (fd);
       return -1;
     }
   else
     return 0;
 }
 
 
 /* Helper to call a connection's main function. */
 static void *
 start_connection_thread (void *arg)
 {
   static unsigned int last_session_id;
   unsigned int session_id;
   union int_and_ptr_u argval;
   gnupg_fd_t fd;
 
   memset (&argval, 0, sizeof argval);
   argval.aptr = arg;
   fd = argval.afd;
 
   if (check_nonce (fd, &socket_nonce))
     {
       log_error ("handler nonce check FAILED\n");
       return NULL;
     }
 
 #ifndef HAVE_W32_SYSTEM
   npth_setspecific (my_tlskey_current_fd, argval.aptr);
 #endif
 
   active_connections++;
   if (opt.verbose)
     log_info (_("handler for fd %d started\n"), FD2INT (fd));
 
   session_id = ++last_session_id;
   if (!session_id)
     session_id = ++last_session_id;
   start_command_handler (fd, session_id);
 
   if (opt.verbose)
     log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
   active_connections--;
 
   workqueue_run_post_session_tasks (session_id);
 
 #ifndef HAVE_W32_SYSTEM
   argval.afd = ASSUAN_INVALID_FD;
   npth_setspecific (my_tlskey_current_fd, argval.aptr);
 #endif
 
   return NULL;
 }
 
 
 #ifdef HAVE_INOTIFY_INIT
 /* Read an inotify event and return true if it matches NAME.  */
 static int
 my_inotify_is_name (int fd, const char *name)
 {
   union {
     struct inotify_event ev;
     char _buf[sizeof (struct inotify_event) + 100 + 1];
   } buf;
   int n;
   const char *s;
 
   s = strrchr (name, '/');
   if (s && s[1])
     name = s + 1;
 
   n = npth_read (fd, &buf, sizeof buf);
   if (n < sizeof (struct inotify_event))
     return 0;
   if (buf.ev.len < strlen (name)+1)
     return 0;
   if (strcmp (buf.ev.name, name))
     return 0; /* Not the desired file.  */
 
   return 1; /* Found.  */
 }
 #endif /*HAVE_INOTIFY_INIT*/
 
 
 /* Main loop in daemon mode.  Note that LISTEN_FD will be owned by
  * this function. */
 static void
 handle_connections (assuan_fd_t listen_fd)
 {
   npth_attr_t tattr;
 #ifndef HAVE_W32_SYSTEM
   int signo;
 #endif
   struct sockaddr_un paddr;
   socklen_t plen = sizeof( paddr );
   int nfd, ret;
   fd_set fdset, read_fdset;
   struct timespec abstime;
   struct timespec curtime;
   struct timespec timeout;
   int saved_errno;
   int my_inotify_fd = -1;
 
   npth_attr_init (&tattr);
   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
 
 #ifndef HAVE_W32_SYSTEM /* FIXME */
   npth_sigev_init ();
   npth_sigev_add (SIGHUP);
   npth_sigev_add (SIGUSR1);
   npth_sigev_add (SIGUSR2);
   npth_sigev_add (SIGINT);
   npth_sigev_add (SIGTERM);
   npth_sigev_fini ();
 #endif
 
 #ifdef HAVE_INOTIFY_INIT
   if (disable_check_own_socket)
     my_inotify_fd = -1;
   else if ((my_inotify_fd = inotify_init ()) == -1)
     log_info ("error enabling fast daemon termination: %s\n",
               strerror (errno));
   else
     {
       /* We need to watch the directory for the file because there
        * won't be an IN_DELETE_SELF for a socket file.  */
       char *slash = strrchr (socket_name, '/');
       log_assert (slash && slash[1]);
       *slash = 0;
       if (inotify_add_watch (my_inotify_fd, socket_name, IN_DELETE) == -1)
         {
           close (my_inotify_fd);
           my_inotify_fd = -1;
         }
       *slash = '/';
     }
 #endif /*HAVE_INOTIFY_INIT*/
 
 
   /* Setup the fdset.  It has only one member.  This is because we use
      pth_select instead of pth_accept to properly sync timeouts with
      to full second.  */
   FD_ZERO (&fdset);
   FD_SET (FD2INT (listen_fd), &fdset);
   nfd = FD2INT (listen_fd);
   if (my_inotify_fd != -1)
     {
       FD_SET (my_inotify_fd, &fdset);
       if (my_inotify_fd > nfd)
         nfd = my_inotify_fd;
     }
 
   npth_clock_gettime (&abstime);
   abstime.tv_sec += TIMERTICK_INTERVAL;
 
   /* Main loop.  */
   for (;;)
     {
       /* Shutdown test.  */
       if (shutdown_pending)
         {
           if (!active_connections)
             break; /* ready */
 
           /* Do not accept new connections but keep on running the
            * loop to cope with the timer events.
            *
            * Note that we do not close the listening socket because a
            * client trying to connect to that socket would instead
            * restart a new dirmngr instance - which is unlikely the
            * intention of a shutdown. */
           /* assuan_sock_close (listen_fd); */
           /* listen_fd = -1; */
           FD_ZERO (&fdset);
           nfd = -1;
           if (my_inotify_fd != -1)
             {
               FD_SET (my_inotify_fd, &fdset);
               nfd = my_inotify_fd;
             }
 	}
 
       /* Take a copy of the fdset.  */
       read_fdset = fdset;
 
       npth_clock_gettime (&curtime);
       if (!(npth_timercmp (&curtime, &abstime, <)))
 	{
 	  /* Timeout.  When a shutdown is pending we use a shorter
            * interval to handle the shutdown more quickly.  */
 	  handle_tick ();
 	  npth_clock_gettime (&abstime);
 	  abstime.tv_sec += (shutdown_pending
                              ? TIMERTICK_INTERVAL_SHUTDOWN
                              : TIMERTICK_INTERVAL);
 	}
       npth_timersub (&abstime, &curtime, &timeout);
 
 #ifndef HAVE_W32_SYSTEM
       ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
                           npth_sigev_sigmask());
       saved_errno = errno;
 
       while (npth_sigev_get_pending(&signo))
 	handle_signal (signo);
 #else
       ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
       saved_errno = errno;
 #endif
 
       if (ret == -1 && saved_errno != EINTR)
 	{
           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
                      strerror (saved_errno));
           gnupg_sleep (1);
           continue;
 	}
 
       if (ret <= 0)
         {
           /* Interrupt or timeout.  Will be handled when calculating the
              next timeout.  */
           continue;
         }
 
       if (shutdown_pending)
         {
           /* Do not anymore accept connections.  */
           continue;
         }
 
 #ifdef HAVE_INOTIFY_INIT
       if (my_inotify_fd != -1 && FD_ISSET (my_inotify_fd, &read_fdset)
           && my_inotify_is_name (my_inotify_fd, socket_name))
         {
           shutdown_pending = 1;
           log_info ("socket file has been removed - shutting down\n");
         }
 #endif /*HAVE_INOTIFY_INIT*/
 
       if (FD_ISSET (FD2INT (listen_fd), &read_fdset))
 	{
           gnupg_fd_t fd;
 
           plen = sizeof paddr;
 	  fd = INT2FD (npth_accept (FD2INT(listen_fd),
 				    (struct sockaddr *)&paddr, &plen));
 	  if (fd == GNUPG_INVALID_FD)
 	    {
 	      log_error ("accept failed: %s\n", strerror (errno));
 	    }
           else
             {
               char threadname[50];
               union int_and_ptr_u argval;
 	      npth_t thread;
 
               memset (&argval, 0, sizeof argval);
               argval.afd = fd;
               snprintf (threadname, sizeof threadname,
                         "conn fd=%d", FD2INT(fd));
 
               ret = npth_create (&thread, &tattr,
                                  start_connection_thread, argval.aptr);
 	      if (ret)
                 {
                   log_error ("error spawning connection handler: %s\n",
                              strerror (ret) );
                   assuan_sock_close (fd);
                 }
 	      npth_setname_np (thread, threadname);
             }
 	}
     }
 
 #ifdef HAVE_INOTIFY_INIT
   if (my_inotify_fd != -1)
     close (my_inotify_fd);
 #endif /*HAVE_INOTIFY_INIT*/
   npth_attr_destroy (&tattr);
   if (listen_fd != GNUPG_INVALID_FD)
     assuan_sock_close (listen_fd);
   cleanup ();
   log_info ("%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13));
 }
 
 const char*
 dirmngr_get_current_socket_name (void)
 {
   if (socket_name)
     return socket_name;
   else
     return dirmngr_socket_name ();
 }
 
 
 
 /* Parse the revision part from the extended version blurb.  */
 static const char *
 get_revision_from_blurb (const char *blurb, int *r_len)
 {
   const char *s = blurb? blurb : "";
   int n;
 
   for (; *s; s++)
     if (*s == '\n' && s[1] == '(')
       break;
   if (*s)
     {
       s += 2;
       for (n=0; s[n] && s[n] != ' '; n++)
         ;
     }
   else
     {
       s = "?";
       n = 1;
     }
   *r_len = n;
   return s;
 }
 
 
 /* Print versions of dirmngr and used libraries.  This is used by
  * "gpgconf --show-versions" so that there is no need to link gpgconf
  * against all these libraries.  This is an internal API and should
  * not be relied upon.  */
 static void
 gpgconf_versions (void)
 {
   const char *s;
   int n;
 
   /* Unfortunately Npth has no way to get the version.  */
 
   s = get_revision_from_blurb (assuan_check_version ("\x01\x01"), &n);
   es_fprintf (es_stdout, "* Libassuan %s (%.*s)\n\n",
               assuan_check_version (NULL), n, s);
 
   s = get_revision_from_blurb (ksba_check_version ("\x01\x01"), &n);
   es_fprintf (es_stdout, "* KSBA %s (%.*s)\n\n",
               ksba_check_version (NULL), n, s);
 
 #ifdef HTTP_USE_NTBTLS
   s = get_revision_from_blurb (ntbtls_check_version ("\x01\x01"), &n);
   es_fprintf (es_stdout, "* NTBTLS %s (%.*s)\n\n",
               ntbtls_check_version (NULL), n, s);
 #elif HTTP_USE_GNUTLS
   es_fprintf (es_stdout, "* GNUTLS %s\n\n",
               gnutls_check_version (NULL));
 #endif
 
 }
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index f20d83384..6c2330dc6 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -1,1626 +1,1635 @@
 @c Copyright (C) 2002 Free Software Foundation, Inc.
 @c This is part of the GnuPG manual.
 @c For copying conditions, see the file gnupg.texi.
 
 @include defs.inc
 
 @node Invoking GPG-AGENT
 @chapter Invoking GPG-AGENT
 @cindex GPG-AGENT command options
 @cindex command options
 @cindex options, GPG-AGENT command
 
 @manpage gpg-agent.1
 @ifset manverb
 .B gpg-agent
 \- Secret key management for GnuPG
 @end ifset
 
 @mansect synopsis
 @ifset manverb
 .B  gpg-agent
 .RB [ \-\-homedir
 .IR dir ]
 .RB [ \-\-options
 .IR file ]
 .RI [ options ]
 .br
 .B  gpg-agent
 .RB [ \-\-homedir
 .IR dir ]
 .RB [ \-\-options
 .IR file ]
 .RI [ options ]
 .B  \-\-server
 .br
 .B  gpg-agent
 .RB [ \-\-homedir
 .IR dir ]
 .RB [ \-\-options
 .IR file ]
 .RI [ options ]
 .B  \-\-daemon
 .RI [ command_line ]
 @end ifset
 
 @mansect description
 @command{gpg-agent} is a daemon to manage secret (private) keys
 independently from any protocol.  It is used as a backend for
 @command{gpg} and @command{gpgsm} as well as for a couple of other
 utilities.
 
 The agent is automatically started on demand by @command{gpg},
 @command{gpgsm}, @command{gpgconf}, or @command{gpg-connect-agent}.
 Thus there is no reason to start it manually.  In case you want to use
 the included Secure Shell Agent you may start the agent using:
 
 @c From dkg on gnupg-devel on 2016-04-21:
 @c
 @c Here's an attempt at writing a short description of the goals of an
 @c isolated cryptographic agent:
 @c
 @c   A cryptographic agent should control access to secret key material.
 @c   The agent permits use of the secret key material by a supplicant
 @c   without providing a copy of the secret key material to the supplicant.
 @c
 @c   An isolated cryptographic agent separates the request for use of
 @c   secret key material from permission for use of secret key material.
 @c   That is, the system or process requesting use of the key (the
 @c   "supplicant") can be denied use of the key by the owner/operator of
 @c   the agent (the "owner"), which the supplicant has no control over.
 @c
 @c   One way of enforcing this split is a per-key or per-session
 @c   passphrase, known only by the owner, which must be supplied to the
 @c   agent to permit the use of the secret key material.  Another way is
 @c   with an out-of-band permission mechanism (e.g. a button or GUI
 @c   interface that the owner has access to, but the supplicant does not).
 @c
 @c   The rationale for this separation is that it allows access to the
 @c   secret key to be tightly controlled and audited, and it doesn't permit
 @c   the supplicant to either copy the key or to override the owner's
 @c   intentions.
 
 @example
 gpg-connect-agent /bye
 @end example
 
 @noindent
 If you want to manually terminate the currently-running agent, you can
 safely do so with:
 
 @example
 gpgconf --kill gpg-agent
 @end example
 
 @noindent
 @efindex GPG_TTY
 You should always add the following lines to your @code{.bashrc} or
 whatever initialization file is used for all shell invocations:
 
 @smallexample
 GPG_TTY=$(tty)
 export GPG_TTY
 @end smallexample
 
 @noindent
 It is important that this environment variable always reflects the
 output of the @code{tty} command.  For W32 systems this option is not
 required.
 
 Please make sure that a proper pinentry program has been installed
 under the default filename (which is system dependent) or use the
 option @option{pinentry-program} to specify the full name of that program.
 It is often useful to install a symbolic link from the actual used
 pinentry (e.g. @file{@value{BINDIR}/pinentry-gtk}) to the expected
 one (e.g. @file{@value{BINDIR}/pinentry}).
 
 @manpause
 @noindent
 @xref{Option Index}, for an index to @command{GPG-AGENT}'s commands and options.
 @mancont
 
 @menu
 * Agent Commands::      List of all commands.
 * Agent Options::       List of all options.
 * Agent Configuration:: Configuration files.
 * Agent Signals::       Use of some signals.
 * Agent Examples::      Some usage examples.
 * Agent Protocol::      The protocol the agent uses.
 @end menu
 
 @mansect commands
 @node Agent Commands
 @section Commands
 
 Commands are not distinguished from options except for the fact that
 only one command is allowed.
 
 @table @gnupgtabopt
 @item --version
 @opindex version
 Print the program version and licensing information.  Note that you cannot
 abbreviate this command.
 
 @item --help
 @itemx -h
 @opindex help
 Print a usage message summarizing the most useful command-line options.
 Note that you cannot abbreviate this command.
 
 @item --dump-options
 @opindex dump-options
 Print a list of all available options and commands.  Note that you cannot
 abbreviate this command.
 
 @item --server
 @opindex server
 Run in server mode and wait for commands on the @code{stdin}.  The
 default mode is to create a socket and listen for commands there.
 
 @item --daemon [@var{command line}]
 @opindex daemon
 Start the gpg-agent as a daemon; that is, detach it from the console
 and run it in the background.
 
 As an alternative you may create a new process as a child of
 gpg-agent: @code{gpg-agent --daemon /bin/sh}.  This way you get a new
 shell with the environment setup properly; after you exit from this
 shell, gpg-agent terminates within a few seconds.
 
 @item --supervised
 @opindex supervised
 Run in the foreground, sending logs by default to stderr, and
 listening on provided file descriptors, which must already be bound to
 listening sockets.  This command is useful when running under systemd
 or other similar process supervision schemes.  This option is not
 supported on Windows.
 
 In --supervised mode, different file descriptors can be provided for
 use as different socket types (e.g. ssh, extra) as long as they are
 identified in the environment variable @code{LISTEN_FDNAMES} (see
 sd_listen_fds(3) on some Linux distributions for more information on
 this convention).
 @end table
 
 @mansect options
 @node Agent Options
 @section Option Summary
 
 Options may either be used on the command line or, after stripping off
 the two leading dashes, in the configuration file.
 
 @table @gnupgtabopt
 
 @anchor{option --options}
 @item --options @var{file}
 @opindex options
 Reads configuration from @var{file} instead of from the default
 per-user configuration file.  The default configuration file is named
 @file{gpg-agent.conf} and expected in the @file{.gnupg} directory
 directly below the home directory of the user.  This option is ignored
 if used in an options file.
 
 @anchor{option --homedir}
 @include opt-homedir.texi
 
 
 @item -v
 @itemx --verbose
 @opindex verbose
 Outputs additional information while running.
 You can increase the verbosity by giving several
 verbose commands to @command{gpg-agent}, such as @samp{-vv}.
 
 @item -q
 @itemx --quiet
 @opindex quiet
 Try to be as quiet as possible.
 
 @item --batch
 @opindex batch
 Don't invoke a pinentry or do any other thing requiring human interaction.
 
 @item --faked-system-time @var{epoch}
 @opindex faked-system-time
 This option is only useful for testing; it sets the system time back or
 forth to @var{epoch} which is the number of seconds elapsed since the year
 1970.
 
 @item --debug-level @var{level}
 @opindex debug-level
 Select the debug level for investigating problems. @var{level} may be
 a numeric value or a keyword:
 
 @table @code
 @item none
 No debugging at all.  A value of less than 1 may be used instead of
 the keyword.
 @item basic
 Some basic debug messages.  A value between 1 and 2 may be used
 instead of the keyword.
 @item advanced
 More verbose debug messages.  A value between 3 and 5 may be used
 instead of the keyword.
 @item expert
 Even more detailed messages.  A value between 6 and 8 may be used
 instead of the keyword.
 @item guru
 All of the debug messages you can get. A value greater than 8 may be
 used instead of the keyword.  The creation of hash tracing files is
 only enabled if the keyword is used.
 @end table
 
 How these messages are mapped to the actual debugging flags is not
 specified and may change with newer releases of this program. They are
 however carefully selected to best aid in debugging.
 
 @item --debug @var{flags}
 @opindex debug
 Set debug flags.  All flags are or-ed and @var{flags} may be given
 in C syntax (e.g. 0x0042) or as a comma separated list of flag names.
 To get a list of all supported flags the single word "help" can be
 used. This option is only useful for debugging and the behavior may
 change at any time without notice.
 
 @item --debug-all
 @opindex debug-all
 Same as @code{--debug=0xffffffff}
 
 @item --debug-wait @var{n}
 @opindex debug-wait
 When running in server mode, wait @var{n} seconds before entering the
 actual processing loop and print the pid.  This gives time to attach a
 debugger.
 
 @item --debug-quick-random
 @opindex debug-quick-random
 This option inhibits the use of the very secure random quality level
 (Libgcrypt’s @code{GCRY_VERY_STRONG_RANDOM}) and degrades all request
 down to standard random quality.  It is only used for testing and
 should not be used for any production quality keys.  This option is
 only effective when given on the command line.
 
 On GNU/Linux, another way to quickly generate insecure keys is to use
 @command{rngd} to fill the kernel's entropy pool with lower quality
 random data.  @command{rngd} is typically provided by the
 @command{rng-tools} package.  It can be run as follows: @samp{sudo
 rngd -f -r /dev/urandom}.
 
 @item --debug-pinentry
 @opindex debug-pinentry
 This option enables extra debug information pertaining to the
 Pinentry.  As of now it is only useful when used along with
 @code{--debug 1024}.
 
 @item --no-detach
 @opindex no-detach
 Don't detach the process from the console.  This is mainly useful for
 debugging.
 
+@item --steal-socket
+@opindex steal-socket
+In @option{--daemon} mode, gpg-agent detects an already running
+gpg-agent and does not allow to start a new instance. This option can
+be used to override this check: the new gpg-agent process will try to
+take over the communication sockets from the already running process
+and start anyway.  This option should in general not be used.
+
+
 @item -s
 @itemx --sh
 @itemx -c
 @itemx --csh
 @opindex sh
 @opindex csh
 @efindex SHELL
 Format the info output in daemon mode for use with the standard Bourne
 shell or the C-shell respectively.  The default is to guess it based on
 the environment variable @code{SHELL} which is correct in almost all
 cases.
 
 
 @item --grab
 @itemx --no-grab
 @opindex grab
 @opindex no-grab
 Tell the pinentry to grab the keyboard and mouse.  This option should
 be used on X-Servers to avoid X-sniffing attacks. Any use of the
 option @option{--grab} overrides an used option @option{--no-grab}.
 The default is @option{--no-grab}.
 
 @anchor{option --log-file}
 @item --log-file @var{file}
 @opindex log-file
 @efindex HKCU\Software\GNU\GnuPG:DefaultLogFile
 Append all logging output to @var{file}.  This is very helpful in
 seeing what the agent actually does. Use @file{socket://} to log to
 socket.  If neither a log file nor a log file descriptor has been set
 on a Windows platform, the Registry entry
 @code{HKCU\Software\GNU\GnuPG:DefaultLogFile}, if set, is used to
 specify the logging output.
 
 
 @anchor{option --no-allow-mark-trusted}
 @item --no-allow-mark-trusted
 @opindex no-allow-mark-trusted
 Do not allow clients to mark keys as trusted, i.e. put them into the
 @file{trustlist.txt} file.  This makes it harder for users to inadvertently
 accept Root-CA keys.
 
 @anchor{option --allow-preset-passphrase}
 @item --allow-preset-passphrase
 @opindex allow-preset-passphrase
 This option allows the use of @command{gpg-preset-passphrase} to seed the
 internal cache of @command{gpg-agent} with passphrases.
 
 @anchor{option --no-allow-loopback-pinentry}
 @item --no-allow-loopback-pinentry
 @item --allow-loopback-pinentry
 @opindex no-allow-loopback-pinentry
 @opindex allow-loopback-pinentry
 Disallow or allow clients to use the loopback pinentry features; see
 the option @option{pinentry-mode} for details.  Allow is the default.
 
 The @option{--force} option of the Assuan command @command{DELETE_KEY}
 is also controlled by this option: The option is ignored if a loopback
 pinentry is disallowed.
 
 @item --no-allow-external-cache
 @opindex no-allow-external-cache
 Tell Pinentry not to enable features which use an external cache for
 passphrases.
 
 Some desktop environments prefer to unlock all
 credentials with one master password and may have installed a Pinentry
 which employs an additional external cache to implement such a policy.
 By using this option the Pinentry is advised not to make use of such a
 cache and instead always ask the user for the requested passphrase.
 
 @item --allow-emacs-pinentry
 @opindex allow-emacs-pinentry
 Tell Pinentry to allow features to divert the passphrase entry to a
 running Emacs instance.  How this is exactly handled depends on the
 version of the used Pinentry.
 
 @item --ignore-cache-for-signing
 @opindex ignore-cache-for-signing
 This option will let @command{gpg-agent} bypass the passphrase cache for all
 signing operation.  Note that there is also a per-session option to
 control this behavior but this command line option takes precedence.
 
 @item --default-cache-ttl @var{n}
 @opindex default-cache-ttl
 Set the time a cache entry is valid to @var{n} seconds.  The default
 is 600 seconds.  Each time a cache entry is accessed, the entry's
 timer is reset.  To set an entry's maximum lifetime, use
 @command{max-cache-ttl}.  Note that a cached passphrase may not be
 evicted immediately from memory if no client requests a cache
 operation.  This is due to an internal housekeeping function which is
 only run every few seconds.
 
 @item --default-cache-ttl-ssh @var{n}
 @opindex default-cache-ttl
 Set the time a cache entry used for SSH keys is valid to @var{n}
 seconds.  The default is 1800 seconds.  Each time a cache entry is
 accessed, the entry's timer is reset.  To set an entry's maximum
 lifetime, use @command{max-cache-ttl-ssh}.
 
 @item --max-cache-ttl @var{n}
 @opindex max-cache-ttl
 Set the maximum time a cache entry is valid to @var{n} seconds.  After
 this time a cache entry will be expired even if it has been accessed
 recently or has been set using @command{gpg-preset-passphrase}.  The
 default is 2 hours (7200 seconds).
 
 @item --max-cache-ttl-ssh @var{n}
 @opindex max-cache-ttl-ssh
 Set the maximum time a cache entry used for SSH keys is valid to
 @var{n} seconds.  After this time a cache entry will be expired even
 if it has been accessed recently or has been set using
 @command{gpg-preset-passphrase}.  The default is 2 hours (7200
 seconds).
 
 @item --enforce-passphrase-constraints
 @opindex enforce-passphrase-constraints
 Enforce the passphrase constraints by not allowing the user to bypass
 them using the ``Take it anyway'' button.
 
 @item --min-passphrase-len @var{n}
 @opindex min-passphrase-len
 Set the minimal length of a passphrase.  When entering a new passphrase
 shorter than this value a warning will be displayed.  Defaults to 8.
 
 @item --min-passphrase-nonalpha @var{n}
 @opindex min-passphrase-nonalpha
 Set the minimal number of digits or special characters required in a
 passphrase.  When entering a new passphrase with less than this number
 of digits or special characters a warning will be displayed.  Defaults
 to 1.
 
 @item --check-passphrase-pattern @var{file}
 @itemx --check-sym-passphrase-pattern @var{file}
 @opindex check-passphrase-pattern
 @opindex check-sym-passphrase-pattern
 Check the passphrase against the pattern given in @var{file}.  When
 entering a new passphrase matching one of these pattern a warning will
 be displayed.  If @var{file} does not contain any slashes and does not
 start with "~/" it is searched in the system configuration directory
 (@file{@value{SYSCONFDIR}}).  The default is not to use any
 pattern file.  The second version of this option is only used when
 creating a new symmetric key to allow the use of different patterns
 for such passphrases.
 
 Security note: It is known that checking a passphrase against a list of
 pattern or even against a complete dictionary is not very effective to
 enforce good passphrases.  Users will soon figure up ways to bypass such
 a policy.  A better policy is to educate users on good security
 behavior and optionally to run a passphrase cracker regularly on all
 users passphrases to catch the very simple ones.
 
 @item --max-passphrase-days @var{n}
 @opindex max-passphrase-days
 Ask the user to change the passphrase if @var{n} days have passed since
 the last change.  With @option{--enforce-passphrase-constraints} set the
 user may not bypass this check.
 
 @item --enable-passphrase-history
 @opindex enable-passphrase-history
 This option does nothing yet.
 
 @item --pinentry-invisible-char @var{char}
 @opindex pinentry-invisible-char
 This option asks the Pinentry to use @var{char} for displaying hidden
 characters.  @var{char} must be one character UTF-8 string.  A
 Pinentry may or may not honor this request.
 
 @item --pinentry-timeout @var{n}
 @opindex pinentry-timeout
 This option asks the Pinentry to timeout after @var{n} seconds with no
 user input.  The default value of 0 does not ask the pinentry to
 timeout, however a Pinentry may use its own default timeout value in
 this case.  A Pinentry may or may not honor this request.
 
 @item --pinentry-formatted-passphrase
 @opindex pinentry-formatted-passphrase
 This option asks the Pinentry to enable passphrase formatting when asking the
 user for a new passphrase and masking of the passphrase is turned off.
 
 If passphrase formatting is enabled, then all non-breaking space characters
 are stripped from the entered passphrase.  Passphrase formatting is mostly
 useful in combination with passphrases generated with the GENPIN
 feature of some Pinentries.  Note that such a generated
 passphrase, if not modified by the user, skips all passphrase
 constraints checking because such constraints would actually weaken
 the generated passphrase.
 
 @item --pinentry-program @var{filename}
 @opindex pinentry-program
 Use program @var{filename} as the PIN entry.  The default is
 installation dependent.  With the default configuration the name of
 the default pinentry is @file{pinentry}; if that file does not exist
 but a @file{pinentry-basic} exist the latter is used.
 
 On a Windows platform the default is to use the first existing program
 from this list:
 @file{bin\pinentry.exe},
 @file{..\Gpg4win\bin\pinentry.exe},
 @file{..\Gpg4win\pinentry.exe},
 @file{..\GNU\GnuPG\pinentry.exe},
 @file{..\GNU\bin\pinentry.exe},
 @file{bin\pinentry-basic.exe}
 where the file names are relative to the GnuPG installation directory.
 
 
 @item --pinentry-touch-file @var{filename}
 @opindex pinentry-touch-file
 By default the filename of the socket gpg-agent is listening for
 requests is passed to Pinentry, so that it can touch that file before
 exiting (it does this only in curses mode).  This option changes the
 file passed to Pinentry to @var{filename}.  The special name
 @code{/dev/null} may be used to completely disable this feature.  Note
 that Pinentry will not create that file, it will only change the
 modification and access time.
 
 
 @item --scdaemon-program @var{filename}
 @opindex scdaemon-program
 Use program @var{filename} as the Smartcard daemon.  The default is
 installation dependent and can be shown with the @command{gpgconf}
 command.
 
 @item --disable-scdaemon
 @opindex disable-scdaemon
 Do not make use of the scdaemon tool.  This option has the effect of
 disabling the ability to do smartcard operations.  Note, that enabling
 this option at runtime does not kill an already forked scdaemon.
 
 @item --disable-check-own-socket
 @opindex disable-check-own-socket
 @command{gpg-agent} employs a periodic self-test to detect a stolen
 socket.  This usually means a second instance of @command{gpg-agent}
 has taken over the socket and @command{gpg-agent} will then terminate
 itself.  This option may be used to disable this self-test for
 debugging purposes.
 
 @item --use-standard-socket
 @itemx --no-use-standard-socket
 @itemx --use-standard-socket-p
 @opindex use-standard-socket
 @opindex no-use-standard-socket
 @opindex use-standard-socket-p
 Since GnuPG 2.1 the standard socket is always used.  These options
 have no more effect.  The command @code{gpg-agent
 --use-standard-socket-p} will thus always return success.
 
 @item --display @var{string}
 @itemx --ttyname @var{string}
 @itemx --ttytype @var{string}
 @itemx --lc-ctype @var{string}
 @itemx --lc-messages @var{string}
 @itemx --xauthority @var{string}
 @opindex display
 @opindex ttyname
 @opindex ttytype
 @opindex lc-ctype
 @opindex lc-messages
 @opindex xauthority
 These options are used with the server mode to pass localization
 information.
 
 @item --keep-tty
 @itemx --keep-display
 @opindex keep-tty
 @opindex keep-display
 Ignore requests to change the current @code{tty} or X window system's
 @code{DISPLAY} variable respectively.  This is useful to lock the
 pinentry to pop up at the @code{tty} or display you started the agent.
 
 @item --listen-backlog @var{n}
 @opindex listen-backlog
 Set the size of the queue for pending connections.  The default is 64.
 
 @anchor{option --extra-socket}
 @item --extra-socket @var{name}
 @opindex extra-socket
 The extra socket is created by default, you may use this option to
 change the name of the socket.  To disable the creation of the socket
 use ``none'' or ``/dev/null'' for @var{name}.
 
 Also listen on native gpg-agent connections on the given socket.  The
 intended use for this extra socket is to setup a Unix domain socket
 forwarding from a remote machine to this socket on the local machine.
 A @command{gpg} running on the remote machine may then connect to the
 local gpg-agent and use its private keys.  This enables decrypting or
 signing data on a remote machine without exposing the private keys to the
 remote machine.
 
 @item --enable-extended-key-format
 @itemx --disable-extended-key-format
 @opindex enable-extended-key-format
 @opindex disable-extended-key-format
 Since version 2.3 keys are created in the extended private key format.
 Changing the passphrase of a key will also convert the key to that new
 format.  This new key format is supported since GnuPG version 2.1.12
 and thus there should be no need to disable it.  The disable option
 allows to revert to the old behavior for new keys; be aware that keys
 are never migrated back to the old format.  However if the enable
 option has been used the disable option won't have an effect.  The
 advantage of the extended private key format is that it is text based
 and can carry additional meta data.
 
 @anchor{option --enable-ssh-support}
 @item --enable-ssh-support
 @itemx --enable-putty-support
 @opindex enable-ssh-support
 @opindex enable-putty-support
 
 The OpenSSH Agent protocol is always enabled, but @command{gpg-agent}
 will only set the @code{SSH_AUTH_SOCK} variable if this flag is given.
 
 In this mode of operation, the agent does not only implement the
 gpg-agent protocol, but also the agent protocol used by OpenSSH
 (through a separate socket).  Consequently, it should be possible to use
 the gpg-agent as a drop-in replacement for the well known ssh-agent.
 
 SSH Keys, which are to be used through the agent, need to be added to
 the gpg-agent initially through the ssh-add utility.  When a key is
 added, ssh-add will ask for the password of the provided key file and
 send the unprotected key material to the agent; this causes the
 gpg-agent to ask for a passphrase, which is to be used for encrypting
 the newly received key and storing it in a gpg-agent specific
 directory.
 
 Once a key has been added to the gpg-agent this way, the gpg-agent
 will be ready to use the key.
 
 Note: in case the gpg-agent receives a signature request, the user might
 need to be prompted for a passphrase, which is necessary for decrypting
 the stored key.  Since the ssh-agent protocol does not contain a
 mechanism for telling the agent on which display/terminal it is running,
 gpg-agent's ssh-support will use the TTY or X display where gpg-agent
 has been started.  To switch this display to the current one, the
 following command may be used:
 
 @smallexample
 gpg-connect-agent updatestartuptty /bye
 @end smallexample
 
 Although all GnuPG components try to start the gpg-agent as needed, this
 is not possible for the ssh support because ssh does not know about it.
 Thus if no GnuPG tool which accesses the agent has been run, there is no
 guarantee that ssh is able to use gpg-agent for authentication.  To fix
 this you may start gpg-agent if needed using this simple command:
 
 @smallexample
 gpg-connect-agent /bye
 @end smallexample
 
 Adding the @option{--verbose} shows the progress of starting the agent.
 
 The @option{--enable-putty-support} is only available under Windows
 and allows the use of gpg-agent with the ssh implementation
 @command{putty}.  This is similar to the regular ssh-agent support but
 makes use of Windows message queue as required by @command{putty}.
 
 @anchor{option --ssh-fingerprint-digest}
 @item --ssh-fingerprint-digest
 @opindex ssh-fingerprint-digest
 
 Select the digest algorithm used to compute ssh fingerprints that are
 communicated to the user, e.g. in pinentry dialogs.  OpenSSH has
 transitioned from using MD5 to the more secure SHA256.
 
 
 @item --auto-expand-secmem @var{n}
 @opindex auto-expand-secmem
 Allow Libgcrypt to expand its secure memory area as required.  The
 optional value @var{n} is a non-negative integer with a suggested size
 in bytes of each additionally allocated secure memory area.  The value
 is rounded up to the next 32 KiB; usual C style prefixes are allowed.
 For an heavy loaded gpg-agent with many concurrent connection this
 option avoids sign or decrypt errors due to out of secure memory error
 returns.
 
 @item --s2k-calibration @var{milliseconds}
 @opindex s2k-calibration
 Change the default calibration time to @var{milliseconds}.  The given
 value is capped at 60 seconds; a value of 0 resets to the compiled-in
 default.  This option is re-read on a SIGHUP (or @code{gpgconf
 --reload gpg-agent}) and the S2K count is then re-calibrated.
 
 @item --s2k-count @var{n}
 @opindex s2k-count
 Specify the iteration count used to protect the passphrase.  This
 option can be used to override the auto-calibration done by default.
 The auto-calibration computes a count which requires by default 100ms
 to mangle a given passphrase.  See also @option{--s2k-calibration}.
 
 To view the actually used iteration count and the milliseconds
 required for an S2K operation use:
 
 @example
 gpg-connect-agent 'GETINFO s2k_count' /bye
 gpg-connect-agent 'GETINFO s2k_time' /bye
 @end example
 
 To view the auto-calibrated count use:
 
 @example
 gpg-connect-agent 'GETINFO s2k_count_cal' /bye
 @end example
 
 
 @end table
 
 
 @mansect files
 @node Agent Configuration
 @section Configuration
 
 There are a few configuration files needed for the operation of the
 agent. By default they may all be found in the current home directory
 (@pxref{option --homedir}).
 
 @table @file
 
 @item gpg-agent.conf
 @efindex gpg-agent.conf
   This is the standard configuration file read by @command{gpg-agent} on
   startup.  It may contain any valid long option; the leading
   two dashes may not be entered and the option may not be abbreviated.
   This file is also read after a @code{SIGHUP} however only a few
   options will actually have an effect.  This default name may be
   changed on the command line (@pxref{option --options}).
   You should backup this file.
 
 @item trustlist.txt
 @efindex trustlist.txt
   This is the list of trusted keys.  You should backup this file.
 
   Comment lines, indicated by a leading hash mark, as well as empty
   lines are ignored.  To mark a key as trusted you need to enter its
   fingerprint followed by a space and a capital letter @code{S}.  Colons
   may optionally be used to separate the bytes of a fingerprint; this
   enables cutting and pasting the fingerprint from a key listing output.  If
   the line is prefixed with a @code{!} the key is explicitly marked as
   not trusted.
 
   Here is an example where two keys are marked as ultimately trusted
   and one as not trusted:
 
   @cartouche
   @smallexample
   # CN=Wurzel ZS 3,O=Intevation GmbH,C=DE
   A6935DD34EF3087973C706FC311AA2CCF733765B S
 
   # CN=PCA-1-Verwaltung-02/O=PKI-1-Verwaltung/C=DE
   DC:BD:69:25:48:BD:BB:7E:31:6E:BB:80:D3:00:80:35:D4:F8:A6:CD S
 
   # CN=Root-CA/O=Schlapphuete/L=Pullach/C=DE
   !14:56:98:D3:FE:9C:CA:5A:31:6E:BC:81:D3:11:4E:00:90:A3:44:C2 S
   @end smallexample
   @end cartouche
 
 Before entering a key into this file, you need to ensure its
 authenticity.  How to do this depends on your organisation; your
 administrator might have already entered those keys which are deemed
 trustworthy enough into this file.  Places where to look for the
 fingerprint of a root certificate are letters received from the CA or
 the website of the CA (after making 100% sure that this is indeed the
 website of that CA).  You may want to consider disallowing interactive
 updates of this file by using the @ref{option --no-allow-mark-trusted}.
 It might even be advisable to change the permissions to read-only so
 that this file can't be changed inadvertently.
 
 As a special feature a line @code{include-default} will include a global
 list of trusted certificates (e.g. @file{@value{SYSCONFDIR}/trustlist.txt}).
 This global list is also used if the local list is not available.
 
 It is possible to add further flags after the @code{S} for use by the
 caller:
 
 @table @code
 
 @item relax
 @cindex relax
 Relax checking of some root certificate requirements.  As of now this
 flag allows the use of root certificates with a missing basicConstraints
 attribute (despite that it is a MUST for CA certificates) and disables
 CRL checking for the root certificate.
 
 @item cm
 If validation of a certificate finally issued by a CA with this flag set
 fails, try again using the chain validation model.
 
 @end table
 
 
 @item sshcontrol
 @efindex sshcontrol
 This file is used when support for the secure shell agent protocol has
 been enabled (@pxref{option --enable-ssh-support}). Only keys present in
 this file are used in the SSH protocol.  You should backup this file.
 
 The @command{ssh-add} tool may be used to add new entries to this file;
 you may also add them manually.  Comment lines, indicated by a leading
 hash mark, as well as empty lines are ignored.  An entry starts with
 optional whitespace, followed by the keygrip of the key given as 40 hex
 digits, optionally followed by the caching TTL in seconds and another
 optional field for arbitrary flags.  A non-zero TTL overrides the global
 default as set by @option{--default-cache-ttl-ssh}.
 
 The only flag support is @code{confirm}.  If this flag is found for a
 key, each use of the key will pop up a pinentry to confirm the use of
 that key.  The flag is automatically set if a new key was loaded into
 @code{gpg-agent} using the option @option{-c} of the @code{ssh-add}
 command.
 
 The keygrip may be prefixed with a @code{!} to disable an entry.
 
 The following example lists exactly one key.  Note that keys available
 through a OpenPGP smartcard in the active smartcard reader are
 implicitly added to this list; i.e. there is no need to list them.
 
 @cartouche
 @smallexample
        # Key added on: 2011-07-20 20:38:46
        # Fingerprint:  5e:8d:c4:ad:e7:af:6e:27:8a:d6:13:e4:79:ad:0b:81
        34B62F25E277CF13D3C6BCEBFD3F85D08F0A864B 0 confirm
 @end smallexample
 @end cartouche
 
 @item private-keys-v1.d/
 @efindex private-keys-v1.d
 
   This is the directory where gpg-agent stores the private keys.  Each
   key is stored in a file with the name made up of the keygrip and the
   suffix @file{key}.  You should backup all files in this directory
   and take great care to keep this backup closed away.
 
 
 @end table
 
 Note that on larger installations, it is useful to put predefined
 files into the directory @file{@value{SYSCONFSKELDIR}} so that newly created
 users start up with a working configuration.  For existing users the
 a small helper script is provided to create these files (@pxref{addgnupghome}).
 
 
 
 @c
 @c Agent Signals
 @c
 @mansect signals
 @node Agent Signals
 @section Use of some signals
 A running @command{gpg-agent} may be controlled by signals, i.e. using
 the @command{kill} command to send a signal to the process.
 
 Here is a list of supported signals:
 
 @table @gnupgtabopt
 
 @item SIGHUP
 @cpindex SIGHUP
 This signal flushes all cached passphrases and if the program has been
 started with a configuration file, the configuration file is read
 again.  Only certain options are honored: @code{quiet},
 @code{verbose}, @code{debug}, @code{debug-all}, @code{debug-level},
 @code{debug-pinentry},
 @code{no-grab},
 @code{pinentry-program},
 @code{pinentry-invisible-char},
 @code{default-cache-ttl},
 @code{max-cache-ttl}, @code{ignore-cache-for-signing},
 @code{s2k-count},
 @code{no-allow-external-cache}, @code{allow-emacs-pinentry},
 @code{no-allow-mark-trusted}, @code{disable-scdaemon}, and
 @code{disable-check-own-socket}.  @code{scdaemon-program} is also
 supported but due to the current implementation, which calls the
 scdaemon only once, it is not of much use unless you manually kill the
 scdaemon.
 
 
 @item SIGTERM
 @cpindex SIGTERM
 Shuts down the process but waits until all current requests are
 fulfilled.  If the process has received 3 of these signals and requests
 are still pending, a shutdown is forced.
 
 @item SIGINT
 @cpindex SIGINT
 Shuts down the process immediately.
 
 @item SIGUSR1
 @cpindex SIGUSR1
 Dump internal information to the log file.
 
 @item SIGUSR2
 @cpindex SIGUSR2
 This signal is used for internal purposes.
 
 @end table
 
 @c
 @c  Examples
 @c
 @mansect examples
 @node Agent Examples
 @section Examples
 
 It is important to set the environment variable @code{GPG_TTY} in
 your login shell, for example in the @file{~/.bashrc} init script:
 
 @cartouche
 @example
   export GPG_TTY=$(tty)
 @end example
 @end cartouche
 
 If you enabled the Ssh Agent Support, you also need to tell ssh about
 it by adding this to your init script:
 
 @cartouche
 @example
 unset SSH_AGENT_PID
 if [ "$@{gnupg_SSH_AUTH_SOCK_by:-0@}" -ne $$ ]; then
   export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
 fi
 @end example
 @end cartouche
 
 
 @c
 @c  Assuan Protocol
 @c
 @manpause
 @node Agent Protocol
 @section Agent's Assuan Protocol
 
 Note: this section does only document the protocol, which is used by
 GnuPG components; it does not deal with the ssh-agent protocol.  To
 see the full specification of each command, use
 
 @example
   gpg-connect-agent 'help COMMAND' /bye
 @end example
 
 @noindent
 or just 'help' to list all available commands.
 
 @noindent
 The @command{gpg-agent} daemon is started on demand by the GnuPG
 components.
 
 To identify a key we use a thing called keygrip which is the SHA-1 hash
 of an canonical encoded S-Expression of the public key as used in
 Libgcrypt.  For the purpose of this interface the keygrip is given as a
 hex string.  The advantage of using this and not the hash of a
 certificate is that it will be possible to use the same keypair for
 different protocols, thereby saving space on the token used to keep the
 secret keys.
 
 The @command{gpg-agent} may send status messages during a command or when
 returning from a command to inform a client about the progress or result of an
 operation.  For example, the @var{INQUIRE_MAXLEN} status message may be sent
 during a server inquire to inform the client of the maximum usable length of
 the inquired data (which should not be exceeded).
 
 @menu
 * Agent PKDECRYPT::       Decrypting a session key
 * Agent PKSIGN::          Signing a Hash
 * Agent GENKEY::          Generating a Key
 * Agent IMPORT::          Importing a Secret Key
 * Agent EXPORT::          Exporting a Secret Key
 * Agent ISTRUSTED::       Importing a Root Certificate
 * Agent GET_PASSPHRASE::  Ask for a passphrase
 * Agent CLEAR_PASSPHRASE:: Expire a cached passphrase
 * Agent PRESET_PASSPHRASE:: Set a passphrase for a keygrip
 * Agent GET_CONFIRMATION:: Ask for confirmation
 * Agent HAVEKEY::         Check whether a key is available
 * Agent LEARN::           Register a smartcard
 * Agent PASSWD::          Change a Passphrase
 * Agent UPDATESTARTUPTTY:: Change the Standard Display
 * Agent GETEVENTCOUNTER:: Get the Event Counters
 * Agent GETINFO::         Return information about the process
 * Agent OPTION::          Set options for the session
 @end menu
 
 @node Agent PKDECRYPT
 @subsection Decrypting a session key
 
 The client asks the server to decrypt a session key.  The encrypted
 session key should have all information needed to select the
 appropriate secret key or to delegate it to a smartcard.
 
 @example
   SETKEY <keyGrip>
 @end example
 
 Tell the server about the key to be used for decryption.  If this is
 not used, @command{gpg-agent} may try to figure out the key by trying to
 decrypt the message with each key available.
 
 @example
   PKDECRYPT
 @end example
 
 The agent checks whether this command is allowed and then does an
 INQUIRY to get the ciphertext the client should then send the cipher
 text.
 
 @example
     S: INQUIRE CIPHERTEXT
     C: D (xxxxxx
     C: D xxxx)
     C: END
 @end example
 
 Please note that the server may send status info lines while reading the
 data lines from the client.  The data send is a SPKI like S-Exp with
 this structure:
 
 @example
      (enc-val
        (<algo>
          (<param_name1> <mpi>)
  	   ...
          (<param_namen> <mpi>)))
 @end example
 
 Where algo is a string with the name of the algorithm; see the libgcrypt
 documentation for a list of valid algorithms.  The number and names of
 the parameters depend on the algorithm.  The agent does return an error
 if there is an inconsistency.
 
 If the decryption was successful the decrypted data is returned by
 means of "D" lines.
 
 Here is an example session:
 @cartouche
 @smallexample
    C: PKDECRYPT
    S: INQUIRE CIPHERTEXT
    C: D (enc-val elg (a 349324324)
    C: D    (b 3F444677CA)))
    C: END
    S: # session key follows
    S: S PADDING 0
    S: D (value 1234567890ABCDEF0)
    S: OK decryption successful
 @end smallexample
 @end cartouche
 
 The “PADDING” status line is only send if gpg-agent can tell what kind
 of padding is used.  As of now only the value 0 is used to indicate
 that the padding has been removed.
 
 
 @node Agent PKSIGN
 @subsection Signing a Hash
 
 The client asks the agent to sign a given hash value.  A default key
 will be chosen if no key has been set.  To set a key a client first
 uses:
 
 @example
    SIGKEY <keyGrip>
 @end example
 
 This can be used multiple times to create multiple signature, the list
 of keys is reset with the next PKSIGN command or a RESET.  The server
 tests whether the key is a valid key to sign something and responds with
 okay.
 
 @example
    SETHASH --hash=<name>|<algo> <hexstring>
 @end example
 
 The client can use this command to tell the server about the data <hexstring>
 (which usually is a hash) to be signed. <algo> is the decimal encoded hash
 algorithm number as used by Libgcrypt.  Either <algo> or --hash=<name>
 must be given.  Valid names for <name> are:
 
 @table @code
 @item sha1
 The SHA-1 hash algorithm
 @item sha256
 The SHA-256 hash algorithm
 @item rmd160
 The RIPE-MD160 hash algorithm
 @item md5
 The old and broken MD5 hash algorithm
 @item tls-md5sha1
 A combined hash algorithm as used by the TLS protocol.
 @end table
 
 @noindent
 The actual signing is done using
 
 @example
    PKSIGN <options>
 @end example
 
 Options are not yet defined, but may later be used to choose among
 different algorithms.  The agent does then some checks, asks for the
 passphrase and as a result the server returns the signature as an SPKI
 like S-expression in "D" lines:
 
 @example
      (sig-val
        (<algo>
          (<param_name1> <mpi>)
  	   ...
          (<param_namen> <mpi>)))
 @end example
 
 
 The operation is affected by the option
 
 @example
    OPTION use-cache-for-signing=0|1
 @end example
 
 The default of @code{1} uses the cache.  Setting this option to @code{0}
 will lead @command{gpg-agent} to ignore the passphrase cache.  Note, that there is
 also a global command line option for @command{gpg-agent} to globally disable the
 caching.
 
 
 Here is an example session:
 @cartouche
 @smallexample
    C: SIGKEY <keyGrip>
    S: OK key available
    C: SIGKEY <keyGrip>
    S: OK key available
    C: PKSIGN
    S: # I did ask the user whether he really wants to sign
    S: # I did ask the user for the passphrase
    S: INQUIRE HASHVAL
    C: D ABCDEF012345678901234
    C: END
    S: # signature follows
    S: D (sig-val rsa (s 45435453654612121212))
    S: OK
 @end smallexample
 @end cartouche
 
 @node Agent GENKEY
 @subsection Generating a Key
 
 This is used to create a new keypair and store the secret key inside the
 active PSE --- which is in most cases a Soft-PSE.  A not-yet-defined
 option allows choosing the storage location.  To get the secret key out
 of the PSE, a special export tool has to be used.
 
 @example
    GENKEY [--no-protection] [--preset] [<cache_nonce>]
 @end example
 
 Invokes the key generation process and the server will then inquire
 on the generation parameters, like:
 
 @example
    S: INQUIRE KEYPARM
    C: D (genkey (rsa (nbits  1024)))
    C: END
 @end example
 
 The format of the key parameters which depends on the algorithm is of
 the form:
 
 @example
     (genkey
       (algo
         (parameter_name_1 ....)
           ....
         (parameter_name_n ....)))
 @end example
 
 If everything succeeds, the server returns the *public key* in a SPKI
 like S-Expression like this:
 
 @example
      (public-key
        (rsa
  	 (n <mpi>)
  	 (e <mpi>)))
 @end example
 
 Here is an example session:
 @cartouche
 @smallexample
    C: GENKEY
    S: INQUIRE KEYPARM
    C: D (genkey (rsa (nbits  1024)))
    C: END
    S: D (public-key
    S: D   (rsa (n 326487324683264) (e 10001)))
    S  OK key created
 @end smallexample
 @end cartouche
 
 The @option{--no-protection} option may be used to prevent prompting for a
 passphrase to protect the secret key while leaving the secret key unprotected.
 The @option{--preset} option may be used to add the passphrase to the cache
 using the default cache parameters.
 
 The @option{--inq-passwd} option may be used to create the key with a
 supplied passphrase.  When used the agent does an inquiry with the
 keyword @code{NEWPASSWD} to retrieve that passphrase.  This option
 takes precedence over @option{--no-protection}; however if the client
 sends a empty (zero-length) passphrase, this is identical to
 @option{--no-protection}.
 
 @node Agent IMPORT
 @subsection Importing a Secret Key
 
 This operation is not yet supported by GpgAgent.  Specialized tools
 are to be used for this.
 
 There is no actual need because we can expect that secret keys
 created by a 3rd party are stored on a smartcard.  If we have
 generated the key ourselves, we do not need to import it.
 
 @node Agent EXPORT
 @subsection Export a Secret Key
 
 Not implemented.
 
 Should be done by an extra tool.
 
 @node Agent ISTRUSTED
 @subsection Importing a Root Certificate
 
 Actually we do not import a Root Cert but provide a way to validate
 any piece of data by storing its Hash along with a description and
 an identifier in the PSE.  Here is the interface description:
 
 @example
     ISTRUSTED <fingerprint>
 @end example
 
 Check whether the OpenPGP primary key or the X.509 certificate with the
 given fingerprint is an ultimately trusted key or a trusted Root CA
 certificate.  The fingerprint should be given as a hexstring (without
 any blanks or colons or whatever in between) and may be left padded with
 00 in case of an MD5 fingerprint.  GPGAgent will answer with:
 
 @example
     OK
 @end example
 
 The key is in the table of trusted keys.
 
 @example
     ERR 304 (Not Trusted)
 @end example
 
 The key is not in this table.
 
 Gpg needs the entire list of trusted keys to maintain the web of
 trust; the following command is therefore quite helpful:
 
 @example
     LISTTRUSTED
 @end example
 
 GpgAgent returns a list of trusted keys line by line:
 
 @example
     S: D 000000001234454556565656677878AF2F1ECCFF P
     S: D 340387563485634856435645634856438576457A P
     S: D FEDC6532453745367FD83474357495743757435D S
     S: OK
 @end example
 
 The first item on a line is the hexified fingerprint where MD5
 fingerprints are @code{00} padded to the left and the second item is a
 flag to indicate the type of key (so that gpg is able to only take care
 of PGP keys).  P = OpenPGP, S = S/MIME.  A client should ignore the rest
 of the line, so that we can extend the format in the future.
 
 Finally a client should be able to mark a key as trusted:
 
 @example
    MARKTRUSTED @var{fingerprint} "P"|"S"
 @end example
 
 The server will then pop up a window to ask the user whether she
 really trusts this key. For this it will probably ask for a text to
 be displayed like this:
 
 @example
    S: INQUIRE TRUSTDESC
    C: D Do you trust the key with the fingerprint @@FPR@@
    C: D bla fasel blurb.
    C: END
    S: OK
 @end example
 
 Known sequences with the pattern @@foo@@ are replaced according to this
 table:
 
 @table @code
 @item @@FPR16@@
 Format the fingerprint according to gpg rules for a v3 keys.
 @item @@FPR20@@
 Format the fingerprint according to gpg rules for a v4 keys.
 @item @@FPR@@
 Choose an appropriate format to format the fingerprint.
 @item @@@@
 Replaced by a single @code{@@}.
 @end table
 
 @node Agent GET_PASSPHRASE
 @subsection Ask for a passphrase
 
 This function is usually used to ask for a passphrase to be used for
 symmetric encryption, but may also be used by programs which need
 special handling of passphrases.  This command uses a syntax which helps
 clients to use the agent with minimum effort.
 
 @example
   GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] \
                  [--qualitybar] @var{cache_id}                \
                  [@var{error_message} @var{prompt} @var{description}]
 @end example
 
 @var{cache_id} is expected to be a string used to identify a cached
 passphrase.  Use a @code{X} to bypass the cache.  With no other
 arguments the agent returns a cached passphrase or an error.  By
 convention either the hexified fingerprint of the key shall be used for
 @var{cache_id} or an arbitrary string prefixed with the name of the
 calling application and a colon: Like @code{gpg:somestring}.
 
 @var{error_message} is either a single @code{X} for no error message or
 a string to be shown as an error message like (e.g. "invalid
 passphrase").  Blanks must be percent escaped or replaced by @code{+}'.
 
 @var{prompt} is either a single @code{X} for a default prompt or the
 text to be shown as the prompt.  Blanks must be percent escaped or
 replaced by @code{+}.
 
 @var{description} is a text shown above the entry field.  Blanks must be
 percent escaped or replaced by @code{+}.
 
 The agent either returns with an error or with a OK followed by the hex
 encoded passphrase.  Note that the length of the strings is implicitly
 limited by the maximum length of a command.  If the option
 @option{--data} is used, the passphrase is not returned on the OK line
 but by regular data lines; this is the preferred method.
 
 If the option @option{--check} is used, the standard passphrase
 constraints checks are applied.  A check is not done if the passphrase
 has been found in the cache.
 
 If the option @option{--no-ask} is used and the passphrase is not in the
 cache the user will not be asked to enter a passphrase but the error
 code @code{GPG_ERR_NO_DATA} is returned.
 
 If the option @option{--qualitybar} is used and a minimum passphrase
 length has been configured, a visual indication of the entered
 passphrase quality is shown.
 
 @example
   CLEAR_PASSPHRASE @var{cache_id}
 @end example
 
 may be used to invalidate the cache entry for a passphrase.  The
 function returns with OK even when there is no cached passphrase.
 
 
 
 @node Agent CLEAR_PASSPHRASE
 @subsection Remove a cached passphrase
 
 Use this command to remove a cached passphrase.
 
 @example
   CLEAR_PASSPHRASE [--mode=normal] <cache_id>
 @end example
 
 The @option{--mode=normal} option can be used to clear a @var{cache_id} that
 was set by gpg-agent.
 
 
 @node Agent PRESET_PASSPHRASE
 @subsection Set a passphrase for a keygrip
 
 This command adds a passphrase to the cache for the specified @var{keygrip}.
 
 @example
   PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]
 @end example
 
 The passphrase is a hexadecimal string when specified. When not specified, the
 passphrase will be retrieved from the pinentry module unless the
 @option{--inquire} option was specified in which case the passphrase will be
 retrieved from the client.
 
 The @var{timeout} parameter keeps the passphrase cached for the specified
 number of seconds. A value of @code{-1} means infinite while @code{0} means
 the default (currently only a timeout of -1 is allowed, which means to never
 expire it).
 
 
 @node Agent GET_CONFIRMATION
 @subsection Ask for confirmation
 
 This command may be used to ask for a simple confirmation by
 presenting a text and 2 buttons: Okay and Cancel.
 
 @example
   GET_CONFIRMATION @var{description}
 @end example
 
 @var{description}is displayed along with a Okay and Cancel
 button. Blanks must be percent escaped or replaced by @code{+}.  A
 @code{X} may be used to display confirmation dialog with a default
 text.
 
 The agent either returns with an error or with a OK.  Note, that the
 length of @var{description} is implicitly limited by the maximum
 length of a command.
 
 
 
 @node Agent HAVEKEY
 @subsection Check whether a key is available
 
 This can be used to see whether a secret key is available.  It does
 not return any information on whether the key is somehow protected.
 
 @example
   HAVEKEY @var{keygrips}
 @end example
 
 The agent answers either with OK or @code{No_Secret_Key} (208).  The
 caller may want to check for other error codes as well.  More than one
 keygrip may be given.  In this case the command returns success if at
 least one of the keygrips corresponds to an available secret key.
 
 
 @node Agent LEARN
 @subsection Register a smartcard
 
 @example
   LEARN [--send]
 @end example
 
 This command is used to register a smartcard.  With the @option{--send}
 option given the certificates are sent back.
 
 
 @node Agent PASSWD
 @subsection Change a Passphrase
 
 @example
   PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset] @var{keygrip}
 @end example
 
 This command is used to interactively change the passphrase of the key
 identified by the hex string @var{keygrip}.  The @option{--preset}
 option may be used to add the new passphrase to the cache using the
 default cache parameters.
 
 
 @node Agent UPDATESTARTUPTTY
 @subsection Change the standard display
 
 @example
   UPDATESTARTUPTTY
 @end example
 
 Set the startup TTY and X-DISPLAY variables to the values of this
 session.  This command is useful to direct future pinentry invocations
 to another screen.  It is only required because there is no way in the
 ssh-agent protocol to convey this information.
 
 
 @node Agent GETEVENTCOUNTER
 @subsection Get the Event Counters
 
 @example
   GETEVENTCOUNTER
 @end example
 
 This function return one status line with the current values of the
 event counters.  The event counters are useful to avoid polling by
 delaying a poll until something has changed.  The values are decimal
 numbers in the range @code{0} to @code{UINT_MAX} and wrapping around to
 0.  The actual values should not be relied upon; they shall only be used
 to detect a change.
 
 The currently defined counters are:
 @table @code
 @item ANY
 Incremented with any change of any of the other counters.
 @item KEY
 Incremented for added or removed private keys.
 @item CARD
 Incremented for each change of the card reader's status.
 @end table
 
 @node Agent GETINFO
 @subsection  Return information about the process
 
 This is a multipurpose function to return a variety of information.
 
 @example
 GETINFO @var{what}
 @end example
 
 The value of @var{what} specifies the kind of information returned:
 @table @code
 @item version
 Return the version of the program.
 @item pid
 Return the process id of the process.
 @item socket_name
 Return the name of the socket used to connect the agent.
 @item ssh_socket_name
 Return the name of the socket used for SSH connections.  If SSH support
 has not been enabled the error @code{GPG_ERR_NO_DATA} will be returned.
 @end table
 
 @node Agent OPTION
 @subsection Set options for the session
 
 Here is a list of session options which are not yet described with
 other commands.  The general syntax for an Assuan option is:
 
 @smallexample
 OPTION  @var{key}=@var{value}
 @end smallexample
 
 @noindent
 Supported @var{key}s are:
 
 @table @code
 @item agent-awareness
 This may be used to tell gpg-agent of which gpg-agent version the
 client is aware of.  gpg-agent uses this information to enable
 features which might break older clients.
 
 @item putenv
 Change the session's environment to be used for the
 Pinentry.  Valid values are:
 
   @table @code
   @item @var{name}
   Delete envvar @var{name}
   @item @var{name}=
   Set envvar @var{name} to the empty string
   @item @var{name}=@var{value}
   Set envvar @var{name} to the string @var{value}.
   @end table
 
 @item use-cache-for-signing
 See Assuan command @code{PKSIGN}.
 
 @item allow-pinentry-notify
 This does not need any value.  It is used to enable the
 PINENTRY_LAUNCHED inquiry.
 
 @item pinentry-mode
 This option is used to change the operation mode of the pinentry.  The
 following values are defined:
 
   @table @code
   @item ask
   This is the default mode which pops up a pinentry as needed.
 
   @item cancel
   Instead of popping up a pinentry, return the error code
   @code{GPG_ERR_CANCELED}.
 
   @item error
   Instead of popping up a pinentry, return the error code
   @code{GPG_ERR_NO_PIN_ENTRY}.
 
   @item loopback
   Use a loopback pinentry.  This fakes a pinentry by using inquiries
   back to the caller to ask for a passphrase.  This option may only be
   set if the agent has been configured for that.
   To disable this feature use @ref{option --no-allow-loopback-pinentry}.
   @end table
 
 @item cache-ttl-opt-preset
 This option sets the cache TTL for new entries created by GENKEY and
 PASSWD commands when using the @option{--preset} option.  It is not
 used a default value is used.
 
 @item s2k-count
 Instead of using the standard S2K count (which is computed on the
 fly), the given S2K count is used for new keys or when changing the
 passphrase of a key.  Values below 65536 are considered to be 0.  This
 option is valid for the entire session or until reset to 0.  This
 option is useful if the key is later used on boxes which are either
 much slower or faster than the actual box.
 
 @item pretend-request-origin
 This option switches the connection into a restricted mode which
 handles all further commands in the same way as they would be handled
 when originating from the extra or browser socket.  Note that this
 option is not available in the restricted mode.  Valid values for this
 option are:
 
   @table @code
   @item none
   @itemx local
   This is a NOP and leaves the connection in the standard way.
 
   @item remote
   Pretend to come from a remote origin in the same way as connections
   from the @option{--extra-socket}.
 
   @item browser
   Pretend to come from a local web browser in the same way as connections
   from the @option{--browser-socket}.
   @end table
 
 @end table
 
 
 @mansect see also
 @ifset isman
 @command{@gpgname}(1),
 @command{gpgsm}(1),
 @command{gpgconf}(1),
 @command{gpg-connect-agent}(1),
 @command{scdaemon}(1)
 @end ifset
 @include see-also-note.texi