Print more directories with gpgconf --list-dirs.
[gnupg.git] / tools / symcryptrun.c
index 9f3a55f..2866804 100644 (file)
@@ -1,11 +1,11 @@
 /* symcryptrun.c - Tool to call simple symmetric encryption tools.
 /* symcryptrun.c - Tool to call simple symmetric encryption tools.
- *     Copyright (C) 2005 Free Software Foundation, Inc.
+ *     Copyright (C) 2005, 2007 Free Software Foundation, Inc.
  *
  * 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
  *
  * 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 2 of the License, or
+ * 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,
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 
  */
 
 
@@ -56,6 +55,9 @@
 
    Other classes may be added in the future.  */
 
 
    Other classes may be added in the future.  */
 
+#define SYMC_BAD_PASSPHRASE    2
+#define SYMC_CANCELED          3
+
 \f
 #include <config.h>
 
 \f
 #include <config.h>
 
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
+#include <signal.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#ifdef HAVE_PTY_H
 #include <pty.h>
 #include <pty.h>
+#endif
 #include <utmp.h>
 #include <ctype.h>
 #ifdef HAVE_LOCALE_H
 #include <utmp.h>
 #include <ctype.h>
 #ifdef HAVE_LOCALE_H
 #define JNLIB_NEED_LOG_LOGV
 #include "i18n.h"
 #include "../common/util.h"
 #define JNLIB_NEED_LOG_LOGV
 #include "i18n.h"
 #include "../common/util.h"
+#include "mkdtemp.h"
 
 /* FIXME: Bah.  For spwq_secure_free.  */
 #define SIMPLE_PWQUERY_IMPLEMENTATION 1
 #include "../common/simple-pwquery.h"
 
 \f
 
 /* FIXME: Bah.  For spwq_secure_free.  */
 #define SIMPLE_PWQUERY_IMPLEMENTATION 1
 #include "../common/simple-pwquery.h"
 
 \f
-/* Used by gcry for logging */
-static void
-my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
+/* From simple-gettext.c.  */
+
+/* We assume to have `unsigned long int' value with at least 32 bits.  */
+#define HASHWORDBITS 32
+
+/* The so called `hashpjw' function by P.J. Weinberger
+   [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+   1986, 1987 Bell Telephone Laboratories, Inc.]  */
+
+static __inline__ ulong
+hash_string( const char *str_param )
 {
 {
-  /* translate the log levels */
-  switch (level)
+    unsigned long int hval, g;
+    const char *str = str_param;
+
+    hval = 0;
+    while (*str != '\0')
     {
     {
-    case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
-    case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
-    case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
-    case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
-    case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
-    case GCRY_LOG_BUG:  level = JNLIB_LOG_BUG; break;
-    case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
-    default:            level = JNLIB_LOG_ERROR; break;      }
-  log_logv (level, fmt, arg_ptr);
+       hval <<= 4;
+       hval += (unsigned long int) *str++;
+       g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
+       if (g != 0)
+       {
+         hval ^= g >> (HASHWORDBITS - 8);
+         hval ^= g;
+       }
+    }
+    return hval;
 }
 
 \f
 }
 
 \f
@@ -124,6 +142,7 @@ enum cmd_and_opt_values
     oKeyfile,
     oDecrypt,
     oEncrypt,
     oKeyfile,
     oDecrypt,
     oEncrypt,
+    oInput
   };
 
 
   };
 
 
@@ -132,23 +151,23 @@ static ARGPARSE_OPTS opts[] =
   {
     { 301, NULL, 0, N_("@\nCommands:\n ") },
 
   {
     { 301, NULL, 0, N_("@\nCommands:\n ") },
 
-    { oDecrypt, "decrypt", 0, N_("decryption modus")},
-    { oEncrypt, "encrypt", 0, N_("encryption modus")},
+    { oDecrypt, "decrypt", 0, N_("decryption modus") },
+    { oEncrypt, "encrypt", 0, N_("encryption modus") },
     
     { 302, NULL, 0, N_("@\nOptions:\n ") },
     
     
     { 302, NULL, 0, N_("@\nOptions:\n ") },
     
-    { oClass, "class", 2, N_("tool class (confucius)")},
-    { oProgram, "program", 2, N_("program filename")},
-
-    { oKeyfile, "keyfile", 2, N_("secret key file (required)")},
+    { oClass, "class", 2, N_("tool class (confucius)") },
+    { oProgram, "program", 2, N_("program filename") },
 
 
+    { oKeyfile, "keyfile", 2, N_("secret key file (required)") },
+    { oInput, "inputfile", 2, N_("input file name (default stdin)") },
     { oVerbose, "verbose",  0, N_("verbose") },
     { oQuiet, "quiet",      0, N_("quiet") },
     { oVerbose, "verbose",  0, N_("verbose") },
     { oQuiet, "quiet",      0, N_("quiet") },
-    { oLogFile, "log-file", 2, N_("use a log file for the server")},
-    { oOptions,  "options"  , 2, N_("|FILE|read options from FILE")},
+    { oLogFile, "log-file", 2, N_("use a log file for the server") },
+    { oOptions,  "options"  , 2, N_("|FILE|read options from FILE") },
 
     /* Hidden options.  */
 
     /* Hidden options.  */
-    { oNoVerbose, "no-verbose",  0, "@"},
+    { oNoVerbose, "no-verbose",  0, "@" },
     { oHomedir, "homedir", 2, "@" },   
     { oNoOptions, "no-options", 0, "@" },/* shortcut for --options /dev/null */
 
     { oHomedir, "homedir", 2, "@" },   
     { oNoOptions, "no-options", 0, "@" },/* shortcut for --options /dev/null */
 
@@ -166,6 +185,7 @@ struct
   char *class;
   char *program;
   char *keyfile;
   char *class;
   char *program;
   char *keyfile;
+  char *input;
 } opt;
 
 \f
 } opt;
 
 \f
@@ -188,7 +208,7 @@ my_strusage (int level)
       break;
     case 41:
       p = _("Syntax: symcryptrun --class CLASS --program PROGRAM "
       break;
     case 41:
       p = _("Syntax: symcryptrun --class CLASS --program PROGRAM "
-           "--keyfile KEYFILE [options...] COMMAND\n"
+           "--keyfile KEYFILE [options...] COMMAND [inputfile]\n"
             "Call a simple symmetric encryption tool\n");
       break;
     case 31: p = "\nHome: "; break;
             "Call a simple symmetric encryption tool\n");
       break;
     case 31: p = "\nHome: "; break;
@@ -201,22 +221,24 @@ my_strusage (int level)
 }
 
 
 }
 
 
-/* Initialize the gettext system.  */
-static void
-i18n_init(void)
-{
-#ifdef USE_SIMPLE_GETTEXT
-  set_gettext_file (PACKAGE_GT);
-#else
-# ifdef ENABLE_NLS
-  setlocale (LC_ALL, "");
-  bindtextdomain (PACKAGE_GT, LOCALEDIR);
-  textdomain (PACKAGE_GT);
-# endif
+\f
+/* This is in the GNU C library in unistd.h.  */
+
+#ifndef TEMP_FAILURE_RETRY
+/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
+   set to EINTR.  */
+
+# define TEMP_FAILURE_RETRY(expression) \
+  (__extension__                                                              \
+    ({ long int __result;                                                     \
+       do __result = (long int) (expression);                                 \
+       while (__result == -1L && errno == EINTR);                             \
+       __result; }))
 #endif
 #endif
-}
 
 
-\f
+/* Include the implementation of map_spwq_error.  */
+MAP_SPWQ_ERROR_IMPL
+
 /* Unlink a file, and shred it if SHRED is true.  */
 int
 remove_file (char *name, int shred)
 /* Unlink a file, and shred it if SHRED is true.  */
 int
 remove_file (char *name, int shred)
@@ -395,48 +417,24 @@ confucius_copy_file (char *infile, char *outfile, int plain)
    pointer, it will be set to true or false, depending on if the user
    canceled the operation or not.  On error (including cancelation), a
    null pointer is returned.  The passphrase must be deallocated with
    pointer, it will be set to true or false, depending on if the user
    canceled the operation or not.  On error (including cancelation), a
    null pointer is returned.  The passphrase must be deallocated with
-   confucius_drop_pass.  */
+   confucius_drop_pass.  CACHEID is the ID to be used for passphrase
+   caching and can be NULL to disable caching.  */
 char *
 char *
-confucius_get_pass (int again, int *canceled)
+confucius_get_pass (const char *cacheid, int again, int *canceled)
 {
   int err;
   char *pw;
 {
   int err;
   char *pw;
-#ifdef HAVE_LANGINFO_CODESET
-  char *orig_codeset = NULL;
-#endif
+  char *orig_codeset;
 
   if (canceled)
     *canceled = 0;
   
 
   if (canceled)
     *canceled = 0;
   
-#ifdef ENABLE_NLS
-  /* The Assuan agent protocol requires us to transmit utf-8 strings */
-  orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL);
-#ifdef HAVE_LANGINFO_CODESET
-  if (!orig_codeset)
-    orig_codeset = nl_langinfo (CODESET);
-#endif
-  if (orig_codeset && !strcmp (orig_codeset, "UTF-8"))
-    orig_codeset = NULL;
-  if (orig_codeset)
-    {
-      /* We only switch when we are able to restore the codeset later. */
-      orig_codeset = xstrdup (orig_codeset);
-      if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8"))
-        orig_codeset = NULL; 
-    }
-#endif
-
-  pw = simple_pwquery (NULL,
+  orig_codeset = i18n_switchto_utf8 ();
+  pw = simple_pwquery (cacheid,
                        again ? _("does not match - try again"):NULL,
                        again ? _("does not match - try again"):NULL,
-                       _("Passphrase:"), NULL, &err);
-
-#ifdef ENABLE_NLS
-  if (orig_codeset)
-    {
-      bind_textdomain_codeset (PACKAGE_GT, orig_codeset);
-      xfree (orig_codeset);
-    }
-#endif
+                       _("Passphrase:"), NULL, 0, &err);
+  err = map_spwq_error (err);
+  i18n_switchback (orig_codeset);
 
   if (!pw)
     {
 
   if (!pw)
     {
@@ -468,15 +466,10 @@ confucius_drop_pass (char *pass)
    requested.  If it is oDecrypt, decryption is requested.  INFILE and
    OUTFILE are the temporary files used in the process.  */
 int
    requested.  If it is oDecrypt, decryption is requested.  INFILE and
    OUTFILE are the temporary files used in the process.  */
 int
-confucius_process (int mode, char *infile, char *outfile)
+confucius_process (int mode, char *infile, char *outfile,
+                  int argc, char *argv[])
 {
 {
-  char *const args[] = { opt.program,
-                        mode == oEncrypt ? "-m1" : "-m2",
-                        "-q", infile,
-                        "-z", outfile,
-                        "-s", opt.keyfile,
-                        mode == oEncrypt ? "-af" : "-f",
-                        NULL };
+  char **args;
   int cstderr[2];
   int master;
   int slave;
   int cstderr[2];
   int master;
   int slave;
@@ -484,6 +477,7 @@ confucius_process (int mode, char *infile, char *outfile)
   pid_t pid;
   pid_t wpid;
   int tries = 0;
   pid_t pid;
   pid_t wpid;
   int tries = 0;
+  char cacheid[40];
 
   signal (SIGPIPE, SIG_IGN);
 
 
   signal (SIGPIPE, SIG_IGN);
 
@@ -505,9 +499,33 @@ confucius_process (int mode, char *infile, char *outfile)
       return 1;
     }
 
       return 1;
     }
 
+  /* Generate a hash from the keyfile name for caching.  */
+  snprintf (cacheid, sizeof (cacheid), "confucius:%lu",
+           hash_string (opt.keyfile));
+  cacheid[sizeof (cacheid) - 1] = '\0';
+  args = malloc (sizeof (char *) * (10 + argc));
+  if (!args)
+    {
+      log_error (_("cannot allocate args vector\n"));
+      return 1;
+    }
+  args[0] = opt.program;
+  args[1] = (mode == oEncrypt) ? "-m1" : "-m2";
+  args[2] = "-q";
+  args[3] = infile;
+  args[4] = "-z";
+  args[5] = outfile;
+  args[6] = "-s";
+  args[7] = opt.keyfile;
+  args[8] = (mode == oEncrypt) ? "-af" : "-f";
+  args[9 + argc] = NULL;
+  while (argc--)
+    args[9 + argc] = argv[argc];
+
   if (pipe (cstderr) < 0)
     {
       log_error (_("could not create pipe: %s\n"), strerror (errno));
   if (pipe (cstderr) < 0)
     {
       log_error (_("could not create pipe: %s\n"), strerror (errno));
+      free (args);
       return 1;
     }
 
       return 1;
     }
 
@@ -516,6 +534,7 @@ confucius_process (int mode, char *infile, char *outfile)
       log_error (_("could not create pty: %s\n"), strerror (errno));
       close (cstderr[0]);
       close (cstderr[1]);
       log_error (_("could not create pty: %s\n"), strerror (errno));
       close (cstderr[0]);
       close (cstderr[1]);
+      free (args);
       return -1;
     }
 
       return -1;
     }
 
@@ -533,6 +552,7 @@ confucius_process (int mode, char *infile, char *outfile)
       close (slave);
       close (cstderr[0]);
       close (cstderr[1]);
       close (slave);
       close (cstderr[0]);
       close (cstderr[1]);
+      free (args);
       return 1;
     }
   else if (pid == 0) 
       return 1;
     }
   else if (pid == 0) 
@@ -569,6 +589,7 @@ confucius_process (int mode, char *infile, char *outfile)
 
       close (slave);
       close (cstderr[1]);
 
       close (slave);
       close (cstderr[1]);
+      free (args);
 
       /* Listen on the output FDs.  */
       do
 
       /* Listen on the output FDs.  */
       do
@@ -672,13 +693,20 @@ confucius_process (int mode, char *infile, char *outfile)
                      char *pass;
                      int canceled;
 
                      char *pass;
                      int canceled;
 
-                     pass = confucius_get_pass (tries ? 1 : 0, &canceled);
+                     /* If this is not the first attempt, the
+                        passphrase seems to be wrong, so clear the
+                        cache.  */
+                     if (tries)
+                       simple_pwclear (cacheid);
+
+                     pass = confucius_get_pass (cacheid,
+                                                tries ? 1 : 0, &canceled);
                      if (!pass)
                        {
                          kill (pid, SIGTERM);
                          close (master);
                          close (cstderr[0]);
                      if (!pass)
                        {
                          kill (pid, SIGTERM);
                          close (master);
                          close (cstderr[0]);
-                         return canceled ? 3 : 1;
+                         return canceled ? SYMC_CANCELED : 1;
                        }
                      write (master, pass, strlen (pass));
                      write (master, "\n", 1);
                        }
                      write (master, pass, strlen (pass));
                      write (master, "\n", 1);
@@ -700,6 +728,8 @@ confucius_process (int mode, char *infile, char *outfile)
          log_error (_("waitpid failed: %s\n"), strerror (errno));
 
          kill (pid, SIGTERM);
          log_error (_("waitpid failed: %s\n"), strerror (errno));
 
          kill (pid, SIGTERM);
+         /* State of cached password is unclear.  Just remove it.  */
+         simple_pwclear (cacheid);
          return 1;
        }
       else
          return 1;
        }
       else
@@ -710,15 +740,22 @@ confucius_process (int mode, char *infile, char *outfile)
          if (!WIFEXITED (res))
            {
              log_error (_("child aborted with status %i\n"), res);
          if (!WIFEXITED (res))
            {
              log_error (_("child aborted with status %i\n"), res);
+
+             /* State of cached password is unclear.  Just remove it.  */
+             simple_pwclear (cacheid);
+
              return 1;
            }
 
          if (WEXITSTATUS (res))
            {
              return 1;
            }
 
          if (WEXITSTATUS (res))
            {
+             /* The passphrase was wrong.  Remove it from the cache.  */
+             simple_pwclear (cacheid);
+
              /* We probably exceeded our number of attempts at guessing
                 the password.  */
              if (tries >= 3)
              /* We probably exceeded our number of attempts at guessing
                 the password.  */
              if (tries >= 3)
-               return 2;
+               return SYMC_BAD_PASSPHRASE;
              else
                return 1;
            }
              else
                return 1;
            }
@@ -735,27 +772,36 @@ confucius_process (int mode, char *infile, char *outfile)
    requested.  If it is oDecrypt, decryption is requested.  The other
    parameters are taken from the global option data.  */
 int
    requested.  If it is oDecrypt, decryption is requested.  The other
    parameters are taken from the global option data.  */
 int
-confucius_main (int mode)
+confucius_main (int mode, int argc, char *argv[])
 {
   int res;
   char *tmpdir;
   char *infile;
 {
   int res;
   char *tmpdir;
   char *infile;
+  int infile_from_stdin = 0;
   char *outfile;
 
   tmpdir = confucius_mktmpdir ();
   if (!tmpdir)
     return 1;
   char *outfile;
 
   tmpdir = confucius_mktmpdir ();
   if (!tmpdir)
     return 1;
-  
-  /* TMPDIR + "/" + "in" + "\0".  */
-  infile = malloc (strlen (tmpdir) + 1 + 2 + 1);
-  if (!infile)
+
+  if (opt.input && !(opt.input[0] == '-' && opt.input[1] == '\0'))
+    infile = xstrdup (opt.input);
+  else
     {
     {
-      log_error (_("cannot allocate infile string: %s\n"), strerror (errno));
-      rmdir (tmpdir);
-      return 1;
+      infile_from_stdin = 1;
+
+      /* TMPDIR + "/" + "in" + "\0".  */
+      infile = malloc (strlen (tmpdir) + 1 + 2 + 1);
+      if (!infile)
+       {
+         log_error (_("cannot allocate infile string: %s\n"),
+                    strerror (errno));
+         rmdir (tmpdir);
+         return 1;
+       }
+      strcpy (infile, tmpdir);
+      strcat (infile, "/in");
     }
     }
-  strcpy (infile, tmpdir);
-  strcat (infile, "/in");
 
   /* TMPDIR + "/" + "out" + "\0".  */
   outfile = malloc (strlen (tmpdir) + 1 + 3 + 1);
 
   /* TMPDIR + "/" + "out" + "\0".  */
   outfile = malloc (strlen (tmpdir) + 1 + 3 + 1);
@@ -769,23 +815,27 @@ confucius_main (int mode)
   strcpy (outfile, tmpdir);
   strcat (outfile, "/out");
 
   strcpy (outfile, tmpdir);
   strcat (outfile, "/out");
 
-  /* Create INFILE and fill it with content.  */
-  res = confucius_copy_file ("-", infile, mode == oEncrypt);
-  if (res)
+  if (infile_from_stdin)
     {
     {
-      free (outfile);
-      free (infile);
-      rmdir (tmpdir);
-      return res;
+      /* Create INFILE and fill it with content.  */
+      res = confucius_copy_file ("-", infile, mode == oEncrypt);
+      if (res)
+       {
+         free (outfile);
+         free (infile);
+         rmdir (tmpdir);
+         return res;
+       }
     }
 
   /* Run the engine and thus create the output file, handling
      passphrase retrieval.  */
     }
 
   /* Run the engine and thus create the output file, handling
      passphrase retrieval.  */
-  res = confucius_process (mode, infile, outfile);
+  res = confucius_process (mode, infile, outfile, argc, argv);
   if (res)
     {
       remove_file (outfile, mode == oDecrypt);
   if (res)
     {
       remove_file (outfile, mode == oDecrypt);
-      remove_file (infile, mode == oEncrypt);
+      if (infile_from_stdin)
+       remove_file (infile, mode == oEncrypt);
       free (outfile);
       free (infile);
       rmdir (tmpdir);
       free (outfile);
       free (infile);
       rmdir (tmpdir);
@@ -797,7 +847,8 @@ confucius_main (int mode)
   if (res)
     {
       remove_file (outfile, mode == oDecrypt);
   if (res)
     {
       remove_file (outfile, mode == oDecrypt);
-      remove_file (infile, mode == oEncrypt);
+      if (infile_from_stdin)
+       remove_file (infile, mode == oEncrypt);
       free (outfile);
       free (infile);
       rmdir (tmpdir);
       free (outfile);
       free (infile);
       rmdir (tmpdir);
@@ -805,7 +856,8 @@ confucius_main (int mode)
     }
   
   remove_file (outfile, mode == oDecrypt);
     }
   
   remove_file (outfile, mode == oDecrypt);
-  remove_file (infile, mode == oEncrypt);
+  if (infile_from_stdin)
+    remove_file (infile, mode == oEncrypt);
   free (outfile);
   free (infile);
   rmdir (tmpdir);
   free (outfile);
   free (infile);
   rmdir (tmpdir);
@@ -831,10 +883,9 @@ main (int argc, char **argv)
   set_strusage (my_strusage);
   log_set_prefix ("symcryptrun", 1);
 
   set_strusage (my_strusage);
   log_set_prefix ("symcryptrun", 1);
 
-  /* Try to auto set the character set.  */
-  set_native_charset (NULL); 
-
+  /* Make sure that our subsystems are ready.  */
   i18n_init();
   i18n_init();
+  init_common_subsystems ();
 
   opt.homedir = default_homedir ();
 
 
   opt.homedir = default_homedir ();
 
@@ -900,6 +951,7 @@ main (int argc, char **argv)
        case oClass:    opt.class = pargs.r.ret_str; break;
        case oProgram:  opt.program = pargs.r.ret_str; break;
        case oKeyfile:  opt.keyfile = pargs.r.ret_str; break;
        case oClass:    opt.class = pargs.r.ret_str; break;
        case oProgram:  opt.program = pargs.r.ret_str; break;
        case oKeyfile:  opt.keyfile = pargs.r.ret_str; break;
+       case oInput:    opt.input = pargs.r.ret_str; break;
 
         case oLogFile:  logfile = pargs.r.ret_str; break;
 
 
         case oLogFile:  logfile = pargs.r.ret_str; break;
 
@@ -941,19 +993,28 @@ main (int argc, char **argv)
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
     {
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
     {
-      log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
+      log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
     }
                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
     }
-  gcry_set_log_handler (my_gcry_logger, NULL);
+  setup_libgcrypt_logging ();
   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
 
   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
 
+  /* Tell simple-pwquery about the the standard socket name.  */
+  {
+    char *tmp = make_filename (opt.homedir, "S.gpg-agent", NULL);
+    simple_pw_set_socket (tmp);
+    xfree (tmp);
+  }
+
   if (!opt.class)
     {
       log_error (_("no class provided\n"));
       res = 1;
     }
   else if (!strcmp (opt.class, "confucius"))
   if (!opt.class)
     {
       log_error (_("no class provided\n"));
       res = 1;
     }
   else if (!strcmp (opt.class, "confucius"))
-    res = confucius_main (mode);
+    {
+      res = confucius_main (mode, argc, argv);
+    }
   else
     {
       log_error (_("class %s is not supported\n"), opt.class);
   else
     {
       log_error (_("class %s is not supported\n"), opt.class);