summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2011-01-18 12:50:02 +0100
committerWerner Koch <wk@gnupg.org>2011-01-18 12:50:02 +0100
commitc2c5d30db8c0411afaaaeb1653096498894a38a8 (patch)
tree88ff681139f7d72967cf3d41793264e6b86869f5 /common
parentFix es_fopenmem and es_mopen bug. (diff)
downloadgnupg2-c2c5d30db8c0411afaaaeb1653096498894a38a8.tar.xz
gnupg2-c2c5d30db8c0411afaaaeb1653096498894a38a8.zip
estream support for iobuf and new memuf functions.
Diffstat (limited to 'common')
-rw-r--r--common/ChangeLog17
-rw-r--r--common/iobuf.c127
-rw-r--r--common/iobuf.h2
-rw-r--r--common/membuf.c45
-rw-r--r--common/membuf.h3
5 files changed, 189 insertions, 5 deletions
diff --git a/common/ChangeLog b/common/ChangeLog
index 1484ae0eb..3ce80cb1a 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,4 +1,12 @@
-2011-01-07 Werner Koch <wk@g10code.com>
+2011-01-18 Werner Koch <wk@g10code.com>
+
+ * iobuf.c (file_es_filter_ctx_t): New.
+ (file_es_filter): New.
+ (iobuf_esopen): New.
+
+ * estream.c (es_func_mem_write): Fix computation of NEWSIZE.
+
+ * membuf.c (clear_membuf, peek_membuf): New.
* util.h (GPG_ERR_NO_KEYSERVER): New.
@@ -10,6 +18,11 @@
* http.h (parsed_uri_s): Add field IS_HTTP.
(http_parse_uri): Support NO_SCHEME_CHECK arg.
+2011-01-10 Werner Koch <wk@g10code.com>
+
+ * session-env.c (update_var): Fix same value detection. Fixes
+ bug#1311.
+
2010-12-17 Werner Koch <wk@g10code.com>
* asshelp.c (lock_spawning): Add arg VERBOSE. Improve timeout
@@ -2263,7 +2276,7 @@
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010, 2011 Free Software Foundation, Inc.
+ 2009, 2010 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
diff --git a/common/iobuf.c b/common/iobuf.c
index b9bed3218..9813d3da6 100644
--- a/common/iobuf.c
+++ b/common/iobuf.c
@@ -1,6 +1,6 @@
/* iobuf.c - File Handling for OpenPGP.
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
- * 2009, 2010 Free Software Foundation, Inc.
+ * 2009, 2010, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -78,6 +78,17 @@ typedef struct
char fname[1]; /* Name of the file. */
} file_filter_ctx_t;
+/* The context used by the estream filter. */
+typedef struct
+{
+ estream_t fp; /* Open estream handle. */
+ int keep_open;
+ int no_cache;
+ int eof_seen;
+ int print_only_name; /* Flags indicating that fname is not a real file. */
+ char fname[1]; /* Name of the file. */
+} file_es_filter_ctx_t;
+
/* Object to control the "close cache". */
struct close_cache_s
@@ -577,6 +588,96 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
}
+/* Similar to file_filter but using the estream system. */
+static int
+file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
+ size_t * ret_len)
+{
+ file_es_filter_ctx_t *a = opaque;
+ estream_t f = a->fp;
+ size_t size = *ret_len;
+ size_t nbytes = 0;
+ int rc = 0;
+
+ (void)chain; /* Not used. */
+
+ if (control == IOBUFCTRL_UNDERFLOW)
+ {
+ assert (size); /* We need a buffer. */
+ if (a->eof_seen)
+ {
+ rc = -1;
+ *ret_len = 0;
+ }
+ else
+ {
+ nbytes = 0;
+ rc = es_read (f, buf, size, &nbytes);
+ if (rc == -1)
+ { /* error */
+ rc = gpg_error_from_syserror ();
+ log_error ("%s: read error: %s\n", a->fname, strerror (errno));
+ }
+ else if (!nbytes)
+ { /* eof */
+ a->eof_seen = 1;
+ rc = -1;
+ }
+ *ret_len = nbytes;
+ }
+ }
+ else if (control == IOBUFCTRL_FLUSH)
+ {
+ if (size)
+ {
+ byte *p = buf;
+ size_t nwritten;
+
+ nbytes = size;
+ do
+ {
+ nwritten = 0;
+ if (es_write (f, p, nbytes, &nwritten))
+ {
+ rc = gpg_error_from_syserror ();
+ log_error ("%s: write error: %s\n",
+ a->fname, strerror (errno));
+ break;
+ }
+ p += nwritten;
+ nbytes -= nwritten;
+ }
+ while (nbytes);
+ nbytes = p - buf;
+ }
+ *ret_len = nbytes;
+ }
+ else if (control == IOBUFCTRL_INIT)
+ {
+ a->eof_seen = 0;
+ a->no_cache = 0;
+ }
+ else if (control == IOBUFCTRL_DESC)
+ {
+ *(char **) buf = "estream_filter";
+ }
+ else if (control == IOBUFCTRL_FREE)
+ {
+ if (f != es_stdin && f != es_stdout)
+ {
+ if (DBG_IOBUF)
+ log_debug ("%s: es_fclose %p\n", a->fname, f);
+ if (!a->keep_open)
+ es_fclose (f);
+ }
+ f = NULL;
+ xfree (a); /* We can free our context now. */
+ }
+
+ return rc;
+}
+
+
#ifdef HAVE_W32_SYSTEM
/* Because network sockets are special objects under Lose32 we have to
use a dedicated filter for them. */
@@ -1258,6 +1359,30 @@ iobuf_fdopen_nc (int fd, const char *mode)
iobuf_t
+iobuf_esopen (estream_t estream, const char *mode, int keep_open)
+{
+ iobuf_t a;
+ file_es_filter_ctx_t *fcx;
+ size_t len;
+
+ a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE);
+ fcx = xtrymalloc (sizeof *fcx + 30);
+ fcx->fp = estream;
+ fcx->print_only_name = 1;
+ fcx->keep_open = keep_open;
+ sprintf (fcx->fname, "[fd %p]", estream);
+ a->filter = file_es_filter;
+ a->filter_ov = fcx;
+ file_es_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
+ file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
+ if (DBG_IOBUF)
+ log_debug ("iobuf-%d.%d: esopen%s `%s'\n",
+ a->no, a->subno, keep_open? "_nc":"", fcx->fname);
+ return a;
+}
+
+
+iobuf_t
iobuf_sockopen (int fd, const char *mode)
{
iobuf_t a;
diff --git a/common/iobuf.h b/common/iobuf.h
index 1d863fdcd..3ac4fa061 100644
--- a/common/iobuf.h
+++ b/common/iobuf.h
@@ -23,6 +23,7 @@
#include "../include/types.h" /* fixme: should be moved elsewhere. */
#include "../common/sysutils.h"
+#include "../common/estream.h"
#define DBG_IOBUF iobuf_debug_mode
@@ -102,6 +103,7 @@ iobuf_t iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname,
iobuf_t iobuf_open (const char *fname);
iobuf_t iobuf_fdopen (int fd, const char *mode);
iobuf_t iobuf_fdopen_nc (int fd, const char *mode);
+iobuf_t iobuf_esopen (estream_t estream, const char *mode, int keep_open);
iobuf_t iobuf_sockopen (int fd, const char *mode);
iobuf_t iobuf_create (const char *fname);
iobuf_t iobuf_append (const char *fname);
diff --git a/common/membuf.c b/common/membuf.c
index f9f82d357..8648044a7 100644
--- a/common/membuf.c
+++ b/common/membuf.c
@@ -1,5 +1,5 @@
/* membuf.c - A simple implementation of a dynamic buffer.
- * Copyright (C) 2001, 2003, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2009, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -56,6 +56,26 @@ init_membuf_secure (membuf_t *mb, int initiallen)
}
+/* Shift the the content of the membuf MB by AMOUNT bytes. The next
+ operation will then behave as if AMOUNT bytes had not been put into
+ the buffer. If AMOUNT is greater than the actual accumulated
+ bytes, the membuf is basically reset to its initial state. */
+void
+clear_membuf (membuf_t *mb, size_t amount)
+{
+ /* No need to clear if we are already out of core. */
+ if (mb->out_of_core)
+ return;
+ if (amount >= mb->len)
+ mb->len = 0;
+ else
+ {
+ mb->len -= amount;
+ memmove (mb->buf, mb->buf+amount, mb->len);
+ }
+}
+
+
void
put_membuf (membuf_t *mb, const void *buf, size_t len)
{
@@ -116,3 +136,26 @@ get_membuf (membuf_t *mb, size_t *len)
mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
return p;
}
+
+
+/* Peek at the membuf MB. On success a pointer to the buffer is
+ returned which is valid until the next operation on MB. If LEN is
+ not NULL the current LEN of the buffer is stored there. On error
+ NULL is returned and ERRNO is set. */
+const void *
+peek_membuf (membuf_t *mb, size_t *len)
+{
+ const char *p;
+
+ if (mb->out_of_core)
+ {
+ gpg_err_set_errno (mb->out_of_core);
+ return NULL;
+ }
+
+ p = mb->buf;
+ if (len)
+ *len = mb->len;
+ return p;
+}
+
diff --git a/common/membuf.h b/common/membuf.h
index 75b506d5d..9f1a7a33b 100644
--- a/common/membuf.h
+++ b/common/membuf.h
@@ -39,9 +39,10 @@ typedef struct private_membuf_s membuf_t;
void init_membuf (membuf_t *mb, int initiallen);
void init_membuf_secure (membuf_t *mb, int initiallen);
+void clear_membuf (membuf_t *mb, size_t amount);
void put_membuf (membuf_t *mb, const void *buf, size_t len);
void put_membuf_str (membuf_t *mb, const char *string);
void *get_membuf (membuf_t *mb, size_t *len);
-
+const void *peek_membuf (membuf_t *mb, size_t *len);
#endif /*GNUPG_COMMON_MEMBUF_H*/