[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