Chnaged the op-assuan interface.

This commit is contained in:
Werner Koch 2009-02-24 15:13:01 +00:00
parent d118b5a2ee
commit f0dccac380
9 changed files with 106 additions and 53 deletions

1
NEWS
View File

@ -5,7 +5,6 @@ Noteworthy changes in version 1.1.9
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_PROTOCOL_ASSUAN NEW. GPGME_PROTOCOL_ASSUAN NEW.
gpgme_assuan_data_cb_t NEW. gpgme_assuan_data_cb_t NEW.
gpgme_assuan_sendfnc_ctx_t NEW.
gpgme_assuan_inquire_cb_t NEW. gpgme_assuan_inquire_cb_t NEW.
gpgme_assuan_status_cb_t NEW. gpgme_assuan_status_cb_t NEW.
gpgme_op_assuan_transact_start NEW. gpgme_op_assuan_transact_start NEW.

View File

@ -1,3 +1,8 @@
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> 2008-11-03 Marcus Brinkmann <marcus@g10code.com>
* Makefile.am (INCLUDES): Replace gpgme path with src. * Makefile.am (INCLUDES): Replace gpgme path with src.

View File

@ -491,6 +491,9 @@ _assuan_cookie_write_flush (void *cookie)
* a INQUIRE response. However, when assuan_transact() is used, this * a INQUIRE response. However, when assuan_transact() is used, this
* function takes care of sending END itself. * 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 * Return value: 0 on success or an error code
**/ **/
@ -499,7 +502,7 @@ assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
{ {
if (!ctx) if (!ctx)
return _assuan_error (ASSUAN_Invalid_Value); return _assuan_error (ASSUAN_Invalid_Value);
if (!buffer && length) if (!buffer && length > 1)
return _assuan_error (ASSUAN_Invalid_Value); return _assuan_error (ASSUAN_Invalid_Value);
if (!buffer) if (!buffer)
@ -508,7 +511,7 @@ assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
if (ctx->outbound.data.error) if (ctx->outbound.data.error)
return ctx->outbound.data.error; return ctx->outbound.data.error;
if (!ctx->is_server) if (!ctx->is_server)
return assuan_write_line (ctx, "END"); return assuan_write_line (ctx, length == 1? "CAN":"END");
} }
else else
{ {

View File

@ -1,3 +1,20 @@
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> 2009-02-04 Werner Koch <wk@g10code.com>
* w32-glib-io.c (_gpgme_io_spawn): Make ARGV argument const to * w32-glib-io.c (_gpgme_io_spawn): Make ARGV argument const to

View File

@ -94,12 +94,6 @@ struct engine_llass
}; };
typedef struct engine_llass *engine_llass_t; 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. */ /* Prototypes. */
@ -212,6 +206,8 @@ llass_new (void **engine, const char *file_name, const char *home_dir)
{ {
home_dir++; home_dir++;
/* Very simple parser only working for the one option we support. */ /* 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) if (!strncmp (home_dir, "GPG_AGENT", 9)
&& (!home_dir[9] || home_dir[9] == ' ')) && (!home_dir[9] || home_dir[9] == ' '))
llass->opt.gpg_agent = 1; llass->opt.gpg_agent = 1;
@ -372,18 +368,6 @@ llass_set_locale (void *engine, int category, const char *value)
} }
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 /* This is the inquiry callback. It handles stuff which ee need to
handle here and passes everything on to the user callback. */ handle here and passes everything on to the user callback. */
static gpgme_error_t static gpgme_error_t
@ -398,12 +382,18 @@ inquire_cb (engine_llass_t llass, const char *keyword, const char *args)
if (llass->user.inq_cb) 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, err = llass->user.inq_cb (llass->user.inq_cb_value,
keyword, args, keyword, args, &data);
inquire_cb_sendfnc, &sendfnc_ctx); 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 else
err = 0; err = 0;
@ -528,9 +518,17 @@ llass_status_handler (void *opaque, int fd)
args++; args++;
err = inquire_cb (llass, src, args); err = inquire_cb (llass, src, args);
if (!err) /* Flush and send END. */ if (!err)
{
/* Flush and send END. */
err = assuan_send_data (llass->assuan_ctx, NULL, 0); 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 else if (linelen >= 3
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R' && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
&& (line[3] == '\0' || line[3] == ' ')) && (line[3] == '\0' || line[3] == ' '))

View File

@ -1671,21 +1671,24 @@ gpgme_error_t gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output,
typedef gpgme_error_t (*gpgme_assuan_data_cb_t) typedef gpgme_error_t (*gpgme_assuan_data_cb_t)
(void *opaque, const void *data, size_t datalen); (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) typedef gpgme_error_t (*gpgme_assuan_inquire_cb_t)
(void *opaque, const char *name, const char *args, (void *opaque, const char *name, const char *args,
gpgme_assuan_sendfnc_t sendfnc, gpgme_data_t *r_data);
gpgme_assuan_sendfnc_ctx_t sendfnc_ctx);
typedef gpgme_error_t (*gpgme_assuan_status_cb_t) typedef gpgme_error_t (*gpgme_assuan_status_cb_t)
(void *opaque, const char *status, const char *args); (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. */ /* 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. /* Send the Assuan COMMAND and return results via the callbacks.
Asynchronous variant. */ Asynchronous variant. */

View File

@ -26,11 +26,11 @@
#include "ops.h" #include "ops.h"
#include "util.h" #include "util.h"
typedef struct typedef struct
{ {
/* The result of the assuan command with 0 for OK and an error value struct _gpgme_op_assuan_result result;
for ERR. */
gpgme_error_t result;
} *op_data_t; } *op_data_t;
@ -55,12 +55,12 @@ result_cb (void *priv, gpgme_error_t result)
if (!opd) if (!opd)
return gpg_error (GPG_ERR_INTERNAL); return gpg_error (GPG_ERR_INTERNAL);
opd->result = result; opd->result.err = result;
return 0; return 0;
} }
gpgme_error_t gpgme_assuan_result_t
gpgme_op_assuan_result (gpgme_ctx_t ctx) gpgme_op_assuan_result (gpgme_ctx_t ctx)
{ {
gpgme_error_t err; gpgme_error_t err;
@ -69,12 +69,12 @@ gpgme_op_assuan_result (gpgme_ctx_t ctx)
err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL);
opd = hook; opd = hook;
if (err) /* Check in case this function is used without having run a command
return err; before. */
if (!opd) if (err || !opd)
return gpg_error (GPG_ERR_INTERNAL); return NULL;
return opd->result; return &opd->result;
} }
@ -105,7 +105,7 @@ opassuan_start (gpgme_ctx_t ctx, int synchronous,
opd = hook; opd = hook;
if (err) if (err)
return 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, return _gpgme_engine_op_assuan_transact (ctx->engine, command,
result_cb, ctx, result_cb, ctx,

View File

@ -1,3 +1,7 @@
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> 2009-02-03 Werner Koch <wk@g10code.com>
* gpg/t-keylist.c (main): Check that new fields is_cardkey and * gpg/t-keylist.c (main): Check that new fields is_cardkey and

View File

@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <locale.h> #include <locale.h>
#include <assert.h>
#include <gpgme.h> #include <gpgme.h>
@ -52,10 +53,36 @@ data_cb (void *opaque, const void *data, size_t datalen)
static gpg_error_t static gpg_error_t
inq_cb (void *opaque, const char *name, const char *args, inq_cb (void *opaque, const char *name, const char *args,
gpgme_assuan_sendfnc_t sendfnc, gpgme_data_t *r_data)
gpgme_assuan_sendfnc_ctx_t sendfnc_value) {
gpgme_data_t data;
gpg_error_t err;
if (name)
{ {
printf ("INQ_CB: name=`%s' args=`%s'\n", name, args); 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; return 0;
} }
@ -70,9 +97,6 @@ status_cb (void *opaque, const char *status, const char *args)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -106,7 +130,7 @@ main (int argc, char **argv)
inq_cb, NULL, inq_cb, NULL,
status_cb, NULL); status_cb, NULL);
fail_if_err (err); fail_if_err (err);
err = gpgme_op_assuan_result (ctx); err = gpgme_op_assuan_result (ctx)->err;
if (err) if (err)
fprintf (stderr, "assuan command `%s' failed: %s <%s> (%d)\n", fprintf (stderr, "assuan command `%s' failed: %s <%s> (%d)\n",
command, gpg_strerror (err), gpg_strsource (err), err); command, gpg_strerror (err), gpg_strsource (err), err);