2001-11-15 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Thu, 15 Nov 2001 21:32:09 +0000 (21:32 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Thu, 15 Nov 2001 21:32:09 +0000 (21:32 +0000)
* verify.c (_gpgme_release_verify_result): Rename RES to RESULT.
Rename R2 to NEXT_RESULT.
(intersect_stati): Rename RES to RESULT.
(gpgme_get_sig_status): Likewise.  Do not check return_type, but
the member verify of result.
(gpgme_get_sig_key): Likewise.

* sign.c (_gpgme_release_sign_result): Rename RES to RESULT.  If
RESULT is zero, return.
(sign_status_handler, command_handler): Do not check return_type,
but the member sign of result.
(gpgme_op_sign): Likewise.  Drop assertion.

* encrypt.c (_gpgme_release_encrypt_result): Rename RES to RESULT.
If RESULT is zero, return.
(encrypt_status_handler): Do not check return_type, but the member
encrypt of result.
(gpgme_op_encrypt): Likewise.  Drop assertion.

* decrypt.c (_gpgme_release_decrypt_result): Rename RES to RESULT.
(create_result_struct): Do not set result_type.
(command_handler, decrypt_status_handler): Do not check
return_type, but the member decrypt of result.
(gpgme_op_decrypt): Likewise.  Drop assertion.

* context.h (enum ResultType): Removed.
(struct gpgme_context_s): Remove member result_type.
(struct result): Replaces union result.
* gpgme.c: Include string.h.
(_gpgme_release_result): Release all members of c->result, which
is now a struct.  Zero out all members of the struct afterwards.

gpgme/ChangeLog
gpgme/context.h
gpgme/decrypt.c
gpgme/encrypt.c
gpgme/gpgme.c
gpgme/sign.c
gpgme/verify.c

index 664bab768a83ff1b300d4424152b1c4949dafa69..bb65b6b32ff063f740b18867baeacbfa9287ee0d 100644 (file)
@@ -1,3 +1,37 @@
+2001-11-15  Marcus Brinkmann  <marcus@g10code.de>
+
+       * verify.c (_gpgme_release_verify_result): Rename RES to RESULT.
+       Rename R2 to NEXT_RESULT.
+       (intersect_stati): Rename RES to RESULT.
+       (gpgme_get_sig_status): Likewise.  Do not check return_type, but
+       the member verify of result.
+       (gpgme_get_sig_key): Likewise.
+
+       * sign.c (_gpgme_release_sign_result): Rename RES to RESULT.  If
+       RESULT is zero, return.
+       (sign_status_handler, command_handler): Do not check return_type,
+       but the member sign of result.
+       (gpgme_op_sign): Likewise.  Drop assertion.
+
+       * encrypt.c (_gpgme_release_encrypt_result): Rename RES to RESULT.
+       If RESULT is zero, return.
+       (encrypt_status_handler): Do not check return_type, but the member
+       encrypt of result.
+       (gpgme_op_encrypt): Likewise.  Drop assertion.
+
+       * decrypt.c (_gpgme_release_decrypt_result): Rename RES to RESULT.
+       (create_result_struct): Do not set result_type.
+       (command_handler, decrypt_status_handler): Do not check
+       return_type, but the member decrypt of result.
+       (gpgme_op_decrypt): Likewise.  Drop assertion.
+
+       * context.h (enum ResultType): Removed.
+       (struct gpgme_context_s): Remove member result_type.
+       (struct result): Replaces union result.
+       * gpgme.c: Include string.h.
+       (_gpgme_release_result): Release all members of c->result, which
+       is now a struct.  Zero out all members of the struct afterwards.
+
 2001-11-11  Marcus Brinkmann  <marcus@g10code.de>
 
        * rungpg.c (_gpgme_gpg_release): Release GPG->cmd.cb_data.
index 0f2de347f16bd4f80cbb9af027a509fa5cdf9bfd..9a0049901b1a16d9f2478f5a17d418aba4a12fcd 100644 (file)
 #include "types.h"
 #include "rungpg.h"  /* for GpgObject */
 
-typedef enum {
-    RESULT_TYPE_NONE = 0,
-    RESULT_TYPE_VERIFY,
-    RESULT_TYPE_DECRYPT,
-    RESULT_TYPE_SIGN,
-    RESULT_TYPE_ENCRYPT
-} ResultType;
-
-
 struct key_queue_item_s {
     struct key_queue_item_s *next;
     GpgmeKey key;
@@ -71,8 +62,7 @@ struct gpgme_context_s {
     int signers_size;  /* size of the following array */
     GpgmeKey *signers;
 
-    ResultType result_type;
-    union {
+    struct {
         VerifyResult verify;
         DecryptResult decrypt;
         SignResult sign;
index 5982301b10f103f036a1e237b46b884c00585056..0b1b896383f01a76fdc821ac3aa60b69325ef9ec 100644 (file)
 #include "context.h"
 #include "ops.h"
 
-
-struct decrypt_result_s {
-    int no_passphrase;
-    int okay;
-    int failed;
-    void *last_pw_handle;
-    char *userid_hint;
-    char *passphrase_info;
-    int bad_passphrase;
+struct decrypt_result_s
+{
+  int no_passphrase;
+  int okay;
+  int failed;
+  void *last_pw_handle;
+  char *userid_hint;
+  char *passphrase_info;
+  int bad_passphrase;
 };
 
-
 void
-_gpgme_release_decrypt_result ( DecryptResult res )
+_gpgme_release_decrypt_result (DecryptResult result)
 {
-    if (!res )
-        return;
-    xfree (res->passphrase_info);
-    xfree (res->userid_hint);
-    xfree (res);
+  if (!result)
+    return;
+  xfree (result->passphrase_info);
+  xfree (result->userid_hint);
+  xfree (result);
 }
 
-
 static GpgmeError
-create_result_struct ( GpgmeCtx ctx )
+create_result_struct (GpgmeCtx ctx)
 {
-    assert ( !ctx->result.decrypt );
-    ctx->result.decrypt = xtrycalloc ( 1, sizeof *ctx->result.decrypt );
-    if ( !ctx->result.decrypt ) {
-        return mk_error (Out_Of_Core);
-    }
-    ctx->result_type = RESULT_TYPE_DECRYPT;
-    return 0;    
+  assert (!ctx->result.decrypt);
+  ctx->result.decrypt = xtrycalloc (1, sizeof *ctx->result.decrypt);
+  if (!ctx->result.decrypt)
+    return mk_error (Out_Of_Core);
+  return 0;    
 }
 
 static void
-decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
+decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 {
     if ( ctx->out_of_core )
         return;
-    if ( ctx->result_type == RESULT_TYPE_NONE ) {
-        if ( create_result_struct ( ctx ) ) {
+    if (! ctx->result.decrypt)
+      {
+        if (create_result_struct (ctx))
+         {
             ctx->out_of_core = 1;
             return;
-        }
-    }
-    assert ( ctx->result_type == RESULT_TYPE_DECRYPT );
+         }
+      }
 
     switch (code) {
       case STATUS_EOF:
@@ -124,16 +121,18 @@ decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
 
 
 static const char *
-command_handler ( void *opaque, GpgStatusCode code, const char *key )
+command_handler (void *opaque, GpgStatusCode code, const char *key)
 {
     GpgmeCtx c = opaque;
 
-    if ( c->result_type == RESULT_TYPE_NONE ) {
-        if ( create_result_struct ( c ) ) {
+    if (! c->result.decrypt)
+      {
+        if (create_result_struct (c))
+         {
             c->out_of_core = 1;
-            return NULL;
-        }
-    }
+            return;
+         }
+      }
 
     if ( !code ) {
         /* We have been called for cleanup */
@@ -258,35 +257,26 @@ gpgme_op_decrypt_start ( GpgmeCtx c,
  * Return value:  0 on success or an errorcode. 
  **/
 GpgmeError
-gpgme_op_decrypt ( GpgmeCtx c,
-                   GpgmeData in, GpgmeData out )
+gpgme_op_decrypt (GpgmeCtx c, GpgmeData in, GpgmeData out)
 {
-    GpgmeError err = gpgme_op_decrypt_start ( c, in, out );
-    if ( !err ) {
-        gpgme_wait (c, 1);
-        if ( c->result_type != RESULT_TYPE_DECRYPT )
-            err = mk_error (General_Error);
-        else if ( c->out_of_core )
-            err = mk_error (Out_Of_Core);
-        else {
-            assert ( c->result.decrypt );
-            if ( c->result.decrypt->no_passphrase ) 
-                err = mk_error (No_Passphrase);
-            else if ( c->result.decrypt->failed ) 
-                err = mk_error (Decryption_Failed);
-            else if (!c->result.decrypt->okay)
-                err = mk_error (No_Data);
+  GpgmeError err = gpgme_op_decrypt_start (c, in, out);
+  if (!err)
+    {
+      gpgme_wait (c, 1);
+      if (!c->result.decrypt)
+       err = mk_error (General_Error);
+      else if (c->out_of_core)
+       err = mk_error (Out_Of_Core);
+      else
+       {
+         if (c->result.decrypt->no_passphrase)
+           err = mk_error (No_Passphrase);
+         else if (c->result.decrypt->failed)
+           err = mk_error (Decryption_Failed);
+         else if (!c->result.decrypt->okay)
+           err = mk_error (No_Data);
         }
-        c->pending = 0;
+      c->pending = 0;
     }
-    return err;
+  return err;
 }
-
-
-
-
-
-
-
-
-
index 3dc7eb035553ad6e053602724a946afcd8dc1f79..2179443ed178a500ce6d9fbd8471926b3861ce99 100644 (file)
         return; /* oops */ \
 } while (0)
 
-
-
-struct encrypt_result_s {
-    int no_recipients;
-    GpgmeData xmlinfo;
+struct encrypt_result_s
+{
+  int no_recipients;
+  GpgmeData xmlinfo;
 };
 
-
 void
-_gpgme_release_encrypt_result (EncryptResult res)
+_gpgme_release_encrypt_result (EncryptResult result)
 {
-    gpgme_data_release (res->xmlinfo);
-    xfree (res);
+  if (!result)
+    return;
+  gpgme_data_release (result->xmlinfo);
+  xfree (result);
 }
 
-
 /* 
  * Parse the args and save the information 
  * in an XML structure.
@@ -99,20 +98,19 @@ append_xml_encinfo (GpgmeData *rdh, char *args)
 
 
 static void
-encrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
+encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 {
-    if ( ctx->out_of_core )
-        return;
-    if ( ctx->result_type == RESULT_TYPE_NONE ) {
-        assert ( !ctx->result.encrypt );
-        ctx->result.encrypt = xtrycalloc ( 1, sizeof *ctx->result.encrypt );
-        if ( !ctx->result.encrypt ) {
+    if (ctx->out_of_core)
+      return;
+    if (!ctx->result.encrypt)
+      {
+        ctx->result.encrypt = xtrycalloc (1, sizeof *ctx->result.encrypt);
+        if (!ctx->result.encrypt)
+         {
             ctx->out_of_core = 1;
             return;
-        }
-        ctx->result_type = RESULT_TYPE_ENCRYPT;
-    }
-    assert ( ctx->result_type == RESULT_TYPE_ENCRYPT );
+         }
+      }
 
     switch (code) {
       case STATUS_EOF:
@@ -230,12 +228,11 @@ gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
     int err = gpgme_op_encrypt_start ( c, recp, in, out );
     if ( !err ) {
         gpgme_wait (c, 1);
-        if ( c->result_type != RESULT_TYPE_ENCRYPT )
+        if (!c->result.encrypt)
             err = mk_error (General_Error);
-        else if ( c->out_of_core )
+        else if (c->out_of_core)
             err = mk_error (Out_Of_Core);
         else {
-            assert ( c->result.encrypt );
             if (c->result.encrypt->no_recipients) 
                 err = mk_error (No_Recipients);
         }
index 870c80b8ca22daa4128c400e788de13854e8d30e..8c0b704156e24598d3164ba3ba3859a54754a348 100644 (file)
@@ -22,6 +22,7 @@
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <assert.h>
 
 #include "util.h"
@@ -81,28 +82,14 @@ gpgme_release ( GpgmeCtx c )
 
 
 void
-_gpgme_release_result ( GpgmeCtx c )
+_gpgme_release_result (GpgmeCtx c)
 {
-    switch (c->result_type) {
-      case RESULT_TYPE_NONE:
-        break;
-      case RESULT_TYPE_VERIFY:
-        _gpgme_release_verify_result ( c->result.verify );
-        break;
-      case RESULT_TYPE_DECRYPT:
-        _gpgme_release_decrypt_result ( c->result.decrypt );
-        break;
-      case RESULT_TYPE_SIGN:
-        _gpgme_release_sign_result ( c->result.sign );
-        break;
-      case RESULT_TYPE_ENCRYPT:
-        _gpgme_release_encrypt_result ( c->result.encrypt );
-        break;
-    }
-
-    c->result.verify = NULL;
-    c->result_type = RESULT_TYPE_NONE;
-    _gpgme_set_op_info (c, NULL);
+  _gpgme_release_verify_result (c->result.verify);
+  _gpgme_release_decrypt_result (c->result.decrypt);
+  _gpgme_release_sign_result (c->result.sign);
+  _gpgme_release_encrypt_result (c->result.encrypt);
+  memset (&c->result, 0, sizeof (c->result));
+  _gpgme_set_op_info (c, NULL);
 }
 
 
index b92ea806520f7d1b8b57a0ba1086e9b2b7be6b47..2f0de1d15669afc0554985d6d37aecb809887480 100644 (file)
         return; /* oops */ \
 } while (0)
 
-
-
-
-struct  sign_result_s {
-    int no_passphrase;
-    int okay;
-    void *last_pw_handle;
-    char *userid_hint;
-    char *passphrase_info;
-    int bad_passphrase;
-    GpgmeData xmlinfo;
+struct sign_result_s
+{
+  int no_passphrase;
+  int okay;
+  void *last_pw_handle;
+  char *userid_hint;
+  char *passphrase_info;
+  int bad_passphrase;
+  GpgmeData xmlinfo;
 };
 
-
 void
-_gpgme_release_sign_result ( SignResult res )
+_gpgme_release_sign_result (SignResult result)
 {
-    gpgme_data_release (res->xmlinfo);
-    xfree (res->userid_hint);
-    xfree (res->passphrase_info);
-    xfree (res);
+  if (!result)
+    return;
+  gpgme_data_release (result->xmlinfo);
+  xfree (result->userid_hint);
+  xfree (result->passphrase_info);
+  xfree (result);
 }
 
-
 /* parse the args and save the information 
  * <type> <pubkey algo> <hash algo> <class> <timestamp> <key fpr>
  * in an XML structure.  With args of NULL the xml structure is closed.
@@ -141,20 +139,19 @@ append_xml_siginfo (GpgmeData *rdh, char *args)
 
 
 static void
-sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
+sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 {
-    if ( ctx->out_of_core )
+    if (ctx->out_of_core)
         return;
-    if ( ctx->result_type == RESULT_TYPE_NONE ) {
-        assert ( !ctx->result.sign );
-        ctx->result.sign = xtrycalloc ( 1, sizeof *ctx->result.sign );
-        if ( !ctx->result.sign ) {
+    if (!ctx->result.sign)
+      {
+        ctx->result.sign = xtrycalloc (1, sizeof *ctx->result.sign);
+        if (!ctx->result.sign)
+         {
             ctx->out_of_core = 1;
             return;
-        }
-        ctx->result_type = RESULT_TYPE_SIGN;
-    }
-    assert ( ctx->result_type == RESULT_TYPE_SIGN );
+         }
+      }
 
     switch (code) {
       case STATUS_EOF:
@@ -207,15 +204,15 @@ command_handler ( void *opaque, GpgStatusCode code, const char *key )
 {
     GpgmeCtx c = opaque;
 
-    if ( c->result_type == RESULT_TYPE_NONE ) {
-        assert ( !c->result.sign );
-        c->result.sign = xtrycalloc ( 1, sizeof *c->result.sign );
-        if ( !c->result.sign ) {
+    if (!c->result.sign)
+      {
+        c->result.sign = xtrycalloc (1, sizeof *c->result.sign);
+        if (!c->result.sign)
+         {
             c->out_of_core = 1;
             return NULL;
-        }
-        c->result_type = RESULT_TYPE_SIGN;
-    }
+         }
+      }
 
     if ( !code ) {
         /* We have been called for cleanup */
@@ -373,22 +370,20 @@ gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out,
  * Return value: 0 on success or an error code.
  **/
 GpgmeError
-gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out, GpgmeSigMode mode )
+gpgme_op_sign (GpgmeCtx c, GpgmeData in, GpgmeData out, GpgmeSigMode mode)
 {
     GpgmeError err = gpgme_op_sign_start ( c, in, out, mode );
     if ( !err ) {
         gpgme_wait (c, 1);
-        if ( c->result_type != RESULT_TYPE_SIGN )
+        if (!c->result.sign)
             err = mk_error (General_Error);
-        else if ( c->out_of_core )
+        else if (c->out_of_core)
             err = mk_error (Out_Of_Core);
         else {
-            assert ( c->result.sign );
-            if ( c->result.sign->no_passphrase ) 
+            if (c->result.sign->no_passphrase)
                 err = mk_error (No_Passphrase);
             else if (!c->result.sign->okay)
                 err = mk_error (No_Data); /* Hmmm: choose a better error? */
-            
         }
         c->pending = 0;
     }
index ededc580c61d3574235f6cec96f9355f0749e731..b7692d10320d8c07ca1e8c0572a19df740d1f869 100644 (file)
 #include "ops.h"
 #include "key.h"
 
-struct verify_result_s {
-    struct verify_result_s *next;
-    GpgmeSigStat status;
-    GpgmeData notation; /* we store an XML fragment here */
-    int collecting;       /* private to finish_sig() */
-    int notation_in_data; /* private to add_notation() */
-    char fpr[41];    /* fingerprint of a good signature or keyid of a bad one*/
-    ulong timestamp; /* signature creation time */
+struct verify_result_s
+{
+  struct verify_result_s *next;
+  GpgmeSigStat status;
+  GpgmeData notation;  /* We store an XML fragment here.  */
+  int collecting;      /* Private to finish_sig().  */
+  int notation_in_data;        /* Private to add_notation().  */
+  char fpr[41];                /* Fingerprint of a good signature or keyid of
+                          a bad one.  */
+  ulong timestamp;     /* Signature creation time.  */
 };
 
 
 void
-_gpgme_release_verify_result ( VerifyResult res )
+_gpgme_release_verify_result (VerifyResult result)
 {
-    while (res) {
-        VerifyResult r2 = res->next;
-        gpgme_data_release ( res->notation );
-        xfree (res);
-        res = r2;
+  while (result)
+    {
+      VerifyResult next_result = result->next;
+      gpgme_data_release (result->notation);
+      xfree (result);
+      result = next_result;
     }
 }
 
-/* fixme: check that we are adding this to the correct signature */
+/* FIXME: Check that we are adding this to the correct signature.  */
 static void
 add_notation ( GpgmeCtx ctx, GpgStatusCode code, const char *data )
 {
@@ -133,16 +136,15 @@ verify_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
 
     if ( ctx->out_of_core )
         return;
-    if ( ctx->result_type == RESULT_TYPE_NONE ) {
-        assert ( !ctx->result.verify );
-        ctx->result.verify = xtrycalloc ( 1, sizeof *ctx->result.verify );
-        if ( !ctx->result.verify ) {
+    if (!ctx->result.verify)
+      {
+        ctx->result.verify = xtrycalloc (1, sizeof *ctx->result.verify);
+        if (!ctx->result.verify)
+         {
             ctx->out_of_core = 1;
             return;
-        }
-        ctx->result_type = RESULT_TYPE_VERIFY;
-    }
-    assert ( ctx->result_type == RESULT_TYPE_VERIFY );
+         }
+      }
 
     if (code == STATUS_GOODSIG
         || code == STATUS_BADSIG || code == STATUS_ERRSIG) {
@@ -293,15 +295,16 @@ gpgme_op_verify_start ( GpgmeCtx c,  GpgmeData sig, GpgmeData text )
  * Figure out a common status value for all signatures 
  */
 static GpgmeSigStat
-intersect_stati ( VerifyResult res )
+intersect_stati (VerifyResult result)
 {
-    GpgmeSigStat status = res->status;
+  GpgmeSigStat status = result->status;
 
-    for (res=res->next; res; res = res->next) {
-        if (status != res->status ) 
-            return GPGME_SIG_STAT_DIFF;
+  for (result = result->next; result; result = result->next)
+    {
+      if (status != result->status) 
+       return GPGME_SIG_STAT_DIFF;
     }
-    return status;
+  return status;
 }
 
 /**
@@ -344,13 +347,12 @@ gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
     rc = gpgme_op_verify_start ( c, sig, text );
     if ( !rc ) {
         gpgme_wait (c, 1);
-        if ( c->result_type != RESULT_TYPE_VERIFY )
+        if (!c->result.verify)
             rc = mk_error (General_Error);
-        else if ( c->out_of_core )
+        else if (c->out_of_core)
             rc = mk_error (Out_Of_Core);
         else {
-            assert ( c->result.verify );
-            /* fixme: Put all notation data into one XML fragment */
+            /* FIXME: Put all notation data into one XML fragment.  */
             if ( c->result.verify->notation ) {
                 GpgmeData dh = c->result.verify->notation;
                 
@@ -384,23 +386,24 @@ gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
  **/
 const char *
 gpgme_get_sig_status (GpgmeCtx c, int idx,
-                      GpgmeSigStat *r_stat, time_t *r_created )
+                      GpgmeSigStat *r_stat, time_t *r_created)
 {
-    VerifyResult res;
-
-    if (!c || c->pending || c->result_type != RESULT_TYPE_VERIFY )
-        return NULL; /* No results yet or verification error */
-
-    for (res = c->result.verify; res && idx>0 ; res = res->next, idx--)
-        ;
-    if (!res)
-        return NULL; /* No more signatures */
-
-    if (r_stat)
-        *r_stat = res->status;
-    if (r_created)
-        *r_created = res->timestamp;
-    return res->fpr;
+  VerifyResult result;
+
+  if (!c || c->pending || !c->result.verify)
+    return NULL;       /* No results yet or verification error.  */
+
+  for (result = c->result.verify;
+       result && idx > 0; result = result->next, idx--)
+    ;
+  if (!result)
+    return NULL;       /* No more signatures.  */
+
+  if (r_stat)
+    *r_stat = result->status;
+  if (r_created)
+    *r_created = result->timestamp;
+  return result->fpr;
 }
 
 
@@ -418,40 +421,38 @@ gpgme_get_sig_status (GpgmeCtx c, int idx,
 GpgmeError
 gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key)
 {
-    VerifyResult res;
-    GpgmeError err = 0;
-
-    if (!c || !r_key)
-        return mk_error (Invalid_Value);
-    if (c->pending || c->result_type != RESULT_TYPE_VERIFY )
-        return mk_error (Busy);
-
-    for (res = c->result.verify; res && idx>0 ; res = res->next, idx--)
-        ;
-    if (!res)
-        return mk_error (EOF);
-
-    if (strlen(res->fpr) < 16) /* we have at least an key ID */
-        return mk_error (Invalid_Key);
-
-    *r_key = _gpgme_key_cache_get (res->fpr);
-    if (!*r_key) {
-        GpgmeCtx listctx;
-
-        /* Fixme: This can be optimized by keeping
-         *        an internal context used for such key listings */
-        if ( (err=gpgme_new (&listctx)) )
-            return err;
-        gpgme_set_keylist_mode( listctx, c->keylist_mode );
-        if ( !(err=gpgme_op_keylist_start (listctx, res->fpr, 0 )) )
-            err=gpgme_op_keylist_next ( listctx, r_key );
-        gpgme_release (listctx);
+  VerifyResult result;
+  GpgmeError err = 0;
+
+  if (!c || !r_key)
+    return mk_error (Invalid_Value);
+  if (c->pending || !c->result.verify)
+    return mk_error (Busy);
+  
+  for (result = c->result.verify;
+       result && idx > 0; result = result->next, idx--)
+    ;
+  if (!result)
+    return mk_error (EOF);
+  
+  if (strlen(result->fpr) < 16)        /* We have at least a key ID.  */
+    return mk_error (Invalid_Key);
+  
+  *r_key = _gpgme_key_cache_get (result->fpr);
+  if (!*r_key)
+    {
+      GpgmeCtx listctx;
+      
+      /* Fixme: This can be optimized by keeping an internal context
+        used for such key listings.  */
+      err = gpgme_new (&listctx);
+      if (err)
+       return err;
+      gpgme_set_keylist_mode (listctx, c->keylist_mode);
+      err = gpgme_op_keylist_start (listctx, result->fpr, 0);
+      if (!err)
+       err = gpgme_op_keylist_next (listctx, r_key);
+      gpgme_release (listctx);
     }
-    return err;
+  return err;
 }
-
-
-
-
-
-