[svn] gpgme - r1413 - trunk/src

svn author marcus cvs at cvs.gnupg.org
Tue Nov 3 20:15:35 CET 2009


Author: marcus
Date: 2009-11-03 20:15:35 +0100 (Tue, 03 Nov 2009)
New Revision: 1413

Added:
   trunk/src/vfs-create.c
   trunk/src/vfs-mount.c
Removed:
   trunk/src/g13.c
Modified:
   trunk/src/ChangeLog
   trunk/src/Makefile.am
   trunk/src/gpgme-tool.c
   trunk/src/gpgme.def
   trunk/src/gpgme.h.in
   trunk/src/libgpgme.vers
Log:
2009-11-03  Marcus Brinkmann  <marcus at g10code.de>

	* Makefile.am (main_sources): Change g13.c to vfs-mount.c.  Add
	vfs-create.c
	* vfs-create.c: New file.
	* g13.c: Renamed to ...
	* vfs-mount.c: ... this new file.
	* gpgme.h.in (gpgme_op_vfs_create): New prototype.
	* gpgme.def, libgpgme.vers: Add gpgme_op_vfs_create.
	* gpgme-tool.c (gt_vfs_create, cmd_vfs_create): New functions.
	(register_commands): Add VFS_CREATE and CREAET.


Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2009-11-02 17:18:48 UTC (rev 1412)
+++ trunk/src/ChangeLog	2009-11-03 19:15:35 UTC (rev 1413)
@@ -1,3 +1,15 @@
+2009-11-03  Marcus Brinkmann  <marcus at g10code.de>
+
+	* Makefile.am (main_sources): Change g13.c to vfs-mount.c.  Add
+	vfs-create.c
+	* vfs-create.c: New file.
+	* g13.c: Renamed to ...
+	* vfs-mount.c: ... this new file.
+	* gpgme.h.in (gpgme_op_vfs_create): New prototype.
+	* gpgme.def, libgpgme.vers: Add gpgme_op_vfs_create.
+	* gpgme-tool.c (gt_vfs_create, cmd_vfs_create): New functions.
+	(register_commands): Add VFS_CREATE and CREAET.
+
 2009-11-02  Marcus Brinkmann  <marcus at g10code.de>
 
 	* debug.h (_gpgme_debug_buffer): Make TAG argument const const.

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2009-11-02 17:18:48 UTC (rev 1412)
+++ trunk/src/Makefile.am	2009-11-03 19:15:35 UTC (rev 1413)
@@ -111,7 +111,7 @@
 	opassuan.c                                                      \
 	engine.h engine-backend.h engine.c engine-gpg.c status-table.h	\
 	$(gpgsm_components) $(assuan_components) $(gpgconf_components)  \
-	$(g13_components) g13.c						\
+	$(g13_components) vfs-mount.c vfs-create.c			\
 	gpgconf.c							\
 	sema.h priv-io.h $(system_components) dirinfo.c			\
 	debug.c debug.h gpgme.c version.c error.c

Deleted: trunk/src/g13.c

Modified: trunk/src/gpgme-tool.c
===================================================================
--- trunk/src/gpgme-tool.c	2009-11-02 17:18:48 UTC (rev 1412)
+++ trunk/src/gpgme-tool.c	2009-11-03 19:15:35 UTC (rev 1413)
@@ -483,6 +483,7 @@
     STATUS_TEXTMODE,
     STATUS_INCLUDE_CERTS,
     STATUS_KEYLIST_MODE,
+    STATUS_RECIPIENT,
     STATUS_ENCRYPT_RESULT
   } status_t;
 
@@ -495,6 +496,7 @@
     "TEXTMODE",
     "INCLUDE_CERTS",
     "KEYLIST_MODE",
+    "RECIPIENT",
     "ENCRYPT_RESULT"
   };
 
@@ -574,15 +576,96 @@
 
 
 gpg_error_t
-gt_recipients_add (gpgme_tool_t gt, const char *fpr)
+gt_get_key (gpgme_tool_t gt, const char *pattern, gpgme_key_t *r_key)
 {
+  gpgme_ctx_t ctx;
+  gpgme_ctx_t listctx;
+  gpgme_error_t err;
+  gpgme_key_t key;
+
+  if (!gt || !r_key || !pattern)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  
+  ctx = gt->ctx;
+
+  err = gpgme_new (&listctx);
+  if (err)
+    return err;
+
+  {
+    gpgme_protocol_t proto;
+    gpgme_engine_info_t info;
+
+    /* Clone the relevant state.  */
+    proto = gpgme_get_protocol (ctx);
+    /* The g13 protocol does not allow keylisting, we need to choose
+       something else.  */
+    if (proto == GPGME_PROTOCOL_G13)
+      proto = GPGME_PROTOCOL_OpenPGP;
+
+    gpgme_set_protocol (listctx, proto);
+    gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
+    info = gpgme_ctx_get_engine_info (ctx);
+    while (info && info->protocol != proto)
+      info = info->next;
+    if (info)
+      gpgme_ctx_set_engine_info (listctx, proto,
+				 info->file_name, info->home_dir);
+  }
+
+  err = gpgme_op_keylist_start (listctx, pattern, 0);
+  if (!err)
+    err = gpgme_op_keylist_next (listctx, r_key);
+  if (!err)
+    {
+    try_next_key:
+      err = gpgme_op_keylist_next (listctx, &key);
+      if (gpgme_err_code (err) == GPG_ERR_EOF)
+	err = 0;
+      else
+	{
+          if (!err
+              && *r_key && (*r_key)->subkeys && (*r_key)->subkeys->fpr
+              && key && key->subkeys && key->subkeys->fpr
+              && !strcmp ((*r_key)->subkeys->fpr, key->subkeys->fpr))
+            {
+              /* The fingerprint is identical.  We assume that this is
+                 the same key and don't mark it as an ambiguous.  This
+                 problem may occur with corrupted keyrings and has
+                 been noticed often with gpgsm.  In fact gpgsm uses a
+                 similar hack to sort out such duplicates but it can't
+                 do that while listing keys.  */
+              gpgme_key_unref (key);
+              goto try_next_key;
+            }
+	  if (!err)
+	    {
+	      gpgme_key_unref (key);
+	      err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
+	    }
+	  gpgme_key_unref (*r_key);
+	}
+    }
+  gpgme_release (listctx);
+  
+  if (! err)
+    gt_write_status (gt, STATUS_RECIPIENT, 
+		     ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ? 
+		     (*r_key)->subkeys->fpr : "invalid", NULL);
+  return err;
+}
+
+
+gpg_error_t
+gt_recipients_add (gpgme_tool_t gt, const char *pattern)
+{
   gpg_error_t err;
   gpgme_key_t key;
 
   if (gt->recipients_nr >= MAX_RECIPIENTS)
     return gpg_error_from_errno (ENOMEM);
 
-  err = gpgme_get_key (gt->ctx, fpr, &key, 0);
+  err = gt_get_key (gt, pattern, &key);
   if (err)
     return err;
 
@@ -962,6 +1045,18 @@
 }
 
 
+gpg_error_t
+gt_vfs_create (gpgme_tool_t gt, const char *container_file, int flags)
+{
+  gpg_error_t err;
+  gpg_error_t op_err;
+  err = gpgme_op_vfs_create (gt->ctx, gt->recipients, container_file,
+			     flags, &op_err);
+  gt_recipients_clear (gt);
+  return err || op_err;
+}
+
+
 // TODO
 #define GT_RESULT_ENCRYPT 0x1
 #define GT_RESULT_DECRYPT 0x2
@@ -1743,6 +1838,27 @@
 
 
 static gpg_error_t
+cmd_vfs_create (assuan_context_t ctx, char *line)
+{
+  struct server *server = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  char *end;
+
+  end = strchr (line, ' ');
+  if (end)
+    {
+      *(end++) = '\0';
+      while (*end == ' ')
+	end++;
+    }
+
+  err = gt_vfs_create (server->gt, line, 0);
+
+  return err;
+}
+
+
+static gpg_error_t
 cmd_result (assuan_context_t ctx, char *line)
 {
   struct server *server = assuan_get_pointer (ctx);
@@ -1835,6 +1951,8 @@
     // TODO: ASSUAN
     { "VFS_MOUNT", cmd_vfs_mount },
     { "MOUNT", cmd_vfs_mount },
+    { "VFS_CREATE", cmd_vfs_create },
+    { "CREATE", cmd_vfs_create },
     // TODO: GPGCONF
     { "RESULT", cmd_result },
     { "STRERROR", cmd_strerror },

Modified: trunk/src/gpgme.def
===================================================================
--- trunk/src/gpgme.def	2009-11-02 17:18:48 UTC (rev 1412)
+++ trunk/src/gpgme.def	2009-11-03 19:15:35 UTC (rev 1413)
@@ -190,6 +190,7 @@
     gpgme_wait_ext			  @145
     gpgme_op_vfs_mount_result		  @146
     gpgme_op_vfs_mount			  @147
+    gpgme_op_vfs_create			  @148
 
 ; END
 

Modified: trunk/src/gpgme.h.in
===================================================================
--- trunk/src/gpgme.h.in	2009-11-02 17:18:48 UTC (rev 1412)
+++ trunk/src/gpgme.h.in	2009-11-03 19:15:35 UTC (rev 1413)
@@ -1808,9 +1808,13 @@
    or destroyed.  Transmission errors are returned directly,
    operational errors are returned in OP_ERR.  */
 gpgme_error_t gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
-				  const char *mount_dir, int flags,
+				  const char *mount_dir, unsigned int flags,
 				  gpgme_error_t *op_err);
 
+gpgme_error_t gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
+				   const char *container_file,
+				   unsigned int flags, gpgme_error_t *op_err);
+
 
 /* Interface to gpgconf(1).  */
 

Modified: trunk/src/libgpgme.vers
===================================================================
--- trunk/src/libgpgme.vers	2009-11-02 17:18:48 UTC (rev 1412)
+++ trunk/src/libgpgme.vers	2009-11-03 19:15:35 UTC (rev 1413)
@@ -71,6 +71,8 @@
 
     gpgme_op_vfs_mount_result;
     gpgme_op_vfs_mount;
+    gpgme_op_vfs_create;
+
 };
 
 

Added: trunk/src/vfs-create.c
===================================================================
--- trunk/src/vfs-create.c	                        (rev 0)
+++ trunk/src/vfs-create.c	2009-11-03 19:15:35 UTC (rev 1413)
@@ -0,0 +1,193 @@
+/* vfs-create.c - vfs create support in GPGME
+   Copyright (C) 2009 g10 Code GmbH
+
+   This file is part of GPGME.
+ 
+   GPGME is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+   
+   GPGME 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
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser 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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "gpgme.h"
+#include "debug.h"
+#include "context.h"
+#include "ops.h"
+#include "util.h"
+
+static gpgme_error_t
+vfs_start (gpgme_ctx_t ctx, int synchronous,
+	   const char *command,
+	   gpgme_assuan_data_cb_t data_cb,
+	   void *data_cb_value,
+	   gpgme_assuan_inquire_cb_t inq_cb,
+	   void *inq_cb_value,
+	   gpgme_assuan_status_cb_t status_cb,
+	   void *status_cb_value)
+{
+  gpgme_error_t err;
+
+  if (!command || !*command)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  /* The flag value 256 is used to suppress an engine reset.  This is
+     required to keep the connection running.  */
+  err = _gpgme_op_reset (ctx, ((synchronous & 255) | 256));
+  if (err)
+    return err;
+
+  return _gpgme_engine_op_assuan_transact (ctx->engine, command,
+					   data_cb, data_cb_value,
+					   inq_cb, inq_cb_value,
+					   status_cb, status_cb_value);
+}
+
+
+
+/* XXXX.  This is the asynchronous variant. */
+static gpgme_error_t
+gpgme_op_vfs_transact_start (gpgme_ctx_t ctx, 
+			     const char *command,
+			     gpgme_assuan_data_cb_t data_cb,
+			     void *data_cb_value,
+			     gpgme_assuan_inquire_cb_t inq_cb,
+			     void *inq_cb_value,
+			     gpgme_assuan_status_cb_t status_cb,
+			     void *status_cb_value)
+{
+  return vfs_start (ctx, 0, command, data_cb, data_cb_value,
+		    inq_cb, inq_cb_value, status_cb, status_cb_value);
+}
+
+
+/* XXXX.  This is the synchronous variant. */
+static gpgme_error_t
+gpgme_op_vfs_transact (gpgme_ctx_t ctx,
+		       const char *command,
+		       gpgme_assuan_data_cb_t data_cb,
+		       void *data_cb_value,
+		       gpgme_assuan_inquire_cb_t inq_cb,
+		       void *inq_cb_value,
+		       gpgme_assuan_status_cb_t status_cb,
+		       void *status_cb_value,
+		       gpgme_error_t *op_err)
+{
+  gpgme_error_t err;
+  
+  err = vfs_start (ctx, 1, command, data_cb, data_cb_value,
+		   inq_cb, inq_cb_value, status_cb, status_cb_value);
+  if (!err)
+    err = _gpgme_wait_one_ext (ctx, op_err);
+  return err;
+}
+
+
+/* The actual exported interface follows.  */
+
+/* The container is automatically uncreateed when the context is reset
+   or destroyed.  This is a synchronous convenience interface, which
+   automatically returns an operation error if there is no
+   transmission error.  */
+static gpgme_error_t
+_gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
+		      const char *container_file, unsigned int flags,
+		      gpgme_error_t *op_err)
+{
+  gpg_error_t err;
+  char *cmd;
+  char *container_file_esc = NULL;
+  int i;
+
+  /* We want to encourage people to check error values, so not getting
+     them is discouraged here.  Also makes our code easier.  */
+  if (! op_err)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_encode_percent_string (container_file, &container_file_esc, 0);
+  if (err)
+    return err;
+
+  i = 0;
+  while (!err && recp[i])
+    {
+      if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
+	{
+	  free (container_file_esc);
+	  return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
+	}
+
+      if (asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0)
+	{
+	  err = gpg_error_from_syserror ();
+	  free (container_file_esc);
+	  return err;
+	}
+      
+      err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
+				   NULL, NULL, op_err);
+      free (cmd);
+      if (err || *op_err)
+	{
+	  free (container_file_esc);
+	  return err;
+	}
+      recp++;
+    }
+
+  if (asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0)
+    {
+      err = gpg_error_from_syserror ();
+      free (container_file_esc);
+      return err;
+    }
+  free (container_file_esc);
+    
+  err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
+			       NULL, NULL, op_err);
+  free (cmd);
+
+  return err;
+}
+
+
+gpgme_error_t
+gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
+		      const char *container_file, unsigned int flags,
+		      gpgme_error_t *op_err)
+{
+  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_vfs_create", ctx,
+	      "container_file=%s, flags=0x%x, op_err=%p",
+	      container_file, flags, op_err);
+
+  if (_gpgme_debug_trace () && recp)
+    {
+      int i = 0;
+
+      while (recp[i])
+	{
+	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
+		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ? 
+		      recp[i]->subkeys->fpr : "invalid");
+	  i++;
+	}
+    }
+
+  return TRACE_ERR (_gpgme_op_vfs_create (ctx, recp, container_file,
+					  flags, op_err));
+}
+

Copied: trunk/src/vfs-mount.c (from rev 1412, trunk/src/g13.c)
===================================================================
--- trunk/src/vfs-mount.c	                        (rev 0)
+++ trunk/src/vfs-mount.c	2009-11-03 19:15:35 UTC (rev 1413)
@@ -0,0 +1,210 @@
+/* vfs-mount.c - vfs mount support in GPGME
+   Copyright (C) 2009 g10 Code GmbH
+
+   This file is part of GPGME.
+ 
+   GPGME is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+   
+   GPGME 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
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser 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.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "gpgme.h"
+#include "debug.h"
+#include "context.h"
+#include "ops.h"
+#include "util.h"
+
+typedef struct
+{
+  struct _gpgme_op_vfs_mount_result result;
+} *op_data_t;
+
+
+
+gpgme_vfs_mount_result_t
+gpgme_op_vfs_mount_result (gpgme_ctx_t ctx)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_VFS_MOUNT, &hook, -1, NULL);
+  opd = hook;
+  /* Check in case this function is used without having run a command
+     before.  */
+  if (err || !opd)
+    return NULL;
+
+  return &opd->result;
+}
+
+
+static gpgme_error_t
+vfs_start (gpgme_ctx_t ctx, int synchronous,
+	   const char *command,
+	   gpgme_assuan_data_cb_t data_cb,
+	   void *data_cb_value,
+	   gpgme_assuan_inquire_cb_t inq_cb,
+	   void *inq_cb_value,
+	   gpgme_assuan_status_cb_t status_cb,
+	   void *status_cb_value)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  if (!command || !*command)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  /* The flag value 256 is used to suppress an engine reset.  This is
+     required to keep the connection running.  */
+  err = _gpgme_op_reset (ctx, ((synchronous & 255) | 256));
+  if (err)
+    return err;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_VFS_MOUNT, &hook, sizeof (*opd),
+			       NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  return _gpgme_engine_op_assuan_transact (ctx->engine, command,
+					   data_cb, data_cb_value,
+					   inq_cb, inq_cb_value,
+					   status_cb, status_cb_value);
+}
+
+
+
+/* XXXX.  This is the asynchronous variant. */
+static gpgme_error_t
+gpgme_op_vfs_transact_start (gpgme_ctx_t ctx, 
+			     const char *command,
+			     gpgme_assuan_data_cb_t data_cb,
+			     void *data_cb_value,
+			     gpgme_assuan_inquire_cb_t inq_cb,
+			     void *inq_cb_value,
+			     gpgme_assuan_status_cb_t status_cb,
+			     void *status_cb_value)
+{
+  return vfs_start (ctx, 0, command, data_cb, data_cb_value,
+		    inq_cb, inq_cb_value, status_cb, status_cb_value);
+}
+
+
+/* XXXX.  This is the synchronous variant. */
+static gpgme_error_t
+gpgme_op_vfs_transact (gpgme_ctx_t ctx,
+		       const char *command,
+		       gpgme_assuan_data_cb_t data_cb,
+		       void *data_cb_value,
+		       gpgme_assuan_inquire_cb_t inq_cb,
+		       void *inq_cb_value,
+		       gpgme_assuan_status_cb_t status_cb,
+		       void *status_cb_value,
+		       gpgme_error_t *op_err)
+{
+  gpgme_error_t err;
+  
+  err = vfs_start (ctx, 1, command, data_cb, data_cb_value,
+		   inq_cb, inq_cb_value, status_cb, status_cb_value);
+  if (!err)
+    err = _gpgme_wait_one_ext (ctx, op_err);
+  return err;
+}
+
+
+/* The actual exported interface follows.  */
+
+/* The container is automatically unmounted when the context is reset
+   or destroyed.  This is a synchronous convenience interface, which
+   automatically returns an operation error if there is no
+   transmission error.  */
+static gpgme_error_t
+_gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
+		     const char *mount_dir, int flags, gpgme_error_t *op_err)
+{
+  gpg_error_t err;
+  char *cmd;
+  char *container_file_esc = NULL;
+
+  /* We want to encourage people to check error values, so not getting
+     them is discouraged here.  Also makes our code easier.  */
+  if (! op_err)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_encode_percent_string (container_file, &container_file_esc, 0);
+  if (err)
+    return err;
+
+  if (asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0)
+    {
+      err = gpg_error_from_syserror ();
+      free (container_file_esc);
+      return err;
+    }
+  free (container_file_esc);
+
+  err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
+			       NULL, NULL, op_err);
+  free (cmd);
+  if (err || *op_err)
+    return err;
+
+  if (mount_dir)
+    {
+      char *mount_dir_esc = NULL;
+
+      err = _gpgme_encode_percent_string (mount_dir, &mount_dir_esc, 0);
+      if (err)
+	return err;
+
+      if (asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0)
+	{
+	  err = gpg_error_from_syserror ();
+	  free (mount_dir_esc);
+	  return err;
+	}
+      free (mount_dir_esc);
+    }
+  else
+    {
+      if (asprintf (&cmd, "MOUNT") < 0)
+	return gpg_error_from_syserror ();
+    }
+    
+  err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
+			       NULL, NULL, op_err);
+  free (cmd);
+
+  return err;
+}
+
+gpgme_error_t
+gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
+		    const char *mount_dir, unsigned int flags,
+		    gpgme_error_t *op_err)
+{
+  TRACE_BEG4 (DEBUG_CTX, "gpgme_op_vfs_mount", ctx,
+	      "container=%s, mount_dir=%s, flags=0x%x, op_err=%p",
+	      container_file, mount_dir, flags, op_err);
+  return TRACE_ERR (_gpgme_op_vfs_mount (ctx, container_file, mount_dir,
+					 flags, op_err));
+}
+




More information about the Gnupg-commits mailing list