[svn] GnuPG - r4573 - in trunk: . agent common doc doc/examples sm tools

svn author wk cvs at cvs.gnupg.org
Wed Aug 29 11:52:07 CEST 2007


Author: wk
Date: 2007-08-29 11:51:37 +0200 (Wed, 29 Aug 2007)
New Revision: 4573

Modified:
   trunk/NEWS
   trunk/agent/genkey.c
   trunk/common/ChangeLog
   trunk/common/exechelp.c
   trunk/common/exechelp.h
   trunk/common/homedir.c
   trunk/common/util.h
   trunk/doc/ChangeLog
   trunk/doc/examples/gpgconf.conf
   trunk/doc/tools.texi
   trunk/sm/export.c
   trunk/sm/import.c
   trunk/tools/ChangeLog
   trunk/tools/gpgconf-comp.c
   trunk/tools/gpgconf.c
   trunk/tools/gpgconf.h
   trunk/tools/no-libgcrypt.c
Log:
New command --check-programs for gpgconf.


Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/NEWS	2007-08-29 09:51:37 UTC (rev 4573)
@@ -11,7 +11,11 @@
    enforce-passphrase-constraints and max-passphrase-days to
    gpg-agent.
 
+ * Add command --check-components to gpgconf.  Gpgconf now uses the
+   installed versions of the programs and does not anymore search via
+   PATH for them.
 
+
 Noteworthy changes in version 2.0.6 (2007-08-16)
 ------------------------------------------------
 

Modified: trunk/agent/genkey.c
===================================================================
--- trunk/agent/genkey.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/agent/genkey.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -126,7 +126,7 @@
 
   if (gnupg_spawn_process_fd (pgmname, argv, fileno (infp), -1, -1, &pid))
     result = 1; /* Execute error - assume password should no be used.  */
-  else if (gnupg_wait_process (pgmname, pid))
+  else if (gnupg_wait_process (pgmname, pid, NULL))
     result = 1; /* Helper returned an error - probably a match.  */
   else
     result = 0; /* Success; i.e. no match.  */

Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/common/ChangeLog	2007-08-29 09:51:37 UTC (rev 4573)
@@ -1,3 +1,11 @@
+2007-08-29  Werner Koch  <wk at g10code.com>
+
+	* exechelp.c (gnupg_wait_process): Add arg EXITCODE.  Changed all
+	callers.
+
+	* util.h (GNUPG_MODULE_NAME_GPGSM, GNUPG_MODULE_NAME_GPG): New.
+	* homedir.c (gnupg_module_name): Add them
+	
 2007-08-28  Werner Koch  <wk at g10code.com>
 
 	* gettime.c (check_isotime, add_isotime): New.  Orginally written

Modified: trunk/common/exechelp.c
===================================================================
--- trunk/common/exechelp.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/common/exechelp.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -570,11 +570,13 @@
 
 
 /* Wait for the process identified by PID to terminate. PGMNAME should
-   be the same as suplieed to the spawn fucntion and is only used for
-   diagnostics. Returns 0 if the process succeded, GPG_ERR_GENERAL for
-   any failures of the spawned program or other error codes.*/
+   be the same as supplied to the spawn function and is only used for
+   diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL
+   for any failures of the spawned program or other error codes.  If
+   EXITCODE is not NULL the exit code of the process is stored at this
+   address or -1 if it could not be retrieved. */
 gpg_error_t
-gnupg_wait_process (const char *pgmname, pid_t pid)
+gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode)
 {
   gpg_err_code_t ec;
 
@@ -583,6 +585,9 @@
   int code;
   DWORD exc;
 
+  if (exitcode)
+    *exitcode = -1;
+
   if (pid == (pid_t)(-1))
     return gpg_error (GPG_ERR_INV_VALUE);
 
@@ -609,10 +614,16 @@
           {
             log_error (_("error running `%s': exit status %d\n"),
                        pgmname, (int)exc );
+            if (exitcode)
+              *exitcode = (int)exc;
             ec = GPG_ERR_GENERAL;
           }
         else
-          ec = 0;
+          {
+            if (exitcode)
+              *exitcode = 0;
+            ec = 0;
+          }
         CloseHandle (proc);
         break;
 
@@ -626,6 +637,9 @@
 #else /* !HAVE_W32_SYSTEM */
   int i, status;
 
+  if (exitcode)
+    *exitcode = -1;
+
   if (pid == (pid_t)(-1))
     return gpg_error (GPG_ERR_INV_VALUE);
 
@@ -650,6 +664,8 @@
     {
       log_error (_("error running `%s': exit status %d\n"), pgmname,
                  WEXITSTATUS (status));
+      if (exitcode)
+        *exitcode = WEXITSTATUS (status);
       ec = GPG_ERR_GENERAL;
     }
   else if (!WIFEXITED (status))
@@ -658,11 +674,14 @@
       ec = GPG_ERR_GENERAL;
     }
   else 
-    ec = 0;
+    {
+      if (exitcode)
+        *exitcode = 0;
+      ec = 0;
+    }
 #endif /* !HAVE_W32_SYSTEM */
 
   return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
-
 }
 
 

Modified: trunk/common/exechelp.h
===================================================================
--- trunk/common/exechelp.h	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/common/exechelp.h	2007-08-29 09:51:37 UTC (rev 4573)
@@ -52,8 +52,10 @@
 /* Wait for the process identified by PID to terminate. PGMNAME should
    be the same as supplied to the spawn fucntion and is only used for
    diagnostics.  Returns 0 if the process succeded, GPG_ERR_GENERAL
-   for any failures of the spawned program or other error codes.*/
-gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid);
+   for any failures of the spawned program or other error codes.  If
+   EXITCODE is not NULL the exit code of the process is stored at this
+   address or -1 if it could not be retrieved.  */
+gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode);
 
 
 /* Spawn a new process and immediatley detach from it.  The name of

Modified: trunk/common/homedir.c
===================================================================
--- trunk/common/homedir.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/common/homedir.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -372,6 +372,12 @@
     case GNUPG_MODULE_NAME_CHECK_PATTERN:
       X(libexecdir, "gpg-check-pattern");
 
+    case GNUPG_MODULE_NAME_GPGSM:
+      X(bindir, "gpgsm");
+
+    case GNUPG_MODULE_NAME_GPG:
+      X(bindir, "gpg2");
+
     default: 
       BUG ();
     }

Modified: trunk/common/util.h
===================================================================
--- trunk/common/util.h	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/common/util.h	2007-08-29 09:51:37 UTC (rev 4573)
@@ -182,12 +182,16 @@
 const char *gnupg_datadir (void);
 const char *dirmngr_socket_name (void);
 
+/* All module names.  We also include gpg and gpgsm for the sake for
+   gpgconf. */
 #define GNUPG_MODULE_NAME_AGENT        1
 #define GNUPG_MODULE_NAME_PINENTRY     2
 #define GNUPG_MODULE_NAME_SCDAEMON     3 
 #define GNUPG_MODULE_NAME_DIRMNGR      4
 #define GNUPG_MODULE_NAME_PROTECT_TOOL 5
 #define GNUPG_MODULE_NAME_CHECK_PATTERN 6
+#define GNUPG_MODULE_NAME_GPGSM         7
+#define GNUPG_MODULE_NAME_GPG           8
 const char *gnupg_module_name (int which);
 
 

Modified: trunk/doc/ChangeLog
===================================================================
--- trunk/doc/ChangeLog	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/doc/ChangeLog	2007-08-29 09:51:37 UTC (rev 4573)
@@ -1,3 +1,7 @@
+2007-08-29  Werner Koch  <wk at g10code.com>
+
+	* tools.texi (Checking programs): New.
+
 2007-08-27  Werner Koch  <wk at g10code.com>
 
 	* examples/pwpattern.list: New.

Modified: trunk/doc/examples/gpgconf.conf
===================================================================
--- trunk/doc/examples/gpgconf.conf	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/doc/examples/gpgconf.conf	2007-08-29 09:51:37 UTC (rev 4573)
@@ -34,7 +34,14 @@
 # :staff  gpg-agent allow-mark-trusted [change]
 #         gpg-agent min-passphrase-len 6
 #
-# *       gpg-agent min-passphrase-len [no-change] 12
+# *       gpg-agent min-passphrase-len [no-change] 8
+#         gpg-agent min-passphrase-nonalpha [no-change] 1 
+#         gpg-agent max-passphrase-days [no-change] 700
+#         gpg-agent enable-passphrase-history [no-change]
+#         gpg-agent enforce-passphrase-policy [default]
+#         gpg-agent enforce-passphrase-policy [no-change]
+#         gpg-agent max-cache-ttl [no-change] 10800
+#         gpg-agent max-cache-ttl-ssh [no-change] 10800
 #         gpg-agent allow-mark-trusted [default]
 #         gpg-agent allow-mark-trusted [no-change]
 #         gpgsm     enable-ocsp           
@@ -46,7 +53,7 @@
 # to 6.  All other users are not allowed to change
 # "min-passphrase-len" and "allow-mark-trusted".  When "gpgconf
 # --apply-defaults" is used for them, "min-passphrase-len" is set to
-# 12, "allow-mark-trusted" deleted from the config file and
+# 8, "allow-mark-trusted" deleted from the config file and
 # "enable-ocsp" is put into the config file of gpgsm.  The latter may
 # be changed by any user.
 #-------------------------------------------------------------------

Modified: trunk/doc/tools.texi
===================================================================
--- trunk/doc/tools.texi	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/doc/tools.texi	2007-08-29 09:51:37 UTC (rev 4573)
@@ -200,6 +200,7 @@
 * Invoking gpgconf::      List of all commands and options.
 * Format conventions::    Formatting conventions relevant for all commands.
 * Listing components::    List all gpgconf components.
+* Checking programs::     Check all programs know to gpgconf.
 * Listing options::       List all options of a component.
 * Changing options::      Changing options of a component.
 * Files used by gpgconf:: What files are used by gpgconf.
@@ -218,6 +219,9 @@
 List all components.  This is the default command used if none is
 specified.
 
+ at item --check-programs
+List all available backend programs and test whether they are runnable.
+
 @item --list-options @var{component}
 List all options of the component @var{component}.
 
@@ -335,6 +339,14 @@
 the verbose option is used).  You should ignore everything in the
 field that follows the number.
 
+ at item @w{boolean value}
+Some fields contain a @emph{boolean value}.  This is a number with
+either the value 0 or 1.  The number may be followed by a space,
+followed by a human readable description of that value (if the verbose
+option is used).  You should ignore everything in the field that follows
+the number; checking just the first character is sufficient in this
+case.
+
 @item option
 Some fields contain an @emph{option} argument.  The format of an
 option argument depends on the type of the option and on some flags:
@@ -436,6 +448,62 @@
 @end example
 
 
+
+ at node Checking programs
+ at subsection Checking programs
+
+The command @code{--check-programs} is similar to
+ at code{--list-components} but works on backend programs and not on
+components.  It runs each program to test wether it is installed and
+runnable.  This also includes a syntax check of all config file options
+of the program.
+
+The command argument @code{--check-programs} lists all available
+programs, one per line.  The format of each line is:
+
+ at code{@var{name}:@var{description}:@var{program name}:@var{available}:@var{config okay}:}
+
+ at table @var
+ at item name
+This field contains a name tag of the program which is identical to the
+name of the component.  The name tag is to be used @emph{verbatim}.  It
+is thus not in any escaped format.
+
+ at item description
+The @emph{string} in this field contains a human-readable description
+of the component.  It can be displayed to the user of the GUI for
+informational purposes.  It is @emph{percent-escaped} and
+ at emph{localized}.
+
+ at item program name
+The @emph{string} in this field contains the absolute name of the
+program's file.  It can be used to unambiguously invoke that program.
+It is @emph{percent-escaped}.
+
+ at item available
+The @emph{boolean value} in this field indicates whether the program is
+installed and runnable.
+
+ at item config okay
+The @emph{boolean value} in this field indicates whether the program's
+config file is syntactically okay.
+
+ at end table
+
+ at noindent
+In the following example the @command{dirmngr} is not runnable and the
+configuration file of @command{scdaemon} is not okay.
+
+ at example
+$ gpgconf --check-programs
+gpg:GPG for OpenPGP:/usr/local/bin/gpg2:1:1:
+gpg-agent:GPG Agent:/usr/local/bin/gpg-agent:1:1:
+scdaemon:Smartcard Daemon:/usr/local/bin/scdaemon:1:0:
+gpgsm:GPG for S/MIME:/usr/local/bin/gpgsm:1:1:
+dirmngr:Directory Manager:/usr/local/bin/dirmngr:0:0:
+ at end example
+
+
 @node Listing options
 @subsection Listing options
 

Modified: trunk/sm/export.c
===================================================================
--- trunk/sm/export.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/sm/export.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -713,7 +713,7 @@
     fclose (fp);
   if (pid != -1)
     {
-      if (!gnupg_wait_process (pgmname, pid))
+      if (!gnupg_wait_process (pgmname, pid, NULL))
         child_err = 0;
     }
   if (!err)

Modified: trunk/sm/import.c
===================================================================
--- trunk/sm/import.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/sm/import.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -635,7 +635,7 @@
     fclose (fp);
   if (pid != -1)
     {
-      if (!gnupg_wait_process (pgmname, pid))
+      if (!gnupg_wait_process (pgmname, pid, NULL))
         child_err = 0;
     }
   if (!err)

Modified: trunk/tools/ChangeLog
===================================================================
--- trunk/tools/ChangeLog	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/tools/ChangeLog	2007-08-29 09:51:37 UTC (rev 4573)
@@ -1,3 +1,12 @@
+2007-08-29  Werner Koch  <wk at g10code.com>
+
+	* gpgconf.c: New comamnd --check-programs.
+	* gpgconf-comp.c (gc_component_check_programs): New.
+	(gc_backend): Add member MODULE_NAME and add these module names.
+	(retrieve_options_from_program): Use module name so that we use an
+	absolute file name and don't rely on $PATH.
+	* no-libgcrypt.c (gcry_control): New.
+
 2007-08-28  Werner Koch  <wk at g10code.com>
 
 	* gpgconf-comp.c <gpg-agent>: Add options --max-passphrase-days
@@ -713,7 +722,7 @@
 	* watchgnupg.c: New.
 
 
- Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without

Modified: trunk/tools/gpgconf-comp.c
===================================================================
--- trunk/tools/gpgconf-comp.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/tools/gpgconf-comp.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -43,6 +43,7 @@
 #define JNLIB_NEED_LOG_LOGV
 #include "util.h"
 #include "i18n.h"
+#include "exechelp.h"
 
 #include "gc-opt-flags.h"
 #include "gpgconf.h"
@@ -153,6 +154,12 @@
      GPGConf.  In this case, PROGRAM is NULL.  */
   char *program;
 
+  /* The module name (GNUPG_MODULE_NAME_foo) as defined by
+     ../common/util.h.  This value is used to get the actual installed
+     path of the program.  0 is used if no backedn program is
+     available. */
+  char module_name;
+
   /* The runtime change callback.  */
   void (*runtime_change) (void);
 
@@ -168,14 +175,18 @@
 } gc_backend[GC_BACKEND_NR] =
   {
     { NULL },		/* GC_BACKEND_ANY dummy entry.  */
-    { "GnuPG", GPGNAME, NULL, "gpgconf-gpg.conf" },
-    { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" },
-    { "GPG Agent", "gpg-agent", gpg_agent_runtime_change,
-      "gpgconf-gpg-agent.conf" },
-    { "SCDaemon", "scdaemon", NULL, "gpgconf-scdaemon.conf" },
-    { "DirMngr", "dirmngr", NULL, "gpgconf-dirmngr.conf" },
-    { "DirMngr LDAP Server List", NULL, NULL, "ldapserverlist-file",
-      "LDAP Server" },
+    { "GnuPG", GPGNAME, GNUPG_MODULE_NAME_GPG,
+      NULL, "gpgconf-gpg.conf" },
+    { "GPGSM", "gpgsm", GNUPG_MODULE_NAME_GPGSM,
+      NULL, "gpgconf-gpgsm.conf" },
+    { "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT, 
+      gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
+    { "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON,
+      NULL, "gpgconf-scdaemon.conf" },
+    { "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR,
+      NULL, "gpgconf-dirmngr.conf" },
+    { "DirMngr LDAP Server List", NULL, 0, 
+      NULL, "ldapserverlist-file", "LDAP Server" },
   };
 
 
@@ -1129,7 +1140,82 @@
     }
 }
 
+
 
+/* Check all components that are available.  */
+void
+gc_component_check_programs (FILE *out)
+{
+  gc_component_t component;
+  unsigned int result;
+  int backend_seen[GC_BACKEND_NR];
+  gc_backend_t backend;
+  gc_option_t *option;
+  const char *desc;
+  const char *pgmname;
+  const char *argv[2];
+  pid_t pid;
+  int exitcode;
+
+  for (component = 0; component < GC_COMPONENT_NR; component++)
+    {
+      if (!gc_component[component].options)
+        continue;
+
+      for (backend = 0; backend < GC_BACKEND_NR; backend++)
+        backend_seen[backend] = 0;
+
+      option = gc_component[component].options;
+      for (; option && option->name; option++)
+        {
+          if ((option->flags & GC_OPT_FLAG_GROUP))
+            continue;
+          backend = option->backend;
+          if (backend_seen[backend])
+            continue;
+          backend_seen[backend] = 1;
+          assert (backend != GC_BACKEND_ANY);
+          if (!gc_backend[backend].program)
+            continue;
+          if (!gc_backend[backend].module_name)
+            continue;
+
+          pgmname = gnupg_module_name (gc_backend[backend].module_name);
+          argv[0] = "--gpgconf-test";
+          argv[1] = NULL;
+
+          /* Note that under Windows the spawn fucntion returns an
+             error if the progrom could not be executed whereas under
+             Unix the wait function returns an error.  */
+          result = 0;
+          if (gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid))
+            result |= 1; /* Program could not be run.  */
+          else if (gnupg_wait_process (pgmname, pid, &exitcode))
+            {
+              if (exitcode == -1)
+                result |= 1; /* Program could not be run or it
+                                terminated abnormally.  */
+              result |= 2; /* Program returned an error.  */
+            }
+          
+          /* If the program could not be run, we can't tell whether
+             the config file is good.  */
+          if ((result&1))
+            result |= 2;  
+          
+          desc = gc_component[component].desc;
+          desc = my_dgettext (gc_component[component].desc_domain, desc);
+          fprintf (out, "%s:%s:",
+                   gc_component[component].name, my_percent_escape (desc));
+          fputs (my_percent_escape (pgmname), out);
+          fprintf (out, ":%d:%d:\n", !(result & 1), !(result & 2));
+          break; /* Loop over options of this component  */
+        }
+    } 
+}
+
+
+
 /* Find the component with the name NAME.  Returns -1 if not
    found.  */
 int
@@ -1362,7 +1448,10 @@
   FILE *config;
   char *config_pathname;
 
-  cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program);
+  cmd_line = xasprintf ("%s --gpgconf-list", 
+                        gc_backend[backend].module_name ?
+                        gnupg_module_name (gc_backend[backend].module_name) :
+                        gc_backend[backend].program );
 
   config = popen (cmd_line, "r");
   if (!config)
@@ -1663,6 +1752,8 @@
   while (process_all && ++component < GC_COMPONENT_NR);
 
 }
+
+
 
 /* Perform a simple validity check based on the type.  Return in
    NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of

Modified: trunk/tools/gpgconf.c
===================================================================
--- trunk/tools/gpgconf.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/tools/gpgconf.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -1,5 +1,5 @@
 /* gpgconf.c - Configuration utility for GnuPG
- *	Copyright (C) 2003 Free Software Foundation, Inc.
+ *	Copyright (C) 2003, 2007 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -40,6 +40,7 @@
     oHomedir,
 
     aListComponents,
+    aCheckPrograms,
     aListOptions,
     aChangeOptions,
     aApplyDefaults,
@@ -54,6 +55,7 @@
     { 300, NULL, 0, N_("@Commands:\n ") },
     
     { aListComponents, "list-components", 256, N_("list all components") },
+    { aCheckPrograms, "check-programs", 256, N_("check all programs") },
     { aListOptions, "list-options", 256, N_("|COMPONENT|list options") },
     { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") },
     { aApplyDefaults, "apply-defaults", 256,
@@ -137,6 +139,7 @@
         case oNoVerbose: opt.verbose = 0; break;
 
         case aListComponents:
+        case aCheckPrograms:
         case aListOptions:
         case aChangeOptions:
         case aApplyDefaults:
@@ -161,6 +164,11 @@
       gc_component_list_components (stdout);
       break;
 
+    case aCheckPrograms:
+      /* Check all programs. */
+      gc_component_check_programs (stdout);
+      break;
+
     case aListOptions:
     case aChangeOptions:
       if (!fname)

Modified: trunk/tools/gpgconf.h
===================================================================
--- trunk/tools/gpgconf.h	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/tools/gpgconf.h	2007-08-29 09:51:37 UTC (rev 4573)
@@ -40,6 +40,9 @@
 /* List all components that are available.  */
 void gc_component_list_components (FILE *out);
 
+/* List all programs along with their status.  */
+void gc_component_check_programs (FILE *out);
+
 /* Find the component with the name NAME.  Returns -1 if not
    found.  */
 int gc_component_find (const char *name);

Modified: trunk/tools/no-libgcrypt.c
===================================================================
--- trunk/tools/no-libgcrypt.c	2007-08-28 17:48:13 UTC (rev 4572)
+++ trunk/tools/no-libgcrypt.c	2007-08-29 09:51:37 UTC (rev 4573)
@@ -102,3 +102,12 @@
   if (a)
     free (a);
 }
+
+
+/* We need this dummy because exechelp.c uses gcry_control to
+   terminate the secure memeory.  */
+gcry_error_t 
+gcry_control (enum gcry_ctl_cmds CMD, ...)
+{
+  return 0;
+}




More information about the Gnupg-commits mailing list