op_decrypt (int (*pass_cb)(void *, const char*, const char*, int, int), void *pass_cb_value,
op_decrypt (gpgme_passphrase_cb_t pass_cb, void *pass_cb_value,
op_decrypt (int (*pass_cb)(void *, const char*, const char*, int, int),	    void *pass_cb_value,	    const char *inbuf, char **outbuf){    /* XXX: violates the information hiding principle */    struct decrypt_key_s *cb = (struct decrypt_key_s *)pass_cb_value;    gpgme_data_t in=NULL, out=NULL;    gpgme_ctx_t ctx;    gpgme_error_t err;    *outbuf = NULL;    op_init ();    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;    /* Needed to parse ENC_TO */    cb->ctx = (void *)ctx;        gpgme_set_passphrase_cb (ctx, pass_cb, pass_cb_value);    err = gpgme_op_decrypt_verify (ctx, in, out);    if (!err) {	size_t n = 0;	*outbuf = gpgme_data_release_and_get_mem (out, &n);	(*outbuf)[n] = 0;	out = NULL;    }    if (gpgme_err_code (err) == GPG_ERR_DECRYPT_FAILED) {	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 */    }    /* XXX: automatically spawn verify_start in case the text was signed? */    {	gpgme_verify_result_t res;	res = gpgme_op_verify_result (ctx);	if (res != NULL && res->signatures != NULL)	    verify_dialog_box (res);    }    clear_error_if_cancel (cb, &err);leave:        gpgme_release (ctx);    gpgme_data_release (in);    gpgme_data_release (out);    return err;}