* assuan-connect.c (assuan_pipe_connect): Implemented the inital
authorWerner Koch <wk@gnupg.org>
Wed, 12 Dec 2001 09:17:23 +0000 (09:17 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 12 Dec 2001 09:17:23 +0000 (09:17 +0000)
handshake.
* assuan-client.c (read_from_server): Renamed to
(_assuan_read_from_server): this and made external.

* assuan-listen.c (assuan_set_hello_line): New.
(assuan_accept): Use a custom hello line is available.

* assuan-buffer.c (assuan_read_line): New.
(assuan_pending_line): New.
(_assuan_write_line): Renamed to ..
(assuan_write_line): this, made public and changed all callers.

assuan/ChangeLog
assuan/assuan-buffer.c
assuan/assuan-client.c
assuan/assuan-connect.c
assuan/assuan-defs.h
assuan/assuan-handler.c
assuan/assuan-inquire.c
assuan/assuan-listen.c
assuan/assuan-pipe-server.c
assuan/assuan.h

index 28f1b2f..9b08c2b 100644 (file)
@@ -1,3 +1,18 @@
+2001-12-12  Werner Koch  <wk@gnupg.org>
+
+       * assuan-connect.c (assuan_pipe_connect): Implemented the inital
+       handshake.
+       * assuan-client.c (read_from_server): Renamed to  
+       (_assuan_read_from_server): this and made external.
+
+       * assuan-listen.c (assuan_set_hello_line): New.
+       (assuan_accept): Use a custom hello line is available.
+
+       * assuan-buffer.c (assuan_read_line): New.
+       (assuan_pending_line): New.
+       (_assuan_write_line): Renamed to ..
+       (assuan_write_line): this, made public and changed all callers.
+
 2001-12-04  Werner Koch  <wk@gnupg.org>
 
        * assuan-connect.c (assuan_pipe_connect): Add more error reporting.
index eec4876..50900c4 100644 (file)
@@ -123,16 +123,25 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
       return -1; 
     }
 
+  ctx->inbound.attic.pending = 0;
   for (n=0; n < nread; n++)
     {
       if (line[n] == '\n')
         {
           if (n+1 < nread)
             {
+              char *s, *d;
+              int i;
+
               n++;
               /* we have to copy the rest because the handlers are
                  allowed to modify the passed buffer */
-              memcpy (ctx->inbound.attic.line, line+n, nread-n);
+              for (d=ctx->inbound.attic.line, s=line+n, i=nread-n; i; i--)
+                {
+                  if (*s=='\n')
+                    ctx->inbound.attic.pending = 1;
+                  *d++ = *s++;
+                }
               ctx->inbound.attic.linelen = nread-n;
               n--;
             }
@@ -150,12 +159,43 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
 }
 
 
+/* Read the next line from the client or server and return a pointer
+   to a buffer with holding that line.  linelen returns the length of
+   the line.  This buffer is valid until another read operation is
+   done on this buffer.  The caller is allowed to modify this buffer.
+   He should only use the buffer if the function returns without an
+   error.
+
+   Returns: 0 on success or an assuan error code
+   See also: assuan_pending_line().
+*/
+AssuanError
+assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
+{
+  if (!ctx)
+    return ASSUAN_Invalid_Value;
+  *line = ctx->inbound.line;
+  *linelen = ctx->inbound.linelen;
+  return _assuan_read_line (ctx);
+}
 
 
-int 
-_assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
+/* Return true when a full line is pending for a read, without the need
+   for actual IO */
+int
+assuan_pending_line (ASSUAN_CONTEXT ctx)
+{
+  return ctx && ctx->inbound.attic.pending;
+}
+
+
+AssuanError 
+assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
 {
   int rc;
+  
+  if (!ctx)
+    return ASSUAN_Invalid_Value;
 
   /* fixme: we should do some kind of line buffering */
   rc = writen (ctx->outbound.fd, line, strlen(line));
@@ -297,7 +337,7 @@ assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
       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, "END");
     }
   else
     {
index 03c7c09..a555cf3 100644 (file)
@@ -32,8 +32,8 @@
 #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
 
 
-static AssuanError
-read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
+AssuanError
+_assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
 {
   char *line;
   int linelen;
@@ -114,12 +114,12 @@ assuan_transact (ASSUAN_CONTEXT ctx,
   unsigned char *line;
   int linelen;
 
-  rc = _assuan_write_line (ctx, command);
+  rc = assuan_write_line (ctx, command);
   if (rc)
     return rc;
 
  again:
-  rc = read_from_server (ctx, &okay, &off);
+  rc = _assuan_read_from_server (ctx, &okay, &off);
   if (rc)
     return rc; /* error reading from server */
 
@@ -162,8 +162,8 @@ assuan_transact (ASSUAN_CONTEXT ctx,
     {
       if (!inquire_cb)
         {
-          _assuan_write_line (ctx, "END"); /* get out of inquire mode */
-          read_from_server (ctx, &okay, &off); /* dummy read the response */
+          assuan_write_line (ctx, "END"); /* get out of inquire mode */
+          _assuan_read_from_server (ctx, &okay, &off); /* dummy read */
           rc = ASSUAN_No_Inquire_Callback;
         }
       else
index abc5d74..683c7f0 100644 (file)
@@ -40,6 +40,7 @@
 #endif
 
 #ifdef HAVE_JNLIB_LOGGING
+#include "../jnlib/logging.h"
 #define LOGERROR1(a,b)   log_error ((a), (b))
 #else
 #define LOGERROR1(a,b)   fprintf (stderr, (a), (b))
@@ -188,35 +189,37 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[])
 
   close (rp[1]);
   close (wp[0]);
-  _assuan_read_line (*ctx); /* FIXME: Handshake.  */
 
-#if 0 /* old stuff */
-  inbound.eof = 0;
-  inbound.linelen = 0;
-  inbound.attic.linelen = 0;
+  /* initial handshake */
+  {
+    int okay, off;
+
+    err = _assuan_read_from_server (*ctx, &okay, &off);
+    if (err)
+      {
+        LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
+      }
+    else if (okay != 1)
+      {
+        LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line);
+        err = ASSUAN_Connect_Failed;
+      }
+  }
 
-  /* The server is available - read the greeting */
-  rc = read_from_agent (&okay);
-  if (rc)
-    {
-      log_error ("can't connect to the agent: %s\n", gnupg_strerror (rc));
-    }
-  else if (!okay)
+  if (err)
     {
-      log_error ("can't connect to the agent: %s\n", inbound.line);
-      rc = seterr (No_Agent);
+      if ((*ctx)->pid != -1)
+        waitpid ((*ctx)->pid, NULL, 0);  /* FIXME Check return value.  */
+      assuan_deinit_pipe_server (*ctx);  /* FIXME: Common code should be factored out.  */
     }
- else
-#endif
-
 
-  return 0;
+  return err;
 }
 
 void
 assuan_pipe_disconnect (ASSUAN_CONTEXT ctx)
 {
-  _assuan_write_line (ctx, "BYE");
+  assuan_write_line (ctx, "BYE");
   close (ctx->inbound.fd);
   close (ctx->outbound.fd);
   waitpid (ctx->pid, NULL, 0);  /* FIXME Check return value.  */
index 5d61707..e0a38a8 100644 (file)
@@ -38,6 +38,7 @@ struct assuan_context_s {
 
   int is_server;  /* set if this is context belongs to a server */
   int in_inquire;
+  char *hello_line;
   
   void *user_pointer;  /* for assuan_[gs]et_pointer () */
 
@@ -51,6 +52,7 @@ struct assuan_context_s {
     struct {
       char line[LINELENGTH];
       int linelen ;
+      int pending; /* i.e. at least one line is available in the attic */
     } attic;
   } inbound;
 
@@ -91,12 +93,12 @@ struct assuan_context_s {
 int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
 
 /*-- assuan-buffer.c --*/
-int _assuan_write_line (ASSUAN_CONTEXT ctx, const char *line);
 int _assuan_read_line (ASSUAN_CONTEXT ctx);
 int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size);
 int _assuan_cookie_write_flush (void *cookie);
 
-
+/*-- assuan-client.c --*/
+AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
 
 
 /*-- assuan-util.c --*/
index aee2407..c8be909 100644 (file)
@@ -377,11 +377,11 @@ process_request (ASSUAN_CONTEXT ctx)
   /* Error handling */
   if (!rc)
     {
-      rc = _assuan_write_line (ctx, "OK");
+      rc = assuan_write_line (ctx, "OK");
     }
   else if (rc == -1)
     { /* No error checking because the peer may have already disconnect */ 
-      _assuan_write_line (ctx, "OK  Bye, bye - hope to meet you again");
+      assuan_write_line (ctx, "OK  Hope to meet you again");
     }
   else 
     {
@@ -397,7 +397,7 @@ process_request (ASSUAN_CONTEXT ctx)
           sprintf (errline, "ERR %d %.50s%s%.100s",
                    rc, assuan_strerror (rc), text? " - ":"", text?text:"");
         }
-      rc = _assuan_write_line (ctx, errline);
+      rc = assuan_write_line (ctx, errline);
     }
 
   return rc;
@@ -538,7 +538,7 @@ assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
           strcat (buffer, " ");
           strcat (buffer, text);
         }
-      _assuan_write_line (ctx, buffer);
+      assuan_write_line (ctx, buffer);
     }
   else if ( (helpbuf = xtrymalloc (n)) )
     {
@@ -549,7 +549,7 @@ assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
           strcat (helpbuf, " ");
           strcat (helpbuf, text);
         }
-      _assuan_write_line (ctx, helpbuf);
+      assuan_write_line (ctx, helpbuf);
       xfree (helpbuf);
     }
 }
index c4514df..8fec77e 100644 (file)
@@ -151,7 +151,7 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
   init_membuf (&mb, maxlen? maxlen:1024, maxlen);
 
   strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
-  rc = _assuan_write_line (ctx, cmdbuf);
+  rc = assuan_write_line (ctx, cmdbuf);
   if (rc)
     goto leave;
 
index f8ccb27..822ef32 100644 (file)
 
 #include "assuan-defs.h"
 
+AssuanError
+assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
+{
+  if (!ctx)
+    return ASSUAN_Invalid_Value;
+  if (!line)
+    {
+      xfree (ctx->hello_line);
+      ctx->hello_line = NULL;
+    }
+  else
+    {
+      char *buf = xtrymalloc (3+strlen(line)+1);
+      if (!buf)
+        return ASSUAN_Out_Of_Core;
+      strcpy (buf, "OK ");
+      strcpy (buf+3, line);
+      xfree (ctx->hello_line);
+      ctx->hello_line = buf;
+    }
+  return 0;
+}
 
 
 /**
@@ -38,7 +60,7 @@
  * Return value: 0 on success or an error if the connection could for
  * some reason not be established.
  **/
-int
+AssuanError
 assuan_accept (ASSUAN_CONTEXT ctx)
 {
   int rc;
@@ -57,9 +79,8 @@ assuan_accept (ASSUAN_CONTEXT ctx)
     }
 
   /* send the hello */
-  
-  rc = _assuan_write_line (ctx,
-                           "OK Hello dear client - what can I do for you?");
+  rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
+                                              : "OK Your orders please");
   if (rc)
     return rc;
   
@@ -70,6 +91,7 @@ assuan_accept (ASSUAN_CONTEXT ctx)
 }
 
 
+
 int
 assuan_get_input_fd (ASSUAN_CONTEXT ctx)
 {
index 58d9aa1..2a9b829 100644 (file)
@@ -55,7 +55,11 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
 void
 assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx)
 {
-  xfree (ctx);
+  if (ctx)
+    {
+      xfree (ctx->hello_line);
+      xfree (ctx);
+    }
 }
 
 
@@ -67,4 +71,3 @@ assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx)
 
 
 
-
index 8b805dd..f97493d 100644 (file)
@@ -46,6 +46,7 @@ typedef enum {
   ASSUAN_Invalid_Response = 11,
   ASSUAN_No_Data_Callback = 12,
   ASSUAN_No_Inquire_Callback = 13,
+  ASSUAN_Connect_Failed = 14,
 
   /* error codes above 99 are meant as status codes */
   ASSUAN_Not_Implemented = 100,
@@ -130,7 +131,8 @@ void assuan_write_status (ASSUAN_CONTEXT ctx,
 
 
 /*-- assuan-listen.c --*/
-int assuan_accept (ASSUAN_CONTEXT ctx);
+AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line);
+AssuanError assuan_accept (ASSUAN_CONTEXT ctx);
 int assuan_get_input_fd (ASSUAN_CONTEXT ctx);
 int assuan_get_output_fd (ASSUAN_CONTEXT ctx);
 
@@ -161,6 +163,10 @@ AssuanError assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
                             char **r_buffer, size_t *r_length, size_t maxlen);
 
 /*-- assuan-buffer.c --*/
+AssuanError assuan_read_line (ASSUAN_CONTEXT ctx,
+                              char **line, size_t *linelen);
+int assuan_pending_line (ASSUAN_CONTEXT ctx);
+AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line );
 AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
                               const void *buffer, size_t length);