From f14941f072e35f2cd04a5733435bb0eeb8b7399f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 10 Nov 2000 20:56:02 +0000 Subject: [PATCH] keylist does now return objects. --- gpgme/context.h | 10 ++++++- gpgme/gpgme.c | 1 + gpgme/gpgme.h | 4 +++ gpgme/keylist.c | 72 +++++++++++++++++++++++++++++++++++++++++------ gpgme/ops.h | 4 +++ gpgme/types.h | 2 -- gpgme/wait.c | 16 +++++++++-- tests/t-keylist.c | 8 +++++- 8 files changed, 102 insertions(+), 15 deletions(-) diff --git a/gpgme/context.h b/gpgme/context.h index ab5a2d3d..4f35625f 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -31,6 +31,12 @@ typedef enum { } ResultType; +struct key_queue_item_s { + struct key_queue_item_s *next; + GpgmeKey key; +}; + + /* Currently we need it at several places, so we put the definition * into this header file */ struct gpgme_context_s { @@ -54,7 +60,9 @@ struct gpgme_context_s { VerifyResult verify; } result; - GpgmeKey tmp_key; /* used by keylist.c */ + GpgmeKey tmp_key; /* used by keylist.c */ + volatile int key_cond; /* something new is available */ + struct key_queue_item_s *key_queue; }; diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 8a8cbb27..09834592 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -62,6 +62,7 @@ gpgme_release_context ( GpgmeCtx c ) _gpgme_gpg_release_object ( c->gpg ); _gpgme_release_result ( c ); _gpgme_key_release ( c->tmp_key ); + /* fixme: release the key_queue */ xfree ( c ); } diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 32a925fc..c32449c4 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -36,6 +36,9 @@ typedef struct gpgme_data_s *GpgmeData; struct gpgme_recipient_set_s; typedef struct gpgme_recipient_set_s *GpgmeRecipientSet; +struct gpgme_key_s; +typedef struct gpgme_key_s *GpgmeKey; + typedef enum { GPGME_EOF = -1, @@ -97,6 +100,7 @@ GpgmeError gpgme_start_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text ); /* Key management functions */ GpgmeError gpgme_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only ); +GpgmeError gpgme_keylist_next ( GpgmeCtx c, GpgmeKey *r_key ); diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 1e7d5b12..61465894 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -127,8 +127,6 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line ) if (!line) return; /* EOF */ - fprintf (stderr, "line=`%s'\n", line ); - for (p = line; p; p = pend) { field++; pend = strchr (p, ':'); @@ -254,20 +252,35 @@ finish_key ( GpgmeCtx ctx ) { GpgmeKey key = ctx->tmp_key; struct user_id_s *u; + struct key_queue_item_s *q, *q2; assert (key); ctx->tmp_key = NULL; - fprintf (stderr, "finish_key: keyid=`%s'\n", key->keyid ); + fprintf (stdout, "finish_key: keyid=`%s'\n", key->keyid ); if ( key->fingerprint ) - fprintf (stderr, "finish_key: fpr=`%s'\n", key->fingerprint ); + fprintf (stdout, "finish_key: fpr=`%s'\n", key->fingerprint ); for (u=key->uids; u; u = u->next ) - fprintf (stderr, "finish_key: uid=`%s'\n", u->name ); + fprintf (stdout, "finish_key: uid=`%s'\n", u->name ); - - /* fixme: call the callback or do something else with the key */ - - _gpgme_key_release (key); + q = xtrymalloc ( sizeof *q ); + if ( !q ) { + _gpgme_key_release (key); + ctx->out_of_core = 1; + return; + } + q->key = key; + q->next = NULL; + /* fixme: lock queue */ + 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 */ } @@ -291,6 +304,7 @@ gpgme_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only ) } _gpgme_key_release (c->tmp_key); c->tmp_key = NULL; + /* Fixme: release key_queue */ rc = _gpgme_gpg_new_object ( &c->gpg ); if (rc) @@ -328,6 +342,46 @@ gpgme_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only ) } +GpgmeError +gpgme_keylist_next ( GpgmeCtx c, GpgmeKey *r_key ) +{ + struct key_queue_item_s *q; + + if (!r_key) + return mk_error (Invalid_Value); + *r_key = NULL; + if (!c) + return mk_error (Invalid_Value); + if ( !c->pending ) + return mk_error (No_Request); + if ( c->out_of_core ) + return mk_error (Out_Of_Core); + + if ( !c->key_queue ) { + _gpgme_wait_on_condition (c, 1, &c->key_cond ); + if ( c->out_of_core ) + return mk_error (Out_Of_Core); + if ( !c->key_cond ) + return mk_error (EOF); + c->key_cond = 0; + assert ( c->key_queue ); + } + q = c->key_queue; + c->key_queue = q->next; + + *r_key = q->key; + xfree (q); + return 0; +} + + + + + + + + + diff --git a/gpgme/ops.h b/gpgme/ops.h index 020f0fae..92e44bad 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -26,6 +26,10 @@ /*-- gpgme.c --*/ void _gpgme_release_result ( GpgmeCtx c ); +/*-- wait.c --*/ +GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c, + int hang, volatile int *cond ); + /*-- recipient.c --*/ void _gpgme_append_gpg_args_from_recipients ( diff --git a/gpgme/types.h b/gpgme/types.h index 045fd7e4..34103bce 100644 --- a/gpgme/types.h +++ b/gpgme/types.h @@ -48,8 +48,6 @@ struct verify_result_s; typedef struct verify_result_s *VerifyResult; /*-- key.c --*/ -struct gpgme_key_s; -typedef struct gpgme_key_s *GpgmeKey; #endif /* TYPES_H */ diff --git a/gpgme/wait.c b/gpgme/wait.c index a84c7465..a3c50930 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -31,6 +31,7 @@ #include "util.h" #include "context.h" +#include "ops.h" #include "wait.h" /* Fixme: implement the following stuff to make the code MT safe. @@ -159,13 +160,24 @@ remove_process ( pid_t pid ) * and no (or the given) request has finished. **/ GpgmeCtx -gpgme_wait ( GpgmeCtx c, int hang ) +gpgme_wait ( GpgmeCtx c, int hang ) +{ + return _gpgme_wait_on_condition ( c, hang, NULL ); +} + +GpgmeCtx +_gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond ) { struct wait_queue_item_s *q; init_wait_queue (); do { - if ( !the_big_select() ) { + int did_work = the_big_select(); + + if ( cond && *cond ) + hang = 0; + + if ( !did_work ) { int status; /* We did no read/write - see whether this process is still diff --git a/tests/t-keylist.c b/tests/t-keylist.c index 43ad3237..ba47d39c 100644 --- a/tests/t-keylist.c +++ b/tests/t-keylist.c @@ -35,10 +35,16 @@ static void doit ( GpgmeCtx ctx, const char *pattern ) { GpgmeError err; + GpgmeKey key; err = gpgme_keylist_start (ctx, pattern, 0 ); fail_if_err (err); - gpgme_wait (ctx, 1); + + while ( !(err = gpgme_keylist_next ( ctx, &key )) ) { + printf ("Got key object (%p)\n", key ); + } + if ( err != GPGME_EOF ) + fail_if_err (err); }