aboutsummaryrefslogtreecommitdiffstats
path: root/src/assuan-buffer.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2001-11-07 17:43:05 +0000
committerWerner Koch <[email protected]>2001-11-07 17:43:05 +0000
commitd5aea23fcaa3b05240242b8a8a192a0ea74bd9b8 (patch)
tree4bed195af93f9611e75c3cb12ef3bf077379a2b1 /src/assuan-buffer.c
parentgpgsm does now build and a dummy server can be started. (diff)
downloadlibassuan-d5aea23fcaa3b05240242b8a8a192a0ea74bd9b8.tar.gz
libassuan-d5aea23fcaa3b05240242b8a8a192a0ea74bd9b8.zip
Assuan server mode is now basically usable
Diffstat (limited to '')
-rw-r--r--src/assuan-buffer.c113
1 files changed, 110 insertions, 3 deletions
diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c
index c767a0e..73786b6 100644
--- a/src/assuan-buffer.c
+++ b/src/assuan-buffer.c
@@ -21,24 +21,131 @@
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
#include "assuan-defs.h"
+static int
+writen ( int fd, const char *buffer, size_t length )
+{
+ while (length)
+ {
+ int nwritten = write (fd, buffer, length);
+
+ if (nwritten < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return -1; /* write error */
+ }
+ length -= nwritten;
+ buffer += nwritten;
+ }
+ return 0; /* okay */
+}
+
+/* read an entire line */
+static int
+readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
+{
+ size_t nleft = buflen;
+ char *p;
+
+ *eof = 0;
+ *r_nread = 0;
+ while (nleft > 0)
+ {
+ int n = read (fd, buf, nleft);
+ if (n < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return -1; /* read error */
+ }
+ else if (!n)
+ {
+ *eof = 1;
+ break; /* allow incomplete lines */
+ }
+ p = buf;
+ nleft -= n;
+ buf += n;
+ *r_nread += n;
+
+ for (; n && *p != '\n'; n--, p++)
+ ;
+ if (n)
+ break;
+ }
+
+ return 0;
+}
+
+
int
_assuan_read_line (ASSUAN_CONTEXT ctx)
{
+ char *line = ctx->inbound.line;
+ int n, nread;
+ int rc;
+ if (ctx->inbound.eof)
+ return -1;
+
+ rc = readline (ctx->inbound.fd, line, LINELENGTH, &nread, &ctx->inbound.eof);
+ if (rc)
+ return ASSUAN_Read_Error;
+ if (!nread)
+ {
+ assert (ctx->inbound.eof);
+ return -1;
+ }
- return -1;
+ for (n=nread-1; n>=0 ; n--)
+ {
+ if (line[n] == '\n')
+ {
+ if (n != nread-1)
+ {
+ fprintf (stderr, "DBG-assuan: %d bytes left over after read\n",
+ nread-1 - n);
+ /* fixme: store them for the next read */
+ }
+ if (n && line[n-1] == '\r')
+ n--;
+ line[n] = 0;
+ ctx->inbound.linelen = n;
+ return 0;
+ }
+ }
+
+ *line = 0;
+ ctx->inbound.linelen = 0;
+ return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
}
int
-_assuan_write_line (ASSUAN_CONTEXT ctx)
+_assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
{
- return -1;
+ int rc;
+
+ /* fixme: we should do some kind of line buffering */
+ rc = writen (ctx->outbound.fd, line, strlen(line));
+ if (rc)
+ rc = ASSUAN_Write_Error;
+ if (!rc)
+ {
+ rc = writen (ctx->outbound.fd, "\n", 1);
+ if (rc)
+ rc = ASSUAN_Write_Error;
+ }
+
+ return rc;
}