diff options
author | Werner Koch <[email protected]> | 2001-11-07 17:43:05 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2001-11-07 17:43:05 +0000 |
commit | d5aea23fcaa3b05240242b8a8a192a0ea74bd9b8 (patch) | |
tree | 4bed195af93f9611e75c3cb12ef3bf077379a2b1 /src/assuan-buffer.c | |
parent | gpgsm does now build and a dummy server can be started. (diff) | |
download | libassuan-d5aea23fcaa3b05240242b8a8a192a0ea74bd9b8.tar.gz libassuan-d5aea23fcaa3b05240242b8a8a192a0ea74bd9b8.zip |
Assuan server mode is now basically usable
Diffstat (limited to '')
-rw-r--r-- | src/assuan-buffer.c | 113 |
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; } |