diff options
author | Marcus Brinkmann <[email protected]> | 2001-11-20 05:27:46 +0000 |
---|---|---|
committer | Marcus Brinkmann <[email protected]> | 2001-11-20 05:27:46 +0000 |
commit | a441158cc77391ba8857928f01fd20ac1569ad85 (patch) | |
tree | 34be0da9e61f66ea17990768062017e68e01e39f /assuan/assuan-buffer.c | |
parent | 2001-11-20 Marcus Brinkmann <[email protected]> (diff) | |
download | gpgme-a441158cc77391ba8857928f01fd20ac1569ad85.tar.gz gpgme-a441158cc77391ba8857928f01fd20ac1569ad85.zip |
2001-11-20 Marcus Brinkmann <[email protected]>
* Makefile.am (SUBDIRS): Support building the assuan library
(currently if GPGSM_PATH is set)..
* configure.ac: Support building the assuan library.
* assuan: New directory, populated with the Assuan library
(copied from the newpg repository).
gpgme/
2001-11-20 Marcus Brinkmann <[email protected]>
* Makefile.am (libgpgme_la_INCLUDES): Remove obsolete directive.
(AM_CPPFLAGS): New directive [BUILD_ASSUAN].
(libgpgme_la_LIBADD): Likewise.
Diffstat (limited to 'assuan/assuan-buffer.c')
-rw-r--r-- | assuan/assuan-buffer.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/assuan/assuan-buffer.c b/assuan/assuan-buffer.c new file mode 100644 index 00000000..912272f1 --- /dev/null +++ b/assuan/assuan-buffer.c @@ -0,0 +1,247 @@ +/* assuan-buffer.c - read and send data + * Copyright (C) 2001 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#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; + } + + 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, const char *line ) +{ + 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; +} + + + +/* Write out the data in buffer as datalines with line wrapping and + percent escaping. This fucntion is used for GNU's custom streams */ +int +_assuan_cookie_write_data (void *cookie, const char *buffer, size_t size) +{ + ASSUAN_CONTEXT ctx = cookie; + char *line; + size_t linelen; + + if (ctx->outbound.data.error) + return 0; + + line = ctx->outbound.data.line; + linelen = ctx->outbound.data.linelen; + line += linelen; + while (size) + { + /* insert data line header */ + if (!linelen) + { + *line++ = 'D'; + *line++ = ' '; + linelen += 2; + } + + /* copy data, keep some space for the CRLF and to escape one character */ + while (size && linelen < LINELENGTH-2-2) + { + if (*buffer == '%' || *buffer == '\r' || *buffer == '\n') + { + sprintf (line, "%%%02X", *(unsigned char*)buffer); + line += 3; + linelen += 3; + buffer++; + } + else + { + *line++ = *buffer++; + linelen++; + } + size--; + } + + if (linelen >= LINELENGTH-2-2) + { + *line++ = '\n'; + linelen++; + if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen)) + { + ctx->outbound.data.error = ASSUAN_Write_Error; + return 0; + } + line = ctx->outbound.data.line; + linelen = 0; + } + } + + ctx->outbound.data.linelen = linelen; + return 0; +} + + +/* Write out any buffered data + This fucntion is used for GNU's custom streams */ +int +_assuan_cookie_write_flush (void *cookie) +{ + ASSUAN_CONTEXT ctx = cookie; + char *line; + size_t linelen; + + if (ctx->outbound.data.error) + return 0; + + line = ctx->outbound.data.line; + linelen = ctx->outbound.data.linelen; + line += linelen; + if (linelen) + { + *line++ = '\n'; + linelen++; + if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen)) + { + ctx->outbound.data.error = ASSUAN_Write_Error; + return 0; + } + ctx->outbound.data.linelen = 0; + } + return 0; +} + + + + |