2002-07-03 Marcus Brinkmann <marcus@g10code.de>

* gpgme.c (gpgme_set_io_cbs): Deal with CTX being NULL.

	* gpgme.c (_gpgme_op_event_cb_user): New function.
	* op-support.c (_gpgme_op_reset): Support a new mode of operation
	for private or user event loop.  Use new user event callback
	wrapper.
	* trustlist.c (gpgme_op_trustlist_start): Use this new mode.
	* keylist.c (gpgme_op_keylist_start): Likewise.

	* rungpg.c (_gpgme_gpg_io_event): New function.
	* rungpg.h (_gpgme_gpg_io_event): New prototype.
	* engine-gpgsm.c (_gpgme_gpg_io_event): New function.
	* engine-gpgsm.h (_gpgme_gpgsm_io_event): New prototype.
	* engine.c (_gpgme_engine_io_event): New function.
	* engine.h (_gpgme_engine_io_event): New prototype.
	* keylist.c (finish_key): Call _gpgme_engine_io_event, and move
	the real work for the default IO callback routines to ...
	(_gpgme_op_keylist_event_cb): ... here.  New function.
	* trustlist.c (trustlist_colon_handler): Signal
	GPGME_EVENT_NEXT_TRUSTITEM.  Move queue manipulation to ...
	(_gpgme_op_trustlist_event_cb): ... here.  New function.
	* gpgme.c (_gpgme_op_event_cb): Call _gpgme_op_keylist_event_cb
	and _gpgme_op_trustlist_event_cb when appropriate.
	* ops.h (_gpgme_op_keylist_event_cb): New prototype.
	(_gpgme_op_trustlist_event_cb): Likewise.
	* op-support.c (_gpgme_op_reset): Add comment why we don't use the
	user provided event handler directly.
	* gpgme.h (GpgmeRegisterIOCb): Return GpgmeError value, and TAG in
	a pointer argument.
	* wait.c (_gpgme_add_io_cb): Likewise.
	* wait.h (_gpgme_add_io_cb): Likewise for prototype.
	* rungpg.c (_gpgme_gpg_add_io_cb): Call IO_CBS->add with new
	argument.  Fix up error handling.
	* engine-gpgsm.c (_gpgme_gpgsm_add_io_cb): Call IO_CBS->add with
	new argument, fix up error handling.
This commit is contained in:
Marcus Brinkmann 2002-07-03 01:57:03 +00:00
parent 0cf2a8a51a
commit b92c8f057c
15 changed files with 242 additions and 95 deletions

View File

@ -1,3 +1,41 @@
2002-07-03 Marcus Brinkmann <marcus@g10code.de>
* gpgme.c (gpgme_set_io_cbs): Deal with CTX being NULL.
* gpgme.c (_gpgme_op_event_cb_user): New function.
* op-support.c (_gpgme_op_reset): Support a new mode of operation
for private or user event loop. Use new user event callback
wrapper.
* trustlist.c (gpgme_op_trustlist_start): Use this new mode.
* keylist.c (gpgme_op_keylist_start): Likewise.
* rungpg.c (_gpgme_gpg_io_event): New function.
* rungpg.h (_gpgme_gpg_io_event): New prototype.
* engine-gpgsm.c (_gpgme_gpg_io_event): New function.
* engine-gpgsm.h (_gpgme_gpgsm_io_event): New prototype.
* engine.c (_gpgme_engine_io_event): New function.
* engine.h (_gpgme_engine_io_event): New prototype.
* keylist.c (finish_key): Call _gpgme_engine_io_event, and move
the real work for the default IO callback routines to ...
(_gpgme_op_keylist_event_cb): ... here. New function.
* trustlist.c (trustlist_colon_handler): Signal
GPGME_EVENT_NEXT_TRUSTITEM. Move queue manipulation to ...
(_gpgme_op_trustlist_event_cb): ... here. New function.
* gpgme.c (_gpgme_op_event_cb): Call _gpgme_op_keylist_event_cb
and _gpgme_op_trustlist_event_cb when appropriate.
* ops.h (_gpgme_op_keylist_event_cb): New prototype.
(_gpgme_op_trustlist_event_cb): Likewise.
* op-support.c (_gpgme_op_reset): Add comment why we don't use the
user provided event handler directly.
* gpgme.h (GpgmeRegisterIOCb): Return GpgmeError value, and TAG in
a pointer argument.
* wait.c (_gpgme_add_io_cb): Likewise.
* wait.h (_gpgme_add_io_cb): Likewise for prototype.
* rungpg.c (_gpgme_gpg_add_io_cb): Call IO_CBS->add with new
argument. Fix up error handling.
* engine-gpgsm.c (_gpgme_gpgsm_add_io_cb): Call IO_CBS->add with
new argument, fix up error handling.
2002-06-28 Marcus Brinkmann <marcus@g10code.de>
* keylist.c (gpgme_op_keylist_ext_start): Always use our own FD

View File

@ -1290,14 +1290,14 @@ static GpgmeError
_gpgme_gpgsm_add_io_cb (GpgsmObject gpgsm, iocb_data_t *iocbd,
GpgmeIOCb handler)
{
GpgmeError err = 0;
GpgmeError err;
iocbd->tag = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv,
iocbd->fd, iocbd->dir,
handler, iocbd->data);
if (!iocbd->tag)
err = mk_error (General_Error);
if (!err && !iocbd->dir)
err = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv,
iocbd->fd, iocbd->dir,
handler, iocbd->data, &iocbd->tag);
if (err)
return err;
if (!iocbd->dir)
/* FIXME Kludge around poll() problem. */
err = _gpgme_io_set_nonblocking (iocbd->fd);
return err;
@ -1338,6 +1338,12 @@ _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs)
gpgsm->io_cbs = *io_cbs;
}
void
_gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data)
{
if (gpgsm->io_cbs.event)
(*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, type, type_data);
}
#else /* ENABLE_GPGSM */
@ -1486,4 +1492,9 @@ _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs)
{
}
void
_gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data)
{
}
#endif /* ! ENABLE_GPGSM */

View File

@ -64,5 +64,6 @@ GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig,
GpgmeData text);
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
void _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs);
void _gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data);
#endif /* ENGINE_GPGSM_H */

View File

@ -587,6 +587,26 @@ _gpgme_engine_set_io_cbs (EngineObject engine,
}
}
void
_gpgme_engine_io_event (EngineObject engine,
GpgmeEventIO type, void *type_data)
{
if (!engine)
return;
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
_gpgme_gpg_io_event (engine->engine.gpg, type, type_data);
break;
case GPGME_PROTOCOL_CMS:
_gpgme_gpgsm_io_event (engine->engine.gpgsm, type, type_data);
break;
default:
break;
}
}
void
_gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid)

View File

@ -78,6 +78,8 @@ GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque);
void _gpgme_engine_set_io_cbs (EngineObject engine,
struct GpgmeIOCbs *io_cbs);
void _gpgme_engine_io_event (EngineObject engine,
GpgmeEventIO type, void *type_data);
void _gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid);
void _gpgme_engine_housecleaning (void);

View File

@ -507,7 +507,10 @@ gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *r_cb, void **r_cb_value)
void
gpgme_set_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs)
{
if (ctx && io_cbs)
if (!ctx)
return;
if (io_cbs)
ctx->io_cbs = *io_cbs;
else
{
@ -544,9 +547,36 @@ _gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data)
{
GpgmeCtx ctx = data;
if (type == GPGME_EVENT_DONE)
ctx->pending = 0;
switch (type)
{
case GPGME_EVENT_DONE:
ctx->pending = 0;
break;
if (ctx->io_cbs.add && ctx->io_cbs.event)
(*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, type_data);
case GPGME_EVENT_NEXT_KEY:
_gpgme_op_keylist_event_cb (data, type, type_data);
break;
case GPGME_EVENT_NEXT_TRUSTITEM:
_gpgme_op_trustlist_event_cb (data, type, type_data);
break;
}
}
void
_gpgme_op_event_cb_user (void *data, GpgmeEventIO type, void *type_data)
{
GpgmeCtx ctx = data;
if (type == GPGME_EVENT_DONE)
{
ctx->pending = 0;
if (ctx->io_cbs.event)
(*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, &ctx->error);
}
else
{
if (ctx->io_cbs.event)
(*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, type_data);
}
}

View File

@ -339,12 +339,13 @@ char *gpgme_get_op_info (GpgmeCtx ctx, int reserved);
typedef void (*GpgmeIOCb) (void *data, int fd);
/* The type of a function that can register FNC as the I/O callback
function for the file descriptor FD with direction dir (0: inbound,
1: outbound). FNC_DATA should be passed as DATA to FNC. The
function for the file descriptor FD with direction dir (0: for writing,
1: for reading). FNC_DATA should be passed as DATA to FNC. The
function should return a TAG suitable for the corresponding
GpgmeRemoveIOCb. */
typedef void *(*GpgmeRegisterIOCb) (void *data, int fd, int dir,
GpgmeIOCb fnc, void *fnc_data);
GpgmeRemoveIOCb, and an error value. */
typedef GpgmeError (*GpgmeRegisterIOCb) (void *data, int fd, int dir,
GpgmeIOCb fnc, void *fnc_data,
void **tag);
/* The type of a function that can remove a previously registered I/O
callback function given TAG as returned by the register
@ -370,13 +371,13 @@ struct GpgmeIOCbs
};
/* Set the I/O callback functions in CTX to IO_CBS. */
void gpgme_set_op_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs);
void gpgme_set_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs);
/* Get the current I/O callback functions. */
void gpgme_get_op_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs);
void gpgme_get_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs);
/* Cancel a pending operation in CTX. */
void gpgme_cancel (GpgmeCtx ctx);
void gpgme_cancel (GpgmeCtx ctx);
/* Process the pending operation and, if HANG is non-zero, wait for
the pending operation to finish. */

View File

@ -514,35 +514,45 @@ static void
finish_key (GpgmeCtx ctx)
{
GpgmeKey key = ctx->tmp_key;
struct key_queue_item_s *q, *q2;
ctx->tmp_key = NULL;
if (key)
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
}
void
_gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data)
{
GpgmeCtx ctx = (GpgmeCtx) data;
GpgmeKey key = (GpgmeKey) type_data;
struct key_queue_item_s *q, *q2;
assert (type == GPGME_EVENT_NEXT_KEY);
_gpgme_key_cache_add (key);
q = xtrymalloc (sizeof *q);
if (!q)
{
ctx->tmp_key = NULL;
_gpgme_key_cache_add (key);
q = xtrymalloc (sizeof *q);
if (!q)
{
gpgme_key_release (key);
ctx->error = mk_error (Out_Of_Core);
return;
}
q->key = key;
q->next = NULL;
/* FIXME: Lock queue. Use a tail pointer? */
if (!(q2 = ctx->key_queue))
ctx->key_queue = q;
else
{
for (; q2->next; q2 = q2->next)
;
q2->next = q;
}
ctx->key_cond = 1;
/* FIXME: Unlock queue. */
gpgme_key_release (key);
ctx->error = mk_error (Out_Of_Core);
return;
}
q->key = key;
q->next = NULL;
/* FIXME: Lock queue. Use a tail pointer? */
if (!(q2 = ctx->key_queue))
ctx->key_queue = q;
else
{
for (; q2->next; q2 = q2->next)
;
q2->next = q;
}
ctx->key_cond = 1;
/* FIXME: Unlock queue. */
}
@ -563,9 +573,7 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
{
GpgmeError err = 0;
/* Keylist operations are always "synchronous" in the sense that we
don't add ourself to the global FD table. */
err = _gpgme_op_reset (ctx, 1);
err = _gpgme_op_reset (ctx, 2);
if (err)
goto leave;

View File

@ -24,8 +24,12 @@
#include "context.h"
#include "ops.h"
/* type is: 0: asynchronous operation (use global or user event loop).
1: synchronous operation (always use private event loop).
2: asynchronous private operation (use private or user
event loop). */
GpgmeError
_gpgme_op_reset (GpgmeCtx ctx, int synchronous)
_gpgme_op_reset (GpgmeCtx ctx, int type)
{
GpgmeError err = 0;
struct GpgmeIOCbs io_cbs;
@ -43,8 +47,9 @@ _gpgme_op_reset (GpgmeCtx ctx, int synchronous)
if (err)
return err;
if (synchronous)
if (type == 1 || (type == 2 && !ctx->io_cbs.add))
{
/* Use private event loop. */
io_cbs.add = _gpgme_add_io_cb;
io_cbs.add_priv = &ctx->fdt;
io_cbs.remove = _gpgme_remove_io_cb;
@ -53,6 +58,7 @@ _gpgme_op_reset (GpgmeCtx ctx, int synchronous)
}
else if (! ctx->io_cbs.add)
{
/* Use global event loop. */
io_cbs.add = _gpgme_add_io_cb;
io_cbs.add_priv = NULL;
io_cbs.remove = _gpgme_remove_io_cb;
@ -61,8 +67,12 @@ _gpgme_op_reset (GpgmeCtx ctx, int synchronous)
}
else
{
/* Use user event loop. */
io_cbs = ctx->io_cbs;
io_cbs.event = _gpgme_op_event_cb;
/* We have to make sure that we notice the termination of the
operation ourself, so we stack another event handler on top
of the user-provided one. */
io_cbs.event = _gpgme_op_event_cb_user;
io_cbs.event_priv = ctx;
}
_gpgme_engine_set_io_cbs (ctx->engine, &io_cbs);

View File

@ -47,6 +47,7 @@ void _gpgme_release_result ( GpgmeCtx c );
void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info);
void _gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data);
void _gpgme_op_event_cb_user (void *data, GpgmeEventIO type, void *type_data);
/*-- wait.c --*/
GpgmeError _gpgme_wait_one (GpgmeCtx ctx);
@ -131,6 +132,10 @@ void _gpgme_release_genkey_result (GenKeyResult res);
/*-- keylist.c --*/
void _gpgme_release_keylist_result (KeylistResult res);
void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data);
/*-- trustlist.c --*/
void _gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data);
/*-- version.c --*/
const char *_gpgme_compare_versions (const char *my_version,

View File

@ -212,8 +212,8 @@ close_notify_handler (int fd, void *opaque)
break;
}
}
if (!not_done && gpg->io_cbs.event)
(*gpg->io_cbs.event) (gpg->io_cbs.event_priv, GPGME_EVENT_DONE, NULL);
if (!not_done)
_gpgme_gpg_io_event (gpg, GPGME_EVENT_DONE, NULL);
}
const char *
@ -807,12 +807,12 @@ static GpgmeError
_gpgme_gpg_add_io_cb (GpgObject gpg, int fd, int dir,
GpgmeIOCb handler, void *data, void **tag)
{
GpgmeError err = 0;
GpgmeError err;
*tag = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data);
if (!tag)
err = mk_error (General_Error);
if (!err && !dir)
err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag);
if (err)
return err;
if (!dir)
/* FIXME Kludge around poll() problem. */
err = _gpgme_io_set_nonblocking (fd);
return err;
@ -1749,3 +1749,11 @@ _gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs)
{
gpg->io_cbs = *io_cbs;
}
void
_gpgme_gpg_io_event (GpgObject gpg, GpgmeEventIO type, void *type_data)
{
if (gpg->io_cbs.event)
(*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data);
}

View File

@ -162,5 +162,6 @@ GpgmeError _gpgme_gpg_op_trustlist (GpgObject gpg, const char *pattern);
GpgmeError _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text);
GpgmeError _gpgme_gpg_spawn (GpgObject gpg, void *opaque);
void _gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs);
void _gpgme_gpg_io_event (GpgObject gpg, GpgmeEventIO type, void *type_data);
#endif /* RUNGPG_H */

View File

@ -87,7 +87,6 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line)
char *p, *pend;
int field = 0;
GpgmeTrustItem item = NULL;
struct trust_queue_item_s *q, *q2;
if (ctx->error)
return;
@ -104,31 +103,12 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line)
switch (field)
{
case 1: /* level */
q = xtrymalloc (sizeof *q);
if (!q)
item = trust_item_new ();
if (!item)
{
ctx->error = mk_error (Out_Of_Core);
return;
}
q->next = NULL;
q->item = item = trust_item_new ();
if (!q->item)
{
xfree (q);
ctx->error = mk_error (Out_Of_Core);
return;
}
/* fixme: lock queue, keep a tail pointer */
q2 = ctx->trust_queue;
if (!q2)
ctx->trust_queue = q;
else
{
while (q2->next)
q2 = q2->next;
q2->next = q;
}
/* fixme: unlock queue */
item->level = atoi (p);
break;
case 2: /* long keyid */
@ -154,8 +134,41 @@ trustlist_colon_handler (GpgmeCtx ctx, char *line)
}
}
if (field)
ctx->key_cond = 1;
if (item)
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_TRUSTITEM, item);
}
void
_gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data)
{
GpgmeCtx ctx = (GpgmeCtx) data;
GpgmeTrustItem item = (GpgmeTrustItem) type_data;
struct trust_queue_item_s *q, *q2;
assert (type == GPGME_EVENT_NEXT_KEY);
q = xtrymalloc (sizeof *q);
if (!q)
{
gpgme_trust_item_release (item);
ctx->error = mk_error (Out_Of_Core);
return;
}
q->item = item;
q->next = NULL;
/* FIXME: lock queue, keep a tail pointer */
q2 = ctx->trust_queue;
if (!q2)
ctx->trust_queue = q;
else
{
while (q2->next)
q2 = q2->next;
q2->next = q;
}
/* FIXME: unlock queue */
ctx->key_cond = 1;
}
@ -167,9 +180,7 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level)
if (!pattern || !*pattern)
return mk_error (Invalid_Value);
/* Trustlist operations are always "synchronous" in the sense that
we don't add ourself to the global FD table. */
err = _gpgme_op_reset (ctx, 1);
err = _gpgme_op_reset (ctx, 2);
if (err)
goto leave;

View File

@ -332,9 +332,9 @@ struct tag
int idx;
};
void *
GpgmeError
_gpgme_add_io_cb (void *data, int fd, int dir,
GpgmeIOCb fnc, void *fnc_data)
GpgmeIOCb fnc, void *fnc_data, void **r_tag)
{
GpgmeError err;
fd_table_t fdt = (fd_table_t) (data ? data : &fdt_global);
@ -344,9 +344,10 @@ _gpgme_add_io_cb (void *data, int fd, int dir,
assert (fdt);
assert (fnc);
*r_tag = NULL;
tag = xtrymalloc (sizeof *tag);
if (!tag)
return NULL;
return mk_error (Out_Of_Core);
tag->fdt = fdt;
/* Allocate a structure to hold info about the handler. */
@ -354,7 +355,7 @@ _gpgme_add_io_cb (void *data, int fd, int dir,
if (!item)
{
xfree (tag);
return NULL;
return mk_error (Out_Of_Core);
}
item->dir = dir;
item->handler = fnc;
@ -365,11 +366,11 @@ _gpgme_add_io_cb (void *data, int fd, int dir,
{
xfree (tag);
xfree (item);
errno = ENOMEM;
return 0;
return mk_error (Out_Of_Core);
}
return tag;
*r_tag = tag;
return 0;
}
void

View File

@ -36,8 +36,8 @@ typedef struct fd_table *fd_table_t;
void _gpgme_fd_table_init (fd_table_t fdt);
void _gpgme_fd_table_deinit (fd_table_t fdt);
void *_gpgme_add_io_cb (void *data, int fd, int dir,
GpgmeIOCb fnc, void *fnc_data);
GpgmeError _gpgme_add_io_cb (void *data, int fd, int dir,
GpgmeIOCb fnc, void *fnc_data, void **r_tag);
void _gpgme_remove_io_cb (void *tag);
void _gpgme_wait_event_cb (void *data, GpgmeEventIO type, void *type_data);