aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gpgme/context.h10
-rw-r--r--gpgme/gpgme.c1
-rw-r--r--gpgme/gpgme.h4
-rw-r--r--gpgme/keylist.c72
-rw-r--r--gpgme/ops.h4
-rw-r--r--gpgme/types.h2
-rw-r--r--gpgme/wait.c16
-rw-r--r--tests/t-keylist.c8
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);
}