2009-11-03 Marcus Brinkmann <marcus@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.
This commit is contained in:
parent
490661821a
commit
97932b102a
@ -1,3 +1,15 @@
|
|||||||
|
2009-11-03 Marcus Brinkmann <marcus@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@g10code.de>
|
2009-11-02 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* debug.h (_gpgme_debug_buffer): Make TAG argument const const.
|
* debug.h (_gpgme_debug_buffer): Make TAG argument const const.
|
||||||
|
@ -111,7 +111,7 @@ main_sources = \
|
|||||||
opassuan.c \
|
opassuan.c \
|
||||||
engine.h engine-backend.h engine.c engine-gpg.c status-table.h \
|
engine.h engine-backend.h engine.c engine-gpg.c status-table.h \
|
||||||
$(gpgsm_components) $(assuan_components) $(gpgconf_components) \
|
$(gpgsm_components) $(assuan_components) $(gpgconf_components) \
|
||||||
$(g13_components) g13.c \
|
$(g13_components) vfs-mount.c vfs-create.c \
|
||||||
gpgconf.c \
|
gpgconf.c \
|
||||||
sema.h priv-io.h $(system_components) dirinfo.c \
|
sema.h priv-io.h $(system_components) dirinfo.c \
|
||||||
debug.c debug.h gpgme.c version.c error.c
|
debug.c debug.h gpgme.c version.c error.c
|
||||||
|
122
src/gpgme-tool.c
122
src/gpgme-tool.c
@ -483,6 +483,7 @@ typedef enum status
|
|||||||
STATUS_TEXTMODE,
|
STATUS_TEXTMODE,
|
||||||
STATUS_INCLUDE_CERTS,
|
STATUS_INCLUDE_CERTS,
|
||||||
STATUS_KEYLIST_MODE,
|
STATUS_KEYLIST_MODE,
|
||||||
|
STATUS_RECIPIENT,
|
||||||
STATUS_ENCRYPT_RESULT
|
STATUS_ENCRYPT_RESULT
|
||||||
} status_t;
|
} status_t;
|
||||||
|
|
||||||
@ -495,6 +496,7 @@ const char *status_string[] =
|
|||||||
"TEXTMODE",
|
"TEXTMODE",
|
||||||
"INCLUDE_CERTS",
|
"INCLUDE_CERTS",
|
||||||
"KEYLIST_MODE",
|
"KEYLIST_MODE",
|
||||||
|
"RECIPIENT",
|
||||||
"ENCRYPT_RESULT"
|
"ENCRYPT_RESULT"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -574,7 +576,88 @@ gt_signers_clear (gpgme_tool_t gt)
|
|||||||
|
|
||||||
|
|
||||||
gpg_error_t
|
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;
|
gpg_error_t err;
|
||||||
gpgme_key_t key;
|
gpgme_key_t key;
|
||||||
@ -582,7 +665,7 @@ gt_recipients_add (gpgme_tool_t gt, const char *fpr)
|
|||||||
if (gt->recipients_nr >= MAX_RECIPIENTS)
|
if (gt->recipients_nr >= MAX_RECIPIENTS)
|
||||||
return gpg_error_from_errno (ENOMEM);
|
return gpg_error_from_errno (ENOMEM);
|
||||||
|
|
||||||
err = gpgme_get_key (gt->ctx, fpr, &key, 0);
|
err = gt_get_key (gt, pattern, &key);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -962,6 +1045,18 @@ gt_vfs_mount (gpgme_tool_t gt, const char *container_file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
// TODO
|
||||||
#define GT_RESULT_ENCRYPT 0x1
|
#define GT_RESULT_ENCRYPT 0x1
|
||||||
#define GT_RESULT_DECRYPT 0x2
|
#define GT_RESULT_DECRYPT 0x2
|
||||||
@ -1742,6 +1837,27 @@ cmd_vfs_mount (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
static gpg_error_t
|
||||||
cmd_result (assuan_context_t ctx, char *line)
|
cmd_result (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
@ -1835,6 +1951,8 @@ register_commands (assuan_context_t ctx)
|
|||||||
// TODO: ASSUAN
|
// TODO: ASSUAN
|
||||||
{ "VFS_MOUNT", cmd_vfs_mount },
|
{ "VFS_MOUNT", cmd_vfs_mount },
|
||||||
{ "MOUNT", cmd_vfs_mount },
|
{ "MOUNT", cmd_vfs_mount },
|
||||||
|
{ "VFS_CREATE", cmd_vfs_create },
|
||||||
|
{ "CREATE", cmd_vfs_create },
|
||||||
// TODO: GPGCONF
|
// TODO: GPGCONF
|
||||||
{ "RESULT", cmd_result },
|
{ "RESULT", cmd_result },
|
||||||
{ "STRERROR", cmd_strerror },
|
{ "STRERROR", cmd_strerror },
|
||||||
|
@ -190,6 +190,7 @@ EXPORTS
|
|||||||
gpgme_wait_ext @145
|
gpgme_wait_ext @145
|
||||||
gpgme_op_vfs_mount_result @146
|
gpgme_op_vfs_mount_result @146
|
||||||
gpgme_op_vfs_mount @147
|
gpgme_op_vfs_mount @147
|
||||||
|
gpgme_op_vfs_create @148
|
||||||
|
|
||||||
; END
|
; END
|
||||||
|
|
||||||
|
@ -1808,9 +1808,13 @@ gpgme_vfs_mount_result_t gpgme_op_vfs_mount_result (gpgme_ctx_t ctx);
|
|||||||
or destroyed. Transmission errors are returned directly,
|
or destroyed. Transmission errors are returned directly,
|
||||||
operational errors are returned in OP_ERR. */
|
operational errors are returned in OP_ERR. */
|
||||||
gpgme_error_t gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
|
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 *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). */
|
/* Interface to gpgconf(1). */
|
||||||
|
|
||||||
|
@ -71,6 +71,8 @@ GPGME_1.1 {
|
|||||||
|
|
||||||
gpgme_op_vfs_mount_result;
|
gpgme_op_vfs_mount_result;
|
||||||
gpgme_op_vfs_mount;
|
gpgme_op_vfs_mount;
|
||||||
|
gpgme_op_vfs_create;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
193
src/vfs-create.c
Normal file
193
src/vfs-create.c
Normal file
@ -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));
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
/* g13.c - g13 support in GPGME
|
/* vfs-mount.c - vfs mount support in GPGME
|
||||||
Copyright (C) 2009 g10 Code GmbH
|
Copyright (C) 2009 g10 Code GmbH
|
||||||
|
|
||||||
This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
@ -198,7 +198,8 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
|
|||||||
|
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
|
gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
|
||||||
const char *mount_dir, int flags, gpgme_error_t *op_err)
|
const char *mount_dir, unsigned int flags,
|
||||||
|
gpgme_error_t *op_err)
|
||||||
{
|
{
|
||||||
TRACE_BEG4 (DEBUG_CTX, "gpgme_op_vfs_mount", ctx,
|
TRACE_BEG4 (DEBUG_CTX, "gpgme_op_vfs_mount", ctx,
|
||||||
"container=%s, mount_dir=%s, flags=0x%x, op_err=%p",
|
"container=%s, mount_dir=%s, flags=0x%x, op_err=%p",
|
Loading…
Reference in New Issue
Block a user