2009-10-26 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (NEED_GPG_VERSION_DEFAULT): Bump to 1.4.0 as 1.3.0 was development versions only. tests/ 2009-10-26 Marcus Brinkmann <marcus@g10code.de> * opassuan/t-command.c: Update to new interface. src/ 2009-10-26 Marcus Brinkmann <marcus@g10code.de> * gpgme.h.in (struct gpgme_io_event_done_data) (gpgme_io_event_done_data_t): New types. (struct _gpgme_op_assuan_result): Deprecate the err member. (gpgme_op_assuan_result): Deprecate (for now). (gpgme_op_assuan_transact_ext): New prototype. (gpgme_op_assuan_transact): Deprecate. (struct _gpgme_op_g13_result): Replace with ... (struct _gpgme_op_vfs_mount_result): ... this. (gpgme_op_g13_mount): Replace with ... (gpgme_op_vfs_mount): ... this. * gpgme.def (gpgme_op_assuan_transact_ext, gpgme_wait_ext) (gpgme_op_vfs_mount_result, gpgme_op_vfs_mount): New. (gpgme_op_g13_mount): Remove. * libgpgme.vers: Likewise. * engine-backend.h (struct engine_ops): Remove RESULT_CB and RESULT_CB_VALUE args in opassuan_transact member. Add CANCEL_OP member. * ops.h (_gpgme_cancel_with_err, _gpgme_wait_on_condition): Add OP_ERR argument. (_gpgme_wait_one_ext): New prototype. * context.h (ctx_op_data_id_t): Add OPDATA_VFS_MOUNT. * engine-g13.c (g13_cancel_op): New function. (parse_status): Remove declaration. (g13_assuan_simple_command): Do nothing with status lines for now. (status_handler): Update opaque value access. (_gpgme_engine_ops_g13): Add new cancel_op member. * gpgme.c (_gpgme_cancel_with_err): Add new parameter OP_ERR. Handle operational errors. (gpgme_cancel, gpgme_io_read, gpgme_io_write): Add debug output. * data.c (_gpgme_data_inbound_handler) (_gpgme_data_outbound_handler): Adjust opaque value access. * engine-gpg.c (command_handler, status_handler) (colon_line_handler): Likewise. * engine-gpgsm.c (status_handler): Likewise. * engine-gpg.c (_gpgme_engine_ops_gpg): Add cancel_op member. * engine-gpgsm.c (_gpgme_engine_ops_gpgsm): Likewise. * g13.c: Rewritten (and will be rewritten again). * engine.h (_gpgme_engine_op_assuan_transact): Remove result_cb and result_cb_value parameters from prototype. (_gpgme_engine_cancel_op): New prototype. * engine.c (engine_ops) [! ENABLE_ASSUAN]: Add missing comma. (_gpgme_engine_op_assuan_transact): Remove result_cb and result_cb_value parameter. (_gpgme_engine_cancel_op): New function. * wait.h (_gpgme_run_io_cb): Add new argument OP_ERR. (struct io_cb_data): New struct to pass opaque data and get a op_err return value. Needed because we can't modify I/O callback handler signature because it is exposed to the user. * wait.c (_gpgme_run_io_cb): Add OP_ERR parameter. Handle operational errors. * wait-user.c (_gpgme_user_io_cb_handler): Handle operational errors. * wait-private.c (_gpgme_wait_on_condition): New argument to retrieve the operational result. Handle operational errors in session based protocols. (_gpgme_wait_one_ext): New function. (_gpgme_wait_one): Pass argument in invocation of _gpgme_wait_on_condition. * wait-global.c (struct ctx_list_item): Add member OP_ERR. (ctx_done): New argument OP_ERR. (ctx_wait): New argument OP_ERR. (gpgme_wait_ext): New function based on gpgme_wait but handling operational errors. (gpgme_wait): Implement in term of gpgme_wait_ext. * keylist.c (gpgme_op_keylist_next): Pass argument in invocation of _gpgme_wait_on_condition. * trustlist.c (gpgme_op_trustlist_next): Pass argument in invocation of _gpgme_wait_on_condition. * engine-assuan.c (struct engine_llass): Replace members RESULT_CB and RESULT_CB_VALUE by LAST_OP_ERR. (_gpgme_engine_assuan_last_op_err): Add this hack function. (llass_cancel_op): New function. (_gpgme_engine_llass_ops): Add cancel_op member. (llass_status_handler): Update opaque value access. (llass_transact): Remove RESULT_CB and RESULT_CB_VALUE arguments. * opassuan.c: Move compat hacks to the end of file. (opassuan_start): Do not set OPD->result.err. Do not pass RESULT_Cb and CTX to _gpgme_engine_op_assuan_transact. (gpgme_op_assuan_transact_ext): New function.
This commit is contained in:
parent
ca67902311
commit
c8e934b276
@ -1,3 +1,8 @@
|
||||
2009-10-26 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* configure.ac (NEED_GPG_VERSION_DEFAULT): Bump to 1.4.0 as 1.3.0
|
||||
was development versions only.
|
||||
|
||||
2009-10-22 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* configure.ac: Add support for G13.
|
||||
|
@ -286,7 +286,7 @@ if test "$have_libassuan" = "yes"; then
|
||||
fi
|
||||
|
||||
# Checks for system services
|
||||
NEED_GPG_VERSION_DEFAULT=1.3.0
|
||||
NEED_GPG_VERSION_DEFAULT=1.4.0
|
||||
NEED_GPGSM_VERSION_DEFAULT=1.9.6
|
||||
NEED_GPGCONF_VERSION_DEFAULT=2.0.4
|
||||
NEED_G13_VERSION_DEFAULT=2.1.0
|
||||
|
@ -1,5 +1,85 @@
|
||||
2009-10-26 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* gpgme.h.in (struct gpgme_io_event_done_data)
|
||||
(gpgme_io_event_done_data_t): New types.
|
||||
(struct _gpgme_op_assuan_result): Deprecate the err member.
|
||||
(gpgme_op_assuan_result): Deprecate (for now).
|
||||
(gpgme_op_assuan_transact_ext): New prototype.
|
||||
(gpgme_op_assuan_transact): Deprecate.
|
||||
(struct _gpgme_op_g13_result): Replace with ...
|
||||
(struct _gpgme_op_vfs_mount_result): ... this.
|
||||
(gpgme_op_g13_mount): Replace with ...
|
||||
(gpgme_op_vfs_mount): ... this.
|
||||
* gpgme.def (gpgme_op_assuan_transact_ext, gpgme_wait_ext)
|
||||
(gpgme_op_vfs_mount_result, gpgme_op_vfs_mount): New.
|
||||
(gpgme_op_g13_mount): Remove.
|
||||
* libgpgme.vers: Likewise.
|
||||
* engine-backend.h (struct engine_ops): Remove RESULT_CB and
|
||||
RESULT_CB_VALUE args in opassuan_transact member. Add CANCEL_OP
|
||||
member.
|
||||
* ops.h (_gpgme_cancel_with_err, _gpgme_wait_on_condition): Add
|
||||
OP_ERR argument.
|
||||
(_gpgme_wait_one_ext): New prototype.
|
||||
* context.h (ctx_op_data_id_t): Add OPDATA_VFS_MOUNT.
|
||||
* engine-g13.c (g13_cancel_op): New function.
|
||||
(parse_status): Remove declaration.
|
||||
(g13_assuan_simple_command): Do nothing with status lines for now.
|
||||
(status_handler): Update opaque value access.
|
||||
(_gpgme_engine_ops_g13): Add new cancel_op member.
|
||||
* gpgme.c (_gpgme_cancel_with_err): Add new parameter OP_ERR.
|
||||
Handle operational errors.
|
||||
(gpgme_cancel, gpgme_io_read, gpgme_io_write): Add debug output.
|
||||
* data.c (_gpgme_data_inbound_handler)
|
||||
(_gpgme_data_outbound_handler): Adjust opaque value access.
|
||||
* engine-gpg.c (command_handler, status_handler)
|
||||
(colon_line_handler): Likewise.
|
||||
* engine-gpgsm.c (status_handler): Likewise.
|
||||
* engine-gpg.c (_gpgme_engine_ops_gpg): Add cancel_op member.
|
||||
* engine-gpgsm.c (_gpgme_engine_ops_gpgsm): Likewise.
|
||||
* g13.c: Rewritten (and will be rewritten again).
|
||||
* engine.h (_gpgme_engine_op_assuan_transact): Remove result_cb
|
||||
and result_cb_value parameters from prototype.
|
||||
(_gpgme_engine_cancel_op): New prototype.
|
||||
* engine.c (engine_ops) [! ENABLE_ASSUAN]: Add missing comma.
|
||||
(_gpgme_engine_op_assuan_transact): Remove result_cb and
|
||||
result_cb_value parameter.
|
||||
(_gpgme_engine_cancel_op): New function.
|
||||
* wait.h (_gpgme_run_io_cb): Add new argument OP_ERR.
|
||||
(struct io_cb_data): New struct to pass opaque data and get a
|
||||
op_err return value. Needed because we can't modify I/O callback
|
||||
handler signature because it is exposed to the user.
|
||||
* wait.c (_gpgme_run_io_cb): Add OP_ERR parameter. Handle
|
||||
operational errors.
|
||||
* wait-user.c (_gpgme_user_io_cb_handler): Handle operational
|
||||
errors.
|
||||
* wait-private.c (_gpgme_wait_on_condition): New argument to
|
||||
retrieve the operational result. Handle operational errors in
|
||||
session based protocols.
|
||||
(_gpgme_wait_one_ext): New function.
|
||||
(_gpgme_wait_one): Pass argument in invocation of
|
||||
_gpgme_wait_on_condition.
|
||||
* wait-global.c (struct ctx_list_item): Add member OP_ERR.
|
||||
(ctx_done): New argument OP_ERR.
|
||||
(ctx_wait): New argument OP_ERR.
|
||||
(gpgme_wait_ext): New function based on gpgme_wait but handling
|
||||
operational errors.
|
||||
(gpgme_wait): Implement in term of gpgme_wait_ext.
|
||||
* keylist.c (gpgme_op_keylist_next): Pass argument in invocation
|
||||
of _gpgme_wait_on_condition.
|
||||
* trustlist.c (gpgme_op_trustlist_next): Pass argument in
|
||||
invocation of _gpgme_wait_on_condition.
|
||||
* engine-assuan.c (struct engine_llass): Replace members RESULT_CB
|
||||
and RESULT_CB_VALUE by LAST_OP_ERR.
|
||||
(_gpgme_engine_assuan_last_op_err): Add this hack function.
|
||||
(llass_cancel_op): New function.
|
||||
(_gpgme_engine_llass_ops): Add cancel_op member.
|
||||
(llass_status_handler): Update opaque value access.
|
||||
(llass_transact): Remove RESULT_CB and RESULT_CB_VALUE arguments.
|
||||
* opassuan.c: Move compat hacks to the end of file.
|
||||
(opassuan_start): Do not set OPD->result.err.
|
||||
Do not pass RESULT_Cb and CTX to _gpgme_engine_op_assuan_transact.
|
||||
(gpgme_op_assuan_transact_ext): New function.
|
||||
|
||||
* debug.h (DEBUG_GLOBAL): New debug level.
|
||||
* conversion.c (gnupg_errors, _gpgme_map_gnupg_error): Removed.
|
||||
* data-user.c (gpgme_data_new_from_cbs): Add debug output.
|
||||
|
@ -38,7 +38,7 @@ typedef enum
|
||||
{
|
||||
OPDATA_DECRYPT, OPDATA_SIGN, OPDATA_ENCRYPT, OPDATA_PASSPHRASE,
|
||||
OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT,
|
||||
OPDATA_VERIFY, OPDATA_TRUSTLIST, OPDATA_ASSUAN
|
||||
OPDATA_VERIFY, OPDATA_TRUSTLIST, OPDATA_ASSUAN, OPDATA_VFS_MOUNT
|
||||
} ctx_op_data_id_t;
|
||||
|
||||
|
||||
|
@ -247,7 +247,8 @@ gpgme_data_get_file_name (gpgme_data_t dh)
|
||||
gpgme_error_t
|
||||
_gpgme_data_inbound_handler (void *opaque, int fd)
|
||||
{
|
||||
gpgme_data_t dh = (gpgme_data_t) opaque;
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
gpgme_data_t dh = (gpgme_data_t) data->handler_value;
|
||||
char buffer[BUFFER_SIZE];
|
||||
char *bufp = buffer;
|
||||
ssize_t buflen;
|
||||
@ -279,7 +280,8 @@ _gpgme_data_inbound_handler (void *opaque, int fd)
|
||||
gpgme_error_t
|
||||
_gpgme_data_outbound_handler (void *opaque, int fd)
|
||||
{
|
||||
gpgme_data_t dh = (gpgme_data_t) opaque;
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
gpgme_data_t dh = (gpgme_data_t) data->handler_value;
|
||||
ssize_t nwritten;
|
||||
TRACE_BEG1 (DEBUG_CTX, "_gpgme_data_outbound_handler", dh,
|
||||
"fd=0x%x", fd);
|
||||
|
@ -70,9 +70,8 @@ struct engine_llass
|
||||
|
||||
struct gpgme_io_cbs io_cbs;
|
||||
|
||||
/* Internal callbacks. */
|
||||
engine_assuan_result_cb_t result_cb;
|
||||
void *result_cb_value;
|
||||
/* Hack for old opassuan.c interface, see there the result struct. */
|
||||
gpg_error_t last_op_err;
|
||||
|
||||
/* User provided callbacks. */
|
||||
struct {
|
||||
@ -95,6 +94,12 @@ struct engine_llass
|
||||
typedef struct engine_llass *engine_llass_t;
|
||||
|
||||
|
||||
gpg_error_t _gpgme_engine_assuan_last_op_err (void *engine)
|
||||
{
|
||||
engine_llass_t llass = engine;
|
||||
return llass->last_op_err;
|
||||
}
|
||||
|
||||
|
||||
/* Prototypes. */
|
||||
static void llass_io_event (void *engine,
|
||||
@ -169,6 +174,21 @@ llass_cancel (void *engine)
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
llass_cancel_op (void *engine)
|
||||
{
|
||||
engine_llass_t llass = engine;
|
||||
|
||||
if (!llass)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (llass->status_cb.fd != -1)
|
||||
_gpgme_io_close (llass->status_cb.fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llass_release (void *engine)
|
||||
{
|
||||
@ -408,8 +428,9 @@ inquire_cb (engine_llass_t llass, const char *keyword, const char *args)
|
||||
static gpgme_error_t
|
||||
llass_status_handler (void *opaque, int fd)
|
||||
{
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
engine_llass_t llass = (engine_llass_t) data->handler_value;
|
||||
gpgme_error_t err = 0;
|
||||
engine_llass_t llass = opaque;
|
||||
char *line;
|
||||
size_t linelen;
|
||||
|
||||
@ -459,8 +480,6 @@ llass_status_handler (void *opaque, int fd)
|
||||
if (linelen && llass->user.data_cb)
|
||||
err = llass->user.data_cb (llass->user.data_cb_value,
|
||||
src, linelen);
|
||||
else
|
||||
err = 0;
|
||||
|
||||
TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass,
|
||||
"fd 0x%x: D inlinedata; status from cb: %s",
|
||||
@ -474,8 +493,6 @@ llass_status_handler (void *opaque, int fd)
|
||||
/* END received. Tell the data callback. */
|
||||
if (llass->user.data_cb)
|
||||
err = llass->user.data_cb (llass->user.data_cb_value, NULL, 0);
|
||||
else
|
||||
err = 0;
|
||||
|
||||
TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass,
|
||||
"fd 0x%x: END line; status from cb: %s",
|
||||
@ -502,8 +519,6 @@ llass_status_handler (void *opaque, int fd)
|
||||
if (llass->user.status_cb)
|
||||
err = llass->user.status_cb (llass->user.status_cb_value,
|
||||
src, args);
|
||||
else
|
||||
err = 0;
|
||||
|
||||
TRACE3 (DEBUG_CTX, "gpgme:llass_status_handler", llass,
|
||||
"fd 0x%x: S line (%s) - status from cb: %s",
|
||||
@ -554,17 +569,15 @@ llass_status_handler (void *opaque, int fd)
|
||||
TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass,
|
||||
"fd 0x%x: ERR line: %s",
|
||||
fd, err ? gpg_strerror (err) : "ok");
|
||||
|
||||
/* Command execution errors are not fatal, as we use
|
||||
a session based protocol. */
|
||||
if (llass->result_cb)
|
||||
err = llass->result_cb (llass->result_cb_value, err);
|
||||
else
|
||||
err = 0;
|
||||
if (!err)
|
||||
{
|
||||
_gpgme_io_close (llass->status_cb.fd);
|
||||
return 0;
|
||||
}
|
||||
data->op_err = err;
|
||||
llass->last_op_err = err;
|
||||
|
||||
/* The caller will do the rest (namely, call cancel_op,
|
||||
which closes status_fd). */
|
||||
return 0;
|
||||
}
|
||||
else if (linelen >= 2
|
||||
&& line[0] == 'O' && line[1] == 'K'
|
||||
@ -572,15 +585,11 @@ llass_status_handler (void *opaque, int fd)
|
||||
{
|
||||
TRACE1 (DEBUG_CTX, "gpgme:llass_status_handler", llass,
|
||||
"fd 0x%x: OK line", fd);
|
||||
if (llass->result_cb)
|
||||
err = llass->result_cb (llass->result_cb_value, 0);
|
||||
else
|
||||
err = 0;
|
||||
if (!err)
|
||||
{
|
||||
_gpgme_io_close (llass->status_cb.fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
llass->last_op_err = 0;
|
||||
|
||||
_gpgme_io_close (llass->status_cb.fd);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -667,8 +676,6 @@ start (engine_llass_t llass, const char *command)
|
||||
static gpgme_error_t
|
||||
llass_transact (void *engine,
|
||||
const char *command,
|
||||
engine_assuan_result_cb_t result_cb,
|
||||
void *result_cb_value,
|
||||
gpgme_assuan_data_cb_t data_cb,
|
||||
void *data_cb_value,
|
||||
gpgme_assuan_inquire_cb_t inq_cb,
|
||||
@ -682,8 +689,6 @@ llass_transact (void *engine,
|
||||
if (!llass || !command || !*command)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
llass->result_cb = result_cb;
|
||||
llass->result_cb_value = result_cb_value;
|
||||
llass->user.data_cb = data_cb;
|
||||
llass->user.data_cb_value = data_cb_value;
|
||||
llass->user.inq_cb = inq_cb;
|
||||
@ -754,5 +759,6 @@ struct engine_ops _gpgme_engine_ops_assuan =
|
||||
NULL, /* conf_save */
|
||||
llass_set_io_cbs,
|
||||
llass_io_event,
|
||||
llass_cancel
|
||||
llass_cancel,
|
||||
llass_cancel_op
|
||||
};
|
||||
|
@ -98,8 +98,6 @@ struct engine_ops
|
||||
unsigned int flags);
|
||||
gpgme_error_t (*opassuan_transact) (void *engine,
|
||||
const char *command,
|
||||
engine_assuan_result_cb_t result_cb,
|
||||
void *result_cb_value,
|
||||
gpgme_assuan_data_cb_t data_cb,
|
||||
void *data_cb_value,
|
||||
gpgme_assuan_inquire_cb_t inq_cb,
|
||||
@ -113,7 +111,11 @@ struct engine_ops
|
||||
void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs);
|
||||
void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data);
|
||||
|
||||
/* Cancel the whole engine session. */
|
||||
gpgme_error_t (*cancel) (void *engine);
|
||||
|
||||
/* Cancel only the current operation, not the whole session. */
|
||||
gpgme_error_t (*cancel_op) (void *engine);
|
||||
};
|
||||
|
||||
|
||||
|
@ -180,6 +180,21 @@ g13_cancel (void *engine)
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
g13_cancel_op (void *engine)
|
||||
{
|
||||
engine_g13_t g13 = engine;
|
||||
|
||||
if (!g13)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (g13->status_cb.fd != -1)
|
||||
_gpgme_io_close (g13->status_cb.fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
g13_release (void *engine)
|
||||
{
|
||||
@ -385,9 +400,6 @@ g13_set_locale (void *engine, int category, const char *value)
|
||||
}
|
||||
|
||||
|
||||
/* Forward declaration. */
|
||||
static gpgme_status_code_t parse_status (const char *name);
|
||||
|
||||
static gpgme_error_t
|
||||
g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
||||
engine_status_handler_t status_fnc,
|
||||
@ -422,7 +434,6 @@ g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
||||
&& line[0] == 'S' && line[1] == ' ')
|
||||
{
|
||||
char *rest;
|
||||
gpgme_status_code_t r;
|
||||
|
||||
rest = strchr (line + 2, ' ');
|
||||
if (!rest)
|
||||
@ -430,12 +441,7 @@ g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
||||
else
|
||||
*(rest++) = 0;
|
||||
|
||||
r = parse_status (line + 2);
|
||||
|
||||
if (r >= 0 && status_fnc)
|
||||
err = status_fnc (status_fnc_value, r, rest);
|
||||
else
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
/* Nothing to do with status lines. */
|
||||
}
|
||||
else
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
@ -449,8 +455,9 @@ g13_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
||||
static gpgme_error_t
|
||||
status_handler (void *opaque, int fd)
|
||||
{
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
engine_g13_t g13 = (engine_g13_t) data->handler_value;
|
||||
gpgme_error_t err = 0;
|
||||
engine_g13_t g13 = opaque;
|
||||
char *line;
|
||||
size_t linelen;
|
||||
|
||||
@ -792,5 +799,6 @@ struct engine_ops _gpgme_engine_ops_g13 =
|
||||
NULL, /* conf_save */
|
||||
g13_set_io_cbs,
|
||||
g13_io_event,
|
||||
g13_cancel
|
||||
g13_cancel,
|
||||
g13_cancel_op,
|
||||
};
|
||||
|
@ -646,10 +646,10 @@ gpg_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc,
|
||||
static gpgme_error_t
|
||||
command_handler (void *opaque, int fd)
|
||||
{
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
|
||||
gpgme_error_t err;
|
||||
engine_gpg_t gpg = (engine_gpg_t) opaque;
|
||||
int processed = 0;
|
||||
|
||||
assert (gpg->cmd.used);
|
||||
assert (gpg->cmd.code);
|
||||
assert (gpg->cmd.fnc);
|
||||
@ -1139,7 +1139,8 @@ read_status (engine_gpg_t gpg)
|
||||
static gpgme_error_t
|
||||
status_handler (void *opaque, int fd)
|
||||
{
|
||||
engine_gpg_t gpg = opaque;
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
|
||||
int err;
|
||||
|
||||
assert (fd == gpg->status.fd[0]);
|
||||
@ -1246,7 +1247,8 @@ read_colon_line (engine_gpg_t gpg)
|
||||
static gpgme_error_t
|
||||
colon_line_handler (void *opaque, int fd)
|
||||
{
|
||||
engine_gpg_t gpg = opaque;
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
|
||||
gpgme_error_t rc = 0;
|
||||
|
||||
assert (fd == gpg->colon.fd[0]);
|
||||
@ -2365,5 +2367,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
|
||||
NULL, /* conf_save */
|
||||
gpg_set_io_cbs,
|
||||
gpg_io_event,
|
||||
gpg_cancel
|
||||
gpg_cancel,
|
||||
NULL /* cancel_op */
|
||||
};
|
||||
|
@ -761,8 +761,9 @@ parse_status (const char *name)
|
||||
static gpgme_error_t
|
||||
status_handler (void *opaque, int fd)
|
||||
{
|
||||
struct io_cb_data *data = (struct io_cb_data *) opaque;
|
||||
engine_gpgsm_t gpgsm = (engine_gpgsm_t) data->handler_value;
|
||||
gpgme_error_t err = 0;
|
||||
engine_gpgsm_t gpgsm = opaque;
|
||||
char *line;
|
||||
size_t linelen;
|
||||
|
||||
@ -799,7 +800,7 @@ status_handler (void *opaque, int fd)
|
||||
err = gpgsm->status.fnc (gpgsm->status.fnc_value,
|
||||
GPGME_STATUS_EOF, "");
|
||||
|
||||
if (!err && gpgsm->colon.fnc && gpgsm->colon.any )
|
||||
if (!err && gpgsm->colon.fnc && gpgsm->colon.any)
|
||||
{
|
||||
/* We must tell a colon function about the EOF. We do
|
||||
this only when we have seen any data lines. Note
|
||||
@ -1939,5 +1940,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
|
||||
NULL, /* conf_save */
|
||||
gpgsm_set_io_cbs,
|
||||
gpgsm_io_event,
|
||||
gpgsm_cancel
|
||||
gpgsm_cancel,
|
||||
NULL /* cancel_op */
|
||||
};
|
||||
|
20
src/engine.c
20
src/engine.c
@ -58,7 +58,7 @@ static struct engine_ops *engine_ops[] =
|
||||
#ifdef ENABLE_ASSUAN
|
||||
&_gpgme_engine_ops_assuan, /* Low-Level Assuan. */
|
||||
#else
|
||||
NULL
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef ENABLE_G13
|
||||
&_gpgme_engine_ops_g13 /* Crypto VFS. */
|
||||
@ -777,8 +777,6 @@ _gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output,
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_assuan_transact (engine_t engine,
|
||||
const char *command,
|
||||
engine_assuan_result_cb_t result_cb,
|
||||
void *result_cb_value,
|
||||
gpgme_assuan_data_cb_t data_cb,
|
||||
void *data_cb_value,
|
||||
gpgme_assuan_inquire_cb_t inq_cb,
|
||||
@ -794,7 +792,6 @@ _gpgme_engine_op_assuan_transact (engine_t engine,
|
||||
|
||||
return (*engine->ops->opassuan_transact) (engine->engine,
|
||||
command,
|
||||
result_cb, result_cb_value,
|
||||
data_cb, data_cb_value,
|
||||
inq_cb, inq_cb_value,
|
||||
status_cb, status_cb_value);
|
||||
@ -848,6 +845,7 @@ _gpgme_engine_io_event (engine_t engine,
|
||||
}
|
||||
|
||||
|
||||
/* Cancel the session and the pending operation if any. */
|
||||
gpgme_error_t
|
||||
_gpgme_engine_cancel (engine_t engine)
|
||||
{
|
||||
@ -859,3 +857,17 @@ _gpgme_engine_cancel (engine_t engine)
|
||||
|
||||
return (*engine->ops->cancel) (engine->engine);
|
||||
}
|
||||
|
||||
|
||||
/* Cancel the pending operation, but not the complete session. */
|
||||
gpgme_error_t
|
||||
_gpgme_engine_cancel_op (engine_t engine)
|
||||
{
|
||||
if (!engine)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (!engine->ops->cancel_op)
|
||||
return 0;
|
||||
|
||||
return (*engine->ops->cancel_op) (engine->engine);
|
||||
}
|
||||
|
@ -133,8 +133,6 @@ gpgme_error_t _gpgme_engine_op_getauditlog (engine_t engine,
|
||||
gpgme_error_t _gpgme_engine_op_assuan_transact
|
||||
(engine_t engine,
|
||||
const char *command,
|
||||
engine_assuan_result_cb_t result_cb,
|
||||
void *result_cb_value,
|
||||
gpgme_assuan_data_cb_t data_cb,
|
||||
void *data_cb_value,
|
||||
gpgme_assuan_inquire_cb_t inq_cb,
|
||||
@ -154,4 +152,6 @@ void _gpgme_engine_io_event (engine_t engine,
|
||||
|
||||
gpgme_error_t _gpgme_engine_cancel (engine_t engine);
|
||||
|
||||
gpgme_error_t _gpgme_engine_cancel_op (engine_t engine);
|
||||
|
||||
#endif /* ENGINE_H */
|
||||
|
105
src/g13.c
105
src/g13.c
@ -31,41 +31,19 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct _gpgme_op_g13_result result;
|
||||
struct _gpgme_op_vfs_mount_result result;
|
||||
} *op_data_t;
|
||||
|
||||
|
||||
|
||||
/* This callback is used to return the status of the assuan command
|
||||
back rather than transmission errors. */
|
||||
static gpgme_error_t
|
||||
result_cb (void *priv, gpgme_error_t result)
|
||||
{
|
||||
gpgme_ctx_t ctx = (gpgme_ctx_t)priv;
|
||||
gpgme_error_t err;
|
||||
void *hook;
|
||||
op_data_t opd;
|
||||
|
||||
err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL);
|
||||
opd = hook;
|
||||
if (err)
|
||||
return err;
|
||||
if (!opd)
|
||||
return gpg_error (GPG_ERR_INTERNAL);
|
||||
|
||||
opd->result.err = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gpgme_g13_result_t
|
||||
gpgme_op_g13_result (gpgme_ctx_t ctx)
|
||||
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_ASSUAN, &hook, -1, NULL);
|
||||
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. */
|
||||
@ -77,14 +55,14 @@ gpgme_op_g13_result (gpgme_ctx_t ctx)
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
opg13_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)
|
||||
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;
|
||||
@ -99,14 +77,13 @@ opg13_start (gpgme_ctx_t ctx, int synchronous,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, sizeof (*opd), NULL);
|
||||
err = _gpgme_op_data_lookup (ctx, OPDATA_VFS_MOUNT, &hook, sizeof (*opd),
|
||||
NULL);
|
||||
opd = hook;
|
||||
if (err)
|
||||
return err;
|
||||
opd->result.err = gpg_error (GPG_ERR_UNFINISHED);
|
||||
|
||||
return _gpgme_engine_op_assuan_transact (ctx->engine, command,
|
||||
result_cb, ctx,
|
||||
data_cb, data_cb_value,
|
||||
inq_cb, inq_cb_value,
|
||||
status_cb, status_cb_value);
|
||||
@ -116,7 +93,7 @@ opg13_start (gpgme_ctx_t ctx, int synchronous,
|
||||
|
||||
/* XXXX. This is the asynchronous variant. */
|
||||
static gpgme_error_t
|
||||
gpgme_op_g13_transact_start (gpgme_ctx_t ctx,
|
||||
gpgme_op_vfs_transact_start (gpgme_ctx_t ctx,
|
||||
const char *command,
|
||||
gpgme_assuan_data_cb_t data_cb,
|
||||
void *data_cb_value,
|
||||
@ -125,59 +102,52 @@ gpgme_op_g13_transact_start (gpgme_ctx_t ctx,
|
||||
gpgme_assuan_status_cb_t status_cb,
|
||||
void *status_cb_value)
|
||||
{
|
||||
return opg13_start (ctx, 0, command, data_cb, data_cb_value,
|
||||
inq_cb, inq_cb_value, status_cb, 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_g13_transact (gpgme_ctx_t ctx,
|
||||
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)
|
||||
void *status_cb_value,
|
||||
gpgme_error_t *op_err)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
|
||||
err = opg13_start (ctx, 1, command, data_cb, data_cb_value,
|
||||
inq_cb, inq_cb_value, status_cb, status_cb_value);
|
||||
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 (ctx);
|
||||
err = _gpgme_wait_one_ext (ctx, op_err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* The actual exported interface follows. */
|
||||
|
||||
static gpg_error_t
|
||||
get_err (gpgme_ctx_t ctx)
|
||||
{
|
||||
gpgme_g13_result_t res;
|
||||
|
||||
res = gpgme_op_g13_result (ctx);
|
||||
if (! res)
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
|
||||
return res->err;
|
||||
}
|
||||
|
||||
|
||||
/* 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. */
|
||||
gpgme_error_t
|
||||
gpgme_op_g13_mount (gpgme_ctx_t ctx, const char *container_file,
|
||||
const char *mount_dir, int flags)
|
||||
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;
|
||||
@ -190,11 +160,10 @@ gpgme_op_g13_mount (gpgme_ctx_t ctx, const char *container_file,
|
||||
}
|
||||
free (container_file_esc);
|
||||
|
||||
err = gpgme_op_g13_transact (ctx, cmd, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL);
|
||||
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, op_err);
|
||||
free (cmd);
|
||||
err = err || get_err (ctx);
|
||||
if (err)
|
||||
if (err || *op_err)
|
||||
return err;
|
||||
|
||||
if (mount_dir)
|
||||
@ -219,11 +188,9 @@ gpgme_op_g13_mount (gpgme_ctx_t ctx, const char *container_file,
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
err = gpgme_op_g13_transact (ctx, cmd, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL);
|
||||
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, op_err);
|
||||
free (cmd);
|
||||
|
||||
/* Note: in symmetry with the asynchronous variant, we don't return
|
||||
the error in the result structure here, if any. */
|
||||
return err;
|
||||
}
|
||||
|
47
src/gpgme.c
47
src/gpgme.c
@ -46,7 +46,7 @@ static char *def_lc_messages;
|
||||
gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL;
|
||||
|
||||
/* Protects all reference counters in result structures. All other
|
||||
accesses to a key are read only. */
|
||||
accesses to a result structure are read only. */
|
||||
DEFINE_STATIC_LOCK (result_ref_lock);
|
||||
|
||||
|
||||
@ -118,17 +118,32 @@ gpgme_new (gpgme_ctx_t *r_ctx)
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err)
|
||||
_gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err,
|
||||
gpg_error_t op_err)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
TRACE_BEG1 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i",
|
||||
ctx_err);
|
||||
struct gpgme_io_event_done_data data;
|
||||
|
||||
err = _gpgme_engine_cancel (ctx->engine);
|
||||
if (err)
|
||||
return TRACE_ERR (err);
|
||||
TRACE_BEG2 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i, op_err=%i",
|
||||
ctx_err, op_err);
|
||||
|
||||
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &ctx_err);
|
||||
if (ctx_err)
|
||||
{
|
||||
err = _gpgme_engine_cancel (ctx->engine);
|
||||
if (err)
|
||||
return TRACE_ERR (err);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = _gpgme_engine_cancel_op (ctx->engine);
|
||||
if (err)
|
||||
return TRACE_ERR (err);
|
||||
}
|
||||
|
||||
data.err = ctx_err;
|
||||
data.op_err = op_err;
|
||||
|
||||
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data);
|
||||
|
||||
return TRACE_ERR (0);
|
||||
}
|
||||
@ -138,7 +153,13 @@ _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err)
|
||||
gpgme_error_t
|
||||
gpgme_cancel (gpgme_ctx_t ctx)
|
||||
{
|
||||
return _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED));
|
||||
gpg_error_t err;
|
||||
|
||||
TRACE_BEG (DEBUG_CTX, "gpgme_cancel", ctx);
|
||||
|
||||
err = _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED), 0);
|
||||
|
||||
return TRACE_ERR (err);
|
||||
}
|
||||
|
||||
|
||||
@ -486,10 +507,12 @@ ssize_t
|
||||
gpgme_io_read (int fd, void *buffer, size_t count)
|
||||
{
|
||||
int ret;
|
||||
TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd,
|
||||
"buffer=%p, count=%u", buffer, count);
|
||||
|
||||
ret = _gpgme_io_read (fd, buffer, count);
|
||||
|
||||
return ret;
|
||||
return TRACE_SYSRES (ret);
|
||||
}
|
||||
|
||||
|
||||
@ -500,10 +523,12 @@ ssize_t
|
||||
gpgme_io_write (int fd, const void *buffer, size_t count)
|
||||
{
|
||||
int ret;
|
||||
TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_write", fd,
|
||||
"buffer=%p, count=%u", buffer, count);
|
||||
|
||||
ret = _gpgme_io_write (fd, buffer, count);
|
||||
|
||||
return ret;
|
||||
return TRACE_SYSRES (ret);
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,7 +185,11 @@ EXPORTS
|
||||
gpgme_op_export_keys @142
|
||||
gpgme_op_export_keys_start @143
|
||||
|
||||
gpgme_op_g13_mount @144
|
||||
gpgme_op_assuan_transact_ext @144
|
||||
|
||||
gpgme_wait_ext @145
|
||||
gpgme_op_vfs_mount_result @146
|
||||
gpgme_op_vfs_mount @147
|
||||
|
||||
; END
|
||||
|
||||
|
@ -960,6 +960,17 @@ typedef enum
|
||||
}
|
||||
gpgme_event_io_t;
|
||||
|
||||
struct gpgme_io_event_done_data
|
||||
{
|
||||
/* A fatal IPC error or an operational error in state-less
|
||||
protocols. */
|
||||
gpgme_error_t err;
|
||||
|
||||
/* An operational errors in session-based protocols. */
|
||||
gpgme_error_t op_err;
|
||||
};
|
||||
typedef struct gpgme_io_event_done_data *gpgme_io_event_done_data_t;
|
||||
|
||||
/* The type of a function that is called when a context finished an
|
||||
operation. */
|
||||
typedef void (*gpgme_event_io_cb_t) (void *data, gpgme_event_io_t type,
|
||||
@ -990,6 +1001,9 @@ ssize_t gpgme_io_write (int fd, const void *buffer, size_t count);
|
||||
the pending operation to finish. */
|
||||
gpgme_ctx_t gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang);
|
||||
|
||||
gpgme_ctx_t gpgme_wait_ext (gpgme_ctx_t ctx, gpgme_error_t *status,
|
||||
gpgme_error_t *op_err, int hang);
|
||||
|
||||
|
||||
/* Functions to handle data objects. */
|
||||
|
||||
@ -1733,21 +1747,6 @@ typedef gpgme_error_t (*gpgme_assuan_inquire_cb_t)
|
||||
typedef gpgme_error_t (*gpgme_assuan_status_cb_t)
|
||||
(void *opaque, const char *status, const char *args);
|
||||
|
||||
struct _gpgme_op_assuan_result
|
||||
{
|
||||
/* The result of the actual assuan command. An OK is indicated by a
|
||||
value of 0 and an ERR by the respective error error value. This
|
||||
is required because assuan operations use a session-based
|
||||
interface. The error code of the GPGME function calls just
|
||||
reflects transmission errors. */
|
||||
gpgme_error_t err;
|
||||
};
|
||||
typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t;
|
||||
|
||||
|
||||
/* Return the result of the last Assuan command. */
|
||||
gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx);
|
||||
|
||||
/* Send the Assuan COMMAND and return results via the callbacks.
|
||||
Asynchronous variant. */
|
||||
gpgme_error_t gpgme_op_assuan_transact_start (gpgme_ctx_t ctx,
|
||||
@ -1761,35 +1760,56 @@ gpgme_error_t gpgme_op_assuan_transact_start (gpgme_ctx_t ctx,
|
||||
|
||||
/* Send the Assuan COMMAND and return results via the callbacks.
|
||||
Synchronous variant. */
|
||||
gpgme_error_t gpgme_op_assuan_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 stat_cb,
|
||||
void *stat_cb_value);
|
||||
gpgme_error_t gpgme_op_assuan_transact_ext (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 stat_cb,
|
||||
void *stat_cb_value,
|
||||
gpgme_error_t *op_err);
|
||||
|
||||
/* Compat. */
|
||||
struct _gpgme_op_assuan_result
|
||||
{
|
||||
/* Deprecated. Use the second value in a DONE event or the
|
||||
synchronous variant gpgme_op_assuan_transact_ext. */
|
||||
gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME;
|
||||
};
|
||||
typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t;
|
||||
|
||||
|
||||
/* Return the result of the last Assuan command. */
|
||||
gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx)
|
||||
_GPGME_DEPRECATED;
|
||||
|
||||
gpgme_error_t
|
||||
gpgme_op_assuan_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_DEPRECATED;
|
||||
|
||||
|
||||
/* Crypto container support. */
|
||||
struct _gpgme_op_g13_result
|
||||
struct _gpgme_op_vfs_mount_result
|
||||
{
|
||||
/* The result of the actual assuan command. An OK is indicated by a
|
||||
value of 0 and an ERR by the respective error error value. This
|
||||
is required because assuan operations use a session-based
|
||||
interface. The error code of the GPGME function calls just
|
||||
reflects transmission errors. */
|
||||
gpgme_error_t err;
|
||||
char *mount_dir;
|
||||
};
|
||||
typedef struct _gpgme_op_g13_result *gpgme_g13_result_t;
|
||||
typedef struct _gpgme_op_vfs_mount_result *gpgme_vfs_mount_result_t;
|
||||
|
||||
gpgme_vfs_mount_result_t gpgme_op_vfs_mount_result (gpgme_ctx_t ctx);
|
||||
|
||||
/* 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. */
|
||||
gpgme_error_t gpgme_op_g13_mount (gpgme_ctx_t ctx, const char *container_file,
|
||||
const char *mount_dir, int flags);
|
||||
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,
|
||||
gpgme_error_t *op_err);
|
||||
|
||||
|
||||
/* Interface to gpgconf(1). */
|
||||
|
@ -928,7 +928,7 @@ gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
|
||||
|
||||
if (!opd->key_queue)
|
||||
{
|
||||
err = _gpgme_wait_on_condition (ctx, &opd->key_cond);
|
||||
err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -65,7 +65,12 @@ GPGME_1.1 {
|
||||
gpgme_op_export_keys;
|
||||
gpgme_op_export_keys_start;
|
||||
|
||||
gpgme_op_g13_mount;
|
||||
gpgme_op_assuan_transact_ext;
|
||||
|
||||
gpgme_wait_ext;
|
||||
|
||||
gpgme_op_vfs_mount_result;
|
||||
gpgme_op_vfs_mount;
|
||||
};
|
||||
|
||||
|
||||
|
193
src/opassuan.c
193
src/opassuan.c
@ -26,39 +26,95 @@
|
||||
#include "ops.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
static gpgme_error_t
|
||||
opassuan_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)
|
||||
{
|
||||
struct _gpgme_op_assuan_result result;
|
||||
gpgme_error_t err;
|
||||
|
||||
} *op_data_t;
|
||||
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. */
|
||||
gpgme_error_t
|
||||
gpgme_op_assuan_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 opassuan_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. */
|
||||
gpgme_error_t
|
||||
gpgme_op_assuan_transact_ext (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 = opassuan_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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* This callback is used to return the status of the assuan command
|
||||
back. Note that this is different from the error code returned
|
||||
from gpgme_op_assuan_transact because the later only reflects error
|
||||
with the connection. */
|
||||
static gpgme_error_t
|
||||
result_cb (void *priv, gpgme_error_t result)
|
||||
/* Compatibility code for old interface. */
|
||||
|
||||
/* Evil hack breaking abstractions for the purpose of localizing our
|
||||
other hack. This is copied from engine.c. */
|
||||
struct engine
|
||||
{
|
||||
gpgme_ctx_t ctx = (gpgme_ctx_t)priv;
|
||||
gpgme_error_t err;
|
||||
void *hook;
|
||||
op_data_t opd;
|
||||
struct engine_ops *ops;
|
||||
void *engine;
|
||||
};
|
||||
|
||||
err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL);
|
||||
opd = hook;
|
||||
if (err)
|
||||
return err;
|
||||
if (!opd)
|
||||
return gpg_error (GPG_ERR_INTERNAL);
|
||||
|
||||
opd->result.err = result;
|
||||
return 0;
|
||||
}
|
||||
typedef struct
|
||||
{
|
||||
struct _gpgme_op_assuan_result result;
|
||||
} *op_data_t;
|
||||
|
||||
gpg_error_t _gpgme_engine_assuan_last_op_err (void *engine);
|
||||
|
||||
gpgme_assuan_result_t
|
||||
gpgme_op_assuan_result (gpgme_ctx_t ctx)
|
||||
@ -74,85 +130,32 @@ gpgme_op_assuan_result (gpgme_ctx_t ctx)
|
||||
if (err || !opd)
|
||||
return NULL;
|
||||
|
||||
/* All of this is a hack for the old style interface. The new style
|
||||
interface returns op errors directly. */
|
||||
opd->result.err = _gpgme_engine_assuan_last_op_err (ctx->engine->engine);
|
||||
|
||||
return &opd->result;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
opassuan_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_ASSUAN, &hook, sizeof (*opd), NULL);
|
||||
opd = hook;
|
||||
if (err)
|
||||
return err;
|
||||
opd->result.err = gpg_error (GPG_ERR_UNFINISHED);
|
||||
|
||||
return _gpgme_engine_op_assuan_transact (ctx->engine, command,
|
||||
result_cb, ctx,
|
||||
data_cb, data_cb_value,
|
||||
inq_cb, inq_cb_value,
|
||||
status_cb, status_cb_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* XXXX. This is the asynchronous variant. */
|
||||
gpgme_error_t
|
||||
gpgme_op_assuan_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 opassuan_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. */
|
||||
gpgme_error_t
|
||||
gpgme_op_assuan_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)
|
||||
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 = opassuan_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 (ctx);
|
||||
/* Users of the old-style session based interfaces need to look at
|
||||
the result structure. */
|
||||
gpgme_op_assuan_transact_ext (ctx, command, data_cb, data_cb_value,
|
||||
inq_cb, inq_cb_value,
|
||||
status_cb, status_cb_value, &op_err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -27,14 +27,17 @@
|
||||
|
||||
|
||||
/* From gpgme.c. */
|
||||
gpgme_error_t _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err);
|
||||
gpgme_error_t _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err,
|
||||
gpg_error_t op_err);
|
||||
|
||||
void _gpgme_release_result (gpgme_ctx_t ctx);
|
||||
|
||||
|
||||
/* From wait.c. */
|
||||
gpgme_error_t _gpgme_wait_one (gpgme_ctx_t ctx);
|
||||
gpgme_error_t _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond);
|
||||
gpgme_error_t _gpgme_wait_one_ext (gpgme_ctx_t ctx, gpgme_error_t *op_err);
|
||||
gpgme_error_t _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond,
|
||||
gpgme_error_t *op_err);
|
||||
|
||||
|
||||
/* From data.c. */
|
||||
|
@ -220,7 +220,7 @@ gpgme_op_trustlist_next (gpgme_ctx_t ctx, gpgme_trust_item_t *r_item)
|
||||
|
||||
if (!opd->trust_queue)
|
||||
{
|
||||
err = _gpgme_wait_on_condition (ctx, &opd->trust_cond);
|
||||
err = _gpgme_wait_on_condition (ctx, &opd->trust_cond, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
if (!opd->trust_cond)
|
||||
|
@ -74,6 +74,7 @@ struct ctx_list_item
|
||||
gpgme_ctx_t ctx;
|
||||
/* The status is set when the ctx is moved to the done list. */
|
||||
gpgme_error_t status;
|
||||
gpgme_error_t op_err;
|
||||
};
|
||||
|
||||
/* The active list contains all contexts that are in the global event
|
||||
@ -112,7 +113,7 @@ ctx_active (gpgme_ctx_t ctx)
|
||||
|
||||
/* Enter the context CTX into the done list with status STATUS. */
|
||||
static void
|
||||
ctx_done (gpgme_ctx_t ctx, gpgme_error_t status)
|
||||
ctx_done (gpgme_ctx_t ctx, gpgme_error_t status, gpgme_error_t op_err)
|
||||
{
|
||||
struct ctx_list_item *li;
|
||||
|
||||
@ -131,6 +132,7 @@ ctx_done (gpgme_ctx_t ctx, gpgme_error_t status)
|
||||
ctx_active_list = li->next;
|
||||
|
||||
li->status = status;
|
||||
li->op_err = op_err;
|
||||
|
||||
/* Add LI to done list. */
|
||||
li->next = ctx_done_list;
|
||||
@ -147,7 +149,7 @@ ctx_done (gpgme_ctx_t ctx, gpgme_error_t status)
|
||||
If a matching context could be found, return it. Return NULL if no
|
||||
context could be found. */
|
||||
static gpgme_ctx_t
|
||||
ctx_wait (gpgme_ctx_t ctx, gpgme_error_t *status)
|
||||
ctx_wait (gpgme_ctx_t ctx, gpgme_error_t *status, gpgme_error_t *op_err)
|
||||
{
|
||||
struct ctx_list_item *li;
|
||||
|
||||
@ -164,6 +166,8 @@ ctx_wait (gpgme_ctx_t ctx, gpgme_error_t *status)
|
||||
ctx = li->ctx;
|
||||
if (status)
|
||||
*status = li->status;
|
||||
if (op_err)
|
||||
*op_err = li->op_err;
|
||||
|
||||
/* Remove LI from done list. */
|
||||
if (li->next)
|
||||
@ -203,15 +207,16 @@ _gpgme_wait_global_event_cb (void *data, gpgme_event_io_t type,
|
||||
if (err)
|
||||
/* An error occured. Close all fds in this context, and
|
||||
send the error in a done event. */
|
||||
_gpgme_cancel_with_err (ctx, err);
|
||||
_gpgme_cancel_with_err (ctx, err, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case GPGME_EVENT_DONE:
|
||||
{
|
||||
gpgme_error_t *errp = (gpgme_error_t *) type_data;
|
||||
assert (errp);
|
||||
ctx_done (ctx, *errp);
|
||||
gpgme_io_event_done_data_t done_data =
|
||||
(gpgme_io_event_done_data_t) type_data;
|
||||
|
||||
ctx_done (ctx, done_data->err, done_data->op_err);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -246,7 +251,8 @@ _gpgme_wait_global_event_cb (void *data, gpgme_event_io_t type,
|
||||
error occurs, NULL is returned and *STATUS is set to the error
|
||||
value. */
|
||||
gpgme_ctx_t
|
||||
gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
gpgme_wait_ext (gpgme_ctx_t ctx, gpgme_error_t *status,
|
||||
gpgme_error_t *op_err, int hang)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -266,6 +272,8 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
UNLOCK (ctx_list_lock);
|
||||
if (status)
|
||||
*status = gpg_error_from_errno (saved_errno);
|
||||
if (op_err)
|
||||
*op_err = 0;
|
||||
return NULL;
|
||||
}
|
||||
fdt.size = i;
|
||||
@ -285,6 +293,8 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
free (fdt.fds);
|
||||
if (status)
|
||||
*status = gpg_error_from_errno (saved_errno);
|
||||
if (op_err)
|
||||
*op_err = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -294,6 +304,7 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
{
|
||||
gpgme_ctx_t ictx;
|
||||
gpgme_error_t err = 0;
|
||||
gpgme_error_t local_op_err = 0;
|
||||
struct wait_item_s *item;
|
||||
|
||||
assert (nr);
|
||||
@ -310,12 +321,12 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
if (!err)
|
||||
err = _gpgme_run_io_cb (&fdt.fds[i], 0);
|
||||
if (err)
|
||||
err = _gpgme_run_io_cb (&fdt.fds[i], 0, &local_op_err);
|
||||
if (err || local_op_err)
|
||||
{
|
||||
/* An error occured. Close all fds in this context,
|
||||
and signal it. */
|
||||
_gpgme_cancel_with_err (ictx, err);
|
||||
_gpgme_cancel_with_err (ictx, err, local_op_err);
|
||||
|
||||
/* Break out of the loop, and retry the select()
|
||||
from scratch, because now all fds should be
|
||||
@ -338,8 +349,10 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
break;
|
||||
if (i == actx->fdt.size)
|
||||
{
|
||||
gpgme_error_t err = 0;
|
||||
|
||||
struct gpgme_io_event_done_data data;
|
||||
data.err = 0;
|
||||
data.op_err = 0;
|
||||
|
||||
/* FIXME: This does not perform too well. We have to
|
||||
release the lock because the I/O event handler
|
||||
acquires it to remove the context from the active
|
||||
@ -349,7 +362,7 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
contexts to be released and call the DONE events
|
||||
afterwards. */
|
||||
UNLOCK (ctx_list_lock);
|
||||
_gpgme_engine_io_event (actx->engine, GPGME_EVENT_DONE, &err);
|
||||
_gpgme_engine_io_event (actx->engine, GPGME_EVENT_DONE, &data);
|
||||
LOCK (ctx_list_lock);
|
||||
goto retry;
|
||||
}
|
||||
@ -357,7 +370,7 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
UNLOCK (ctx_list_lock);
|
||||
|
||||
{
|
||||
gpgme_ctx_t dctx = ctx_wait (ctx, status);
|
||||
gpgme_ctx_t dctx = ctx_wait (ctx, status, op_err);
|
||||
|
||||
if (dctx)
|
||||
{
|
||||
@ -369,6 +382,8 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
ctx = NULL;
|
||||
if (status)
|
||||
*status = 0;
|
||||
if (op_err)
|
||||
*op_err = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,3 +391,10 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
gpgme_ctx_t
|
||||
gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
{
|
||||
return gpgme_wait_ext (ctx, status, NULL, hang);
|
||||
}
|
||||
|
@ -72,7 +72,8 @@ _gpgme_wait_private_event_cb (void *data, gpgme_event_io_t type,
|
||||
finished and return its error value. Otherwise, wait until COND is
|
||||
satisfied or the operation finished. */
|
||||
gpgme_error_t
|
||||
_gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
|
||||
_gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond,
|
||||
gpgme_error_t *op_err_p)
|
||||
{
|
||||
gpgme_error_t err = 0;
|
||||
int hang = 1;
|
||||
@ -87,8 +88,10 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
|
||||
/* An error occured. Close all fds in this context, and
|
||||
signal it. */
|
||||
err = gpg_error_from_errno (errno);
|
||||
_gpgme_cancel_with_err (ctx, err);
|
||||
_gpgme_cancel_with_err (ctx, err, 0);
|
||||
|
||||
if (op_err_p)
|
||||
*op_err_p = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -96,6 +99,8 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
|
||||
{
|
||||
if (ctx->fdt.fds[i].fd != -1 && ctx->fdt.fds[i].signaled)
|
||||
{
|
||||
gpgme_error_t op_err = 0;
|
||||
|
||||
ctx->fdt.fds[i].signaled = 0;
|
||||
assert (nr);
|
||||
nr--;
|
||||
@ -106,15 +111,33 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
if (!err)
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0);
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0, &op_err);
|
||||
if (err)
|
||||
{
|
||||
/* An error occured. Close all fds in this context,
|
||||
and signal it. */
|
||||
_gpgme_cancel_with_err (ctx, err);
|
||||
_gpgme_cancel_with_err (ctx, err, 0);
|
||||
|
||||
if (op_err_p)
|
||||
*op_err_p = 0;
|
||||
return err;
|
||||
}
|
||||
else if (op_err)
|
||||
{
|
||||
/* An operational error occured. Cancel the current
|
||||
operation but not the session, and signal it. */
|
||||
_gpgme_cancel_with_err (ctx, 0, op_err);
|
||||
|
||||
/* NOTE: This relies on the operational error being
|
||||
generated after the operation really has
|
||||
completed, for example after no further status
|
||||
line output is generated. Otherwise the
|
||||
following I/O will spill over into the next
|
||||
operation. */
|
||||
if (op_err_p)
|
||||
*op_err_p = op_err;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +146,10 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
|
||||
break;
|
||||
if (i == ctx->fdt.size)
|
||||
{
|
||||
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
|
||||
struct gpgme_io_event_done_data data;
|
||||
data.err = 0;
|
||||
data.op_err = 0;
|
||||
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data);
|
||||
hang = 0;
|
||||
}
|
||||
if (cond && *cond)
|
||||
@ -131,14 +157,26 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
|
||||
}
|
||||
while (hang);
|
||||
|
||||
if (op_err_p)
|
||||
*op_err_p = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Wait until the blocking operation in context CTX has finished and
|
||||
return the error value. */
|
||||
return the error value. This variant can not be used for
|
||||
session-based protocols. */
|
||||
gpgme_error_t
|
||||
_gpgme_wait_one (gpgme_ctx_t ctx)
|
||||
{
|
||||
return _gpgme_wait_on_condition (ctx, NULL);
|
||||
return _gpgme_wait_on_condition (ctx, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Wait until the blocking operation in context CTX has finished and
|
||||
return the error value. This is the right variant to use for
|
||||
sesion-based protocols. */
|
||||
gpgme_error_t
|
||||
_gpgme_wait_one_ext (gpgme_ctx_t ctx, gpgme_error_t *op_err)
|
||||
{
|
||||
return _gpgme_wait_on_condition (ctx, NULL, op_err);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ gpgme_error_t
|
||||
_gpgme_user_io_cb_handler (void *data, int fd)
|
||||
{
|
||||
gpgme_error_t err = 0;
|
||||
gpgme_error_t op_err = 0;
|
||||
struct tag *tag = (struct tag *) data;
|
||||
gpgme_ctx_t ctx;
|
||||
|
||||
@ -54,9 +55,9 @@ _gpgme_user_io_cb_handler (void *data, int fd)
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
if (! err)
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0);
|
||||
if (err)
|
||||
_gpgme_cancel_with_err (ctx, err);
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0, &op_err);
|
||||
if (err || op_err)
|
||||
_gpgme_cancel_with_err (ctx, err, op_err);
|
||||
else
|
||||
{
|
||||
unsigned int i;
|
||||
@ -64,8 +65,15 @@ _gpgme_user_io_cb_handler (void *data, int fd)
|
||||
for (i = 0; i < ctx->fdt.size; i++)
|
||||
if (ctx->fdt.fds[i].fd != -1)
|
||||
break;
|
||||
|
||||
if (i == ctx->fdt.size)
|
||||
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
|
||||
{
|
||||
struct gpgme_io_event_done_data done_data;
|
||||
|
||||
done_data.err = 0;
|
||||
done_data.op_err = 0;
|
||||
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &done_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
14
src/wait.c
14
src/wait.c
@ -180,9 +180,13 @@ _gpgme_remove_io_cb (void *data)
|
||||
we are called from our own event loops. So if CHECKED is 1, the
|
||||
check is skipped. */
|
||||
gpgme_error_t
|
||||
_gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked)
|
||||
_gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked,
|
||||
gpgme_error_t *op_err)
|
||||
{
|
||||
struct wait_item_s *item;
|
||||
struct io_cb_data iocb_data;
|
||||
gpgme_error_t err;
|
||||
|
||||
item = (struct wait_item_s *) an_fds->opaque;
|
||||
assert (item);
|
||||
|
||||
@ -207,5 +211,11 @@ _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked)
|
||||
|
||||
TRACE2 (DEBUG_CTX, "_gpgme_run_io_cb", item, "handler (%p, %d)",
|
||||
item->handler_value, an_fds->fd);
|
||||
return item->handler (item->handler_value, an_fds->fd);
|
||||
|
||||
iocb_data.handler_value = item->handler_value;
|
||||
iocb_data.op_err = 0;
|
||||
err = item->handler (&iocb_data, an_fds->fd);
|
||||
|
||||
*op_err = iocb_data.op_err;
|
||||
return err;
|
||||
}
|
||||
|
18
src/wait.h
18
src/wait.h
@ -75,8 +75,22 @@ void _gpgme_wait_user_remove_io_cb (void *tag);
|
||||
void _gpgme_wait_user_event_cb (void *data, gpgme_event_io_t type,
|
||||
void *type_data);
|
||||
|
||||
gpgme_error_t _gpgme_wait_one (gpgme_ctx_t ctx);
|
||||
gpgme_error_t _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked,
|
||||
gpgme_error_t *err);
|
||||
|
||||
gpgme_error_t _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked);
|
||||
|
||||
/* Session based interfaces require to make a distinction between IPC
|
||||
errors and operational errors. To glue this into the old
|
||||
interface, I/O handlers (esp. the status handler) are called with a
|
||||
struct as the opaque value that contains the handlers opaque value
|
||||
but also a field for the operational error to be returned. */
|
||||
struct io_cb_data
|
||||
{
|
||||
/* If this is the first field, the old internal code will still work. */
|
||||
void *handler_value;
|
||||
|
||||
/* The I/O callback can pass an operational error here. */
|
||||
gpgme_error_t op_err;
|
||||
};
|
||||
|
||||
#endif /* WAIT_H */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2009-10-26 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* opassuan/t-command.c: Update to new interface.
|
||||
|
||||
2009-10-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* run-verify.c: New.
|
||||
|
@ -101,6 +101,7 @@ int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
gpgme_error_t op_err;
|
||||
gpgme_ctx_t ctx;
|
||||
const char *command;
|
||||
|
||||
@ -125,18 +126,9 @@ main (int argc, char **argv)
|
||||
err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_ASSUAN);
|
||||
fail_if_err (err);
|
||||
|
||||
err = gpgme_op_assuan_transact (ctx, command,
|
||||
data_cb, NULL,
|
||||
inq_cb, NULL,
|
||||
status_cb, NULL);
|
||||
fail_if_err (err);
|
||||
err = gpgme_op_assuan_result (ctx)->err;
|
||||
if (err)
|
||||
fprintf (stderr, "assuan command `%s' failed: %s <%s> (%d)\n",
|
||||
command, gpg_strerror (err), gpg_strsource (err), err);
|
||||
else
|
||||
fprintf (stderr, "assuan command `%s' succeeded\n", command);
|
||||
|
||||
err = gpgme_op_assuan_transact_ext (ctx, command, data_cb, NULL,
|
||||
inq_cb, NULL, status_cb, NULL, &op_err);
|
||||
fail_if_err (err || op_err);
|
||||
|
||||
gpgme_release (ctx);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user