~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_PROTOCOL_ASSUAN NEW.
gpgme_assuan_data_cb_t NEW.
- gpgme_assuan_sendfnc_ctx_t NEW.
gpgme_assuan_inquire_cb_t NEW.
gpgme_assuan_status_cb_t NEW.
gpgme_op_assuan_transact_start NEW.
+2009-02-24 Werner Koch <wk@g10code.com>
+
+ * assuan-buffer.c (assuan_send_data): Add hack to optionally send
+ a final "CAN".
+
2008-11-03 Marcus Brinkmann <marcus@g10code.com>
* Makefile.am (INCLUDES): Replace gpgme path with src.
* a INQUIRE response. However, when assuan_transact() is used, this
* function takes care of sending END itself.
*
+ * If BUFFER is NULL and LENGTH is 1 and we are a client, a "CAN" is
+ * send instead of an "END".
+ *
* Return value: 0 on success or an error code
**/
\f
{
if (!ctx)
return _assuan_error (ASSUAN_Invalid_Value);
- if (!buffer && length)
+ if (!buffer && length > 1)
return _assuan_error (ASSUAN_Invalid_Value);
if (!buffer)
if (ctx->outbound.data.error)
return ctx->outbound.data.error;
if (!ctx->is_server)
- return assuan_write_line (ctx, "END");
+ return assuan_write_line (ctx, length == 1? "CAN":"END");
}
else
{
+2009-02-24 Werner Koch <wk@g10code.com>
+
+ * gpgme.h.in (struct _gpgme_op_assuan_result): New.
+ (gpgme_assuan_result_t): New.
+ (gpgme_op_assuan_result): Change return type.
+ (struct _gpgme_assuan_sendfnc_ctx)
+ (gpgme_assuan_sendfnc_ctx_t, gpgme_assuan_sendfnc_t):Remove.
+ (gpgme_assuan_inquire_cb_t): Changed.
+ * opassuan.c (op_data_t): Make use of a result structure.
+ (gpgme_op_assuan_result): Change return type.
+ (opassuan_start): Use result structure.
+ (result_cb): Ditto.
+ * engine-assuan.c (struct _gpgme_assuan_sendfnc_ctx): Remove.
+ (inquire_cb_sendfnc): Remove.
+ (inquire_cb): Change for new callback scheme. Not yet finished.
+ (llass_status_handler): Allow sending a CANCEL from the inquire CB.
+
2009-02-04 Werner Koch <wk@g10code.com>
* w32-glib-io.c (_gpgme_io_spawn): Make ARGV argument const to
};
typedef struct engine_llass *engine_llass_t;
-/* Helper to pass data to a callback. */
-struct _gpgme_assuan_sendfnc_ctx
-{
- assuan_context_t assuan_ctx;
-};
-
/* Prototypes. */
{
home_dir++;
/* Very simple parser only working for the one option we support. */
+ /* Note that wk promised to write a regression test if this
+ parser will be extended. */
if (!strncmp (home_dir, "GPG_AGENT", 9)
&& (!home_dir[9] || home_dir[9] == ' '))
llass->opt.gpg_agent = 1;
}
-
-static gpgme_error_t
-inquire_cb_sendfnc (gpgme_assuan_sendfnc_ctx_t ctx,
- const void *data, size_t datalen)
-{
- if (data && datalen)
- return assuan_send_data (ctx->assuan_ctx, data, datalen);
- else
- return 0; /* Don't allow an inquire to send a flush. */
-}
-
-
/* This is the inquiry callback. It handles stuff which ee need to
handle here and passes everything on to the user callback. */
static gpgme_error_t
if (llass->user.inq_cb)
{
- struct _gpgme_assuan_sendfnc_ctx sendfnc_ctx;
+ gpgme_data_t data = NULL;
- sendfnc_ctx.assuan_ctx = llass->assuan_ctx;
err = llass->user.inq_cb (llass->user.inq_cb_value,
- keyword, args,
- inquire_cb_sendfnc, &sendfnc_ctx);
+ keyword, args, &data);
+ if (!err && data)
+ {
+ /* FIXME: Returning data is not yet implemented. However we
+ need to allow the caller to cleanup his data object.
+ Thus we run the callback in finish mode immediately. */
+ err = llass->user.inq_cb (llass->user.inq_cb_value,
+ NULL, NULL, &data);
+ }
}
else
err = 0;
args++;
err = inquire_cb (llass, src, args);
- if (!err) /* Flush and send END. */
- err = assuan_send_data (llass->assuan_ctx, NULL, 0);
+ if (!err)
+ {
+ /* Flush and send END. */
+ err = assuan_send_data (llass->assuan_ctx, NULL, 0);
+ }
+ else if (gpg_err_code (err) == GPG_ERR_ASS_CANCELED)
+ {
+ /* Flush and send CANcel. */
+ err = assuan_send_data (llass->assuan_ctx, NULL, 1);
+ }
}
else if (linelen >= 3
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
typedef gpgme_error_t (*gpgme_assuan_data_cb_t)
(void *opaque, const void *data, size_t datalen);
-struct _gpgme_assuan_sendfnc_ctx;
-typedef struct _gpgme_assuan_sendfnc_ctx *gpgme_assuan_sendfnc_ctx_t;
-typedef gpgme_error_t (*gpgme_assuan_sendfnc_t)
- (gpgme_assuan_sendfnc_ctx_t ctx, const void *data, size_t datalen);
-
typedef gpgme_error_t (*gpgme_assuan_inquire_cb_t)
(void *opaque, const char *name, const char *args,
- gpgme_assuan_sendfnc_t sendfnc,
- gpgme_assuan_sendfnc_ctx_t sendfnc_ctx);
+ gpgme_data_t *r_data);
typedef gpgme_error_t (*gpgme_assuan_status_cb_t)
(void *opaque, const char *status, const char *args);
+struct _gpgme_op_assuan_result
+{
+ /* The result of the actual assuan command. An OK is indicated by a
+ value of 0 and an ERR by the respective error error value. */
+ gpgme_error_t err;
+};
+typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t;
+
+
/* Return the result of the last Assuan command. */
-gpgme_error_t gpgme_op_assuan_result (gpgme_ctx_t ctx);
+gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx);
/* Send the Assuan COMMAND and return results via the callbacks.
Asynchronous variant. */
#include "ops.h"
#include "util.h"
+
typedef struct
{
- /* The result of the assuan command with 0 for OK and an error value
- for ERR. */
- gpgme_error_t result;
+ struct _gpgme_op_assuan_result result;
+
} *op_data_t;
if (!opd)
return gpg_error (GPG_ERR_INTERNAL);
- opd->result = result;
+ opd->result.err = result;
return 0;
}
-gpgme_error_t
+gpgme_assuan_result_t
gpgme_op_assuan_result (gpgme_ctx_t ctx)
{
gpgme_error_t err;
err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL);
opd = hook;
- if (err)
- return err;
- if (!opd)
- return gpg_error (GPG_ERR_INTERNAL);
+ /* Check in case this function is used without having run a command
+ before. */
+ if (err || !opd)
+ return NULL;
- return opd->result;
+ return &opd->result;
}
opd = hook;
if (err)
return err;
- opd->result = gpg_error (GPG_ERR_UNFINISHED);
+ opd->result.err = gpg_error (GPG_ERR_UNFINISHED);
return _gpgme_engine_op_assuan_transact (ctx->engine, command,
result_cb, ctx,
+2009-02-24 Werner Koch <wk@g10code.com>
+
+ * opassuan/t-command.c: Adjust for changed new op_assuan interface.
+
2009-02-03 Werner Koch <wk@g10code.com>
* gpg/t-keylist.c (main): Check that new fields is_cardkey and
#include <stdlib.h>
#include <string.h>
#include <locale.h>
+#include <assert.h>
#include <gpgme.h>
static gpg_error_t
inq_cb (void *opaque, const char *name, const char *args,
- gpgme_assuan_sendfnc_t sendfnc,
- gpgme_assuan_sendfnc_ctx_t sendfnc_value)
+ gpgme_data_t *r_data)
{
- printf ("INQ_CB: name=`%s' args=`%s'\n", name, args);
+ gpgme_data_t data;
+ gpg_error_t err;
+
+ if (name)
+ {
+ printf ("INQ_CB: name=`%s' args=`%s'\n", name, args);
+ /* There shall be no data object. */
+ assert (!*r_data);
+
+ err = gpgme_data_new (&data);
+ fail_if_err (err);
+ *r_data = data;
+ printf (" sending data object %p\n", data);
+ }
+ else /* Finished using the formerly returned data object. */
+ {
+ printf ("INQ_CB: data object %p finished\n", *r_data);
+ /* There shall be a data object so that it can be cleaned up. */
+ assert (r_data);
+
+ gpgme_data_release (*r_data);
+ }
+
+ /* Uncomment the next lines and send a "SCD LEARN" to test sending
+ cancel from in inquiry. */
+ /* if (name && !strcmp (name, "KNOWNCARDP")) */
+ /* return gpg_error (GPG_ERR_ASS_CANCELED); */
+
return 0;
}
-
-
-
int
main (int argc, char **argv)
{
inq_cb, NULL,
status_cb, NULL);
fail_if_err (err);
- err = gpgme_op_assuan_result (ctx);
+ err = gpgme_op_assuan_result (ctx)->err;
if (err)
fprintf (stderr, "assuan command `%s' failed: %s <%s> (%d)\n",
command, gpg_strerror (err), gpg_strsource (err), err);