diff options
Diffstat (limited to '')
| -rw-r--r-- | gpgme/keylist.c | 512 | 
1 files changed, 229 insertions, 283 deletions
| diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 54ce4a97..84ac8e31 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -28,89 +28,80 @@  #include <assert.h>  #include <ctype.h> +#include "gpgme.h"  #include "util.h"  #include "context.h"  #include "ops.h" -#include "key.h"  #include "debug.h" -struct keylist_result +struct key_queue_item_s  { -  int truncated; -  GpgmeData xmlinfo; +  struct key_queue_item_s *next; +  GpgmeKey key;  }; -typedef struct keylist_result *KeylistResult; -static void -release_keylist_result (void *hook) +typedef struct  { -  KeylistResult result = (KeylistResult) hook; +  struct _gpgme_op_keylist_result result; -  if (result->xmlinfo) -    gpgme_data_release (result->xmlinfo); -} +  GpgmeKey tmp_key; +  GpgmeUserID tmp_uid; +  /* Something new is available.  */ +  int key_cond; +  struct key_queue_item_s *key_queue; +} *op_data_t; -/* Append some XML info.  args is currently ignore but we might want -   to add more information in the future (like source of the -   keylisting.  With args of NULL the XML structure is closed.  */  static void -append_xml_keylistinfo (GpgmeData *rdh, char *args) +release_op_data (void *hook)  { -  GpgmeData dh; - -  if (!*rdh) -    { -      if (gpgme_data_new (rdh)) -	return; /* FIXME: We are ignoring out-of-core.  */ -      dh = *rdh; -      _gpgme_data_append_string (dh, "<GnupgOperationInfo>\n"); -    } -  else +  op_data_t opd = (op_data_t) hook; +  struct key_queue_item_s *key = opd->key_queue; + +  if (opd->tmp_key) +    gpgme_key_unref (opd->tmp_key); +  if (opd->tmp_uid) +    free (opd->tmp_uid); +  while (key)      { -      dh = *rdh; -      _gpgme_data_append_string (dh, "  </keylisting>\n"); -    } +      struct key_queue_item_s *next = key->next; -  if (!args) -    { -      /* Just close the XML containter.  */ -      _gpgme_data_append_string (dh, "</GnupgOperationInfo>\n"); -      return; +      gpgme_key_unref (key->key); +      key = next;      } - -  _gpgme_data_append_string (dh, "  <keylisting>\n    <truncated/>\n"); -      } +GpgmeKeyListResult +gpgme_op_keylist_result (GpgmeCtx ctx) +{ +  op_data_t opd; +  GpgmeError err; + +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL); +  if (err || !opd) +    return NULL; + +  return &opd->result; +} + +  static GpgmeError -keylist_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args) +keylist_status_handler (void *priv, GpgmeStatusCode code, char *args)  { +  GpgmeCtx ctx = (GpgmeCtx) priv;    GpgmeError err; -  KeylistResult result; +  op_data_t opd; -  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &result, -			       sizeof (*result), release_keylist_result); +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL);    if (err)      return err;    switch (code)      {      case GPGME_STATUS_TRUNCATED: -      result->truncated = 1; -      break; - -    case GPGME_STATUS_EOF: -      if (result->truncated) -        append_xml_keylistinfo (&result->xmlinfo, "1"); -      if (result->xmlinfo) -	{ -	  append_xml_keylistinfo (&result->xmlinfo, NULL); -	  _gpgme_set_op_info (ctx, result->xmlinfo); -	  result->xmlinfo = NULL; -        } +      opd->result.truncated = 1;        break;      default: @@ -139,21 +130,21 @@ set_mainkey_trust_info (GpgmeKey key, const char *src)        switch (*src)  	{  	case 'e': -	  key->keys.flags.expired = 1; +	  key->subkeys->expired = 1;  	  break;  	case 'r': -	  key->keys.flags.revoked = 1; +	  key->subkeys->revoked = 1;  	  break;  	case 'd':            /* Note that gpg 1.3 won't print that anymore but only uses               the capabilities field. */ -	  key->keys.flags.disabled = 1; +	  key->subkeys->disabled = 1;  	  break;  	case 'i': -	  key->keys.flags.invalid = 1; +	  key->subkeys->invalid = 1;  	  break;          }        src++; @@ -164,7 +155,7 @@ set_mainkey_trust_info (GpgmeKey key, const char *src)  static void  set_userid_flags (GpgmeKey key, const char *src)  { -  struct user_id_s *uid = key->last_uid; +  GpgmeUserID uid = key->_last_uid;    assert (uid);    /* Look at letters and stop at the first digit.  */ @@ -202,7 +193,7 @@ set_userid_flags (GpgmeKey key, const char *src)  static void -set_subkey_trust_info (struct subkey_s *subkey, const char *src) +set_subkey_trust_info (GpgmeSubkey subkey, const char *src)  {    /* Look at letters and stop at the first digit.  */    while (*src && !isdigit (*src)) @@ -210,19 +201,19 @@ set_subkey_trust_info (struct subkey_s *subkey, const char *src)        switch (*src)  	{  	case 'e': -	  subkey->flags.expired = 1; +	  subkey->expired = 1;  	  break;  	case 'r': -	  subkey->flags.revoked = 1; +	  subkey->revoked = 1;  	  break;  	case 'd': -	  subkey->flags.disabled = 1; +	  subkey->disabled = 1;  	  break;  	case 'i': -	  subkey->flags.invalid = 1; +	  subkey->invalid = 1;  	  break;          }        src++; @@ -238,15 +229,15 @@ set_mainkey_capability (GpgmeKey key, const char *src)        switch (*src)  	{  	case 'e': -	  key->keys.flags.can_encrypt = 1; +	  key->subkeys->can_encrypt = 1;  	  break;  	case 's': -	  key->keys.flags.can_sign = 1; +	  key->subkeys->can_sign = 1;  	  break;  	case 'c': -	  key->keys.flags.can_certify = 1; +	  key->subkeys->can_certify = 1;  	  break;          case 'd': @@ -256,19 +247,19 @@ set_mainkey_capability (GpgmeKey key, const char *src)               and D, so that a future gpg version will be able to               disable certain subkeys. Currently it is expected that               gpg sets this for the primary key. */ -       	  key->keys.flags.disabled = 1; +       	  key->subkeys->disabled = 1;            break;  	case 'E': -	  key->gloflags.can_encrypt = 1; +	  key->can_encrypt = 1;  	  break;  	case 'S': -	  key->gloflags.can_sign = 1; +	  key->can_sign = 1;  	  break;  	case 'C': -	  key->gloflags.can_certify = 1; +	  key->can_certify = 1;  	  break;          }        src++; @@ -277,22 +268,22 @@ set_mainkey_capability (GpgmeKey key, const char *src)  static void -set_subkey_capability (struct subkey_s *subkey, const char *src) +set_subkey_capability (GpgmeSubkey subkey, const char *src)  {    while (*src)      {        switch (*src)  	{  	case 'e': -	  subkey->flags.can_encrypt = 1; +	  subkey->can_encrypt = 1;  	  break;  	case 's': -	  subkey->flags.can_sign = 1; +	  subkey->can_sign = 1;  	  break;  	case 'c': -	  subkey->flags.can_certify = 1; +	  subkey->can_certify = 1;  	  break;          }        src++; @@ -308,23 +299,23 @@ set_ownertrust (GpgmeKey key, const char *src)        switch (*src)  	{  	case 'n': -	  key->otrust = GPGME_VALIDITY_NEVER; +	  key->owner_trust = GPGME_VALIDITY_NEVER;  	  break;  	case 'm': -	  key->otrust = GPGME_VALIDITY_MARGINAL; +	  key->owner_trust = GPGME_VALIDITY_MARGINAL;  	  break;  	case 'f': -	  key->otrust = GPGME_VALIDITY_FULL; +	  key->owner_trust = GPGME_VALIDITY_FULL;  	  break;  	case 'u': -	  key->otrust = GPGME_VALIDITY_ULTIMATE; +	  key->owner_trust = GPGME_VALIDITY_ULTIMATE;  	  break;          default: -	  key->otrust = GPGME_VALIDITY_UNKNOWN; +	  key->owner_trust = GPGME_VALIDITY_UNKNOWN;  	  break;          }        src++; @@ -332,14 +323,14 @@ set_ownertrust (GpgmeKey key, const char *src)  } -/* We have read an entire key into ctx->tmp_key and should now finish -   it.  It is assumed that this releases ctx->tmp_key.  */ +/* We have read an entire key into tmp_key and should now finish it. +   It is assumed that this releases tmp_key.  */  static void -finish_key (GpgmeCtx ctx) +finish_key (GpgmeCtx ctx, op_data_t opd)  { -  GpgmeKey key = ctx->tmp_key; +  GpgmeKey key = opd->tmp_key; -  ctx->tmp_key = NULL; +  opd->tmp_key = NULL;    if (key)      _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key); @@ -348,28 +339,37 @@ finish_key (GpgmeCtx ctx)  /* Note: We are allowed to modify LINE.  */  static GpgmeError -keylist_colon_handler (GpgmeCtx ctx, char *line) +keylist_colon_handler (void *priv, char *line)  { +  GpgmeCtx ctx = (GpgmeCtx) priv;    enum      { -      RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_SSB, RT_SEC, -      RT_CRT, RT_CRS, RT_REV +      RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, +      RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV      }    rectype = RT_NONE;  #define NR_FIELDS 13    char *field[NR_FIELDS];    int fields = 0; -  GpgmeKey key = ctx->tmp_key; -  struct subkey_s *subkey = NULL; -  struct certsig_s *certsig = NULL; +  op_data_t opd; +  GpgmeError err; +  GpgmeKey key; +  GpgmeSubkey subkey = NULL; +  GpgmeKeySig keysig = NULL;    DEBUG3 ("keylist_colon_handler ctx = %p, key = %p, line = %s\n",  	  ctx, key, line ? line : "(null)"); +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL); +  if (err) +    return err; + +  key = opd->tmp_key; +    if (!line)      {        /* End Of File.  */ -      finish_key (ctx); +      finish_key (ctx, opd);        return 0;      } @@ -385,67 +385,22 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)      rectype = RT_SIG;    else if (!strcmp (field[0], "rev"))      rectype = RT_REV; -  else if (!strcmp (field[0], "uid") && key) -    rectype = RT_UID; -  else if (!strcmp (field[0], "sub") && key) -    { -      /* Start a new subkey.  */ -      rectype = RT_SUB;  -      if (!(subkey = _gpgme_key_add_subkey (key))) -	return GPGME_Out_Of_Core; -    } -  else if (!strcmp (field[0], "ssb") && key) -    { -      /* Start a new secret subkey.  */ -      rectype = RT_SSB; -      if (!(subkey = _gpgme_key_add_secret_subkey (key))) -	return GPGME_Out_Of_Core; -    }    else if (!strcmp (field[0], "pub")) -    { -      /* Start a new keyblock.  */ -      if (_gpgme_key_new (&key)) -	/* The only kind of error we can get.  */ -	return GPGME_Out_Of_Core; -      rectype = RT_PUB; -      finish_key (ctx); -      assert (!ctx->tmp_key); -      ctx->tmp_key = key; -    } +    rectype = RT_PUB;    else if (!strcmp (field[0], "sec")) -    { -      /* Start a new keyblock,  */ -      if (_gpgme_key_new_secret (&key)) -	return GPGME_Out_Of_Core; -      rectype = RT_SEC; -      finish_key (ctx); -      assert (!ctx->tmp_key); -      ctx->tmp_key = key; -    } +    rectype = RT_SEC;    else if (!strcmp (field[0], "crt")) -    { -      /* Start a new certificate.  */ -      if (_gpgme_key_new (&key)) -	return GPGME_Out_Of_Core; -      key->x509 = 1; -      rectype = RT_CRT; -      finish_key (ctx); -      assert (!ctx->tmp_key); -      ctx->tmp_key = key; -    } +    rectype = RT_CRT;    else if (!strcmp (field[0], "crs")) -    { -      /* Start a new certificate.  */ -      if (_gpgme_key_new_secret (&key)) -	return GPGME_Out_Of_Core; -      key->x509 = 1; -      rectype = RT_CRS; -      finish_key (ctx); -      assert (!ctx->tmp_key); -      ctx->tmp_key = key; -    } +    rectype = RT_CRS;    else if (!strcmp (field[0], "fpr") && key)       rectype = RT_FPR; +  else if (!strcmp (field[0], "uid") && key) +    rectype = RT_UID; +  else if (!strcmp (field[0], "sub") && key) +    rectype = RT_SUB;  +  else if (!strcmp (field[0], "ssb") && key) +    rectype = RT_SSB;    else       rectype = RT_NONE; @@ -453,29 +408,32 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)       this, clear the user ID pointer when encountering anything but a       signature.  */    if (rectype != RT_SIG && rectype != RT_REV) -    ctx->tmp_uid = NULL; +    opd->tmp_uid = NULL;    switch (rectype)      { +    case RT_PUB: +    case RT_SEC:      case RT_CRT:      case RT_CRS: -      /* Field 8 has the X.509 serial number.  */ -      if (fields >= 8) +      /* Start a new keyblock.  */ +      err = _gpgme_key_new (&key); +      if (err) +	return err; +      err = _gpgme_key_add_subkey (key, &subkey); +      if (err)  	{ -	  key->issuer_serial = strdup (field[7]); -	  if (!key->issuer_serial) -	    return GPGME_Out_Of_Core; +	  gpgme_key_unref (key); +	  return err;  	} -      /* Field 10 is not used for gpg due to --fixed-list-mode option -	 but GPGSM stores the issuer name.  */ -      if (fields >= 10 && _gpgme_decode_c_string (field[9], -						  &key->issuer_name, 0)) -	return GPGME_Out_Of_Core; -      /* Fall through!  */ +      if (rectype == RT_SEC || rectype == RT_CRS) +	key->secret = 1; +      if (rectype == RT_CRT || rectype == RT_CRS) +	key->protocol = GPGME_PROTOCOL_CMS; +      finish_key (ctx, opd); +      opd->tmp_key = key; -    case RT_PUB: -    case RT_SEC:        /* Field 2 has the trust info.  */        if (fields >= 2)  	set_mainkey_trust_info (key, field[1]); @@ -486,7 +444,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	  int i = atoi (field[2]);  	  /* Ignore invalid values.  */  	  if (i > 1) -	    key->keys.key_len = i;  +	    subkey->length = i;   	}        /* Field 4 has the public key algorithm.  */ @@ -494,25 +452,39 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	{  	  int i = atoi (field[3]);  	  if (i >= 1 && i < 128) -	    key->keys.key_algo = i; +	    subkey->pubkey_algo = i;  	}        /* Field 5 has the long keyid.  */ -      if (fields >= 5 && strlen (field[4]) == DIM(key->keys.keyid) - 1) -	strcpy (key->keys.keyid, field[4]); +      if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1) +	strcpy (subkey->_keyid, field[4]);        /* Field 6 has the timestamp (seconds).  */        if (fields >= 6) -	key->keys.timestamp = parse_timestamp (field[5]); +	subkey->timestamp = parse_timestamp (field[5]);        /* Field 7 has the expiration time (seconds).  */        if (fields >= 7) -	key->keys.expires_at = parse_timestamp (field[6]); +	subkey->expires = parse_timestamp (field[6]); +      /* Field 8 has the X.509 serial number.  */ +      if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS)) +	{ +	  key->issuer_serial = strdup (field[7]); +	  if (!key->issuer_serial) +	    return GPGME_Out_Of_Core; +	} +	          /* Field 9 has the ownertrust.  */        if (fields >= 9)  	set_ownertrust (key, field[8]); +      /* Field 10 is not used for gpg due to --fixed-list-mode option +	 but GPGSM stores the issuer name.  */ +      if (fields >= 10 && (rectype == RT_CRT || rectype == RT_CRS)) +	if (_gpgme_decode_c_string (field[9], &key->issuer_name, 0)) +	  return GPGME_Out_Of_Core; +        /* Field 11 has the signature class.  */        /* Field 12 has the capabilities.  */ @@ -522,6 +494,14 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)      case RT_SUB:      case RT_SSB: +      /* Start a new subkey.  */ +      err = _gpgme_key_add_subkey (key, &subkey); +      if (err) +	return err; + +      if (rectype == RT_SSB) +	subkey->secret = 1; +        /* Field 2 has the trust info.  */        if (fields >= 2)  	set_subkey_trust_info (subkey, field[1]); @@ -532,7 +512,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	  int i = atoi (field[2]);  	  /* Ignore invalid values.  */  	  if (i > 1) -	    subkey->key_len = i; +	    subkey->length = i;  	}        /* Field 4 has the public key algorithm.  */ @@ -540,12 +520,12 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	{  	  int i = atoi (field[3]);  	  if (i >= 1 && i < 128) -	    subkey->key_algo = i; +	    subkey->pubkey_algo = i;  	}        /* Field 5 has the long keyid.  */ -      if (fields >= 5 && strlen (field[4]) == DIM(subkey->keyid) - 1) -	strcpy (subkey->keyid, field[4]); +      if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1) +	strcpy (subkey->_keyid, field[4]);        /* Field 6 has the timestamp (seconds).  */        if (fields >= 6) @@ -553,7 +533,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)        /* Field 7 has the expiration time (seconds).  */        if (fields >= 7) -	subkey->expires_at = parse_timestamp (field[6]); +	subkey->expires = parse_timestamp (field[6]);        /* Field 8 is reserved (LID).  */        /* Field 9 has the ownertrust.  */ @@ -576,17 +556,17 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	    {  	      if (field[1])  		set_userid_flags (key, field[1]); -	      ctx->tmp_uid = key->last_uid; +	      opd->tmp_uid = key->_last_uid;  	    }  	}        break;      case RT_FPR:        /* Field 10 has the fingerprint (take only the first one).  */ -      if (fields >= 10 && !key->keys.fingerprint && field[9] && *field[9]) +      if (fields >= 10 && !key->subkeys->fpr && field[9] && *field[9])  	{ -	  key->keys.fingerprint = strdup (field[9]); -	  if (!key->keys.fingerprint) +	  key->subkeys->fpr = strdup (field[9]); +	  if (!key->subkeys->fpr)  	    return GPGME_Out_Of_Core;  	} @@ -601,13 +581,13 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)      case RT_SIG:      case RT_REV: -      if (!ctx->tmp_uid) +      if (!opd->tmp_uid)  	return 0;        /* Start a new (revoked) signature.  */ -      assert (ctx->tmp_uid == key->last_uid); -      certsig = _gpgme_key_add_certsig (key, (fields >= 10) ? field[9] : NULL); -      if (!certsig) +      assert (opd->tmp_uid == key->_last_uid); +      keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL); +      if (!keysig)  	return GPGME_Out_Of_Core;        /* Field 2 has the calculated trust ('!', '-', '?', '%').  */ @@ -615,23 +595,23 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	switch (field[1][0])  	  {  	  case '!': -	    certsig->sig_stat = GPGME_SIG_STAT_GOOD; +	    keysig->status = GPGME_No_Error;  	    break;  	  case '-': -	    certsig->sig_stat = GPGME_SIG_STAT_BAD; +	    keysig->status = GPGME_Bad_Signature;  	    break;  	  case '?': -	    certsig->sig_stat = GPGME_SIG_STAT_NOKEY; +	    keysig->status = GPGME_No_Public_Key;  	    break;  	  case '%': -	    certsig->sig_stat = GPGME_SIG_STAT_ERROR; +	    keysig->status = GPGME_General_Error;  	    break;  	  default: -	    certsig->sig_stat = GPGME_SIG_STAT_NONE; +	    keysig->status = GPGME_No_Error;  	    break;  	  } @@ -640,20 +620,20 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	{  	  int i = atoi (field[3]);  	  if (i >= 1 && i < 128) -	    certsig->algo = i; +	    keysig->pubkey_algo = i;  	}        /* Field 5 has the long keyid.  */ -      if (fields >= 5 && strlen (field[4]) == DIM(certsig->keyid) - 1) -	strcpy (certsig->keyid, field[4]); +      if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1) +	strcpy (keysig->_keyid, field[4]);        /* Field 6 has the timestamp (seconds).  */        if (fields >= 6) -	certsig->timestamp = parse_timestamp (field[5]); +	keysig->timestamp = parse_timestamp (field[5]);        /* Field 7 has the expiration time (seconds).  */        if (fields >= 7) -	certsig->expires_at = parse_timestamp (field[6]); +	keysig->expires = parse_timestamp (field[6]);        /* Field 11 has the signature class (eg, 0x30 means revoked).  */        if (fields >= 11) @@ -662,12 +642,12 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  	    int class = _gpgme_hextobyte (field[10]);  	    if (class >= 0)  	      { -		certsig->sig_class = class; +		keysig->class = class;  		if (class == 0x30) -		  certsig->flags.revoked = 1; +		  keysig->revoked = 1;  	      }  	    if (field[10][2] == 'x') -	      certsig->flags.exportable = 1; +	      keysig->exportable = 1;  	  }        break; @@ -682,162 +662,134 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)  void  _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data)  { +  GpgmeError err;    GpgmeCtx ctx = (GpgmeCtx) data;    GpgmeKey key = (GpgmeKey) type_data; +  op_data_t opd;    struct key_queue_item_s *q, *q2;    assert (type == GPGME_EVENT_NEXT_KEY); +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL); +  if (err) +    return; +    q = malloc (sizeof *q);    if (!q)      { -      gpgme_key_release (key); +      gpgme_key_unref (key);        /* FIXME       return GPGME_Out_Of_Core; */        return;      }    q->key = key;    q->next = NULL; -  /* FIXME: Lock queue.  Use a tail pointer?  */ -  if (!(q2 = ctx->key_queue)) -    ctx->key_queue = q; +  /* FIXME: Use a tail pointer?  */ +  if (!(q2 = opd->key_queue)) +    opd->key_queue = q;    else      {        for (; q2->next; q2 = q2->next)  	;        q2->next = q;      } -  ctx->key_cond = 1; -  /* FIXME: Unlock queue.  */ +  opd->key_cond = 1;  } -/** - * gpgme_op_keylist_start: - * @c: context  - * @pattern: a GnuPG user ID or NULL for all - * @secret_only: List only keys where the secret part is available - *  - * Note that this function also cancels a pending key listing - * operaton. To actually retrieve the key, use - * gpgme_op_keylist_next(). - *  - * Return value:  0 on success or an errorcode.  - **/ +/* Start a keylist operation within CTX, searching for keys which +   match PATTERN.  If SECRET_ONLY is true, only secret keys are +   returned.  */  GpgmeError  gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)  { -  GpgmeError err = 0; +  GpgmeError err; +  op_data_t opd;    err = _gpgme_op_reset (ctx, 2);    if (err) -    goto leave; +    return err; -  gpgme_key_release (ctx->tmp_key); -  ctx->tmp_key = NULL; -  /* Fixme: Release key_queue.  */ +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, +			       sizeof (*opd), release_op_data); +  if (err) +    return err;    _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx); +    err = _gpgme_engine_set_colon_line_handler (ctx->engine,  					      keylist_colon_handler, ctx);    if (err) -    goto leave; - -  err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only, -				  ctx->keylist_mode); +    return err; - leave: -  if (err) -    { -      _gpgme_engine_release (ctx->engine); -      ctx->engine = NULL; -    } -  return err; +  return _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only, +				   ctx->keylist_mode);  } -/** - * gpgme_op_keylist_ext_start: - * @c: context  - * @pattern: a NULL terminated array of search patterns - * @secret_only: List only keys where the secret part is available - * @reserved: Should be 0. - *  - * Note that this function also cancels a pending key listing - * operaton. To actually retrieve the key, use - * gpgme_op_keylist_next(). - *  - * Return value:  0 on success or an errorcode.  - **/ +/* Start a keylist operation within CTX, searching for keys which +   match PATTERN.  If SECRET_ONLY is true, only secret keys are +   returned.  */  GpgmeError  gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],  			    int secret_only, int reserved)  { -  GpgmeError err = 0; +  GpgmeError err; +  op_data_t opd;    err = _gpgme_op_reset (ctx, 2);    if (err) -    goto leave; +    return err; -  gpgme_key_release (ctx->tmp_key); -  ctx->tmp_key = NULL; +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, +			       sizeof (*opd), release_op_data); +  if (err) +    return err;    _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);    err = _gpgme_engine_set_colon_line_handler (ctx->engine,  					      keylist_colon_handler, ctx);    if (err) -    goto leave; - -  err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only, -				      reserved, ctx->keylist_mode); +    return err; - leave: -  if (err) -    { -      _gpgme_engine_release (ctx->engine); -      ctx->engine = NULL; -    } -  return err; +  return _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only, +				       reserved, ctx->keylist_mode);  } -/** - * gpgme_op_keylist_next: - * @c: Context - * @r_key: Returned key object - *  - * Return the next key from the key listing started with - * gpgme_op_keylist_start().  The caller must free the key using - * gpgme_key_release().  If the last key has already been returned the - * last time the function was called, %GPGME_EOF is returned and the - * operation is finished. - *  - * Return value: 0 on success, %GPGME_EOF or another error code. - **/ +/* Return the next key from the keylist in R_KEY.  */  GpgmeError  gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key)  { +  GpgmeError err;    struct key_queue_item_s *queue_item; +  op_data_t opd; -  if (!r_key) +  if (!ctx || !r_key)      return GPGME_Invalid_Value;    *r_key = NULL;    if (!ctx)      return GPGME_Invalid_Value; -  if (!ctx->key_queue) +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL); +  if (err) +    return err; + +  if (!opd->key_queue)      { -      GpgmeError err = _gpgme_wait_on_condition (ctx, &ctx->key_cond); +      err = _gpgme_wait_on_condition (ctx, &opd->key_cond);        if (err)  	return err; -      if (!ctx->key_cond) + +      if (!opd->key_cond)  	return GPGME_EOF; -      ctx->key_cond = 0;  -      assert (ctx->key_queue); + +      opd->key_cond = 0;  +      assert (opd->key_queue);      } -  queue_item = ctx->key_queue; -  ctx->key_queue = queue_item->next; -  if (!ctx->key_queue) -    ctx->key_cond = 0; +  queue_item = opd->key_queue; +  opd->key_queue = queue_item->next; +  if (!opd->key_queue) +    opd->key_cond = 0;    *r_key = queue_item->key;    free (queue_item); @@ -845,13 +797,7 @@ gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key)  } -/** - * gpgme_op_keylist_end: - * @c: Context - *  - * Ends the keylist operation and allows to use the context for some - * other operation next. - **/ +/* Terminate a pending keylist operation within CTX.  */  GpgmeError  gpgme_op_keylist_end (GpgmeCtx ctx)  { | 
