diff options
author | Werner Koch <wk@gnupg.org> | 2007-03-19 15:35:04 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2007-03-19 15:35:04 +0100 |
commit | 12b661166c1eb5d2f09d50b4581b18d36eec94b1 (patch) | |
tree | 79179be0c079bbd30d4c89690128fd668c54a553 /common | |
parent | From STABLE-BRANCH-1-4 (diff) | |
download | gnupg2-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/ChangeLog | 7 | ||||
-rw-r--r-- | common/estream.c | 191 | ||||
-rw-r--r-- | common/estream.h | 17 | ||||
-rw-r--r-- | common/miscellaneous.c | 1 | ||||
-rw-r--r-- | common/util.h | 1 |
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 |