2009-11-10 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Activate UIServer if FD passing is enabled and Assuan is available. m4/ 2009-11-10 Marcus Brinkmann <marcus@g10code.de> * libassuan.m4: Fix LIBASSUAN_VERSION. src/ 2009-11-10 Marcus Brinkmann <marcus@g10code.de> * Makefile.am (uiserver_components): New variable. (main_sources): Add it. * ops.h, key.c (_gpgme_key_append_name): Take CONVERT argument, implement it. Adjust callers. (gpgme_key_from_uid): New function. * gpgme.h.in (gpgme_protocol_t): Add GPGME_PROTOCOL_DEFAULT. (gpgme_encrypt_flags_t): Add GPGME_ENCRYPT_PREPARE, GPGME_ENCRYPT_EXPECT_SIGN. (gpgme_set_sub_protocol, gpgme_key_from_uid): New functions. * libgpgme.vers, gpgme.def: Add new functions. * gpgme.c (gpgme_set_protocol): Add UIServer protocol. (gpgme_set_sub_protocol): New function. (gpgme_get_protocol_name): Add UIServer and default protocol. * assuan-support.c: Return correct error values, implement socketpair for POSIX. * priv-io.h, posix-io.c, w32-io.c, w32-glib-io.c, w32-qt-io.cpp (_gpgme_io_spawn): Add ATFORK and ATFORKVALUE arguments. Implement it for POSIX. Adjust all callers. * engine.h, engine-backend.h (_gpgme_engine_set_protocol) (_gpgme_engine_op_decrypt_verify): New prototypes. Adjust all users. * engine.c (engine_ops, gpgme_get_engine_info): Add UIServer engine. (_gpgme_engine_set_protocol, _gpgme_engine_op_decrypt_verify): New function. * decrypt-verify.c (decrypt_verify_start): Call _gpgme_engine_op_decrypt_verify. * util.h, posix-util.c, w32-util.c (_gpgme_get_uiserver_socket_path): New function. * engine-gpgsm.c (gpgsm_set_fd): Fix _gpgme_io_pipe invocation. * gpgme-tool.c: Some support for UIServer protocol. * engine-uiserver.c: New file.
This commit is contained in:
parent
8435f18d96
commit
96cf17b159
@ -1,3 +1,8 @@
|
||||
2009-11-10 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* configure.ac: Activate UIServer if FD passing is enabled and
|
||||
Assuan is available.
|
||||
|
||||
2009-10-30 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* configure.ac: Check for argp.h and error_t.
|
||||
|
2
NEWS
2
NEWS
@ -8,6 +8,8 @@ Noteworthy changes in version 1.2.1 (unreleased)
|
||||
|
||||
* New engine GPGME_PROTOCOL_G13 to support the new g13 tool.
|
||||
|
||||
* New engine GPGME_PROTOCOL_UISERVER to support UI Servers.
|
||||
|
||||
* Interface changes relative to the 1.2.0 release:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
GPGME_STATUS_INV_SGNR NEW
|
||||
|
5
TODO
5
TODO
@ -1,5 +1,10 @@
|
||||
Hey Emacs, this is -*- org -*- mode!
|
||||
|
||||
* Document all the new stuff.
|
||||
* Fix the remaining UI Server problems:
|
||||
** VERIFY --silent support.
|
||||
** ENCRYPT/DECRYPT/VERIFY/SIGN reset the engine, shouldn't be done with UISERVER?
|
||||
|
||||
* IMPORTANT
|
||||
** When using descriptor passing, we need to set the fd to blocking before
|
||||
issueing simple commands, because we are mixing synchronous
|
||||
|
28
configure.ac
28
configure.ac
@ -634,13 +634,6 @@ AC_ARG_ENABLE(gpgconf-test,
|
||||
run_gpgconf_test=$enableval)
|
||||
AM_CONDITIONAL(RUN_GPGCONF_TESTS, test "$run_gpgconf_test" = "yes")
|
||||
|
||||
# Only build if supported.
|
||||
AM_CONDITIONAL(BUILD_GPGCONF, test "$GPGCONF" != "no")
|
||||
if test "$GPGCONF" != "no"; then
|
||||
AC_DEFINE(HAVE_GPGCONF, 1,
|
||||
[Defined if we are building with gpgconf support.])
|
||||
fi
|
||||
|
||||
|
||||
NO_OVERRIDE=no
|
||||
AC_ARG_WITH(g13,
|
||||
@ -737,13 +730,6 @@ AC_ARG_ENABLE(g13-test,
|
||||
run_g13_test=$enableval)
|
||||
AM_CONDITIONAL(RUN_G13_TESTS, test "$run_g13_test" = "yes")
|
||||
|
||||
# Only build if supported.
|
||||
AM_CONDITIONAL(BUILD_G13, test "$G13" != "no")
|
||||
if test "$G13" != "no"; then
|
||||
AC_DEFINE(HAVE_G13, 1,
|
||||
[Defined if we are building with g13 support.])
|
||||
fi
|
||||
|
||||
|
||||
# Check for funopen
|
||||
AC_CHECK_FUNCS(funopen)
|
||||
@ -803,6 +789,17 @@ fi
|
||||
AM_CONDITIONAL(USE_DESCRIPTOR_PASSING, test "$use_descriptor_passing" = "yes")
|
||||
|
||||
|
||||
uiserver=no
|
||||
if test "$use_descriptor_passing" = "yes" && test "$have_libassuan" = "yes"; then
|
||||
uiserver=yes
|
||||
fi
|
||||
if test "$uiserver" != "no"; then
|
||||
AC_DEFINE(ENABLE_UISERVER, 1,
|
||||
[Defined if we are building with uiserver support.])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_UISERVER, test "$uiserver" != "no")
|
||||
|
||||
|
||||
AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
|
||||
|
||||
# Generate values for the DLL version info
|
||||
@ -912,6 +909,9 @@ echo "
|
||||
|
||||
Assuan version: $LIBASSUAN_VERSION
|
||||
|
||||
UI Server: $uiserver
|
||||
FD Passing: $use_descriptor_passing
|
||||
|
||||
GPGME Pthread: $have_pthread
|
||||
GPGME Pth: $have_pth
|
||||
"
|
||||
|
@ -1,3 +1,7 @@
|
||||
2009-11-10 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* libassuan.m4: Fix LIBASSUAN_VERSION.
|
||||
|
||||
2006-06-08 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* pth.m4: Add --all to pth-config invocation.
|
||||
|
@ -63,7 +63,7 @@ AC_DEFUN([AM_PATH_LIBASSUAN],
|
||||
if test $ok = yes; then
|
||||
LIBASSUAN_CFLAGS=`$LIBASSUAN_CONFIG $libassuan_config_args --cflags`
|
||||
LIBASSUAN_LIBS=`$LIBASSUAN_CONFIG $libassuan_config_args --libs`
|
||||
LIBASSUAN_VERSION="$LIBASSUAN_CONFIG_VERSION"
|
||||
LIBASSUAN_VERSION="$libassuan_config_version"
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
|
@ -1,3 +1,38 @@
|
||||
2009-11-10 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* Makefile.am (uiserver_components): New variable.
|
||||
(main_sources): Add it.
|
||||
* ops.h, key.c (_gpgme_key_append_name): Take CONVERT argument,
|
||||
implement it. Adjust callers.
|
||||
(gpgme_key_from_uid): New function.
|
||||
* gpgme.h.in (gpgme_protocol_t): Add GPGME_PROTOCOL_DEFAULT.
|
||||
(gpgme_encrypt_flags_t): Add GPGME_ENCRYPT_PREPARE,
|
||||
GPGME_ENCRYPT_EXPECT_SIGN.
|
||||
(gpgme_set_sub_protocol, gpgme_key_from_uid): New functions.
|
||||
* libgpgme.vers, gpgme.def: Add new functions.
|
||||
* gpgme.c (gpgme_set_protocol): Add UIServer protocol.
|
||||
(gpgme_set_sub_protocol): New function.
|
||||
(gpgme_get_protocol_name): Add UIServer and default protocol.
|
||||
* assuan-support.c: Return correct error values, implement
|
||||
socketpair for POSIX.
|
||||
* priv-io.h, posix-io.c, w32-io.c, w32-glib-io.c,
|
||||
w32-qt-io.cpp (_gpgme_io_spawn): Add ATFORK and ATFORKVALUE
|
||||
arguments. Implement it for POSIX. Adjust all callers.
|
||||
* engine.h, engine-backend.h (_gpgme_engine_set_protocol)
|
||||
(_gpgme_engine_op_decrypt_verify): New prototypes. Adjust all
|
||||
users.
|
||||
* engine.c (engine_ops, gpgme_get_engine_info): Add UIServer
|
||||
engine.
|
||||
(_gpgme_engine_set_protocol, _gpgme_engine_op_decrypt_verify): New
|
||||
function.
|
||||
* decrypt-verify.c (decrypt_verify_start): Call
|
||||
_gpgme_engine_op_decrypt_verify.
|
||||
* util.h, posix-util.c,
|
||||
w32-util.c (_gpgme_get_uiserver_socket_path): New function.
|
||||
* engine-gpgsm.c (gpgsm_set_fd): Fix _gpgme_io_pipe invocation.
|
||||
* gpgme-tool.c: Some support for UIServer protocol.
|
||||
* engine-uiserver.c: New file.
|
||||
|
||||
2009-11-09 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* engine-gpgsm.c (gpgsm_new): Close server side FDs.
|
||||
|
@ -92,6 +92,13 @@ else
|
||||
g13_components =
|
||||
endif
|
||||
|
||||
if HAVE_UISERVER
|
||||
uiserver_components = engine-uiserver.c
|
||||
else
|
||||
uiserver_components =
|
||||
endif
|
||||
|
||||
|
||||
# These are the source files common to all library versions. We used
|
||||
# to build a non-installed library for that, but that does not work
|
||||
# correctly on all platforms (in particular, one can not specify the
|
||||
@ -111,6 +118,7 @@ main_sources = \
|
||||
opassuan.c \
|
||||
engine.h engine-backend.h engine.c engine-gpg.c status-table.h \
|
||||
$(gpgsm_components) $(assuan_components) $(gpgconf_components) \
|
||||
$(uiserver_components) \
|
||||
$(g13_components) vfs-mount.c vfs-create.c \
|
||||
gpgconf.c \
|
||||
sema.h priv-io.h $(system_components) dirinfo.c \
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "assuan.h"
|
||||
|
||||
@ -76,7 +77,8 @@ my_recvmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
|
||||
int flags)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#else
|
||||
return _gpgme_io_recvmsg (fd, msg, flags);
|
||||
#endif
|
||||
@ -89,7 +91,8 @@ my_sendmsg (assuan_context_t ctx, assuan_fd_t fd, const assuan_msghdr_t msg,
|
||||
int flags)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#else
|
||||
return _gpgme_io_sendmsg (fd, msg, flags);
|
||||
#endif
|
||||
@ -107,14 +110,17 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue, unsigned int flags)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int err;
|
||||
struct spawn_fd_item_s *fd_items;
|
||||
int i;
|
||||
|
||||
assert (name);
|
||||
|
||||
if (! name)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (fd_child_list)
|
||||
@ -126,7 +132,7 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
|
||||
i += 3;
|
||||
fd_items = malloc (sizeof (struct spawn_fd_item_s) * i);
|
||||
if (! fd_items)
|
||||
return gpg_error_from_syserror ();
|
||||
return -1;
|
||||
i = 0;
|
||||
if (fd_child_list)
|
||||
{
|
||||
@ -152,7 +158,8 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
|
||||
fd_items[i].fd = -1;
|
||||
fd_items[i].dup_to = -1;
|
||||
|
||||
err = _gpgme_io_spawn (name, argv, IOSPAWN_FLAG_NOCLOSE, fd_items, r_pid);
|
||||
err = _gpgme_io_spawn (name, argv, IOSPAWN_FLAG_NOCLOSE, fd_items,
|
||||
atfork, atforkvalue, r_pid);
|
||||
if (! err)
|
||||
{
|
||||
i = 0;
|
||||
@ -195,8 +202,13 @@ static int
|
||||
my_socketpair (assuan_context_t ctx, int namespace, int style,
|
||||
int protocol, assuan_fd_t filedes[2])
|
||||
{
|
||||
assert ("Should never happen.");
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#else
|
||||
/* FIXME: Debug output missing. */
|
||||
return __assuan_socketpair (ctx, namespace, style, protocol, filedes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,7 +77,7 @@ decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
|
||||
_gpgme_engine_set_status_handler (ctx->engine,
|
||||
decrypt_verify_status_handler, ctx);
|
||||
|
||||
return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain);
|
||||
return _gpgme_engine_op_decrypt_verify (ctx->engine, cipher, plain);
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ read_gpgconf_dirs (void)
|
||||
|
||||
cfd[0].fd = rp[1];
|
||||
|
||||
status = _gpgme_io_spawn (pgmname, argv, 0, cfd, NULL);
|
||||
status = _gpgme_io_spawn (pgmname, argv, 0, cfd, NULL, NULL, NULL);
|
||||
if (status < 0)
|
||||
{
|
||||
_gpgme_io_close (rp[0]);
|
||||
|
@ -743,7 +743,9 @@ struct engine_ops _gpgme_engine_ops_assuan =
|
||||
NULL, /* set_command_handler */
|
||||
NULL, /* set_colon_line_handler */
|
||||
llass_set_locale,
|
||||
NULL, /* set_protocol */
|
||||
NULL, /* decrypt */
|
||||
NULL, /* decrypt_verify */
|
||||
NULL, /* delete */
|
||||
NULL, /* edit */
|
||||
NULL, /* encrypt */
|
||||
|
@ -58,8 +58,11 @@ struct engine_ops
|
||||
engine_colon_line_handler_t fnc,
|
||||
void *fnc_value);
|
||||
gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
|
||||
gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol);
|
||||
gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph,
|
||||
gpgme_data_t plain);
|
||||
gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph,
|
||||
gpgme_data_t plain);
|
||||
gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret);
|
||||
gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
|
||||
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
|
||||
@ -88,12 +91,11 @@ struct engine_ops
|
||||
gpgme_keylist_mode_t mode);
|
||||
gpgme_error_t (*sign) (void *engine, gpgme_data_t in, gpgme_data_t out,
|
||||
gpgme_sig_mode_t mode, int use_armor,
|
||||
int use_textmode,
|
||||
int include_certs, gpgme_ctx_t ctx /* FIXME */);
|
||||
int use_textmode, int include_certs,
|
||||
gpgme_ctx_t ctx /* FIXME */);
|
||||
gpgme_error_t (*trustlist) (void *engine, const char *pattern);
|
||||
gpgme_error_t (*verify) (void *engine, gpgme_data_t sig,
|
||||
gpgme_data_t signed_text,
|
||||
gpgme_data_t plaintext);
|
||||
gpgme_data_t signed_text, gpgme_data_t plaintext);
|
||||
gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output,
|
||||
unsigned int flags);
|
||||
gpgme_error_t (*opassuan_transact) (void *engine,
|
||||
@ -132,5 +134,8 @@ extern struct engine_ops _gpgme_engine_ops_assuan; /* Low-level Assuan. */
|
||||
#ifdef ENABLE_G13
|
||||
extern struct engine_ops _gpgme_engine_ops_g13; /* Crypto VFS. */
|
||||
#endif
|
||||
#ifdef ENABLE_UISERVER
|
||||
extern struct engine_ops _gpgme_engine_ops_uiserver;
|
||||
#endif
|
||||
|
||||
#endif /* ENGINE_BACKEND_H */
|
||||
|
@ -757,7 +757,9 @@ struct engine_ops _gpgme_engine_ops_g13 =
|
||||
NULL, /* set_command_handler */
|
||||
NULL, /* set_colon_line_handler */
|
||||
g13_set_locale,
|
||||
NULL, /* set_protocol */
|
||||
NULL, /* decrypt */
|
||||
NULL, /* decrypt_verify */
|
||||
NULL, /* delete */
|
||||
NULL, /* edit */
|
||||
NULL, /* encrypt */
|
||||
|
@ -1332,7 +1332,7 @@ start (engine_gpg_t gpg)
|
||||
status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
|
||||
_gpgme_get_gpg_path (), gpg->argv,
|
||||
IOSPAWN_FLAG_ALLOW_SET_FG,
|
||||
fd_list, &pid);
|
||||
fd_list, NULL, NULL, &pid);
|
||||
saved_errno = errno;
|
||||
|
||||
free (fd_list);
|
||||
@ -2347,7 +2347,9 @@ struct engine_ops _gpgme_engine_ops_gpg =
|
||||
gpg_set_command_handler,
|
||||
gpg_set_colon_line_handler,
|
||||
gpg_set_locale,
|
||||
NULL, /* set_protocol */
|
||||
gpg_decrypt,
|
||||
gpg_decrypt, /* decrypt_verify */
|
||||
gpg_delete,
|
||||
gpg_edit,
|
||||
gpg_encrypt,
|
||||
|
@ -221,7 +221,7 @@ gpgconf_read (void *engine, char *arg1, char *arg2,
|
||||
|
||||
cfd[0].fd = rp[1];
|
||||
|
||||
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL);
|
||||
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
|
||||
if (status < 0)
|
||||
{
|
||||
_gpgme_io_close (rp[0]);
|
||||
@ -659,7 +659,7 @@ gpgconf_write (void *engine, char *arg1, char *arg2, gpgme_data_t conf)
|
||||
|
||||
cfd[0].fd = rp[0];
|
||||
|
||||
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL);
|
||||
status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
|
||||
if (status < 0)
|
||||
{
|
||||
_gpgme_io_close (rp[0]);
|
||||
@ -897,7 +897,9 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
|
||||
NULL, /* set_command_handler */
|
||||
NULL, /* set_colon_line_handler */
|
||||
NULL, /* set_locale */
|
||||
NULL, /* set_protocol */
|
||||
NULL, /* decrypt */
|
||||
NULL, /* decrypt_verify */
|
||||
NULL, /* delete */
|
||||
NULL, /* edit */
|
||||
NULL, /* encrypt */
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "wait.h"
|
||||
#include "priv-io.h"
|
||||
#include "sema.h"
|
||||
#include "data.h"
|
||||
|
||||
#include "assuan.h"
|
||||
#include "status-table.h"
|
||||
@ -657,7 +658,7 @@ gpgsm_set_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type, const char *opt)
|
||||
{
|
||||
int fds[2];
|
||||
|
||||
if (_gpgme_io_pipe (fds, 0) < 0)
|
||||
if (_gpgme_io_pipe (fds, dir) < 0)
|
||||
return gpg_error_from_errno (errno);
|
||||
|
||||
iocb_data->fd = dir ? fds[0] : fds[1];
|
||||
@ -1914,8 +1915,10 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
|
||||
NULL, /* set_command_handler */
|
||||
gpgsm_set_colon_line_handler,
|
||||
gpgsm_set_locale,
|
||||
NULL, /* set_protocol */
|
||||
gpgsm_decrypt,
|
||||
gpgsm_delete,
|
||||
gpgsm_decrypt,
|
||||
gpgsm_delete, /* decrypt_verify */
|
||||
NULL, /* edit */
|
||||
gpgsm_encrypt,
|
||||
NULL, /* encrypt_sign */
|
||||
|
1361
src/engine-uiserver.c
Normal file
1361
src/engine-uiserver.c
Normal file
File diff suppressed because it is too large
Load Diff
39
src/engine.c
39
src/engine.c
@ -61,7 +61,12 @@ static struct engine_ops *engine_ops[] =
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef ENABLE_G13
|
||||
&_gpgme_engine_ops_g13 /* Crypto VFS. */
|
||||
&_gpgme_engine_ops_g13, /* Crypto VFS. */
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef ENABLE_UISERVER
|
||||
&_gpgme_engine_ops_uiserver /* Crypto VFS. */
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
@ -200,7 +205,8 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
|
||||
GPGME_PROTOCOL_CMS,
|
||||
GPGME_PROTOCOL_GPGCONF,
|
||||
GPGME_PROTOCOL_ASSUAN,
|
||||
GPGME_PROTOCOL_G13 };
|
||||
GPGME_PROTOCOL_G13,
|
||||
GPGME_PROTOCOL_UISERVER };
|
||||
unsigned int proto;
|
||||
|
||||
for (proto = 0; proto < DIM (proto_list); proto++)
|
||||
@ -550,6 +556,20 @@ _gpgme_engine_set_locale (engine_t engine, int category,
|
||||
return (*engine->ops->set_locale) (engine->engine, category, value);
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
|
||||
{
|
||||
if (!engine)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (!engine->ops->set_protocol)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
return (*engine->ops->set_protocol) (engine->engine, protocol);
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
|
||||
gpgme_data_t plain)
|
||||
@ -563,6 +583,21 @@ _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
|
||||
return (*engine->ops->decrypt) (engine->engine, ciph, plain);
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
|
||||
gpgme_data_t plain)
|
||||
{
|
||||
if (!engine)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (!engine->ops->decrypt_verify)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain);
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
|
||||
int allow_secret)
|
||||
|
@ -59,7 +59,8 @@ gpgme_error_t _gpgme_engine_reset (engine_t engine);
|
||||
|
||||
gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
|
||||
const char *value);
|
||||
|
||||
gpgme_error_t _gpgme_engine_set_protocol (engine_t engine,
|
||||
gpgme_protocol_t protocol);
|
||||
void _gpgme_engine_release (engine_t engine);
|
||||
void _gpgme_engine_set_status_handler (engine_t engine,
|
||||
engine_status_handler_t fnc,
|
||||
@ -72,7 +73,9 @@ gpgme_error_t
|
||||
_gpgme_engine_set_colon_line_handler (engine_t engine,
|
||||
engine_colon_line_handler_t fnc,
|
||||
void *fnc_value);
|
||||
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine,
|
||||
gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
|
||||
gpgme_data_t plain);
|
||||
gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine,
|
||||
gpgme_data_t ciph,
|
||||
gpgme_data_t plain);
|
||||
gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
|
||||
|
@ -669,6 +669,9 @@ gt_recipients_add (gpgme_tool_t gt, const char *pattern)
|
||||
if (gt->recipients_nr >= MAX_RECIPIENTS)
|
||||
return gpg_error_from_errno (ENOMEM);
|
||||
|
||||
if (gpgme_get_protocol (gt->ctx) == GPGME_PROTOCOL_UISERVER)
|
||||
err = gpgme_key_from_uid (&key, pattern);
|
||||
else
|
||||
err = gt_get_key (gt, pattern, &key);
|
||||
if (err)
|
||||
return err;
|
||||
@ -780,6 +783,10 @@ gt_protocol_from_name (const char *name)
|
||||
return GPGME_PROTOCOL_ASSUAN;
|
||||
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_G13)))
|
||||
return GPGME_PROTOCOL_G13;
|
||||
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_UISERVER)))
|
||||
return GPGME_PROTOCOL_UISERVER;
|
||||
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_DEFAULT)))
|
||||
return GPGME_PROTOCOL_DEFAULT;
|
||||
return GPGME_PROTOCOL_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -791,6 +798,13 @@ gt_set_protocol (gpgme_tool_t gt, gpgme_protocol_t proto)
|
||||
}
|
||||
|
||||
|
||||
gpg_error_t
|
||||
gt_set_sub_protocol (gpgme_tool_t gt, gpgme_protocol_t proto)
|
||||
{
|
||||
return gpgme_set_sub_protocol (gt->ctx, proto);
|
||||
}
|
||||
|
||||
|
||||
gpg_error_t
|
||||
gt_get_protocol (gpgme_tool_t gt)
|
||||
{
|
||||
@ -1248,6 +1262,17 @@ cmd_protocol (assuan_context_t ctx, char *line)
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
cmd_sub_protocol (assuan_context_t ctx, char *line)
|
||||
{
|
||||
struct server *server = assuan_get_pointer (ctx);
|
||||
if (line && *line)
|
||||
return gt_set_sub_protocol (server->gt, gt_protocol_from_name (line));
|
||||
/* FIXME. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
cmd_armor (assuan_context_t ctx, char *line)
|
||||
{
|
||||
@ -1456,31 +1481,36 @@ _cmd_sign_encrypt (assuan_context_t ctx, char *line, int sign)
|
||||
gpg_error_t err;
|
||||
assuan_fd_t inp_fd;
|
||||
assuan_fd_t out_fd;
|
||||
gpgme_data_t inp_data;
|
||||
gpgme_data_t out_data;
|
||||
gpgme_data_t inp_data = NULL;
|
||||
gpgme_data_t out_data = NULL;
|
||||
gpgme_encrypt_flags_t flags = 0;
|
||||
|
||||
if (strstr (line, "--always-trust"))
|
||||
flags |= GPGME_ENCRYPT_ALWAYS_TRUST;
|
||||
if (strstr (line, "--no-encrypt-to"))
|
||||
flags |= GPGME_ENCRYPT_NO_ENCRYPT_TO;
|
||||
if (strstr (line, "--prepare"))
|
||||
flags |= GPGME_ENCRYPT_PREPARE;
|
||||
if (strstr (line, "--expect-sign"))
|
||||
flags |= GPGME_ENCRYPT_EXPECT_SIGN;
|
||||
|
||||
inp_fd = assuan_get_input_fd (ctx);
|
||||
if (inp_fd == ASSUAN_INVALID_FD)
|
||||
return GPG_ERR_ASS_NO_INPUT;
|
||||
out_fd = assuan_get_output_fd (ctx);
|
||||
if (out_fd == ASSUAN_INVALID_FD)
|
||||
return GPG_ERR_ASS_NO_OUTPUT;
|
||||
|
||||
if (inp_fd != ASSUAN_INVALID_FD)
|
||||
{
|
||||
err = server_data_obj (inp_fd, server->input_enc, &inp_data);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (out_fd != ASSUAN_INVALID_FD)
|
||||
{
|
||||
err = server_data_obj (out_fd, server->output_enc, &out_data);
|
||||
if (err)
|
||||
{
|
||||
gpgme_data_release (inp_data);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = gt_sign_encrypt (server->gt, flags, inp_data, out_data, sign);
|
||||
|
||||
@ -1957,6 +1987,7 @@ register_commands (assuan_context_t ctx)
|
||||
// TODO: Set engine info.
|
||||
{ "ENGINE", cmd_engine },
|
||||
{ "PROTOCOL", cmd_protocol, hlp_protocol },
|
||||
{ "SUB_PROTOCOL", cmd_sub_protocol },
|
||||
{ "ARMOR", cmd_armor },
|
||||
{ "TEXTMODE", cmd_textmode },
|
||||
{ "INCLUDE_CERTS", cmd_include_certs },
|
||||
|
26
src/gpgme.c
26
src/gpgme.c
@ -265,13 +265,14 @@ gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
|
||||
{
|
||||
TRACE_BEG2 (DEBUG_CTX, "gpgme_set_protocol", ctx, "protocol=%i (%s)",
|
||||
protocol, gpgme_get_protocol_name (protocol)
|
||||
? gpgme_get_protocol_name (protocol) : "unknown");
|
||||
? gpgme_get_protocol_name (protocol) : "invalid");
|
||||
|
||||
if (protocol != GPGME_PROTOCOL_OpenPGP
|
||||
&& protocol != GPGME_PROTOCOL_CMS
|
||||
&& protocol != GPGME_PROTOCOL_GPGCONF
|
||||
&& protocol != GPGME_PROTOCOL_ASSUAN
|
||||
&& protocol != GPGME_PROTOCOL_G13)
|
||||
&& protocol != GPGME_PROTOCOL_G13
|
||||
&& protocol != GPGME_PROTOCOL_UISERVER)
|
||||
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
|
||||
|
||||
if (ctx->protocol != protocol)
|
||||
@ -296,11 +297,24 @@ gpgme_get_protocol (gpgme_ctx_t ctx)
|
||||
TRACE2 (DEBUG_CTX, "gpgme_get_protocol", ctx,
|
||||
"ctx->protocol=%i (%s)", ctx->protocol,
|
||||
gpgme_get_protocol_name (ctx->protocol)
|
||||
? gpgme_get_protocol_name (ctx->protocol) : "unknown");
|
||||
? gpgme_get_protocol_name (ctx->protocol) : "invalid");
|
||||
return ctx->protocol;
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
gpgme_set_sub_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
TRACE_BEG2 (DEBUG_CTX, "gpgme_set_sub_protocol", ctx, "protocol=%i (%s)",
|
||||
protocol, gpgme_get_protocol_name (protocol)
|
||||
? gpgme_get_protocol_name (protocol) : "invalid");
|
||||
|
||||
err = _gpgme_engine_set_protocol (ctx->engine, protocol);
|
||||
return TRACE_ERR (err);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
gpgme_get_protocol_name (gpgme_protocol_t protocol)
|
||||
{
|
||||
@ -321,6 +335,12 @@ gpgme_get_protocol_name (gpgme_protocol_t protocol)
|
||||
case GPGME_PROTOCOL_G13:
|
||||
return "G13";
|
||||
|
||||
case GPGME_PROTOCOL_UISERVER:
|
||||
return "UIServer";
|
||||
|
||||
case GPGME_PROTOCOL_DEFAULT:
|
||||
return "default";
|
||||
|
||||
case GPGME_PROTOCOL_UNKNOWN:
|
||||
return "unknown";
|
||||
|
||||
|
@ -192,5 +192,8 @@ EXPORTS
|
||||
gpgme_op_vfs_mount @147
|
||||
gpgme_op_vfs_create @148
|
||||
|
||||
gpgme_key_from_uid @149
|
||||
gpgme_set_sub_protocol @150
|
||||
|
||||
; END
|
||||
|
||||
|
@ -326,6 +326,7 @@ typedef enum
|
||||
GPGME_PROTOCOL_ASSUAN = 3, /* Low-level access to an Assuan server. */
|
||||
GPGME_PROTOCOL_G13 = 4,
|
||||
GPGME_PROTOCOL_UISERVER= 5,
|
||||
GPGME_PROTOCOL_DEFAULT = 254,
|
||||
GPGME_PROTOCOL_UNKNOWN = 255
|
||||
}
|
||||
gpgme_protocol_t;
|
||||
@ -803,6 +804,15 @@ gpgme_error_t gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t proto);
|
||||
/* Get the protocol used with CTX */
|
||||
gpgme_protocol_t gpgme_get_protocol (gpgme_ctx_t ctx);
|
||||
|
||||
/* Set the crypto protocol to be used by CTX to PROTO.
|
||||
gpgme_set_protocol actually sets the backend engine. This sets the
|
||||
crypto protocol used in engines that support more than one crypto
|
||||
prococol (for example, an UISERVER can support OpenPGP and CMS).
|
||||
This is reset to the default with gpgme_set_protocol. */
|
||||
gpgme_error_t gpgme_set_sub_protocol (gpgme_ctx_t ctx,
|
||||
gpgme_protocol_t proto);
|
||||
|
||||
|
||||
/* Get the string describing protocol PROTO, or NULL if invalid. */
|
||||
const char *gpgme_get_protocol_name (gpgme_protocol_t proto);
|
||||
|
||||
@ -1209,7 +1219,9 @@ gpgme_encrypt_result_t gpgme_op_encrypt_result (gpgme_ctx_t ctx);
|
||||
typedef enum
|
||||
{
|
||||
GPGME_ENCRYPT_ALWAYS_TRUST = 1,
|
||||
GPGME_ENCRYPT_NO_ENCRYPT_TO = 2
|
||||
GPGME_ENCRYPT_NO_ENCRYPT_TO = 2,
|
||||
GPGME_ENCRYPT_PREPARE = 4,
|
||||
GPGME_ENCRYPT_EXPECT_SIGN = 8
|
||||
}
|
||||
gpgme_encrypt_flags_t;
|
||||
|
||||
@ -1981,6 +1993,13 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p);
|
||||
follow chained components! */
|
||||
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
|
||||
|
||||
|
||||
/* UIServer support. */
|
||||
|
||||
/* Create a dummy key to specify an email address. */
|
||||
gpgme_error_t gpgme_key_from_uid (gpgme_key_t *key, const char *name);
|
||||
|
||||
|
||||
|
||||
/* Various functions. */
|
||||
|
||||
|
31
src/key.c
31
src/key.c
@ -202,7 +202,7 @@ parse_x509_user_id (char *src, char **name, char **email,
|
||||
/* Take a name from the --with-colon listing, remove certain escape
|
||||
sequences sequences and put it into the list of UIDs. */
|
||||
gpgme_error_t
|
||||
_gpgme_key_append_name (gpgme_key_t key, char *src)
|
||||
_gpgme_key_append_name (gpgme_key_t key, char *src, int convert)
|
||||
{
|
||||
gpgme_user_id_t uid;
|
||||
char *dst;
|
||||
@ -219,7 +219,10 @@ _gpgme_key_append_name (gpgme_key_t key, char *src)
|
||||
|
||||
uid->uid = ((char *) uid) + sizeof (*uid);
|
||||
dst = uid->uid;
|
||||
if (convert)
|
||||
_gpgme_decode_c_string (src, &dst, src_len + 1);
|
||||
else
|
||||
memcpy (dst, src, src_len + 1);
|
||||
|
||||
dst += strlen (dst) + 1;
|
||||
if (key->protocol == GPGME_PROTOCOL_CMS)
|
||||
@ -370,6 +373,32 @@ gpgme_key_unref (gpgme_key_t key)
|
||||
free (key);
|
||||
}
|
||||
|
||||
|
||||
/* Support functions. */
|
||||
|
||||
/* Create a dummy key to specify an email address. */
|
||||
gpgme_error_t
|
||||
gpgme_key_from_uid (gpgme_key_t *r_key, const char *name)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
gpgme_key_t key;
|
||||
|
||||
*r_key = NULL;
|
||||
err = _gpgme_key_new (&key);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Note: protocol doesn't matter if only email is provided. */
|
||||
err = _gpgme_key_append_name (key, name, 0);
|
||||
if (err)
|
||||
gpgme_key_unref (key);
|
||||
else
|
||||
*r_key = key;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Compatibility interfaces. */
|
||||
|
||||
|
@ -650,7 +650,7 @@ keylist_colon_handler (void *priv, char *line)
|
||||
/* Field 2 has the trust info, and field 10 has the user ID. */
|
||||
if (fields >= 10)
|
||||
{
|
||||
if (_gpgme_key_append_name (key, field[9]))
|
||||
if (_gpgme_key_append_name (key, field[9], 1))
|
||||
return gpg_error_from_errno (GPG_ERR_ENOMEM); /* FIXME */
|
||||
else
|
||||
{
|
||||
|
@ -73,6 +73,8 @@ GPGME_1.1 {
|
||||
gpgme_op_vfs_mount;
|
||||
gpgme_op_vfs_create;
|
||||
|
||||
gpgme_key_from_uid;
|
||||
gpgme_set_sub_protocol;
|
||||
};
|
||||
|
||||
|
||||
|
@ -128,7 +128,7 @@ gpgme_error_t _gpgme_progress_status_handler (void *priv,
|
||||
gpgme_error_t _gpgme_key_new (gpgme_key_t *r_key);
|
||||
gpgme_error_t _gpgme_key_add_subkey (gpgme_key_t key,
|
||||
gpgme_subkey_t *r_subkey);
|
||||
gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, char *src);
|
||||
gpgme_error_t _gpgme_key_append_name (gpgme_key_t key, char *src, int convert);
|
||||
gpgme_key_sig_t _gpgme_key_add_sig (gpgme_key_t key, char *src);
|
||||
|
||||
|
||||
|
@ -305,7 +305,9 @@ _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal)
|
||||
/* Returns 0 on success, -1 on error. */
|
||||
int
|
||||
_gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
|
||||
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
|
||||
struct spawn_fd_item_s *fd_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue, pid_t *r_pid)
|
||||
{
|
||||
pid_t pid;
|
||||
int i;
|
||||
@ -344,6 +346,9 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
|
||||
int seen_stdin = 0;
|
||||
int seen_stderr = 0;
|
||||
|
||||
if (atfork)
|
||||
atfork (atforkvalue, 0);
|
||||
|
||||
/* First close all fds which will not be inherited. */
|
||||
for (fd = 0; fd < max_fds; fd++)
|
||||
{
|
||||
|
@ -69,6 +69,30 @@ _gpgme_get_g13_path (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
_gpgme_get_uiserver_socket_path (void)
|
||||
{
|
||||
static char *socket_path;
|
||||
char *homedir;
|
||||
const char name[] = "S.uiserver";
|
||||
|
||||
if (socket_path)
|
||||
return socket_path;
|
||||
|
||||
homedir = _gpgme_get_default_homedir ();
|
||||
if (! homedir)
|
||||
return NULL;
|
||||
|
||||
socket_path = malloc (strlen (homedir) + 1 + strlen (name) + 1);
|
||||
if (! socket_path)
|
||||
return NULL;
|
||||
|
||||
strcpy (stpcpy (stpcpy (socket_path, homedir), "/"), name);
|
||||
return socket_path;
|
||||
}
|
||||
|
||||
|
||||
/* See w32-util.c */
|
||||
int
|
||||
_gpgme_get_conf_int (const char *key, int *value)
|
||||
|
@ -76,7 +76,9 @@ int _gpgme_io_set_nonblocking (int fd);
|
||||
optionally dup() the child fds. Finally, all fds in the list are
|
||||
closed in the parent. */
|
||||
int _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
|
||||
struct spawn_fd_item_s *fd_list, pid_t *r_pid);
|
||||
struct spawn_fd_item_s *fd_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue, pid_t *r_pid);
|
||||
|
||||
int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);
|
||||
|
||||
|
@ -33,6 +33,8 @@ const char *_gpgme_get_gpg_path (void);
|
||||
const char *_gpgme_get_gpgsm_path (void);
|
||||
const char *_gpgme_get_gpgconf_path (void);
|
||||
const char *_gpgme_get_g13_path (void);
|
||||
const char *_gpgme_get_uiserver_socket_path (void);
|
||||
|
||||
int _gpgme_get_conf_int (const char *key, int *value);
|
||||
void _gpgme_allow_set_foreground_window (pid_t pid);
|
||||
|
||||
|
@ -309,7 +309,7 @@ _gpgme_get_program_version (const char *const file_name)
|
||||
|
||||
cfd[0].fd = rp[1];
|
||||
|
||||
status = _gpgme_io_spawn (file_name, argv, 0, cfd, NULL);
|
||||
status = _gpgme_io_spawn (file_name, argv, 0, cfd, NULL, NULL, NULL);
|
||||
if (status < 0)
|
||||
{
|
||||
_gpgme_io_close (rp[0]);
|
||||
|
@ -585,7 +585,9 @@ build_commandline (char **argv)
|
||||
|
||||
int
|
||||
_gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
|
||||
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
|
||||
struct spawn_fd_item_s *fd_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue, pid_t *r_pid)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
PROCESS_INFORMATION pi =
|
||||
|
@ -1042,7 +1042,9 @@ build_commandline (char **argv)
|
||||
|
||||
int
|
||||
_gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
|
||||
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
|
||||
struct spawn_fd_item_s *fd_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue, pid_t *r_pid)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
PROCESS_INFORMATION pi =
|
||||
|
@ -398,7 +398,9 @@ build_commandline (char **argv)
|
||||
|
||||
int
|
||||
_gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
|
||||
struct spawn_fd_item_s *fd_list, pid_t *r_pid)
|
||||
struct spawn_fd_item_s *fd_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue, pid_t *r_pid)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
PROCESS_INFORMATION pi =
|
||||
|
@ -380,6 +380,29 @@ _gpgme_get_g13_path (void)
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
_gpgme_get_uiserver_socket_path (void)
|
||||
{
|
||||
static char *socket_path;
|
||||
char *homedir;
|
||||
const char name[] = "S.uiserver";
|
||||
|
||||
if (socket_path)
|
||||
return socket_path;
|
||||
|
||||
homedir = _gpgme_get_default_homedir ();
|
||||
if (! homedir)
|
||||
return NULL;
|
||||
|
||||
socket_path = malloc (strlen (homedir) + 1 + strlen (name) + 1);
|
||||
if (! socket_path)
|
||||
return NULL;
|
||||
|
||||
strcpy (stpcpy (stpcpy (socket_path, homedir), "\\"), name);
|
||||
return socket_path;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
_gpgme_get_w32spawn_path (void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user