Various changes.
[gnupg.git] / assuan / assuan-buffer.c
index 50900c4..da6b201 100644 (file)
 
 #include <config.h>
 #include <stdlib.h>
+#include <string.h>
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
 #include <assert.h>
-
 #include "assuan-defs.h"
 
+#ifdef HAVE_JNLIB_LOGGING
+#include "../jnlib/logging.h"
+#endif
+
+
+static const char *
+my_log_prefix (void)
+{
+#ifdef HAVE_JNLIB_LOGGING
+  return log_get_prefix (NULL);
+#else
+  return "";
+#endif
+}
+
 
 static int
 writen ( int fd, const char *buffer, size_t length )
 {
   while (length)
     {
-      int nwritten = write (fd, buffer, length);
+      int nwritten = _assuan_write_wrapper?
+        _assuan_write_wrapper (fd, buffer, length):
+        write (fd, buffer, length);
       
       if (nwritten < 0)
         {
@@ -58,7 +75,10 @@ readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
   *r_nread = 0;
   while (nleft > 0)
     {
-      int n = read (fd, buf, nleft);
+      int n = _assuan_read_wrapper?
+        _assuan_read_wrapper (fd, buf, nleft):
+        read (fd, buf, nleft);
+
       if (n < 0)
         {
           if (errno == EINTR)
@@ -89,41 +109,52 @@ int
 _assuan_read_line (ASSUAN_CONTEXT ctx)
 {
   char *line = ctx->inbound.line;
-  int n, nread;
+  int n, nread, atticlen;
   int rc;
-  
+
   if (ctx->inbound.eof)
     return -1;
 
-  if (ctx->inbound.attic.linelen)
+  atticlen = ctx->inbound.attic.linelen;
+  if (atticlen)
     {
-      memcpy (line, ctx->inbound.attic.line, ctx->inbound.attic.linelen);
-      nread = ctx->inbound.attic.linelen;
+      memcpy (line, ctx->inbound.attic.line, atticlen);
       ctx->inbound.attic.linelen = 0;
-      for (n=0; n < nread && line[n] != '\n'; n++)
+      for (n=0; n < atticlen && line[n] != '\n'; n++)
         ;
-      if (n < nread)
-        rc = 0; /* found another line in the attic */
+      if (n < atticlen)
+       {
+         rc = 0; /* found another line in the attic */
+         nread = atticlen;
+         atticlen = 0;
+       }
       else
         { /* read the rest */
-          n = nread;
-          assert (n < LINELENGTH);
-          rc = readline (ctx->inbound.fd, line + n, LINELENGTH - n,
-                         &nread, &ctx->inbound.eof);
+          assert (atticlen < LINELENGTH);
+          rc = readline (ctx->inbound.fd, line + atticlen,
+                        LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
         }
     }
   else
     rc = readline (ctx->inbound.fd, line, LINELENGTH,
                    &nread, &ctx->inbound.eof);
   if (rc)
-    return ASSUAN_Read_Error;
+    {
+      if (ctx->log_fp)
+        fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
+                 my_log_prefix (), ctx, strerror (errno)); 
+      return ASSUAN_Read_Error;
+    }
   if (!nread)
     {
       assert (ctx->inbound.eof);
+      if (ctx->log_fp)
+        fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n", my_log_prefix (),ctx); 
       return -1; 
     }
 
   ctx->inbound.attic.pending = 0;
+  nread += atticlen;
   for (n=0; n < nread; n++)
     {
       if (line[n] == '\n')
@@ -149,10 +180,23 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
             n--;
           line[n] = 0;
           ctx->inbound.linelen = n;
+          if (ctx->log_fp)
+            {
+              fprintf (ctx->log_fp, "%s[%p] <- ", my_log_prefix (), ctx); 
+              if (ctx->confidential)
+                fputs ("[Confidential data not shown]", ctx->log_fp);
+              else
+                _assuan_log_print_buffer (ctx->log_fp, 
+                                          ctx->inbound.line,
+                                          ctx->inbound.linelen);
+              putc ('\n', ctx->log_fp);
+            }
           return 0;
         }
     }
 
+  if (ctx->log_fp)
+    fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", my_log_prefix (), ctx);
   *line = 0;
   ctx->inbound.linelen = 0;
   return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
@@ -172,11 +216,15 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
 AssuanError
 assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
 {
+  AssuanError err;
+
   if (!ctx)
     return ASSUAN_Invalid_Value;
+
+  err = _assuan_read_line (ctx);
   *line = ctx->inbound.line;
   *linelen = ctx->inbound.linelen;
-  return _assuan_read_line (ctx);
+  return err;
 }
 
 
@@ -198,6 +246,17 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
     return ASSUAN_Invalid_Value;
 
   /* fixme: we should do some kind of line buffering */
+  if (ctx->log_fp)
+    {
+      fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx); 
+      if (ctx->confidential)
+        fputs ("[Confidential data not shown]", ctx->log_fp);
+      else
+        _assuan_log_print_buffer (ctx->log_fp, 
+                                  line, strlen (line));
+      putc ('\n', ctx->log_fp);
+    }
+
   rc = writen (ctx->outbound.fd, line, strlen(line));
   if (rc)
     rc = ASSUAN_Write_Error;
@@ -258,6 +317,17 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
       
       if (linelen >= LINELENGTH-2-2)
         {
+          if (ctx->log_fp)
+            {
+              fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx); 
+              if (ctx->confidential)
+                fputs ("[Confidential data not shown]", ctx->log_fp);
+              else 
+                _assuan_log_print_buffer (ctx->log_fp, 
+                                          ctx->outbound.data.line,
+                                          linelen);
+              putc ('\n', ctx->log_fp);
+            }
           *line++ = '\n';
           linelen++;
           if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
@@ -292,6 +362,17 @@ _assuan_cookie_write_flush (void *cookie)
   line += linelen;
   if (linelen)
     {
+      if (ctx->log_fp)
+        {
+          fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx); 
+          if (ctx->confidential)
+            fputs ("[Confidential data not shown]", ctx->log_fp);
+          else
+            _assuan_log_print_buffer (ctx->log_fp, 
+                                      ctx->outbound.data.line,
+                                      linelen);
+          putc ('\n', ctx->log_fp);
+            }
       *line++ = '\n';
       linelen++;
       if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))