Added missing Vstr wrappers for asprintf.
[strongswan.git] / src / libstrongswan / printf_hook.c
index 692ad9c..9c1757b 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "printf_hook.h"
 
-#include <utils.h>
-#include <debug.h>
+#include "utils.h"
+#include "debug.h"
 
 #include <stdio.h>
 #include <stdarg.h>
@@ -44,17 +44,17 @@ struct private_printf_hook_t {
  * 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
         */
@@ -75,7 +75,8 @@ 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(HAVE_PRINTF_HOOKS) && !defined(USE_VSTR)
+#if !defined(USE_VSTR) && \
+       (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER))
 
 /**
  * Printf hook print function. This is actually of type "printf_function",
@@ -89,11 +90,11 @@ static int custom_print(FILE *stream, const struct printf_info *info,
        char buf[PRINTF_BUF_LEN];
        printf_hook_spec_t spec;
        printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)];
-       
+
        spec.hash = info->alt;
        spec.minus = info->left;
        spec.width = info->width;
-       
+
        written = handler->hook(buf, sizeof(buf), &spec, args);
        if (written > 0)
        {
@@ -104,13 +105,17 @@ static int custom_print(FILE *stream, const struct printf_info *info,
 
 /**
  * Printf hook arginfo function, which is actually of type
- * "printf_arginfo_function".
+ * "printf_arginfo_[size_]function".
  */
-static int custom_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+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)
@@ -118,6 +123,7 @@ static int custom_arginfo(const struct printf_info *info, size_t n, int *argtype
                        argtypes[i] = handler->argtypes[i];
                }
        }
+       /* we never set "size", as we have no user defined types */
        return handler->numargs;
 }
 
@@ -136,7 +142,7 @@ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec)
        const void *args[ARGS_MAX];
        printf_hook_spec_t spec;
        printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(fmt_spec->name[0])];
-       
+
        for (i = 0; i < handler->numargs; i++)
        {
                switch(handler->argtypes[i])
@@ -149,11 +155,11 @@ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec)
                                break;
                }
        }
-       
+
        spec.hash = fmt_spec->fmt_hash;
        spec.minus = fmt_spec->fmt_minus;
        spec.width = fmt_spec->fmt_field_width;
-       
+
        written = handler->hook(buf, sizeof(buf), &spec, args);
        if (written > 0)
        {
@@ -185,15 +191,9 @@ static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler
 /**
  * Management of thread-specific Vstr_conf objects
  */
-#include <pthread.h>
+#include <threading/thread_value.h>
 
-static pthread_key_t vstr_conf_key;
-static pthread_once_t vstr_conf_key_once = PTHREAD_ONCE_INIT;
-
-static void init_vstr_conf_key(void)
-{
-       pthread_key_create(&vstr_conf_key, (void*)vstr_free_conf);
-}
+static thread_value_t *vstr_conf;
 
 static Vstr_conf *create_vstr_conf()
 {
@@ -217,12 +217,11 @@ static Vstr_conf *create_vstr_conf()
 static inline Vstr_conf *get_vstr_conf()
 {
        Vstr_conf *conf;
-       pthread_once(&vstr_conf_key_once, init_vstr_conf_key);
-       conf = (Vstr_conf*)pthread_getspecific(vstr_conf_key);
+       conf = (Vstr_conf*)vstr_conf->get(vstr_conf);
        if (!conf)
        {
                conf = create_vstr_conf();
-               pthread_setspecific(vstr_conf_key, conf);
+               vstr_conf->set(vstr_conf, conf);
        }
        return conf;
 }
@@ -266,6 +265,15 @@ int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...)
        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(int fd, const char *format,
                                                                                                va_list args)
 {
@@ -318,6 +326,26 @@ int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format,
 {
        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
 
@@ -331,22 +359,24 @@ static void add_handler(private_printf_hook_t *this, char spec,
        printf_hook_handler_t *handler;
        printf_hook_argtype_t argtype;
        va_list args;
-       
+
        if (!IS_VALID_SPEC(spec))
        {
-               DBG1("'%c' is not a valid printf hook specifier, not registered!", 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("Too many arguments for printf hook with specifier '%c', not registered!", spec);
+                       DBG1(DBG_LIB, "Too many arguments for printf hook with "
+                                "specifier '%c', not registered!", spec);
                        va_end(args);
                        free(handler);
                        return;
@@ -354,13 +384,18 @@ static void add_handler(private_printf_hook_t *this, char spec,
                handler->argtypes[i] = argtype;
        }
        va_end(args);
-       
+
        handler->numargs = i + 1;
-       
+
        if (handler->numargs > 0)
        {
-#if defined(HAVE_PRINTF_HOOKS) && !defined(USE_VSTR)
+#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);
@@ -385,7 +420,7 @@ static void destroy(private_printf_hook_t *this)
 #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];
@@ -398,10 +433,10 @@ static void destroy(private_printf_hook_t *this)
                        free(handler);
                }
        }
-       
+
 #ifdef USE_VSTR
        /* freeing the Vstr_conf of the main thread */
-       pthread_key_delete(vstr_conf_key);
+       vstr_conf->destroy(vstr_conf);
        vstr_free_conf(conf);
        vstr_exit();
 #endif
@@ -414,21 +449,22 @@ static void destroy(private_printf_hook_t *this)
 printf_hook_t *printf_hook_create()
 {
        private_printf_hook_t *this = malloc_thing(private_printf_hook_t);
-       
+
        this->public.add_handler = (void(*)(printf_hook_t*, char, printf_hook_function_t, ...))add_handler;
        this->public.destroy = (void(*)(printf_hook_t*))destroy;
-       
+
        memset(printf_hooks, 0, sizeof(printf_hooks));
-       
+
 #ifdef USE_VSTR
        if (!vstr_init())
        {
-               DBG1("failed to initialize Vstr library!");
+               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;
 }