aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/asshelp.c13
-rw-r--r--common/asshelp.h1
-rw-r--r--common/dotlock.c6
-rw-r--r--common/estream.c140
-rw-r--r--common/estream.h4
5 files changed, 161 insertions, 3 deletions
diff --git a/common/asshelp.c b/common/asshelp.c
index c5d8bdf84..7ac6ff0cc 100644
--- a/common/asshelp.c
+++ b/common/asshelp.c
@@ -97,6 +97,19 @@ setup_libassuan_logging (unsigned int *debug_var_address)
assuan_set_log_cb (my_libassuan_log_handler, debug_var_address);
}
+/* Change the Libassuan log categories to those given by NEWCATS.
+ NEWCATS is 0 the default category of ASSUAN_LOG_CONTROL is
+ selected. Note, that setup_libassuan_logging overrides the values
+ given here. */
+void
+set_libassuan_log_cats (unsigned int newcats)
+{
+ if (newcats)
+ log_cats = newcats;
+ else /* Default to log the control channel. */
+ log_cats = (1 << (ASSUAN_LOG_CONTROL - 1));
+}
+
static gpg_error_t
diff --git a/common/asshelp.h b/common/asshelp.h
index 0eb6553f9..728c03949 100644
--- a/common/asshelp.h
+++ b/common/asshelp.h
@@ -26,6 +26,7 @@
#include "session-env.h"
void setup_libassuan_logging (unsigned int *debug_var_address);
+void set_libassuan_log_cats (unsigned int newcats);
gpg_error_t
diff --git a/common/dotlock.c b/common/dotlock.c
index b4734b99f..5e17e64c6 100644
--- a/common/dotlock.c
+++ b/common/dotlock.c
@@ -583,7 +583,8 @@ use_hardlinks_p (const char *tname)
strcpy (lname, tname);
strcat (lname, "x");
- link (tname, lname);
+ /* We ignore the return value of link() because it is unreliable. */
+ (void) link (tname, lname);
if (stat (tname, &sb))
res = -1; /* Ooops. */
@@ -1004,7 +1005,8 @@ dotlock_take_unix (dotlock_t h, long timeout)
{
struct stat sb;
- link (h->tname, h->lockname);
+ /* We ignore the return value of link() because it is unreliable. */
+ (void) link (h->tname, h->lockname);
if (stat (h->tname, &sb))
{
diff --git a/common/estream.c b/common/estream.c
index 383210dff..32602a0f7 100644
--- a/common/estream.c
+++ b/common/estream.c
@@ -217,6 +217,17 @@ struct notify_list_s
};
typedef struct notify_list_s *notify_list_t;
+
+/* A private cookie function to implement an internal IOCTL
+ service. */
+typedef int (*cookie_ioctl_function_t) (void *cookie, int cmd,
+ void *ptr, size_t *len);
+/* IOCTL commands for the private cookie function. */
+#define COOKIE_IOCTL_SNATCH_BUFFER 1
+
+
+
+
/* An internal stream object. */
struct estream_internal
{
@@ -231,6 +242,7 @@ struct estream_internal
es_cookie_read_function_t func_read;
es_cookie_write_function_t func_write;
es_cookie_seek_function_t func_seek;
+ cookie_ioctl_function_t func_ioctl;
es_cookie_close_function_t func_close;
int strategy;
es_syshd_t syshd; /* A copy of the sytem handle. */
@@ -771,6 +783,33 @@ es_func_mem_seek (void *cookie, off_t *offset, int whence)
return 0;
}
+/* An IOCTL function for memory objects. */
+static int
+es_func_mem_ioctl (void *cookie, int cmd, void *ptr, size_t *len)
+{
+ estream_cookie_mem_t mem_cookie = cookie;
+ int ret;
+
+ if (cmd == COOKIE_IOCTL_SNATCH_BUFFER)
+ {
+ /* Return the internal buffer of the stream to the caller and
+ invalidate it for the stream. */
+ *(void**)ptr = mem_cookie->memory;
+ *len = mem_cookie->offset;
+ mem_cookie->memory = NULL;
+ mem_cookie->memory_size = 0;
+ mem_cookie->offset = 0;
+ ret = 0;
+ }
+ else
+ {
+ _set_errno (EINVAL);
+ ret = -1;
+ }
+
+ return ret;
+}
+
/* Destroy function for memory objects. */
static int
@@ -1608,6 +1647,7 @@ es_initialize (estream_t stream,
stream->intern->func_read = functions.func_read;
stream->intern->func_write = functions.func_write;
stream->intern->func_seek = functions.func_seek;
+ stream->intern->func_ioctl = NULL;
stream->intern->func_close = functions.func_close;
stream->intern->strategy = _IOFBF;
stream->intern->syshd = *syshd;
@@ -2667,6 +2707,47 @@ es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode)
if (es_create (&stream, cookie, &syshd, estream_functions_mem, modeflags, 0))
(*estream_functions_mem.func_close) (cookie);
+ if (stream)
+ stream->intern->func_ioctl = es_func_mem_ioctl;
+
+ return stream;
+}
+
+
+
+/* This is the same as es_fopenmem but intializes the memory with a
+ copy of (DATA,DATALEN). The stream is initally set to the
+ beginning. If MEMLIMIT is not 0 but shorter than DATALEN it
+ DATALEN will be used as the value for MEMLIMIT. */
+estream_t
+es_fopenmem_init (size_t memlimit, const char *ES__RESTRICT mode,
+ const void *data, size_t datalen)
+{
+ estream_t stream;
+
+ if (memlimit && memlimit < datalen)
+ memlimit = datalen;
+
+ stream = es_fopenmem (memlimit, mode);
+ if (stream && data && datalen)
+ {
+ if (es_writen (stream, data, datalen, NULL))
+ {
+ int saveerrno = errno;
+ es_fclose (stream);
+ stream = NULL;
+ _set_errno (saveerrno);
+ }
+ else
+ {
+ es_seek (stream, 0L, SEEK_SET, NULL);
+ es_set_indicators (stream, 0, 0);
+ }
+ }
+
+ if (stream)
+ stream->intern->func_ioctl = es_func_mem_ioctl;
+
return stream;
}
@@ -3082,6 +3163,65 @@ es_fclose (estream_t stream)
}
+/* This is a special version of es_fclose which can be used with
+ es_fopenmem to return the memory buffer. This is feature is useful
+ to write to a memory buffer using estream. Note that the function
+ does not close the stream if the stream does not support snatching
+ the buffer. On error NULL is stored at R_BUFFER. Note that if no
+ write operation has happened, NULL may also be stored at BUFFER on
+ success. The caller needs to release the returned memory using
+ es_free. */
+int
+es_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen)
+{
+ int err;
+
+ /* Note: There is no need to lock the stream in a close call. The
+ object will be destroyed after the close and thus any other
+ contender for the lock would work on a closed stream. */
+
+ if (r_buffer)
+ {
+ cookie_ioctl_function_t func_ioctl = stream->intern->func_ioctl;
+ size_t buflen;
+
+ *r_buffer = NULL;
+
+ if (!func_ioctl)
+ {
+ _set_errno (EOPNOTSUPP);
+ err = -1;
+ goto leave;
+ }
+
+ if (stream->flags.writing)
+ {
+ err = es_flush (stream);
+ if (err)
+ goto leave;
+ stream->flags.writing = 0;
+ }
+
+ err = func_ioctl (stream->intern->cookie, COOKIE_IOCTL_SNATCH_BUFFER,
+ r_buffer, &buflen);
+ if (err)
+ goto leave;
+ if (r_buflen)
+ *r_buflen = buflen;
+ }
+
+ err = do_close (stream, 0);
+
+ leave:
+ if (err && r_buffer)
+ {
+ mem_free (*r_buffer);
+ *r_buffer = NULL;
+ }
+ return err;
+}
+
+
/* Register or unregister a close notification function for STREAM.
FNC is the function to call and FNC_VALUE the value passed as
second argument. To register the notification the value for MODE
diff --git a/common/estream.h b/common/estream.h
index 49662766e..bbe5b62d6 100644
--- a/common/estream.h
+++ b/common/estream.h
@@ -1,5 +1,5 @@
/* estream.h - Extended stream I/O Library
- * Copyright (C) 2004, 2005, 2006, 2007, 2010 g10 Code GmbH
+ * Copyright (C) 2004, 2005, 2006, 2007, 2010, 2011 g10 Code GmbH
*
* This file is part of Libestream.
*
@@ -88,6 +88,7 @@
#define es_freopen _ESTREAM_PREFIX(es_freopen)
#define es_fopencookie _ESTREAM_PREFIX(es_fopencookie)
#define es_fclose _ESTREAM_PREFIX(es_fclose)
+#define es_fclose_snatch _ESTREAM_PREFIX(es_fclose_snatch)
#define es_onclose _ESTREAM_PREFIX(es_onclose)
#define es_fileno _ESTREAM_PREFIX(es_fileno)
#define es_fileno_unlocked _ESTREAM_PREFIX(es_fileno_unlocked)
@@ -285,6 +286,7 @@ estream_t es_fopencookie (void *ES__RESTRICT cookie,
const char *ES__RESTRICT mode,
es_cookie_io_functions_t functions);
int es_fclose (estream_t stream);
+int es_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen);
int es_onclose (estream_t stream, int mode,
void (*fnc) (estream_t, void*), void *fnc_value);
int es_fileno (estream_t stream);