2006-12-17 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Fix two typos in last change. gpgme/ 2006-12-17 Marcus Brinkmann <marcus@g10code.de> * gpgme.c (gpgme_set_protocol): Shut down the engine when switching protocols. (gpgme_ctx_set_engine_info): Likewise for engine info. * engine.h (_gpgme_engine_reset): New function prototype. * engine.c (_gpgme_engine_reset): New function. * engine-backend.h (struct engine_ops): New member RESET. * rungpg.c (_gpgme_engine_ops_gpg): Add NULL for reset function. * engine-gpgsm.c (_gpgme_engine_ops_gpgsm) [USE_DESCRIPTOR_PASSING]: Add gpgsm_reset for reset. (_gpgme_engine_ops_gpgsm) [!USE_DESCRIPTOR_PASSING]: Add NULL for reset function. (gpgsm_reset) [USE_DESCRIPTOR_PASSING]: New function. * op-support.c (_gpgme_op_reset): Try to use the engine's reset function if available. * engine-gpgsm.c (gpgsm_new): Move code to dup status_fd to ... (start): ... here. * posix-io.c (_gpgme_io_recvmsg, _gpgme_io_sendmsg): New functions.
This commit is contained in:
parent
f9bf0d5b79
commit
13d2e5d1c7
@ -1,3 +1,7 @@
|
|||||||
|
2006-12-17 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* configure.ac: Fix two typos in last change.
|
||||||
|
|
||||||
2006-12-03 Marcus Brinkmann <marcus@g10code.de>
|
2006-12-03 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* configure.ac: Use descriptor passing only if --enable-fd-passing
|
* configure.ac: Use descriptor passing only if --enable-fd-passing
|
||||||
|
2
TODO
2
TODO
@ -78,6 +78,8 @@ Hey Emacs, this is -*- outline -*- mode!
|
|||||||
release everything properly at a reset and at an error. Think hard
|
release everything properly at a reset and at an error. Think hard
|
||||||
about where to guarantee what (ie, what happens if start fails, are
|
about where to guarantee what (ie, what happens if start fails, are
|
||||||
the fds unregistered immediately - i think so?)
|
the fds unregistered immediately - i think so?)
|
||||||
|
Note that we need support in gpgsm to set include-certs to default
|
||||||
|
as RESET does not reset it.
|
||||||
** Optimize the case where a data object has 0an underlying fd we can pass
|
** Optimize the case where a data object has 0an underlying fd we can pass
|
||||||
directly to the engine. This will be automatic with socket I/O and
|
directly to the engine. This will be automatic with socket I/O and
|
||||||
descriptor passing.
|
descriptor passing.
|
||||||
|
@ -75,6 +75,8 @@ int _gpgme_ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
|
|||||||
int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length);
|
int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length);
|
||||||
int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags);
|
int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags);
|
||||||
int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
|
int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
|
||||||
|
int _gpgme_io_sendmsg (int sock, const struct msghdr *msg, int flags);
|
||||||
|
int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||||
#endif /*!HAVE_W32_SYSTEM*/
|
#endif /*!HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
#define read _gpgme_io_read
|
#define read _gpgme_io_read
|
||||||
@ -83,8 +85,8 @@ int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
|
|||||||
#define select _gpgme_ath_select
|
#define select _gpgme_ath_select
|
||||||
#define accept _gpgme_ath_accept
|
#define accept _gpgme_ath_accept
|
||||||
#define connect _gpgme_ath_connect
|
#define connect _gpgme_ath_connect
|
||||||
#define sendmsg _gpgme_ath_sendmsg
|
#define sendmsg _gpgme_io_sendmsg
|
||||||
#define recvmsg _gpgme_ath_recvmsg
|
#define recvmsg _gpgme_io_recvmsg
|
||||||
#endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/
|
#endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/
|
||||||
/**** End GPGME specific modifications. ******/
|
/**** End GPGME specific modifications. ******/
|
||||||
|
|
||||||
|
@ -491,7 +491,7 @@ AC_CHECK_MEMBER(struct cmsghdr.cmsg_len,
|
|||||||
|
|
||||||
AC_ARG_ENABLE(fd-passing,
|
AC_ARG_ENABLE(fd-passing,
|
||||||
AC_HELP_STRING([--enable-fd-passing], [use FD passing if supported]),
|
AC_HELP_STRING([--enable-fd-passing], [use FD passing if supported]),
|
||||||
use_desciptor_passing=$withval)
|
use_descriptor_passing=$enableval)
|
||||||
|
|
||||||
if test "$supports_descriptor_passing" != "yes"; then
|
if test "$supports_descriptor_passing" != "yes"; then
|
||||||
use_descriptor_passing=no
|
use_descriptor_passing=no
|
||||||
|
@ -1,5 +1,23 @@
|
|||||||
2006-12-17 Marcus Brinkmann <marcus@g10code.de>
|
2006-12-17 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpgme.c (gpgme_set_protocol): Shut down the engine when
|
||||||
|
switching protocols.
|
||||||
|
(gpgme_ctx_set_engine_info): Likewise for engine info.
|
||||||
|
* engine.h (_gpgme_engine_reset): New function prototype.
|
||||||
|
* engine.c (_gpgme_engine_reset): New function.
|
||||||
|
* engine-backend.h (struct engine_ops): New member RESET.
|
||||||
|
* rungpg.c (_gpgme_engine_ops_gpg): Add NULL for reset function.
|
||||||
|
* engine-gpgsm.c (_gpgme_engine_ops_gpgsm)
|
||||||
|
[USE_DESCRIPTOR_PASSING]: Add gpgsm_reset for reset.
|
||||||
|
(_gpgme_engine_ops_gpgsm) [!USE_DESCRIPTOR_PASSING]: Add NULL for
|
||||||
|
reset function.
|
||||||
|
(gpgsm_reset) [USE_DESCRIPTOR_PASSING]: New function.
|
||||||
|
* op-support.c (_gpgme_op_reset): Try to use the engine's reset
|
||||||
|
function if available.
|
||||||
|
* engine-gpgsm.c (gpgsm_new): Move code to dup status_fd to ...
|
||||||
|
(start): ... here.
|
||||||
|
* posix-io.c (_gpgme_io_recvmsg, _gpgme_io_sendmsg): New functions.
|
||||||
|
|
||||||
* engine.h (_gpgme_engine_new): Remove arguments lc_ctype and
|
* engine.h (_gpgme_engine_new): Remove arguments lc_ctype and
|
||||||
lc_messages from prototype.
|
lc_messages from prototype.
|
||||||
(_gpgme_engine_set_locale): New prototype.
|
(_gpgme_engine_set_locale): New prototype.
|
||||||
|
@ -49,6 +49,7 @@ struct engine_ops
|
|||||||
|
|
||||||
/* Member functions. */
|
/* Member functions. */
|
||||||
void (*release) (void *engine);
|
void (*release) (void *engine);
|
||||||
|
gpgme_error_t (*reset) (void *engine);
|
||||||
void (*set_status_handler) (void *engine, engine_status_handler_t fnc,
|
void (*set_status_handler) (void *engine, engine_status_handler_t fnc,
|
||||||
void *fnc_value);
|
void *fnc_value);
|
||||||
gpgme_error_t (*set_command_handler) (void *engine,
|
gpgme_error_t (*set_command_handler) (void *engine,
|
||||||
|
@ -334,15 +334,15 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
|
|||||||
char dft_ttyname[64];
|
char dft_ttyname[64];
|
||||||
char *dft_ttytype = NULL;
|
char *dft_ttytype = NULL;
|
||||||
char *optstr;
|
char *optstr;
|
||||||
int fdlist[5];
|
|
||||||
int nfds;
|
|
||||||
|
|
||||||
gpgsm = calloc (1, sizeof *gpgsm);
|
gpgsm = calloc (1, sizeof *gpgsm);
|
||||||
if (!gpgsm)
|
if (!gpgsm)
|
||||||
return gpg_error_from_errno (errno);
|
return gpg_error_from_errno (errno);
|
||||||
|
|
||||||
gpgsm->status_cb.fd = -1;
|
gpgsm->status_cb.fd = -1;
|
||||||
|
gpgsm->status_cb.dir = 1;
|
||||||
gpgsm->status_cb.tag = 0;
|
gpgsm->status_cb.tag = 0;
|
||||||
|
gpgsm->status_cb.data = gpgsm;
|
||||||
|
|
||||||
gpgsm->input_cb.fd = -1;
|
gpgsm->input_cb.fd = -1;
|
||||||
gpgsm->input_cb.dir = 0;
|
gpgsm->input_cb.dir = 0;
|
||||||
@ -423,30 +423,6 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
|
|||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
/* We need to know the fd used by assuan for reads. We do this by
|
|
||||||
using the assumption that the first returned fd from
|
|
||||||
assuan_get_active_fds() is always this one. */
|
|
||||||
nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
|
|
||||||
fdlist, DIM (fdlist));
|
|
||||||
if (nfds < 1)
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_GENERAL); /* FIXME */
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
/* We duplicate the file descriptor, so we can close it without
|
|
||||||
disturbing assuan. Alternatively, we could special case
|
|
||||||
status_fd and register/unregister it manually as needed, but this
|
|
||||||
increases code duplication and is more complicated as we can not
|
|
||||||
use the close notifications etc. */
|
|
||||||
gpgsm->status_cb.fd = dup (fdlist[0]);
|
|
||||||
if (gpgsm->status_cb.fd < 0)
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_GENERAL); /* FIXME */
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
gpgsm->status_cb.dir = 1;
|
|
||||||
gpgsm->status_cb.data = gpgsm;
|
|
||||||
|
|
||||||
err = _gpgme_getenv ("DISPLAY", &dft_display);
|
err = _gpgme_getenv ("DISPLAY", &dft_display);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -518,14 +494,6 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err
|
|
||||||
&& (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
|
|
||||||
close_notify_handler, gpgsm)))
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_GENERAL);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !USE_DESCRIPTOR_PASSING
|
#if !USE_DESCRIPTOR_PASSING
|
||||||
if (!err
|
if (!err
|
||||||
&& (_gpgme_io_set_close_notify (gpgsm->input_cb.fd,
|
&& (_gpgme_io_set_close_notify (gpgsm->input_cb.fd,
|
||||||
@ -997,6 +965,33 @@ static gpgme_error_t
|
|||||||
start (engine_gpgsm_t gpgsm, const char *command)
|
start (engine_gpgsm_t gpgsm, const char *command)
|
||||||
{
|
{
|
||||||
gpgme_error_t err;
|
gpgme_error_t err;
|
||||||
|
int fdlist[5];
|
||||||
|
int nfds;
|
||||||
|
|
||||||
|
/* We need to know the fd used by assuan for reads. We do this by
|
||||||
|
using the assumption that the first returned fd from
|
||||||
|
assuan_get_active_fds() is always this one. */
|
||||||
|
nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
|
||||||
|
fdlist, DIM (fdlist));
|
||||||
|
if (nfds < 1)
|
||||||
|
return gpg_error (GPG_ERR_GENERAL); /* FIXME */
|
||||||
|
|
||||||
|
/* We duplicate the file descriptor, so we can close it without
|
||||||
|
disturbing assuan. Alternatively, we could special case
|
||||||
|
status_fd and register/unregister it manually as needed, but this
|
||||||
|
increases code duplication and is more complicated as we can not
|
||||||
|
use the close notifications etc. */
|
||||||
|
gpgsm->status_cb.fd = dup (fdlist[0]);
|
||||||
|
if (gpgsm->status_cb.fd < 0)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
|
if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
|
||||||
|
close_notify_handler, gpgsm))
|
||||||
|
{
|
||||||
|
close (gpgsm->status_cb.fd);
|
||||||
|
gpgsm->status_cb.fd = -1;
|
||||||
|
return gpg_error (GPG_ERR_GENERAL);
|
||||||
|
}
|
||||||
|
|
||||||
err = add_io_cb (gpgsm, &gpgsm->status_cb, status_handler);
|
err = add_io_cb (gpgsm, &gpgsm->status_cb, status_handler);
|
||||||
if (!err && gpgsm->input_cb.fd != -1)
|
if (!err && gpgsm->input_cb.fd != -1)
|
||||||
@ -1016,6 +1011,19 @@ start (engine_gpgsm_t gpgsm, const char *command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if USE_DESCRIPTOR_PASSING
|
||||||
|
static gpgme_error_t
|
||||||
|
gpgsm_reset (void *engine)
|
||||||
|
{
|
||||||
|
engine_gpgsm_t gpgsm = engine;
|
||||||
|
|
||||||
|
/* We must send a reset because we need to reset the list of
|
||||||
|
signers. Note that RESET does not reset OPTION commands. */
|
||||||
|
return gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET", NULL, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
|
gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
|
||||||
{
|
{
|
||||||
@ -1385,6 +1393,7 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
|
|||||||
if (!pattern)
|
if (!pattern)
|
||||||
pattern = "";
|
pattern = "";
|
||||||
|
|
||||||
|
/* Always send list-mode option because RESET does not reset it. */
|
||||||
if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
|
if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
|
||||||
return gpg_error_from_errno (errno);
|
return gpg_error_from_errno (errno);
|
||||||
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
|
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
|
||||||
@ -1393,6 +1402,8 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
||||||
|
/* Always send key validation because RESET does not reset it. */
|
||||||
|
|
||||||
/* Use the validation mode if required. We don't check for an error
|
/* Use the validation mode if required. We don't check for an error
|
||||||
yet because this is a pretty fresh gpgsm features. */
|
yet because this is a pretty fresh gpgsm features. */
|
||||||
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
|
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
|
||||||
@ -1448,6 +1459,7 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
|
|||||||
if (mode & GPGME_KEYLIST_MODE_EXTERN)
|
if (mode & GPGME_KEYLIST_MODE_EXTERN)
|
||||||
list_mode |= 2;
|
list_mode |= 2;
|
||||||
|
|
||||||
|
/* Always send list-mode option because RESET does not reset it. */
|
||||||
if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
|
if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
|
||||||
return gpg_error_from_errno (errno);
|
return gpg_error_from_errno (errno);
|
||||||
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
|
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
|
||||||
@ -1455,6 +1467,7 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
/* Always send key validation because RESET does not reset it. */
|
||||||
/* Use the validation mode if required. We don't check for an error
|
/* Use the validation mode if required. We don't check for an error
|
||||||
yet because this is a pretty fresh gpgsm features. */
|
yet because this is a pretty fresh gpgsm features. */
|
||||||
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
|
gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
|
||||||
@ -1561,12 +1574,8 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
|
|||||||
if (!gpgsm)
|
if (!gpgsm)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
/* We must send a reset because we need to reset the list of
|
/* FIXME: This does not work as RESET does not reset it so we can't
|
||||||
signers. Note that RESET does not reset OPTION commands. */
|
revert back to default. */
|
||||||
err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET", NULL, NULL);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT)
|
if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT)
|
||||||
{
|
{
|
||||||
/* FIXME: Make sure that if we run multiple operations, that we
|
/* FIXME: Make sure that if we run multiple operations, that we
|
||||||
@ -1704,6 +1713,11 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
|
|||||||
|
|
||||||
/* Member functions. */
|
/* Member functions. */
|
||||||
gpgsm_release,
|
gpgsm_release,
|
||||||
|
#if USE_DESCRIPTOR_PASSING
|
||||||
|
gpgsm_reset,
|
||||||
|
#else
|
||||||
|
NULL, /* reset */
|
||||||
|
#endif
|
||||||
gpgsm_set_status_handler,
|
gpgsm_set_status_handler,
|
||||||
NULL, /* set_command_handler */
|
NULL, /* set_command_handler */
|
||||||
gpgsm_set_colon_line_handler,
|
gpgsm_set_colon_line_handler,
|
||||||
|
@ -420,6 +420,19 @@ _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gpgme_error_t
|
||||||
|
_gpgme_engine_reset (engine_t engine)
|
||||||
|
{
|
||||||
|
if (!engine)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
if (!engine->ops->reset)
|
||||||
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
|
return (*engine->ops->reset) (engine->engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_gpgme_engine_release (engine_t engine)
|
_gpgme_engine_release (engine_t engine)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,7 @@ gpgme_error_t _gpgme_set_engine_info (gpgme_engine_info_t info,
|
|||||||
|
|
||||||
gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info,
|
gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info,
|
||||||
engine_t *r_engine);
|
engine_t *r_engine);
|
||||||
|
gpgme_error_t _gpgme_engine_reset (engine_t engine);
|
||||||
|
|
||||||
gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
|
gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
|
||||||
const char *value);
|
const char *value);
|
||||||
|
@ -159,7 +159,17 @@ gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
|
|||||||
if (protocol != GPGME_PROTOCOL_OpenPGP && protocol != GPGME_PROTOCOL_CMS)
|
if (protocol != GPGME_PROTOCOL_OpenPGP && protocol != GPGME_PROTOCOL_CMS)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
ctx->protocol = protocol;
|
if (ctx->protocol != protocol)
|
||||||
|
{
|
||||||
|
/* Shut down the engine when switching protocols. */
|
||||||
|
if (ctx->engine)
|
||||||
|
{
|
||||||
|
_gpgme_engine_release (ctx->engine);
|
||||||
|
ctx->engine = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->protocol = protocol;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,8 +427,12 @@ gpgme_error_t
|
|||||||
gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
|
gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
|
||||||
const char *file_name, const char *home_dir)
|
const char *file_name, const char *home_dir)
|
||||||
{
|
{
|
||||||
/* FIXME: Make sure to reset the context if we are running in daemon
|
/* Shut down the engine when changing engine info. */
|
||||||
mode. */
|
if (ctx->engine)
|
||||||
|
{
|
||||||
|
_gpgme_engine_release (ctx->engine);
|
||||||
|
ctx->engine = NULL;
|
||||||
|
}
|
||||||
return _gpgme_set_engine_info (ctx->engine_info, proto,
|
return _gpgme_set_engine_info (ctx->engine_info, proto,
|
||||||
file_name, home_dir);
|
file_name, home_dir);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ extern "C" {
|
|||||||
AM_PATH_GPGME macro) check that this header matches the installed
|
AM_PATH_GPGME macro) check that this header matches the installed
|
||||||
library. Warning: Do not edit the next line. configure will do
|
library. Warning: Do not edit the next line. configure will do
|
||||||
that for you! */
|
that for you! */
|
||||||
#define GPGME_VERSION "1.1.3-cvs1188"
|
#define GPGME_VERSION "1.1.3-cvs1196"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,28 +68,37 @@ gpgme_error_t
|
|||||||
_gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
_gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
||||||
{
|
{
|
||||||
gpgme_error_t err = 0;
|
gpgme_error_t err = 0;
|
||||||
gpgme_engine_info_t info;
|
|
||||||
struct gpgme_io_cbs io_cbs;
|
struct gpgme_io_cbs io_cbs;
|
||||||
|
|
||||||
info = ctx->engine_info;
|
|
||||||
while (info && info->protocol != ctx->protocol)
|
|
||||||
info = info->next;
|
|
||||||
|
|
||||||
if (!info)
|
|
||||||
return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
|
|
||||||
|
|
||||||
_gpgme_release_result (ctx);
|
_gpgme_release_result (ctx);
|
||||||
|
|
||||||
if (ctx->engine)
|
if (ctx->engine)
|
||||||
{
|
{
|
||||||
_gpgme_engine_release (ctx->engine);
|
/* Attempt to reset an existing engine. */
|
||||||
ctx->engine = NULL;
|
|
||||||
|
err = _gpgme_engine_reset (ctx->engine);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
_gpgme_engine_release (ctx->engine);
|
||||||
|
ctx->engine = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an engine object. */
|
if (!ctx->engine)
|
||||||
err = _gpgme_engine_new (info, &ctx->engine);
|
{
|
||||||
if (err)
|
gpgme_engine_info_t info;
|
||||||
return err;
|
info = ctx->engine_info;
|
||||||
|
while (info && info->protocol != ctx->protocol)
|
||||||
|
info = info->next;
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
|
||||||
|
|
||||||
|
/* Create an engine object. */
|
||||||
|
err = _gpgme_engine_new (info, &ctx->engine);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
err = _gpgme_engine_set_locale (ctx->engine, LC_CTYPE, ctx->lc_ctype);
|
err = _gpgme_engine_set_locale (ctx->engine, LC_CTYPE, ctx->lc_ctype);
|
||||||
if (!err)
|
if (!err)
|
||||||
|
@ -412,3 +412,86 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
|
|||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags)
|
||||||
|
{
|
||||||
|
int nread;
|
||||||
|
int saved_errno;
|
||||||
|
struct iovec *iov;
|
||||||
|
|
||||||
|
nread = 0;
|
||||||
|
iov = msg->msg_iov;
|
||||||
|
while (iov < msg->msg_iov + msg->msg_iovlen)
|
||||||
|
{
|
||||||
|
nread += iov->iov_len;
|
||||||
|
iov++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG2 ("fd %d: about to receive %d bytes\n",
|
||||||
|
fd, (int) nread);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
nread = _gpgme_ath_recvmsg (fd, msg, flags);
|
||||||
|
}
|
||||||
|
while (nread == -1 && errno == EINTR);
|
||||||
|
saved_errno = errno;
|
||||||
|
DEBUG2 ("fd %d: got %d bytes\n", fd, nread);
|
||||||
|
if (nread > 0)
|
||||||
|
{
|
||||||
|
int nr = nread;
|
||||||
|
|
||||||
|
iov = msg->msg_iov;
|
||||||
|
while (nr > 0)
|
||||||
|
{
|
||||||
|
int len = nr > iov->iov_len ? iov->iov_len : nr;
|
||||||
|
_gpgme_debug (2, "fd %d: got `%.*s'\n", fd, len,
|
||||||
|
msg->msg_iov->iov_base);
|
||||||
|
iov++;
|
||||||
|
nr -= len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errno = saved_errno;
|
||||||
|
return nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_gpgme_io_sendmsg (int fd, const struct msghdr *msg, int flags)
|
||||||
|
{
|
||||||
|
int saved_errno;
|
||||||
|
int nwritten;
|
||||||
|
struct iovec *iov;
|
||||||
|
|
||||||
|
nwritten = 0;
|
||||||
|
iov = msg->msg_iov;
|
||||||
|
while (iov < msg->msg_iov + msg->msg_iovlen)
|
||||||
|
{
|
||||||
|
nwritten += iov->iov_len;
|
||||||
|
iov++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int) nwritten);
|
||||||
|
iov = msg->msg_iov;
|
||||||
|
while (nwritten > 0)
|
||||||
|
{
|
||||||
|
int len = nwritten > iov->iov_len ? iov->iov_len : nwritten;
|
||||||
|
_gpgme_debug (2, "fd %d: write `%.*s'\n", fd, len,
|
||||||
|
msg->msg_iov->iov_base);
|
||||||
|
iov++;
|
||||||
|
nwritten -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
nwritten = _gpgme_ath_sendmsg (fd, msg, flags);
|
||||||
|
}
|
||||||
|
while (nwritten == -1 && errno == EINTR);
|
||||||
|
saved_errno = errno;
|
||||||
|
DEBUG2 ("fd %d: wrote %d bytes\n", fd, (int) nwritten);
|
||||||
|
errno = saved_errno;
|
||||||
|
return nwritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2078,6 +2078,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
|
|||||||
|
|
||||||
/* Member functions. */
|
/* Member functions. */
|
||||||
gpg_release,
|
gpg_release,
|
||||||
|
NULL, /* reset */
|
||||||
gpg_set_status_handler,
|
gpg_set_status_handler,
|
||||||
gpg_set_command_handler,
|
gpg_set_command_handler,
|
||||||
gpg_set_colon_line_handler,
|
gpg_set_colon_line_handler,
|
||||||
|
Loading…
Reference in New Issue
Block a user