if (dk.opts & OPT_FLAG_CANCEL) err = 0;
if (err && (dk.opts & OPT_FLAG_CANCEL)) err = gpg_error (GPG_ERR_CANCELED);
op_decrypt (const char *inbuf, char **outbuf, int ttl){  struct decrypt_key_s dk;  gpgme_data_t in = NULL;  gpgme_data_t out = NULL;  gpgme_ctx_t ctx;  gpgme_error_t err;    *outbuf = NULL;  op_init ();  memset (&dk, 0, sizeof dk);  dk.ttl = ttl;  err = gpgme_new (&ctx);  if (err)    return err;  err = gpgme_data_new_from_mem (&in, inbuf, strlen (inbuf), 1);  if (err)    goto leave;  err = gpgme_data_new (&out);  if (err)    goto leave;  gpgme_set_passphrase_cb (ctx, passphrase_callback_box, &dk);  dk.ctx = ctx;  err = gpgme_op_decrypt_verify (ctx, in, out);  dk.ctx = NULL;  update_passphrase_cache (err, &dk);  /* Act upon the result of the decryption operation. */  if (!err)     {      /* Decryption succeeded.  Store the result at OUTBUF. */      size_t n = 0;      gpgme_verify_result_t res;      *outbuf = gpgme_data_release_and_get_mem (out, &n);      (*outbuf)[n] = 0; /* Make sure it is really a string. */      out = NULL; /* (That GPGME object is no any longer valid.) */      /* Now check the state of any signature. */      res = gpgme_op_verify_result (ctx);      if (res && res->signatures)        verify_dialog_box (res);    }  else if (gpgme_err_code (err) == GPG_ERR_DECRYPT_FAILED)    {      /* The decryption failed.  See whether we can determine the real         problem. */      gpgme_decrypt_result_t res;      res = gpgme_op_decrypt_result (ctx);      if (res != NULL && res->recipients != NULL &&          gpgme_err_code (res->recipients->status) == GPG_ERR_NO_SECKEY)        err = GPG_ERR_NO_SECKEY;      /* XXX: return the keyids */    }  else    {      /* Decryption failed for other reasons. */    }  /* If the callback indicated a cancel operation, clear the error. */  if (dk.opts & OPT_FLAG_CANCEL)    err = 0;  leave:      if (ctx)    gpgme_release (ctx);  if (in)    gpgme_data_release (in);  if (out)    gpgme_data_release (out);  return err;}