summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2007-03-19 15:35:04 +0100
committerWerner Koch <wk@gnupg.org>2007-03-19 15:35:04 +0100
commit12b661166c1eb5d2f09d50b4581b18d36eec94b1 (patch)
tree79179be0c079bbd30d4c89690128fd668c54a553 /common
parentFrom STABLE-BRANCH-1-4 (diff)
downloadgnupg2-12b661166c1eb5d2f09d50b4581b18d36eec94b1.tar.xz
gnupg2-12b661166c1eb5d2f09d50b4581b18d36eec94b1.zip
Changes to let the key listing use estream to help systems without
funopen.
Diffstat (limited to 'common')
-rw-r--r--common/ChangeLog7
-rw-r--r--common/estream.c191
-rw-r--r--common/estream.h17
-rw-r--r--common/miscellaneous.c1
-rw-r--r--common/util.h1
5 files changed, 215 insertions, 2 deletions
diff --git a/common/ChangeLog b/common/ChangeLog
index 6e2ce2b3b..58695ed35 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,10 @@
+2007-03-19 Werner Koch <wk@g10code.com>
+
+ * estream.c (es_fprintf_unlocked): New.
+ (es_write_sanitized): New.
+ (es_write_hexstring): New.
+ (es_write_sanitized_utf8_buffer) [GNUPG_MAJOR_VERSION]: New.
+
2007-03-09 David Shaw <dshaw@jabberwocky.com>
From STABLE-BRANCH-1-4
diff --git a/common/estream.c b/common/estream.c
index e63bc8919..31e91d5ee 100644
--- a/common/estream.c
+++ b/common/estream.c
@@ -1,5 +1,5 @@
/* estream.c - Extended Stream I/O Library
- * Copyright (C) 2004, 2006 g10 Code GmbH
+ * Copyright (C) 2004, 2006, 2007 g10 Code GmbH
*
* This file is part of Libestream.
*
@@ -49,6 +49,10 @@
# include <pth.h>
#endif
+#ifdef GNUPG_MAJOR_VERSION
+#include "../common/util.h"
+#endif
+
#ifndef HAVE_MKSTEMP
int mkstemp (char *template);
#endif
@@ -205,7 +209,9 @@ static estream_mutex_t estream_list_lock = ESTREAM_MUTEX_INITIALIZER;
/* Macros. */
/* Calculate array dimension. */
+#ifndef DIM
#define DIM(array) (sizeof (array) / sizeof (*array))
+#endif
/* Evaluate EXPRESSION, setting VARIABLE to the return code, if
VARIABLE is zero. */
@@ -740,6 +746,14 @@ static es_cookie_io_functions_t estream_functions_file =
static int
es_convert_mode (const char *mode, unsigned int *flags)
{
+
+ /* FIXME: We need to allow all combinations for mode flags and for
+ binary we need to do a
+
+ #ifdef HAVE_DOSISH_SYSTEM
+ setmode (fd, O_BINARY);
+ #endif
+ */
struct
{
const char *mode;
@@ -2702,6 +2716,21 @@ es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format,
}
+static int
+es_fprintf_unlocked (estream_t ES__RESTRICT stream,
+ const char *ES__RESTRICT format, ...)
+{
+ int ret;
+
+ va_list ap;
+ va_start (ap, format);
+ ret = es_print (stream, format, ap);
+ va_end (ap);
+
+ return ret;
+}
+
+
int
es_fprintf (estream_t ES__RESTRICT stream,
const char *ES__RESTRICT format, ...)
@@ -2839,3 +2868,163 @@ es_opaque_get (estream_t stream)
return opaque;
}
+
+
+/* Print a BUFFER to STREAM while replacing all control characters and
+ the characters in DELIMITERS by standard C escape sequences.
+ Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL
+ the number of bytes actually written are stored at this
+ address. */
+int
+es_write_sanitized (estream_t ES__RESTRICT stream,
+ const void * ES__RESTRICT buffer, size_t length,
+ const char * delimiters,
+ size_t * ES__RESTRICT bytes_written)
+{
+ const unsigned char *p = buffer;
+ size_t count = 0;
+ int ret;
+
+ ESTREAM_LOCK (stream);
+ for (; length; length--, p++, count++)
+ {
+ if (*p < 0x20
+ || (*p >= 0x7f && *p < 0xa0)
+ || (delimiters
+ && (strchr (delimiters, *p) || *p == '\\')))
+ {
+ es_putc_unlocked ('\\', stream);
+ count++;
+ if (*p == '\n')
+ {
+ es_putc_unlocked ('n', stream);
+ count++;
+ }
+ else if (*p == '\r')
+ {
+ es_putc_unlocked ('r', stream);
+ count++;
+ }
+ else if (*p == '\f')
+ {
+ es_putc_unlocked ('f', stream);
+ count++;
+ }
+ else if (*p == '\v')
+ {
+ es_putc_unlocked ('v', stream);
+ count++;
+ }
+ else if (*p == '\b')
+ {
+ es_putc_unlocked ('b', stream);
+ count++;
+ }
+ else if (!*p)
+ {
+ es_putc_unlocked('0', stream);
+ count++;
+ }
+ else
+ {
+ es_fprintf_unlocked (stream, "x%02x", *p);
+ count += 3;
+ }
+ }
+ else
+ {
+ es_putc_unlocked (*p, stream);
+ count++;
+ }
+ }
+
+ if (bytes_written)
+ *bytes_written = count;
+ ret = es_ferror_unlocked (stream)? -1 : 0;
+ ESTREAM_UNLOCK (stream);
+
+ return ret;
+}
+
+
+/* Write LENGTH bytes of BUFFER to STREAM as a hex encoded string.
+ RESERVED must be 0. Returns 0 on success or -1 on error. If
+ BYTES_WRITTEN is not NULL the number of bytes actually written are
+ stored at this address. */
+int
+es_write_hexstring (estream_t ES__RESTRICT stream,
+ const void *ES__RESTRICT buffer, size_t length,
+ int reserved, size_t *ES__RESTRICT bytes_written )
+{
+ int ret;
+ const unsigned char *s;
+ size_t count = 0;
+
+#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
+
+ if (!length)
+ return 0;
+
+ ESTREAM_LOCK (stream);
+
+ for (s = buffer; length; s++, length--)
+ {
+ es_putc_unlocked ( tohex ((*s>>4)&15), stream);
+ es_putc_unlocked ( tohex (*s&15), stream);
+ count += 2;
+ }
+
+ if (bytes_written)
+ *bytes_written = count;
+ ret = es_ferror_unlocked (stream)? -1 : 0;
+
+ ESTREAM_UNLOCK (stream);
+
+ return ret;
+
+#undef tohex
+}
+
+
+
+#ifdef GNUPG_MAJOR_VERSION
+/* Special estream function to print an UTF8 string in the native
+ encoding. The interface is the same as es_write_sanitized, however
+ only one delimiter may be supported.
+
+ THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG. */
+int
+es_write_sanitized_utf8_buffer (estream_t stream,
+ const void *buffer, size_t length,
+ const char *delimiters, size_t *bytes_written)
+{
+ const char *p = buffer;
+ size_t i;
+
+ /* We can handle plain ascii simpler, so check for it first. */
+ for (i=0; i < length; i++ )
+ {
+ if ( (p[i] & 0x80) )
+ break;
+ }
+ if (i < length)
+ {
+ int delim = delimiters? *delimiters : 0;
+ char *buf;
+ int ret;
+
+ /*(utf8 conversion already does the control character quoting). */
+ buf = utf8_to_native (p, length, delim);
+ if (bytes_written)
+ *bytes_written = strlen (buf);
+ ret = es_fputs (buf, stream);
+ xfree (buf);
+ return i;
+ }
+ else
+ return es_write_sanitized (stream, p, length, delimiters, bytes_written);
+}
+#endif /*GNUPG_MAJOR_VERSION*/
+
+
+
diff --git a/common/estream.h b/common/estream.h
index 123a65a97..aede40868 100644
--- a/common/estream.h
+++ b/common/estream.h
@@ -172,6 +172,13 @@ int es_read (estream_t ES__RESTRICT stream,
int es_write (estream_t ES__RESTRICT stream,
const void *ES__RESTRICT buffer, size_t bytes_to_write,
size_t *ES__RESTRICT bytes_written);
+int es_write_sanitized (estream_t ES__RESTRICT stream,
+ const void *ES__RESTRICT buffer, size_t length,
+ const char *delimiters,
+ size_t *ES__RESTRICT bytes_written);
+int es_write_hexstring (estream_t ES__RESTRICT stream,
+ const void *ES__RESTRICT buffer, size_t length,
+ int reserved, size_t *ES__RESTRICT bytes_written);
size_t es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems,
estream_t ES__RESTRICT stream);
@@ -203,5 +210,15 @@ estream_t es_tmpfile (void);
void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque);
void *es_opaque_get (estream_t stream);
+
+
+#ifdef GNUPG_MAJOR_VERSION
+int es_write_sanitized_utf8_buffer (estream_t stream,
+ const void *buffer, size_t length,
+ const char *delimiters,
+ size_t *bytes_written);
+#endif /*GNUPG_MAJOR_VERSION*/
+
+
#endif /*ESTREAM_H*/
diff --git a/common/miscellaneous.c b/common/miscellaneous.c
index 364f13489..948c8ef48 100644
--- a/common/miscellaneous.c
+++ b/common/miscellaneous.c
@@ -74,6 +74,7 @@ make_printable_string (const void *p, size_t n, int delim )
}
+
/*
* Check if the file is compressed.
*/
diff --git a/common/util.h b/common/util.h
index f93283045..324fbb265 100644
--- a/common/util.h
+++ b/common/util.h
@@ -43,7 +43,6 @@
#include "../jnlib/dotlock.h"
#include "../jnlib/utf8conv.h"
-
#if __GNUC__ >= 4
# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
#else