[svn] assuan - r325 - in trunk: . src
svn author marcus
cvs at cvs.gnupg.org
Wed Dec 2 19:35:35 CET 2009
Author: marcus
Date: 2009-12-02 19:35:34 +0100 (Wed, 02 Dec 2009)
New Revision: 325
Removed:
trunk/src/assuan-client.c
Modified:
trunk/NEWS
trunk/src/ChangeLog
trunk/src/Makefile.am
trunk/src/assuan-defs.h
trunk/src/assuan-pipe-connect.c
trunk/src/assuan-socket-connect.c
trunk/src/assuan.h
trunk/src/client.c
trunk/src/libassuan.def
trunk/src/libassuan.vers
Log:
src/
2009-12-02 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (common_sources): Remove assuan-client.c.
* assuan-client.c: File removed.
* assuan.h (ASSUAN_RESPONSE_ERROR, ASSUAN_RESPONSE_OK)
(ASSUAN_RESPONSE_STATUS, ASSUAN_RESPONSE_INQUIRE)
(ASSUAN_RESPONSE_STATUS): New macros.
(assuan_response_t): New type.
(assuan_client_read_response, assuan_client_parse_response): New
prototypes.
* libassuan.def, libassuan.vers: Add assuan_client_read_response,
assuan_client_parse_response.
* assuan-client.c (xtoi_1, xtoi_2, assuan_transact)
(_assuan_read_from_server): Moved to ...
* client.c: ... here, with updates to use new functions and types.
Include <stdlib.h>.
(assuan_client_read_response, assuan_client_parse_response): New
functions.
* assuan-defs.h (_assuan_read_from_server): Use assuan_response_t.
* assuan-pipe-connect.c (initial_handshake): Use assuan_response_t
and ASSUAN_RESPONSE_OK.
* assuan-socket-connect.c (assuan_socket_connect): Likewise.
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/ChangeLog 2009-12-02 18:35:34 UTC (rev 325)
@@ -1,3 +1,26 @@
+2009-12-02 Marcus Brinkmann <marcus at g10code.de>
+
+ * Makefile.am (common_sources): Remove assuan-client.c.
+ * assuan-client.c: File removed.
+ * assuan.h (ASSUAN_RESPONSE_ERROR, ASSUAN_RESPONSE_OK)
+ (ASSUAN_RESPONSE_STATUS, ASSUAN_RESPONSE_INQUIRE)
+ (ASSUAN_RESPONSE_STATUS): New macros.
+ (assuan_response_t): New type.
+ (assuan_client_read_response, assuan_client_parse_response): New
+ prototypes.
+ * libassuan.def, libassuan.vers: Add assuan_client_read_response,
+ assuan_client_parse_response.
+ * assuan-client.c (xtoi_1, xtoi_2, assuan_transact)
+ (_assuan_read_from_server): Moved to ...
+ * client.c: ... here, with updates to use new functions and types.
+ Include <stdlib.h>.
+ (assuan_client_read_response, assuan_client_parse_response): New
+ functions.
+ * assuan-defs.h (_assuan_read_from_server): Use assuan_response_t.
+ * assuan-pipe-connect.c (initial_handshake): Use assuan_response_t
+ and ASSUAN_RESPONSE_OK.
+ * assuan-socket-connect.c (assuan_socket_connect): Likewise.
+
2009-12-01 Marcus Brinkmann <marcus at g10code.de>
* assuan-pipe-server.c (assuan_init_pipe_server): Fix debug output.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/NEWS 2009-12-02 18:35:34 UTC (rev 325)
@@ -88,6 +88,8 @@
ASSUAN_SOCKET_CONNECT_FDPASSING NEW
assuan_peercred_t NEW
assuan_get_peercred CHANGED: Return assuan_peercred_t.
+assuan_client_read_response NEW
+assuan_client_parse_response NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/Makefile.am 2009-12-02 18:35:34 UTC (rev 325)
@@ -44,7 +44,6 @@
assuan-handler.c \
assuan-inquire.c \
assuan-listen.c \
- assuan-client.c \
assuan-pipe-server.c \
assuan-socket-server.c \
assuan-pipe-connect.c \
Deleted: trunk/src/assuan-client.c
Modified: trunk/src/assuan-defs.h
===================================================================
--- trunk/src/assuan-defs.h 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/assuan-defs.h 2009-12-02 18:35:34 UTC (rev 325)
@@ -277,9 +277,9 @@
gpg_error_t _assuan_write_line (assuan_context_t ctx, const char *prefix,
const char *line, size_t len);
-/*-- assuan-client.c --*/
+/*-- client.c --*/
gpg_error_t _assuan_read_from_server (assuan_context_t ctx,
- int *okay, int *off);
+ assuan_response_t *okay, int *off);
/*-- assuan-error.c --*/
Modified: trunk/src/assuan-pipe-connect.c
===================================================================
--- trunk/src/assuan-pipe-connect.c 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/assuan-pipe-connect.c 2009-12-02 18:35:34 UTC (rev 325)
@@ -88,14 +88,15 @@
static gpg_error_t
initial_handshake (assuan_context_t ctx)
{
- int okay, off;
+ assuan_response_t response;
+ int off;
gpg_error_t err;
- err = _assuan_read_from_server (ctx, &okay, &off);
+ err = _assuan_read_from_server (ctx, &response, &off);
if (err)
TRACE1 (ctx, ASSUAN_LOG_SYSIO, "initial_handshake", ctx,
"can't connect server: %s", gpg_strerror (err));
- else if (okay != 1)
+ else if (response != ASSUAN_RESPONSE_OK)
{
TRACE1 (ctx, ASSUAN_LOG_SYSIO, "initial_handshake", ctx,
"can't connect server: `%s'", ctx->inbound.line);
Modified: trunk/src/assuan-socket-connect.c
===================================================================
--- trunk/src/assuan-socket-connect.c 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/assuan-socket-connect.c 2009-12-02 18:35:34 UTC (rev 325)
@@ -124,13 +124,14 @@
/* initial handshake */
{
- int okay, off;
+ assuan_response_t response;
+ int off;
- err = _assuan_read_from_server (ctx, &okay, &off);
+ err = _assuan_read_from_server (ctx, &response, &off);
if (err)
TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect_ext", ctx,
"can't connect to server: %s\n", gpg_strerror (err));
- else if (okay != 1)
+ else if (response != ASSUAN_RESPONSE_OK)
{
char *sname = _assuan_encode_c_string (ctx, ctx->inbound.line);
if (sname)
Modified: trunk/src/assuan.h
===================================================================
--- trunk/src/assuan.h 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/assuan.h 2009-12-02 18:35:34 UTC (rev 325)
@@ -408,6 +408,26 @@
gpg_error_t assuan_get_peercred (assuan_context_t ctx,
assuan_peercred_t *peercred);
+
+
+/* Client interface. */
+#define ASSUAN_RESPONSE_ERROR 0
+#define ASSUAN_RESPONSE_OK 1
+#define ASSUAN_RESPONSE_DATA 2
+#define ASSUAN_RESPONSE_INQUIRE 3
+#define ASSUAN_RESPONSE_STATUS 4
+#define ASSUAN_RESPONSE_END 5
+typedef int assuan_response_t;
+
+/* This already de-escapes data lines. */
+gpg_error_t assuan_client_read_response (assuan_context_t ctx,
+ char **line, int *linelen);
+
+gpg_error_t assuan_client_parse_response (assuan_context_t ctx,
+ char *line, int linelen,
+ assuan_response_t *response,
+ int *off);
+
/*-- assuan-client.c --*/
gpg_error_t
assuan_transact (assuan_context_t ctx,
Modified: trunk/src/client.c
===================================================================
--- trunk/src/client.c 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/client.c 2009-12-02 18:35:34 UTC (rev 325)
@@ -22,9 +22,16 @@
#include <config.h>
#endif
+#include <stdlib.h>
+
#include "assuan-defs.h"
#include "debug.h"
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+
void
_assuan_client_finish (assuan_context_t ctx)
{
@@ -58,3 +65,243 @@
_assuan_client_finish (ctx);
}
+
+
+/* This function also does deescaping for data lines. */
+gpg_error_t
+assuan_client_read_response (assuan_context_t ctx,
+ char **line_r, int *linelen_r)
+{
+ gpg_error_t rc;
+ char *line = NULL;
+ int linelen = 0;
+
+ *line_r = NULL;
+ *linelen_r = 0;
+
+ do
+ {
+ do
+ {
+ rc = _assuan_read_line (ctx);
+ }
+ while (_assuan_error_is_eagain (ctx, rc));
+ if (rc)
+ return rc;
+ line = ctx->inbound.line;
+ linelen = ctx->inbound.linelen;
+ }
+ while (*line == '#' || !linelen);
+
+ /* For data lines, we deescape immediately. The user will never
+ have to worry about it. */
+ if (linelen >= 1 && line[0] == 'D' && line[1] == ' ')
+ {
+ char *s, *d;
+ for (s=d=line; linelen; linelen--)
+ {
+ if (*s == '%' && linelen > 2)
+ { /* handle escaping */
+ s++;
+ *d++ = xtoi_2 (s);
+ s += 2;
+ linelen -= 2;
+ }
+ else
+ *d++ = *s++;
+ }
+ *d = 0; /* add a hidden string terminator */
+
+ ctx->inbound.linelen = linelen;
+ }
+
+ *line_r = line;
+ *linelen_r = linelen;
+
+ return 0;
+}
+
+
+gpg_error_t
+assuan_client_parse_response (assuan_context_t ctx, char *line, int linelen,
+ assuan_response_t *response, int *off)
+{
+ *response = ASSUAN_RESPONSE_ERROR;
+ *off = 0;
+
+ if (linelen >= 1
+ && line[0] == 'D' && line[1] == ' ')
+ {
+ *response = ASSUAN_RESPONSE_DATA; /* data line */
+ *off = 2;
+ }
+ else if (linelen >= 1
+ && line[0] == 'S'
+ && (line[1] == '\0' || line[1] == ' '))
+ {
+ *response = ASSUAN_RESPONSE_STATUS;
+ *off = 1;
+ while (line[*off] == ' ')
+ ++*off;
+ }
+ else if (linelen >= 2
+ && line[0] == 'O' && line[1] == 'K'
+ && (line[2] == '\0' || line[2] == ' '))
+ {
+ *response = ASSUAN_RESPONSE_OK;
+ *off = 2;
+ while (line[*off] == ' ')
+ ++*off;
+ }
+ else if (linelen >= 3
+ && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
+ && (line[3] == '\0' || line[3] == ' '))
+ {
+ *response = ASSUAN_RESPONSE_ERROR;
+ *off = 3;
+ while (line[*off] == ' ')
+ ++*off;
+ }
+ else if (linelen >= 7
+ && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
+ && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
+ && line[6] == 'E'
+ && (line[7] == '\0' || line[7] == ' '))
+ {
+ *response = ASSUAN_RESPONSE_INQUIRE;
+ *off = 7;
+ while (line[*off] == ' ')
+ ++*off;
+ }
+ else if (linelen >= 3
+ && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
+ && (line[3] == '\0' || line[3] == ' '))
+ {
+ *response = ASSUAN_RESPONSE_END;
+ *off = 3;
+ }
+ else
+ return _assuan_error (ctx, GPG_ERR_ASS_INV_RESPONSE);
+
+ return 0;
+}
+
+
+gpg_error_t
+_assuan_read_from_server (assuan_context_t ctx, assuan_response_t *response,
+ int *off)
+{
+ gpg_error_t rc;
+ char *line;
+ int linelen;
+
+ *response = ASSUAN_RESPONSE_ERROR;
+ *off = 0;
+ rc = assuan_client_read_response (ctx, &line, &linelen);
+ if (!rc)
+ rc = assuan_client_parse_response (ctx, line, linelen, response, off);
+ return rc;
+}
+
+
+/**
+ * assuan_transact:
+ * @ctx: The Assuan context
+ * @command: Command line to be send to the server
+ * @data_cb: Callback function for data lines
+ * @data_cb_arg: first argument passed to @data_cb
+ * @inquire_cb: Callback function for a inquire response
+ * @inquire_cb_arg: first argument passed to @inquire_cb
+ * @status_cb: Callback function for a status response
+ * @status_cb_arg: first argument passed to @status_cb
+ *
+ * FIXME: Write documentation
+ *
+ * Return value: 0 on success or error code. The error code may be
+ * the one one returned by the server in error lines or from the
+ * callback functions. Take care: When a callback returns an error
+ * this function returns immediately with an error and thus the caller
+ * will altter return an Assuan error (write erro in most cases).
+ **/
+gpg_error_t
+assuan_transact (assuan_context_t ctx,
+ const char *command,
+ gpg_error_t (*data_cb)(void *, const void *, size_t),
+ void *data_cb_arg,
+ gpg_error_t (*inquire_cb)(void*, const char *),
+ void *inquire_cb_arg,
+ gpg_error_t (*status_cb)(void*, const char *),
+ void *status_cb_arg)
+{
+ gpg_error_t rc;
+ assuan_response_t response;
+ int off;
+ char *line;
+ int linelen;
+
+ rc = assuan_write_line (ctx, command);
+ if (rc)
+ return rc;
+
+ if (*command == '#' || !*command)
+ return 0; /* Don't expect a response for a comment line. */
+
+ again:
+ rc = _assuan_read_from_server (ctx, &response, &off);
+ if (rc)
+ return rc; /* error reading from server */
+
+ line = ctx->inbound.line + off;
+ linelen = ctx->inbound.linelen - off;
+
+ if (response == ASSUAN_RESPONSE_ERROR)
+ rc = atoi (line);
+ else if (response == ASSUAN_RESPONSE_DATA)
+ {
+ if (!data_cb)
+ rc = _assuan_error (ctx, GPG_ERR_ASS_NO_DATA_CB);
+ else
+ {
+ rc = data_cb (data_cb_arg, line, linelen);
+ if (!rc)
+ goto again;
+ }
+ }
+ else if (response == ASSUAN_RESPONSE_INQUIRE)
+ {
+ if (!inquire_cb)
+ {
+ assuan_write_line (ctx, "END"); /* get out of inquire mode */
+ _assuan_read_from_server (ctx, &response, &off); /* dummy read */
+ rc = _assuan_error (ctx, GPG_ERR_ASS_NO_INQUIRE_CB);
+ }
+ else
+ {
+ rc = inquire_cb (inquire_cb_arg, line);
+ if (!rc)
+ rc = assuan_send_data (ctx, NULL, 0); /* flush and send END */
+ if (!rc)
+ goto again;
+ }
+ }
+ else if (response == ASSUAN_RESPONSE_STATUS)
+ {
+ if (status_cb)
+ rc = status_cb (status_cb_arg, line);
+ if (!rc)
+ goto again;
+ }
+ else if (response == ASSUAN_RESPONSE_END)
+ {
+ if (!data_cb)
+ rc = _assuan_error (ctx, GPG_ERR_ASS_NO_DATA_CB);
+ else
+ {
+ rc = data_cb (data_cb_arg, NULL, 0);
+ if (!rc)
+ goto again;
+ }
+ }
+
+ return rc;
+}
Modified: trunk/src/libassuan.def
===================================================================
--- trunk/src/libassuan.def 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/libassuan.def 2009-12-02 18:35:34 UTC (rev 325)
@@ -94,6 +94,8 @@
__assuan_spawn @73
__assuan_usleep @74
assuan_fdopen @75
+ assuan_client_read_response @76
+ assuan_client_parse_response @77
; END
Modified: trunk/src/libassuan.vers
===================================================================
--- trunk/src/libassuan.vers 2009-12-01 19:19:35 UTC (rev 324)
+++ trunk/src/libassuan.vers 2009-12-02 18:35:34 UTC (rev 325)
@@ -24,6 +24,8 @@
global:
assuan_accept;
assuan_begin_confidential;
+ assuan_client_read_response;
+ assuan_client_parse_response;
assuan_close_input_fd;
assuan_close_output_fd;
assuan_command_parse_fd;
More information about the Gnupg-commits
mailing list