summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2001-11-24 21:10:22 +0000
committerWerner Koch <wk@gnupg.org>2001-11-24 21:10:22 +0000
commit3330fe3b478d4f0e9ec7806de01b54e22d853f6c (patch)
tree92293db9f4682cc2fa3cecdea7b584fb823ed153
parent91d758a5f16d481b6316cad0eaece61b95abeec4 (diff)
downloadlibassuan-3330fe3b478d4f0e9ec7806de01b54e22d853f6c.tar.gz
* assuan-buffer.c (_assuan_read_line): Deal with reads of more
than a line. * assuan-defs.h: Add space in the context for this.
-rw-r--r--src/ChangeLog7
-rw-r--r--src/assuan-buffer.c36
-rw-r--r--src/assuan-defs.h6
3 files changed, 41 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
new file mode 100644
index 0000000..6560526
--- /dev/null
+++ b/src/ChangeLog
@@ -0,0 +1,7 @@
+2001-11-24 Werner Koch <wk@gnupg.org>
+
+ * assuan-buffer.c (_assuan_read_line): Deal with reads of more
+ than a line.
+ * assuan-defs.h: Add space in the context for this.
+
+
diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c
index 912272f..f3fe2b1 100644
--- a/src/assuan-buffer.c
+++ b/src/assuan-buffer.c
@@ -78,7 +78,7 @@ readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
for (; n && *p != '\n'; n--, p++)
;
if (n)
- break;
+ break; /* at least one full line available - that's enough for now */
}
return 0;
@@ -95,7 +95,26 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
if (ctx->inbound.eof)
return -1;
- rc = readline (ctx->inbound.fd, line, LINELENGTH, &nread, &ctx->inbound.eof);
+ if (ctx->inbound.attic.linelen)
+ {
+ memcpy (line, ctx->inbound.attic.line, ctx->inbound.attic.linelen);
+ nread = ctx->inbound.attic.linelen;
+ ctx->inbound.attic.linelen = 0;
+ for (n=0; n < nread && line[n] != '\n'; n++)
+ ;
+ if (n < nread)
+ rc = 0; /* found another line in the attic */
+ else
+ { /* read the rest */
+ n = nread;
+ assert (n < LINELENGTH);
+ rc = readline (ctx->inbound.fd, line + n, LINELENGTH - n,
+ &nread, &ctx->inbound.eof);
+ }
+ }
+ else
+ rc = readline (ctx->inbound.fd, line, LINELENGTH,
+ &nread, &ctx->inbound.eof);
if (rc)
return ASSUAN_Read_Error;
if (!nread)
@@ -104,15 +123,18 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
return -1;
}
- for (n=nread-1; n>=0 ; n--)
+ for (n=0; n < nread; n++)
{
if (line[n] == '\n')
{
- if (n != nread-1)
+ if (n+1 < nread)
{
- fprintf (stderr, "DBG-assuan: %d bytes left over after read\n",
- nread-1 - n);
- /* fixme: store them for the next read */
+ 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);
+ ctx->inbound.attic.linelen = nread-n;
+ n--;
}
if (n && line[n-1] == '\r')
n--;
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index 8723fd3..3772e29 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -24,7 +24,7 @@
#include <sys/types.h>
#include "assuan.h"
-#define LINELENGTH 1002 /* 1000 + [CR,]LF */
+#define LINELENGTH 102 /* 1000 + [CR,]LF */
struct cmdtbl_s {
const char *name;
@@ -45,6 +45,10 @@ struct assuan_context_s {
int linelen; /* w/o CR, LF - might not be the same as
strlen(line) due to embedded nuls. However a nul
is always written at this pos */
+ struct {
+ char line[LINELENGTH];
+ int linelen ;
+ } attic;
} inbound;
struct {