New debug functions log_printcanon and log_printsexp.
[gnupg.git] / common / estream.h
index 382b6da..e3c28fe 100644 (file)
@@ -1,22 +1,55 @@
-/* estream.h - Extended stream I/O/ Library
-   Copyright (C) 2004 g10 Code GmbH
-
-   This file is part of Libestream.
-   Libestream 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.
-   Libestream 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
-   Lesser General Public License for more details.
-   You should have received a copy of the GNU General Public License
-   along with Libestream; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+/* estream.h - Extended stream I/O Library
+ * Copyright (C) 2004, 2005, 2006, 2007, 2010, 2011 g10 Code GmbH
+ *
+ * This file is part of Libestream.
+ *
+ * Libestream 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.
+ *
+ * Libestream 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 Libestream; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * ALTERNATIVELY, Libestream may be distributed under the terms of the
+ * following license, in which case the provisions of this license are
+ * required INSTEAD OF the GNU General Public License. If you wish to
+ * allow use of your version of this file only under the terms of the
+ * GNU General Public License, and not to allow others to use your
+ * version of this file under the terms of the following license,
+ * indicate your decision by deleting this paragraph and the license
+ * below.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #ifndef ESTREAM_H
 #define ESTREAM_H
 #include <stdarg.h>
 #include <stdio.h>
 
-\f
+/* To use this file with libraries the following macro is useful:
+
+     #define _ESTREAM_EXT_SYM_PREFIX _foo_
+
+       This prefixes all external symbols with "_foo_".
+
+ */
+
+
+#ifdef _ESTREAM_EXT_SYM_PREFIX
+#ifndef _ESTREAM_PREFIX
+#define _ESTREAM_PREFIX1(x,y)  x ## y
+#define _ESTREAM_PREFIX2(x,y) _ESTREAM_PREFIX1(x,y)
+#define _ESTREAM_PREFIX(x)    _ESTREAM_PREFIX2(_ESTREAM_EXT_SYM_PREFIX,x)
+#endif /*_ESTREAM_PREFIX*/
+#define es_fopen              _ESTREAM_PREFIX(es_fopen)
+#define es_mopen              _ESTREAM_PREFIX(es_mopen)
+#define es_fopenmem           _ESTREAM_PREFIX(es_fopenmem)
+#define es_fopenmem_init      _ESTREAM_PREFIX(es_fopenmem_init)
+#define es_fdopen             _ESTREAM_PREFIX(es_fdopen)
+#define es_fdopen_nc          _ESTREAM_PREFIX(es_fdopen_nc)
+#define es_sysopen            _ESTREAM_PREFIX(es_sysopen)
+#define es_sysopen_nc         _ESTREAM_PREFIX(es_sysopen_nc)
+#define es_fpopen             _ESTREAM_PREFIX(es_fpopen)
+#define es_fpopen_nc          _ESTREAM_PREFIX(es_fpopen_nc)
+#define _es_set_std_fd        _ESTREAM_PREFIX(_es_set_std_fd)
+#define _es_get_std_stream    _ESTREAM_PREFIX(_es_get_std_stream)
+#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)
+#define es_flockfile          _ESTREAM_PREFIX(es_flockfile)
+#define es_ftrylockfile       _ESTREAM_PREFIX(es_ftrylockfile)
+#define es_funlockfile        _ESTREAM_PREFIX(es_funlockfile)
+#define es_feof               _ESTREAM_PREFIX(es_feof)
+#define es_feof_unlocked      _ESTREAM_PREFIX(es_feof_unlocked)
+#define es_ferror             _ESTREAM_PREFIX(es_ferror)
+#define es_ferror_unlocked    _ESTREAM_PREFIX(es_ferror_unlocked)
+#define es_clearerr           _ESTREAM_PREFIX(es_clearerr)
+#define es_clearerr_unlocked  _ESTREAM_PREFIX(es_clearerr_unlocked)
+#define es_fflush             _ESTREAM_PREFIX(es_fflush)
+#define es_fseek              _ESTREAM_PREFIX(es_fseek)
+#define es_fseeko             _ESTREAM_PREFIX(es_fseeko)
+#define es_ftell              _ESTREAM_PREFIX(es_ftell)
+#define es_ftello             _ESTREAM_PREFIX(es_ftello)
+#define es_rewind             _ESTREAM_PREFIX(es_rewind)
+#define es_fgetc              _ESTREAM_PREFIX(es_fgetc)
+#define es_fputc              _ESTREAM_PREFIX(es_fputc)
+#define _es_getc_underflow    _ESTREAM_PREFIX(_es_getc_underflow)
+#define _es_putc_overflow     _ESTREAM_PREFIX(_es_putc_overflow)
+#define es_ungetc             _ESTREAM_PREFIX(es_ungetc)
+#define es_read               _ESTREAM_PREFIX(es_read)
+#define es_write              _ESTREAM_PREFIX(es_write)
+#define es_write_sanitized    _ESTREAM_PREFIX(es_write_sanitized)
+#define es_write_hexstring    _ESTREAM_PREFIX(es_write_hexstring)
+#define es_fread              _ESTREAM_PREFIX(es_fread)
+#define es_fwrite             _ESTREAM_PREFIX(es_fwrite)
+#define es_fgets              _ESTREAM_PREFIX(es_fgets)
+#define es_fputs              _ESTREAM_PREFIX(es_fputs)
+#define es_fputs_unlocked     _ESTREAM_PREFIX(es_fputs_unlocked)
+#define es_getline            _ESTREAM_PREFIX(es_getline)
+#define es_read_line          _ESTREAM_PREFIX(es_read_line)
+#define es_free               _ESTREAM_PREFIX(es_free)
+#define es_fprintf            _ESTREAM_PREFIX(es_fprintf)
+#define es_fprintf_unlocked   _ESTREAM_PREFIX(es_fprintf_unlocked)
+#define es_printf             _ESTREAM_PREFIX(es_printf)
+#define es_printf_unlocked    _ESTREAM_PREFIX(es_printf_unlocked)
+#define es_vfprintf           _ESTREAM_PREFIX(es_vfprint)
+#define es_vfprintf_unlocked  _ESTREAM_PREFIX(es_vfprint_unlocked)
+#define es_setvbuf            _ESTREAM_PREFIX(es_setvbuf)
+#define es_setbuf             _ESTREAM_PREFIX(es_setbuf)
+#define es_set_binary         _ESTREAM_PREFIX(es_set_binary)
+#define es_tmpfile            _ESTREAM_PREFIX(es_tmpfile)
+#define es_opaque_set         _ESTREAM_PREFIX(es_opaque_set)
+#define es_opaque_get         _ESTREAM_PREFIX(es_opaque_get)
+#define es_fname_set          _ESTREAM_PREFIX(es_fname_set)
+#define es_fname_get          _ESTREAM_PREFIX(es_fname_get)
+#define es_write_sanitized_utf8_buffer  \
+              _ESTREAM_PREFIX(es_write_sanitized_utf8_buffer)
+#endif /*_ESTREAM_EXT_SYM_PREFIX*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0
+}
+#endif
+#endif
+
+
 /* Forward declaration for the (opaque) internal type.  */
 struct estream_internal;
 
@@ -60,8 +186,10 @@ struct es__stream
   size_t unread_data_len;
 
   /* Various flags.  */
-#define ES__FLAG_WRITING       (1 << 0)
-  unsigned int flags;
+  struct {
+    unsigned int writing: 1;
+    unsigned int reserved: 7;
+  } flags;
 
   /* A pointer to our internal data for this stream.  */
   struct estream_internal *intern;
@@ -72,9 +200,9 @@ typedef struct es__stream *estream_t;
 
 \f
 typedef ssize_t (*es_cookie_read_function_t) (void *cookie,
-                                             char *buffer, size_t size);
+                                             void *buffer, size_t size);
 typedef ssize_t (*es_cookie_write_function_t) (void *cookie,
-                                              const char *buffer,
+                                              const void *buffer,
                                               size_t size);
 typedef int (*es_cookie_seek_function_t) (void *cookie,
                                          off_t *pos, int whence);
@@ -88,7 +216,39 @@ typedef struct es_cookie_io_functions
   es_cookie_close_function_t func_close;
 } es_cookie_io_functions_t;
 
+
+enum es_syshd_types
+  {
+    ES_SYSHD_NONE,  /* No system handle available.  */
+    ES_SYSHD_FD,    /* A file descriptor as returned by open().  */
+    ES_SYSHD_SOCK,  /* A socket as returned by socket().        */
+    ES_SYSHD_RVID,  /* A rendevous id (see libassuan's gpgcedev.c).  */
+    ES_SYSHD_HANDLE /* A HANDLE object (Windows).  */
+  };
+
+typedef struct
+{
+  enum es_syshd_types type;
+  union {
+    int fd;
+    int sock;
+    int rvid;
+    void *handle;
+  } u;
+} es_syshd_t;
+
+
+
 \f
+#ifndef _ESTREAM_GCC_A_PRINTF
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
+# define _ESTREAM_GCC_A_PRINTF( f, a )  __attribute__ ((format (printf,f,a)))
+#else
+# define _ESTREAM_GCC_A_PRINTF( f, a )
+#endif
+#endif /*_ESTREAM_GCC_A_PRINTF*/
+
+
 #ifndef ES__RESTRICT
 #  if defined __GNUC__ && defined __GNUC_MINOR__
 #    if  (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 92))
@@ -104,14 +264,21 @@ int es_init (void);
 
 estream_t es_fopen (const char *ES__RESTRICT path,
                    const char *ES__RESTRICT mode);
-estream_t es_mopen (unsigned char *ES__RESTRICT data,
+estream_t es_mopen (void *ES__RESTRICT data,
                    size_t data_n, size_t data_len,
                    unsigned int grow,
                    void *(*func_realloc) (void *mem, size_t size),
                    void (*func_free) (void *mem),
                    const char *ES__RESTRICT mode);
-estream_t es_open_memstream (char **ptr, size_t *size);
+estream_t es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode);
+estream_t es_fopenmem_init (size_t memlimit, const char *ES__RESTRICT mode,
+                            const void *data, size_t datalen);
 estream_t es_fdopen (int filedes, const char *mode);
+estream_t es_fdopen_nc (int filedes, const char *mode);
+estream_t es_sysopen (es_syshd_t *syshd, const char *mode);
+estream_t es_sysopen_nc (es_syshd_t *syshd, const char *mode);
+estream_t es_fpopen (FILE *fp, const char *mode);
+estream_t es_fpopen_nc (FILE *fp, const char *mode);
 estream_t es_freopen (const char *ES__RESTRICT path,
                      const char *ES__RESTRICT mode,
                      estream_t ES__RESTRICT stream);
@@ -119,8 +286,21 @@ 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);
 int es_fileno_unlocked (estream_t stream);
+int es_syshd (estream_t stream, es_syshd_t *syshd);
+int es_syshd_unlocked (estream_t stream, es_syshd_t *syshd);
+
+void _es_set_std_fd (int no, int fd);
+estream_t _es_get_std_stream (int fd);
+
+#define es_stdin  _es_get_std_stream (0)
+#define es_stdout _es_get_std_stream (1)
+#define es_stderr _es_get_std_stream (2)
+
 
 void es_flockfile (estream_t stream);
 int es_ftrylockfile (estream_t stream);
@@ -147,14 +327,14 @@ int _es_getc_underflow (estream_t stream);
 int _es_putc_overflow (int c, estream_t stream);
 
 #define es_getc_unlocked(stream)                               \
-  (((! ((stream)->flags & 1))                                  \
+  (((!(stream)->flags.writing)                                 \
     && ((stream)->data_offset < (stream)->data_len)            \
     && (! (stream)->unread_data_len))                          \
   ? ((int) (stream)->buffer[((stream)->data_offset)++])                \
   : _es_getc_underflow ((stream)))
 
 #define es_putc_unlocked(c, stream)                            \
-  ((((stream)->flags & 1)                                      \
+  (((stream)->flags.writing                                    \
     && ((stream)->data_offset < (stream)->buffer_size)         \
     && (c != '\n'))                                            \
   ? ((int) ((stream)->buffer[((stream)->data_offset)++] = (c)))        \
@@ -166,11 +346,18 @@ int _es_putc_overflow (int c, estream_t stream);
 int es_ungetc (int c, estream_t stream);
 
 int es_read (estream_t ES__RESTRICT stream,
-            char *ES__RESTRICT buffer, size_t bytes_to_read,
+            void *ES__RESTRICT buffer, size_t bytes_to_read,
             size_t *ES__RESTRICT bytes_read);
 int es_write (estream_t ES__RESTRICT stream,
-             const char *ES__RESTRICT buffer, size_t bytes_to_write,
+             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);
@@ -179,23 +366,65 @@ size_t es_fwrite (const void *ES__RESTRICT ptr, size_t size, size_t memb,
 
 char *es_fgets (char *ES__RESTRICT s, int n, estream_t ES__RESTRICT stream);
 int es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream);
+int es_fputs_unlocked (const char *ES__RESTRICT s,
+                       estream_t ES__RESTRICT stream);
 
 ssize_t es_getline (char *ES__RESTRICT *ES__RESTRICT lineptr,
                    size_t *ES__RESTRICT n,
                    estream_t stream);
+ssize_t es_read_line (estream_t stream,
+                      char **addr_of_buffer, size_t *length_of_buffer,
+                      size_t *max_length);
+void es_free (void *a);
 
 int es_fprintf (estream_t ES__RESTRICT stream,
-               const char *ES__RESTRICT format, ...);
+               const char *ES__RESTRICT format, ...)
+     _ESTREAM_GCC_A_PRINTF(2,3);
+int es_fprintf_unlocked (estream_t ES__RESTRICT stream,
+                         const char *ES__RESTRICT format, ...)
+     _ESTREAM_GCC_A_PRINTF(2,3);
+
+int es_printf (const char *ES__RESTRICT format, ...)
+     _ESTREAM_GCC_A_PRINTF(1,2);
+int es_printf_unlocked (const char *ES__RESTRICT format, ...)
+     _ESTREAM_GCC_A_PRINTF(1,2);
+
 int es_vfprintf (estream_t ES__RESTRICT stream,
-                const char *ES__RESTRICT format, va_list ap);
+                const char *ES__RESTRICT format, va_list ap)
+     _ESTREAM_GCC_A_PRINTF(2,0);
+int es_vfprintf_unlocked (estream_t ES__RESTRICT stream,
+                          const char *ES__RESTRICT format, va_list ap)
+     _ESTREAM_GCC_A_PRINTF(2,0);
+
+char *es_asprintf (const char *ES__RESTRICT format, ...)
+     _ESTREAM_GCC_A_PRINTF(1,2);
+char *es_vasprintf (const char *ES__RESTRICT format, va_list ap)
+     _ESTREAM_GCC_A_PRINTF(1,0);
 
 int es_setvbuf (estream_t ES__RESTRICT stream,
                char *ES__RESTRICT buf, int mode, size_t size);
 void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf);
 
+void es_set_binary (estream_t stream);
+
+
 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);
 
+void es_fname_set (estream_t stream, const char *fname);
+const char *es_fname_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*/
+
+#ifdef __cplusplus
+}
 #endif
+#endif /*ESTREAM_H*/