threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \
utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
-utils/printf_hook.c utils/settings.c
+utils/printf_hook/printf_hook_vstr.c utils/settings.c
# adding the plugin source files
threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \
utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
-utils/printf_hook.c utils/settings.c
+utils/settings.c
if USE_DEV_HEADERS
strongswan_includedir = ${dev_headers}
threading/rwlock.h threading/rwlock_condvar.h threading/lock_profiler.h \
utils/utils.h utils/chunk.h utils/debug.h utils/enum.h utils/identification.h \
utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
-utils/leak_detective.h utils/printf_hook.h utils/settings.h utils/integrity_checker.h
+utils/leak_detective.h utils/printf_hook/printf_hook.h \
+utils/printf_hook/printf_hook_vstr.h \
+utils/settings.h utils/integrity_checker.h
endif
library.lo : $(top_builddir)/config.status
endif
if USE_VSTR
+ libstrongswan_la_SOURCES += utils/printf_hook/printf_hook_vstr.c
libstrongswan_la_LIBADD += -lvstr
endif
+if !USE_VSTR
+ libstrongswan_la_SOURCES += utils/printf_hook/printf_hook_glibc.c
+endif
+
if USE_LIBCAP
libstrongswan_la_LIBADD += -lcap
endif
#endif
/* make sure we include printf_hook.h and utils.h first */
-#include "utils/printf_hook.h"
+#include "utils/printf_hook/printf_hook.h"
#include "utils/utils.h"
#include "networking/host_resolver.h"
#include "networking/streams/stream_manager.h"
#ifndef ENUM_H_
#define ENUM_H_
-#include "printf_hook.h"
+#include <utils/printf_hook/printf_hook.h>
typedef struct enum_name_t enum_name_t;
+++ /dev/null
-/*
- * Copyright (C) 2009-2013 Tobias Brunner
- * Copyright (C) 2006-2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program 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.
- */
-
-#include "printf_hook.h"
-
-#include "utils.h"
-#include "debug.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/uio.h>
-
-typedef struct private_printf_hook_t private_printf_hook_t;
-typedef struct printf_hook_handler_t printf_hook_handler_t;
-
-#define PRINTF_BUF_LEN 8192
-#define ARGS_MAX 3
-
-/**
- * private data of printf_hook
- */
-struct private_printf_hook_t {
-
- /**
- * public functions
- */
- printf_hook_t public;
-};
-
-/**
- * struct with information about a registered handler
- */
-struct printf_hook_handler_t {
-
- /**
- * callback function
- */
- printf_hook_function_t hook;
-
- /**
- * number of arguments
- */
- int numargs;
-
- /**
- * types of the arguments
- */
- int argtypes[ARGS_MAX];
-
-#ifdef USE_VSTR
- /**
- * name required for Vstr
- */
- char *name;
-#endif
-};
-
-/* A-Z | 6 other chars | a-z */
-#define NUM_HANDLERS 58
-static printf_hook_handler_t *printf_hooks[NUM_HANDLERS];
-
-#define SPEC_TO_INDEX(spec) ((int)(spec) - (int)'A')
-#define IS_VALID_SPEC(spec) (SPEC_TO_INDEX(spec) > -1 && SPEC_TO_INDEX(spec) < NUM_HANDLERS)
-
-#if !defined(USE_VSTR) && \
- (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER))
-
-/**
- * Printf hook print function. This is actually of type "printf_function",
- * however glibc does it typedef to function, but uclibc to a pointer.
- * So we redefine it here.
- */
-static int custom_print(FILE *stream, const struct printf_info *info,
- const void *const *args)
-{
- printf_hook_spec_t spec;
- printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
- printf_hook_data_t data = {
- .stream = stream,
- };
-
- spec.hash = info->alt;
- spec.plus = info->showsign;
- spec.minus = info->left;
- spec.width = info->width;
-
- return handler->hook(&data, &spec, args);
-}
-
-/**
- * Printf hook arginfo function, which is actually of type
- * "printf_arginfo_[size_]function".
- */
-static int custom_arginfo(const struct printf_info *info, size_t n, int *argtypes
-#ifdef HAVE_PRINTF_SPECIFIER
- , int *size
-#endif
- )
-{
- int i;
- printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
-
- if (handler->numargs <= n)
- {
- for (i = 0; i < handler->numargs; ++i)
- {
- argtypes[i] = handler->argtypes[i];
- }
- }
- /* we never set "size", as we have no user defined types */
- return handler->numargs;
-}
-
-#else
-
-#include <errno.h>
-#include <unistd.h> /* for STDOUT_FILENO */
-
-/**
- * These are used below, whenever the public wrapper functions are called before
- * initialization or after destruction.
- */
-#undef vprintf
-#undef vfprintf
-#undef vsnprintf
-
-/**
- * Vstr custom format specifier callback function.
- */
-static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec)
-{
- int i;
- const void *args[ARGS_MAX];
- printf_hook_spec_t spec;
- printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(fmt_spec->name[0])];
- printf_hook_data_t data = {
- .base = base,
- .pos = pos,
- };
-
- for (i = 0; i < handler->numargs; i++)
- {
- switch(handler->argtypes[i])
- {
- case PRINTF_HOOK_ARGTYPE_INT:
- args[i] = VSTR_FMT_CB_ARG_PTR(fmt_spec, i);
- break;
- case PRINTF_HOOK_ARGTYPE_POINTER:
- args[i] = &VSTR_FMT_CB_ARG_PTR(fmt_spec, i);
- break;
- }
- }
-
- spec.hash = fmt_spec->fmt_hash;
- spec.plus = fmt_spec->fmt_plus;
- spec.minus = fmt_spec->fmt_minus;
- spec.width = fmt_spec->fmt_field_width;
-
- handler->hook(&data, &spec, args);
- return 1;
-}
-
-/**
- * Add a custom format handler to the given Vstr_conf object
- */
-static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler)
-{
- int *at = handler->argtypes;
- switch(handler->numargs)
- {
- case 1:
- vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0],
- VSTR_TYPE_FMT_END);
- break;
- case 2:
- vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0],
- at[1], VSTR_TYPE_FMT_END);
- break;
- case 3:
- vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0],
- at[1], at[2], VSTR_TYPE_FMT_END);
- break;
- }
-}
-
-/**
- * Management of thread-specific Vstr_conf objects
- */
-#include <threading/thread_value.h>
-
-static thread_value_t *vstr_conf = NULL;
-
-static Vstr_conf *create_vstr_conf()
-{
- int i;
- Vstr_conf *conf = vstr_make_conf();
- vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '%');
- vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_TYPE_GRPALLOC_CACHE,
- VSTR_TYPE_CNTL_CONF_GRPALLOC_CSTR);
- vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_NUM_BUF_SZ, PRINTF_BUF_LEN);
- for (i = 0; i < NUM_HANDLERS; ++i)
- {
- printf_hook_handler_t *handler = printf_hooks[i];
- if (handler)
- {
- vstr_fmt_add_handler(conf, handler);
- }
- }
- return conf;
-}
-
-static inline Vstr_conf *get_vstr_conf()
-{
- Vstr_conf *conf = NULL;
- if (vstr_conf)
- {
- conf = (Vstr_conf*)vstr_conf->get(vstr_conf);
- if (!conf)
- {
- conf = create_vstr_conf();
- vstr_conf->set(vstr_conf, conf);
- }
- }
- return conf;
-}
-
-/**
- * Described in header
- */
-size_t vstr_print_in_hook(struct Vstr_base *base, size_t pos, const char *fmt,
- ...)
-{
- va_list args;
- int written;
-
- va_start(args, fmt);
- written = vstr_add_vfmt(base, pos, fmt, args);
- va_end(args);
- return written;
-}
-
-/**
- * Wrapper functions for printf and alike
- */
-int vstr_wrapper_printf(const char *format, ...)
-{
- int written;
- va_list args;
- va_start(args, format);
- written = vstr_wrapper_vprintf(format, args);
- va_end(args);
- return written;
-}
-int vstr_wrapper_fprintf(FILE *stream, const char *format, ...)
-{
- int written;
- va_list args;
- va_start(args, format);
- written = vstr_wrapper_vfprintf(stream, format, args);
- va_end(args);
- return written;
-}
-int vstr_wrapper_sprintf(char *str, const char *format, ...)
-{
- int written;
- va_list args;
- va_start(args, format);
- written = vstr_wrapper_vsprintf(str, format, args);
- va_end(args);
- return written;
-}
-int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...)
-{
- int written;
- va_list args;
- va_start(args, format);
- written = vstr_wrapper_vsnprintf(str, size, format, args);
- va_end(args);
- return written;
-}
-int vstr_wrapper_asprintf(char **str, const char *format, ...)
-{
- int written;
- va_list args;
- va_start(args, format);
- written = vstr_wrapper_vasprintf(str, format, args);
- va_end(args);
- return written;
-}
-static inline int vstr_wrapper_vprintf_internal(Vstr_conf *conf, FILE *stream,
- const char *format,
- va_list args)
-{
- struct iovec *iov;
- int iovcnt, written = 0;
- Vstr_base *s = vstr_make_base(conf);
- vstr_add_vfmt(s, 0, format, args);
- if (vstr_export_iovec_ptr_all(s, &iov, &iovcnt))
- {
- while (iovcnt--)
- {
- if (iov->iov_base)
- {
- written += fwrite(iov->iov_base, 1, iov->iov_len, stream);
- }
- iov++;
- }
- }
- vstr_free_base(s);
- return written;
-}
-int vstr_wrapper_vprintf(const char *format, va_list args)
-{
- Vstr_conf *conf = get_vstr_conf();
- if (conf)
- {
- return vstr_wrapper_vprintf_internal(conf, stdout, format, args);
- }
- return vprintf(format, args);
-}
-int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list args)
-{
- Vstr_conf *conf = get_vstr_conf();
- if (conf)
- {
- return vstr_wrapper_vprintf_internal(conf, stream, format, args);
- }
- return vfprintf(stream, format, args);
-}
-static inline int vstr_wrapper_vsnprintf_internal(char *str, size_t size,
- const char *format,
- va_list args)
-{
- Vstr_conf *conf = get_vstr_conf();
- if (conf)
- {
- int written;
- Vstr_base *s = vstr_make_base(conf);
- vstr_add_vfmt(s, 0, format, args);
- written = s->len;
- vstr_export_cstr_buf(s, 1, s->len, str, (size > 0) ? size : s->len + 1);
- vstr_free_base(s);
- return written;
- }
- return vsnprintf(str, size, format, args);
-}
-int vstr_wrapper_vsprintf(char *str, const char *format, va_list args)
-{
- return vstr_wrapper_vsnprintf_internal(str, 0, format, args);
-}
-int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format,
- va_list args)
-{
- return (size > 0) ? vstr_wrapper_vsnprintf_internal(str, size, format, args) : 0;
-}
-int vstr_wrapper_vasprintf(char **str, const char *format, va_list args)
-{
- size_t len = 100;
- int written;
- *str = malloc(len);
- while (TRUE)
- {
- va_list ac;
- va_copy(ac, args);
- written = vstr_wrapper_vsnprintf_internal(*str, len, format, ac);
- va_end(ac);
- if (written < len)
- {
- break;
- }
- len = written + 1;
- *str = realloc(*str, len);
- }
- return written;
-}
-#endif
-
-METHOD(printf_hook_t, add_handler, void,
- private_printf_hook_t *this, char spec,
- printf_hook_function_t hook, ...)
-{
- int i = -1;
- printf_hook_handler_t *handler;
- printf_hook_argtype_t argtype;
- va_list args;
-
- if (!IS_VALID_SPEC(spec))
- {
- DBG1(DBG_LIB, "'%c' is not a valid printf hook specifier, "
- "not registered!", spec);
- return;
- }
-
- handler = malloc_thing(printf_hook_handler_t);
- handler->hook = hook;
-
- va_start(args, hook);
- while ((argtype = va_arg(args, printf_hook_argtype_t)) != PRINTF_HOOK_ARGTYPE_END)
- {
- if (++i >= ARGS_MAX)
- {
- DBG1(DBG_LIB, "Too many arguments for printf hook with "
- "specifier '%c', not registered!", spec);
- va_end(args);
- free(handler);
- return;
- }
- handler->argtypes[i] = argtype;
- }
- va_end(args);
-
- handler->numargs = i + 1;
-
- if (handler->numargs > 0)
- {
-#if !defined(USE_VSTR) && \
- (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER))
-# ifdef HAVE_PRINTF_SPECIFIER
- register_printf_specifier(spec, custom_print, custom_arginfo);
-# else
- register_printf_function(spec, custom_print, custom_arginfo);
-# endif
-#else
- Vstr_conf *conf = get_vstr_conf();
- handler->name = malloc(2);
- handler->name[0] = spec;
- handler->name[1] = '\0';
- vstr_fmt_add_handler(conf, handler);
-#endif
- printf_hooks[SPEC_TO_INDEX(spec)] = handler;
- }
- else
- {
- free(handler);
- }
-}
-
-METHOD(printf_hook_t, destroy, void,
- private_printf_hook_t *this)
-{
- int i;
-#ifdef USE_VSTR
- Vstr_conf *conf = get_vstr_conf();
-#endif
-
- for (i = 0; i < NUM_HANDLERS; ++i)
- {
- printf_hook_handler_t *handler = printf_hooks[i];
- if (handler)
- {
-#ifdef USE_VSTR
- vstr_fmt_del(conf, handler->name);
- free(handler->name);
-#endif
- free(handler);
- }
- }
-
-#ifdef USE_VSTR
- /* freeing the Vstr_conf of the main thread */
- vstr_conf->destroy(vstr_conf);
- vstr_conf = NULL;
- vstr_exit();
-#endif
- free(this);
-}
-
-/*
- * see header file
- */
-printf_hook_t *printf_hook_create()
-{
- private_printf_hook_t *this;
-
- INIT(this,
- .public = {
- .add_handler = _add_handler,
- .destroy = _destroy,
- },
- );
-
- memset(printf_hooks, 0, sizeof(printf_hooks));
-
-#ifdef USE_VSTR
- if (!vstr_init())
- {
- DBG1(DBG_LIB, "failed to initialize Vstr library!");
- free(this);
- return NULL;
- }
- vstr_conf = thread_value_create((thread_cleanup_t)vstr_free_conf);
-#endif
-
- return &this->public;
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Copyright (C) 2006-2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program 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.
- */
-
-/**
- * @defgroup printf_hook printf_hook
- * @{ @ingroup utils
- */
-
-#ifndef PRINTF_HOOK_H_
-#define PRINTF_HOOK_H_
-
-typedef struct printf_hook_t printf_hook_t;
-typedef struct printf_hook_spec_t printf_hook_spec_t;
-typedef struct printf_hook_data_t printf_hook_data_t;
-typedef enum printf_hook_argtype_t printf_hook_argtype_t;
-
-#if !defined(USE_VSTR) && \
- !defined(HAVE_PRINTF_FUNCTION) && \
- !defined(HAVE_PRINTF_SPECIFIER)
-/* assume newer glibc register_printf_specifier if none given */
-#define HAVE_PRINTF_SPECIFIER
-#endif
-
-#if !defined(USE_VSTR) && \
- (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER))
-
-#include <stdio.h>
-#include <printf.h>
-
-enum printf_hook_argtype_t {
- PRINTF_HOOK_ARGTYPE_END = -1,
- PRINTF_HOOK_ARGTYPE_INT = PA_INT,
- PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER,
-};
-
-/**
- * Data to pass to a printf hook.
- */
-struct printf_hook_data_t {
-
- /**
- * Output FILE stream
- */
- FILE *stream;;
-};
-
-/**
- * Helper macro to be used in printf hook callbacks.
- */
-#define print_in_hook(data, fmt, ...) ({\
- ssize_t _written = fprintf(data->stream, fmt, ##__VA_ARGS__);\
- if (_written < 0)\
- {\
- _written = 0;\
- }\
- _written;\
-})
-
-#else
-
-#include <vstr.h>
-
-enum printf_hook_argtype_t {
- PRINTF_HOOK_ARGTYPE_END = VSTR_TYPE_FMT_END,
- PRINTF_HOOK_ARGTYPE_INT = VSTR_TYPE_FMT_INT,
- PRINTF_HOOK_ARGTYPE_POINTER = VSTR_TYPE_FMT_PTR_VOID,
-};
-
-/**
- * Redefining printf and alike
- */
-#include <stdio.h>
-#include <stdarg.h>
-
-int vstr_wrapper_printf(const char *format, ...);
-int vstr_wrapper_fprintf(FILE *stream, const char *format, ...);
-int vstr_wrapper_sprintf(char *str, const char *format, ...);
-int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...);
-int vstr_wrapper_asprintf(char **str, const char *format, ...);
-
-int vstr_wrapper_vprintf(const char *format, va_list ap);
-int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list ap);
-int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap);
-int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap);
-int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap);
-
-#ifdef printf
-#undef printf
-#endif
-#ifdef fprintf
-#undef fprintf
-#endif
-#ifdef sprintf
-#undef sprintf
-#endif
-#ifdef snprintf
-#undef snprintf
-#endif
-#ifdef asprintf
-#undef asprintf
-#endif
-#ifdef vprintf
-#undef vprintf
-#endif
-#ifdef vfprintf
-#undef vfprintf
-#endif
-#ifdef vsprintf
-#undef vsprintf
-#endif
-#ifdef vsnprintf
-#undef vsnprintf
-#endif
-#ifdef vasprintf
-#undef vasprintf
-#endif
-
-#define printf vstr_wrapper_printf
-#define fprintf vstr_wrapper_fprintf
-#define sprintf vstr_wrapper_sprintf
-#define snprintf vstr_wrapper_snprintf
-#define asprintf vstr_wrapper_asprintf
-
-#define vprintf vstr_wrapper_vprintf
-#define vfprintf vstr_wrapper_vfprintf
-#define vsprintf vstr_wrapper_vsprintf
-#define vsnprintf vstr_wrapper_vsnprintf
-#define vasprintf vstr_wrapper_vasprintf
-
-/**
- * Data to pass to a printf hook.
- */
-struct printf_hook_data_t {
-
- /**
- * Base to append printf to
- */
- Vstr_base *base;
-
- /**
- * Position in base to write to
- */
- size_t pos;
-};
-
-/**
- * Wrapper around vstr_add_vfmt(), avoids having to link all users of
- * print_in_hook() against libvstr.
- *
- * @param base Vstr_string to add string to
- * @param pos position to write to
- * @param fmt format string
- * @param ... arguments
- * @return number of characters written
- */
-size_t vstr_print_in_hook(struct Vstr_base *base, size_t pos, const char *fmt,
- ...);
-
-/**
- * Helper macro to be used in printf hook callbacks.
- */
-#define print_in_hook(data, fmt, ...) ({\
- size_t _written; \
- _written = vstr_print_in_hook(data->base, data->pos, fmt, ##__VA_ARGS__);\
- data->pos += _written;\
- _written;\
-})
-
-#endif
-
-/**
- * Callback function type for printf hooks.
- *
- * @param data hook data, to pass to print_in_hook()
- * @param spec format specifier
- * @param args arguments array
- * @return number of characters written
- */
-typedef int (*printf_hook_function_t)(printf_hook_data_t *data,
- printf_hook_spec_t *spec,
- const void *const *args);
-
-/**
- * Properties of the format specifier
- */
-struct printf_hook_spec_t {
- /**
- * TRUE if a '#' was used in the format specifier
- */
- int hash;
-
- /**
- * TRUE if a '-' was used in the format specifier
- */
- int minus;
-
- /**
- * TRUE if a '+' was used in the format specifier
- */
- int plus;
-
- /**
- * The width as given in the format specifier.
- */
- int width;
-};
-
-/**
- * Printf handler management.
- */
-struct printf_hook_t {
-
- /**
- * Register a printf handler.
- *
- * @param spec printf hook format character
- * @param hook hook function
- * @param ... list of PRINTF_HOOK_ARGTYPE_*, MUST end with PRINTF_HOOK_ARGTYPE_END
- */
- void (*add_handler)(printf_hook_t *this, char spec,
- printf_hook_function_t hook, ...);
-
- /**
- * Destroy a printf_hook instance.
- */
- void (*destroy)(printf_hook_t *this);
-};
-
-/**
- * Create a printf_hook instance.
- */
-printf_hook_t *printf_hook_create();
-
-#endif /** PRINTF_HOOK_H_ @}*/
--- /dev/null
+/*
+ * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2006-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+/**
+ * @defgroup printf_hook printf_hook
+ * @{ @ingroup utils
+ */
+
+#ifndef PRINTF_HOOK_H_
+#define PRINTF_HOOK_H_
+
+#include <stdlib.h>
+
+typedef struct printf_hook_t printf_hook_t;
+typedef struct printf_hook_spec_t printf_hook_spec_t;
+typedef struct printf_hook_data_t printf_hook_data_t;
+typedef enum printf_hook_argtype_t printf_hook_argtype_t;
+
+#if defined(USE_VSTR)
+# include "printf_hook_vstr.h"
+#endif
+
+/**
+ * Argument types to pass to printf hook.
+ */
+enum printf_hook_argtype_t {
+ PRINTF_HOOK_ARGTYPE_END,
+ PRINTF_HOOK_ARGTYPE_INT,
+ PRINTF_HOOK_ARGTYPE_POINTER,
+};
+
+/**
+ * Callback function type for printf hooks.
+ *
+ * @param data hook data, to pass to print_in_hook()
+ * @param spec format specifier
+ * @param args arguments array
+ * @return number of characters written
+ */
+typedef int (*printf_hook_function_t)(printf_hook_data_t *data,
+ printf_hook_spec_t *spec,
+ const void *const *args);
+
+/**
+ * Properties of the format specifier
+ */
+struct printf_hook_spec_t {
+
+ /**
+ * TRUE if a '#' was used in the format specifier
+ */
+ int hash;
+
+ /**
+ * TRUE if a '-' was used in the format specifier
+ */
+ int minus;
+
+ /**
+ * TRUE if a '+' was used in the format specifier
+ */
+ int plus;
+
+ /**
+ * The width as given in the format specifier.
+ */
+ int width;
+};
+
+/**
+ * Printf handler management.
+ */
+struct printf_hook_t {
+
+ /**
+ * Register a printf handler.
+ *
+ * @param spec printf hook format character
+ * @param hook hook function
+ * @param ... list of PRINTF_HOOK_ARGTYPE_*, MUST end with PRINTF_HOOK_ARGTYPE_END
+ */
+ void (*add_handler)(printf_hook_t *this, char spec,
+ printf_hook_function_t hook, ...);
+
+ /**
+ * Destroy a printf_hook instance.
+ */
+ void (*destroy)(printf_hook_t *this);
+};
+
+/**
+ * Create a printf_hook instance.
+ */
+printf_hook_t *printf_hook_create();
+
+/**
+ * Print with format string within a printf hook.
+ *
+ * @param data hook data, as passed to printf hook
+ * @param fmt printf format string
+ * @param ... arguments to format string
+ * @return number of characters written
+ */
+size_t print_in_hook(printf_hook_data_t *data, char *fmt, ...);
+
+#endif /** PRINTF_HOOK_H_ @}*/
--- /dev/null
+/*
+ * Copyright (C) 2009-2013 Tobias Brunner
+ * Copyright (C) 2006-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include "printf_hook.h"
+
+#include <utils/utils.h>
+#include <utils/debug.h>
+
+#include <printf.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+typedef struct private_printf_hook_t private_printf_hook_t;
+typedef struct printf_hook_handler_t printf_hook_handler_t;
+
+/**
+ * private data of printf_hook
+ */
+struct private_printf_hook_t {
+
+ /**
+ * public functions
+ */
+ printf_hook_t public;
+};
+
+/**
+ * struct with information about a registered handler
+ */
+struct printf_hook_handler_t {
+
+ /**
+ * callback function
+ */
+ printf_hook_function_t hook;
+
+ /**
+ * number of arguments
+ */
+ int numargs;
+
+ /**
+ * types of the arguments, PA_*
+ */
+ int argtypes[3];
+};
+
+/**
+ * Data to pass to a printf hook.
+ */
+struct printf_hook_data_t {
+
+ /**
+ * Output FILE stream
+ */
+ FILE *stream;;
+};
+
+/* A-Z | 6 other chars | a-z */
+static printf_hook_handler_t *printf_hooks[58];
+
+#define SPEC_TO_INDEX(spec) ((int)(spec) - (int)'A')
+
+/**
+ * Glibc variant of print_in_hook()
+ */
+size_t print_in_hook(printf_hook_data_t *data, char *fmt, ...)
+{
+ ssize_t written;
+ va_list args;
+
+ va_start(args, fmt);
+ written = vfprintf(data->stream, fmt, args);
+ va_end(args);
+
+ if (written < 0)
+ {
+ written = 0;
+ }
+ return written;
+}
+
+/**
+ * Printf hook print function. This is actually of type "printf_function",
+ * however glibc does it typedef to function, but uclibc to a pointer.
+ * So we redefine it here.
+ */
+static int custom_print(FILE *stream, const struct printf_info *info,
+ const void *const *args)
+{
+ printf_hook_spec_t spec;
+ printf_hook_handler_t *handler;
+ printf_hook_data_t data = {
+ .stream = stream,
+ };
+
+ handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
+ spec.hash = info->alt;
+ spec.plus = info->showsign;
+ spec.minus = info->left;
+ spec.width = info->width;
+
+ return handler->hook(&data, &spec, args);
+}
+
+/**
+ * Printf hook arginfo function, which is actually of type
+ * "printf_arginfo_[size_]function".
+ */
+static int custom_arginfo(const struct printf_info *info, size_t n, int *argtypes
+#ifdef HAVE_PRINTF_SPECIFIER
+ , int *size
+#endif
+ )
+{
+ int i;
+ printf_hook_handler_t *handler;
+
+ handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
+ if (handler->numargs <= n)
+ {
+ for (i = 0; i < handler->numargs; ++i)
+ {
+ argtypes[i] = handler->argtypes[i];
+ }
+ }
+ /* we never set "size", as we have no user defined types */
+ return handler->numargs;
+}
+
+METHOD(printf_hook_t, add_handler, void,
+ private_printf_hook_t *this, char spec,
+ printf_hook_function_t hook, ...)
+{
+ int i = -1;
+ bool failed = FALSE;
+ printf_hook_handler_t *handler;
+ printf_hook_argtype_t argtype;
+ va_list args;
+
+ if (SPEC_TO_INDEX(spec) <= -1 ||
+ SPEC_TO_INDEX(spec) >= countof(printf_hooks))
+ {
+ DBG1(DBG_LIB, "'%c' is not a valid printf hook specifier, "
+ "not registered!", spec);
+ return;
+ }
+
+ INIT(handler,
+ .hook = hook,
+ );
+
+ va_start(args, hook);
+ while (!failed)
+ {
+ argtype = va_arg(args, printf_hook_argtype_t);
+
+ if (argtype == PRINTF_HOOK_ARGTYPE_END)
+ {
+ break;
+ }
+ if (++i >= countof(handler->argtypes))
+ {
+ DBG1(DBG_LIB, "Too many arguments for printf hook with "
+ "specifier '%c', not registered!", spec);
+ failed = TRUE;
+ break;
+ }
+ switch (argtype)
+ {
+ case PRINTF_HOOK_ARGTYPE_INT:
+ handler->argtypes[i] = PA_INT;
+ break;
+ case PRINTF_HOOK_ARGTYPE_POINTER:
+ handler->argtypes[i] = PA_POINTER;
+ break;
+ default:
+ DBG1(DBG_LIB, "Invalid printf hook arg type for '%c'", spec);
+ failed = TRUE;
+ break;
+ }
+ }
+ va_end(args);
+
+ handler->numargs = i + 1;
+ if (!failed && handler->numargs > 0)
+ {
+# ifdef HAVE_PRINTF_SPECIFIER
+ register_printf_specifier(spec, custom_print, custom_arginfo);
+# else
+ register_printf_function(spec, custom_print, custom_arginfo);
+# endif
+ printf_hooks[SPEC_TO_INDEX(spec)] = handler;
+ }
+ else
+ {
+ free(handler);
+ }
+}
+
+METHOD(printf_hook_t, destroy, void,
+ private_printf_hook_t *this)
+{
+ int i;
+
+ for (i = 0; i < countof(printf_hooks); i++)
+ {
+ free(printf_hooks[i]);
+ }
+ free(this);
+}
+
+/*
+ * see header file
+ */
+printf_hook_t *printf_hook_create()
+{
+ private_printf_hook_t *this;
+
+ INIT(this,
+ .public = {
+ .add_handler = _add_handler,
+ .destroy = _destroy,
+ },
+ );
+
+ memset(printf_hooks, 0, sizeof(printf_hooks));
+
+ return &this->public;
+}
--- /dev/null
+/*
+ * Copyright (C) 2009-2013 Tobias Brunner
+ * Copyright (C) 2006-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+#include "printf_hook.h"
+
+#include <utils/utils.h>
+#include <utils/debug.h>
+#include <threading/thread_value.h>
+
+#include <vstr.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+typedef struct private_printf_hook_t private_printf_hook_t;
+typedef struct printf_hook_handler_t printf_hook_handler_t;
+
+#define PRINTF_BUF_LEN 8192
+#define ARGS_MAX 3
+
+/**
+ * private data of printf_hook
+ */
+struct private_printf_hook_t {
+
+ /**
+ * public functions
+ */
+ printf_hook_t public;
+};
+
+/**
+ * struct with information about a registered handler
+ */
+struct printf_hook_handler_t {
+
+ /**
+ * callback function
+ */
+ printf_hook_function_t hook;
+
+ /**
+ * number of arguments
+ */
+ int numargs;
+
+ /**
+ * types of the arguments, VSTR_TYPE_FMT_*
+ */
+ int argtypes[ARGS_MAX];
+
+ /**
+ * name required for Vstr
+ */
+ char *name;
+};
+
+/**
+ * Data to pass to a printf hook.
+ */
+struct printf_hook_data_t {
+
+ /**
+ * Base to append printf to
+ */
+ Vstr_base *base;
+
+ /**
+ * Position in base to write to
+ */
+ size_t pos;
+};
+
+/* A-Z | 6 other chars | a-z */
+static printf_hook_handler_t *printf_hooks[58];
+
+#define SPEC_TO_INDEX(spec) ((int)(spec) - (int)'A')
+
+/**
+ * These are used below, whenever the public wrapper functions are called before
+ * initialization or after destruction.
+ */
+#undef vprintf
+#undef vfprintf
+#undef vsnprintf
+
+/**
+ * Vstr variant of print_in_hook()
+ */
+size_t print_in_hook(printf_hook_data_t *data, char *fmt, ...)
+{
+ size_t written;
+ va_list args;
+
+ va_start(args, fmt);
+ written = vstr_add_vfmt(data->base, data->pos, fmt, args);
+ va_end(args);
+
+ data->pos += written;
+ return written;
+}
+
+/**
+ * Vstr custom format specifier callback function.
+ */
+static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec)
+{
+ int i;
+ const void *args[ARGS_MAX];
+ printf_hook_spec_t spec;
+ printf_hook_handler_t *handler;
+ printf_hook_data_t data = {
+ .base = base,
+ .pos = pos,
+ };
+
+ handler = printf_hooks[SPEC_TO_INDEX(fmt_spec->name[0])];
+ for (i = 0; i < handler->numargs; i++)
+ {
+ switch (handler->argtypes[i])
+ {
+ case VSTR_TYPE_FMT_INT:
+ args[i] = VSTR_FMT_CB_ARG_PTR(fmt_spec, i);
+ break;
+ case VSTR_TYPE_FMT_PTR_VOID:
+ args[i] = &VSTR_FMT_CB_ARG_PTR(fmt_spec, i);
+ break;
+ }
+ }
+
+ spec.hash = fmt_spec->fmt_hash;
+ spec.plus = fmt_spec->fmt_plus;
+ spec.minus = fmt_spec->fmt_minus;
+ spec.width = fmt_spec->fmt_field_width;
+
+ handler->hook(&data, &spec, args);
+
+ return 1;
+}
+
+/**
+ * Add a custom format handler to the given Vstr_conf object
+ */
+static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler)
+{
+ int *at;
+
+ at = handler->argtypes;
+ switch (handler->numargs)
+ {
+ case 1:
+ vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0],
+ VSTR_TYPE_FMT_END);
+ break;
+ case 2:
+ vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0],
+ at[1], VSTR_TYPE_FMT_END);
+ break;
+ case 3:
+ vstr_fmt_add(conf, handler->name, custom_fmt_cb, at[0],
+ at[1], at[2], VSTR_TYPE_FMT_END);
+ break;
+ }
+}
+
+/**
+ * Thread specific vstr config
+ */
+static thread_value_t *vstr_conf = NULL;
+
+/**
+ * Create vstr config for current thread
+ */
+static Vstr_conf *create_vstr_conf()
+{
+ Vstr_conf *conf;
+ int i;
+
+ conf = vstr_make_conf();
+ vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '%');
+ vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_TYPE_GRPALLOC_CACHE,
+ VSTR_TYPE_CNTL_CONF_GRPALLOC_CSTR);
+ vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_NUM_BUF_SZ, PRINTF_BUF_LEN);
+
+ for (i = 0; i < countof(printf_hooks); i++)
+ {
+ if (printf_hooks[i])
+ {
+ vstr_fmt_add_handler(conf, printf_hooks[i]);
+ }
+ }
+ return conf;
+}
+
+/**
+ * Get vstr config of current thread
+ */
+static inline Vstr_conf *get_vstr_conf()
+{
+ Vstr_conf *conf = NULL;
+
+ if (vstr_conf)
+ {
+ conf = (Vstr_conf*)vstr_conf->get(vstr_conf);
+ if (!conf)
+ {
+ conf = create_vstr_conf();
+ vstr_conf->set(vstr_conf, conf);
+ }
+ }
+ return conf;
+}
+
+/**
+ * Wrapper functions for printf and alike
+ */
+int vstr_wrapper_printf(const char *format, ...)
+{
+ int written;
+ va_list args;
+ va_start(args, format);
+ written = vstr_wrapper_vprintf(format, args);
+ va_end(args);
+ return written;
+}
+
+int vstr_wrapper_fprintf(FILE *stream, const char *format, ...)
+{
+ int written;
+ va_list args;
+ va_start(args, format);
+ written = vstr_wrapper_vfprintf(stream, format, args);
+ va_end(args);
+ return written;
+}
+
+int vstr_wrapper_sprintf(char *str, const char *format, ...)
+{
+ int written;
+ va_list args;
+ va_start(args, format);
+ written = vstr_wrapper_vsprintf(str, format, args);
+ va_end(args);
+ return written;
+}
+
+int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...)
+{
+ int written;
+ va_list args;
+ va_start(args, format);
+ written = vstr_wrapper_vsnprintf(str, size, format, args);
+ va_end(args);
+ return written;
+}
+
+int vstr_wrapper_asprintf(char **str, const char *format, ...)
+{
+ int written;
+ va_list args;
+ va_start(args, format);
+ written = vstr_wrapper_vasprintf(str, format, args);
+ va_end(args);
+ return written;
+}
+
+static inline int vstr_wrapper_vprintf_internal(Vstr_conf *conf, FILE *stream,
+ const char *format,
+ va_list args)
+{
+ struct iovec *iov;
+ int iovcnt, written = 0;
+ Vstr_base *s;
+
+ s = vstr_make_base(conf);
+ vstr_add_vfmt(s, 0, format, args);
+ if (vstr_export_iovec_ptr_all(s, &iov, &iovcnt))
+ {
+ while (iovcnt--)
+ {
+ if (iov->iov_base)
+ {
+ written += fwrite(iov->iov_base, 1, iov->iov_len, stream);
+ }
+ iov++;
+ }
+ }
+ vstr_free_base(s);
+ return written;
+}
+
+int vstr_wrapper_vprintf(const char *format, va_list args)
+{
+ Vstr_conf *conf;
+
+ conf = get_vstr_conf();
+ if (conf)
+ {
+ return vstr_wrapper_vprintf_internal(conf, stdout, format, args);
+ }
+ return vprintf(format, args);
+}
+
+int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list args)
+{
+ Vstr_conf *conf;
+
+ conf = get_vstr_conf();
+ if (conf)
+ {
+ return vstr_wrapper_vprintf_internal(conf, stream, format, args);
+ }
+ return vfprintf(stream, format, args);
+}
+
+static inline int vstr_wrapper_vsnprintf_internal(char *str, size_t size,
+ const char *format,
+ va_list args)
+{
+ Vstr_conf *conf;
+ Vstr_base *s;
+ int written;
+
+ conf = get_vstr_conf();
+ if (conf)
+ {
+ s = vstr_make_base(conf);
+ vstr_add_vfmt(s, 0, format, args);
+ written = s->len;
+ vstr_export_cstr_buf(s, 1, s->len, str, (size > 0) ? size : s->len + 1);
+ vstr_free_base(s);
+ return written;
+ }
+ return vsnprintf(str, size, format, args);
+}
+
+int vstr_wrapper_vsprintf(char *str, const char *format, va_list args)
+{
+ return vstr_wrapper_vsnprintf_internal(str, 0, format, args);
+}
+
+int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format,
+ va_list args)
+{
+ if (size > 0)
+ {
+ return vstr_wrapper_vsnprintf_internal(str, size, format, args);
+ }
+ return 0;
+}
+
+int vstr_wrapper_vasprintf(char **str, const char *format, va_list args)
+{
+ size_t len = 100;
+ int written;
+
+ *str = malloc(len);
+ while (TRUE)
+ {
+ va_list ac;
+ va_copy(ac, args);
+ written = vstr_wrapper_vsnprintf_internal(*str, len, format, ac);
+ va_end(ac);
+ if (written < len)
+ {
+ break;
+ }
+ len = written + 1;
+ *str = realloc(*str, len);
+ }
+ return written;
+}
+
+METHOD(printf_hook_t, add_handler, void,
+ private_printf_hook_t *this, char spec, printf_hook_function_t hook, ...)
+{
+ int i = -1;
+ bool failed = FALSE;
+ printf_hook_handler_t *handler;
+ printf_hook_argtype_t argtype;
+ va_list args;
+
+ if (SPEC_TO_INDEX(spec) <= -1 ||
+ SPEC_TO_INDEX(spec) >= countof(printf_hooks))
+ {
+ DBG1(DBG_LIB, "'%c' is not a valid printf hook specifier, "
+ "not registered!", spec);
+ return;
+ }
+
+ INIT(handler,
+ .hook = hook,
+ );
+
+ va_start(args, hook);
+ while (!failed)
+ {
+ argtype = va_arg(args, printf_hook_argtype_t);
+ if (argtype == PRINTF_HOOK_ARGTYPE_END)
+ {
+ break;
+ }
+ if (++i >= ARGS_MAX)
+ {
+ DBG1(DBG_LIB, "Too many arguments for printf hook with "
+ "specifier '%c', not registered!", spec);
+ failed = TRUE;
+ break;
+ }
+ switch (argtype)
+ {
+ case PRINTF_HOOK_ARGTYPE_INT:
+ handler->argtypes[i] = VSTR_TYPE_FMT_INT;
+ break;
+ case PRINTF_HOOK_ARGTYPE_POINTER:
+ handler->argtypes[i] = VSTR_TYPE_FMT_PTR_VOID;
+ break;
+ default:
+ DBG1(DBG_LIB, "Invalid printf hook arg type for '%c'", spec);
+ failed = TRUE;
+ break;
+ }
+ }
+ va_end(args);
+
+ handler->numargs = i + 1;
+
+ if (!failed && handler->numargs > 0)
+ {
+ Vstr_conf *conf = get_vstr_conf();
+ handler->name = malloc(2);
+ handler->name[0] = spec;
+ handler->name[1] = '\0';
+ vstr_fmt_add_handler(conf, handler);
+ printf_hooks[SPEC_TO_INDEX(spec)] = handler;
+ }
+ else
+ {
+ free(handler);
+ }
+}
+
+METHOD(printf_hook_t, destroy, void,
+ private_printf_hook_t *this)
+{
+ int i;
+ Vstr_conf *conf;
+ printf_hook_handler_t *handler;
+
+ conf = get_vstr_conf();
+ for (i = 0; i < countof(printf_hooks); ++i)
+ {
+ handler = printf_hooks[i];
+ if (handler)
+ {
+ vstr_fmt_del(conf, handler->name);
+ free(handler->name);
+ free(handler);
+ }
+ }
+
+ /* freeing the Vstr_conf of the main thread */
+ vstr_conf->destroy(vstr_conf);
+ vstr_conf = NULL;
+ vstr_exit();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+printf_hook_t *printf_hook_create()
+{
+ private_printf_hook_t *this;
+
+ INIT(this,
+ .public = {
+ .add_handler = _add_handler,
+ .destroy = _destroy,
+ },
+ );
+
+ memset(printf_hooks, 0, sizeof(printf_hooks));
+
+ if (!vstr_init())
+ {
+ DBG1(DBG_LIB, "failed to initialize Vstr library!");
+ free(this);
+ return NULL;
+ }
+ vstr_conf = thread_value_create((thread_cleanup_t)vstr_free_conf);
+
+ return &this->public;
+}
--- /dev/null
+/*
+ * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2006-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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.
+ */
+
+/**
+ * @defgroup printf_hook_vstr printf_hook_vstr
+ * @{ @ingroup utils
+ */
+
+#ifndef PRINTF_HOOK_VSTR_H_
+#define PRINTF_HOOK_VSTR_H_
+
+#include <stdarg.h>
+#include <stdio.h>
+
+int vstr_wrapper_printf(const char *format, ...);
+int vstr_wrapper_fprintf(FILE *stream, const char *format, ...);
+int vstr_wrapper_sprintf(char *str, const char *format, ...);
+int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...);
+int vstr_wrapper_asprintf(char **str, const char *format, ...);
+
+int vstr_wrapper_vprintf(const char *format, va_list ap);
+int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list ap);
+int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap);
+int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap);
+int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap);
+
+#ifdef printf
+#undef printf
+#endif
+#ifdef fprintf
+#undef fprintf
+#endif
+#ifdef sprintf
+#undef sprintf
+#endif
+#ifdef snprintf
+#undef snprintf
+#endif
+#ifdef asprintf
+#undef asprintf
+#endif
+#ifdef vprintf
+#undef vprintf
+#endif
+#ifdef vfprintf
+#undef vfprintf
+#endif
+#ifdef vsprintf
+#undef vsprintf
+#endif
+#ifdef vsnprintf
+#undef vsnprintf
+#endif
+#ifdef vasprintf
+#undef vasprintf
+#endif
+
+#define printf vstr_wrapper_printf
+#define fprintf vstr_wrapper_fprintf
+#define sprintf vstr_wrapper_sprintf
+#define snprintf vstr_wrapper_snprintf
+#define asprintf vstr_wrapper_asprintf
+
+#define vprintf vstr_wrapper_vprintf
+#define vfprintf vstr_wrapper_vfprintf
+#define vsprintf vstr_wrapper_vsprintf
+#define vsnprintf vstr_wrapper_vsnprintf
+#define vasprintf vstr_wrapper_vasprintf
+
+#endif /** PRINTF_HOOK_VSTR_H_ @}*/