diff options
| -rw-r--r-- | gpgme/context.h | 10 | ||||
| -rw-r--r-- | gpgme/gpgme.c | 1 | ||||
| -rw-r--r-- | gpgme/gpgme.h | 4 | ||||
| -rw-r--r-- | gpgme/keylist.c | 72 | ||||
| -rw-r--r-- | gpgme/ops.h | 4 | ||||
| -rw-r--r-- | gpgme/types.h | 2 | ||||
| -rw-r--r-- | gpgme/wait.c | 16 | ||||
| -rw-r--r-- | 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);  } | 
