diff options
| author | Marcus Brinkmann <[email protected]> | 2001-11-15 21:32:09 +0000 | 
|---|---|---|
| committer | Marcus Brinkmann <[email protected]> | 2001-11-15 21:32:09 +0000 | 
| commit | 9144124a610015d3ef17e59828cdcca84d18ab39 (patch) | |
| tree | c9480a66c2b25b52ae2bf28b6f8cb198d9363cc4 | |
| parent | 2001-11-11 Marcus Brinkmann <[email protected]> (diff) | |
| download | gpgme-9144124a610015d3ef17e59828cdcca84d18ab39.tar.gz gpgme-9144124a610015d3ef17e59828cdcca84d18ab39.zip | |
2001-11-15  Marcus Brinkmann  <[email protected]>
	* 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.
| -rw-r--r-- | gpgme/ChangeLog | 34 | ||||
| -rw-r--r-- | gpgme/context.h | 12 | ||||
| -rw-r--r-- | gpgme/decrypt.c | 120 | ||||
| -rw-r--r-- | gpgme/encrypt.c | 45 | ||||
| -rw-r--r-- | gpgme/gpgme.c | 29 | ||||
| -rw-r--r-- | gpgme/sign.c | 77 | ||||
| -rw-r--r-- | gpgme/verify.c | 169 | 
7 files changed, 240 insertions, 246 deletions
| diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 664bab76..bb65b6b3 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,37 @@ +2001-11-15  Marcus Brinkmann  <[email protected]> + +	* 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  <[email protected]>  	* rungpg.c (_gpgme_gpg_release): Release GPG->cmd.cb_data. diff --git a/gpgme/context.h b/gpgme/context.h index 0f2de347..9a004990 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -26,15 +26,6 @@  #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; diff --git a/gpgme/decrypt.c b/gpgme/decrypt.c index 5982301b..0b1b8963 100644 --- a/gpgme/decrypt.c +++ b/gpgme/decrypt.c @@ -29,53 +29,50 @@  #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;  } - - - - - - - - - diff --git a/gpgme/encrypt.c b/gpgme/encrypt.c index 3dc7eb03..2179443e 100644 --- a/gpgme/encrypt.c +++ b/gpgme/encrypt.c @@ -36,22 +36,21 @@          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);          } diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 870c80b8..8c0b7041 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -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);  } diff --git a/gpgme/sign.c b/gpgme/sign.c index b92ea806..2f0de1d1 100644 --- a/gpgme/sign.c +++ b/gpgme/sign.c @@ -36,30 +36,28 @@          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;      } diff --git a/gpgme/verify.c b/gpgme/verify.c index ededc580..b7692d10 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -30,29 +30,32 @@  #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;  } - - - - - - | 
