Moved utils.[ch] to utils folder
authorTobias Brunner <tobias@strongswan.org>
Tue, 16 Oct 2012 14:17:57 +0000 (16:17 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 24 Oct 2012 14:07:53 +0000 (16:07 +0200)
12 files changed:
src/libimcv/imcv.c
src/libstrongswan/Android.mk
src/libstrongswan/Makefile.am
src/libstrongswan/collections/enumerator.h
src/libstrongswan/library.h
src/libstrongswan/utils.c [deleted file]
src/libstrongswan/utils.h [deleted file]
src/libstrongswan/utils/chunk.h
src/libstrongswan/utils/integrity_checker.h
src/libstrongswan/utils/settings.h
src/libstrongswan/utils/utils.c [new file with mode: 0644]
src/libstrongswan/utils/utils.h [new file with mode: 0644]

index f9de41f..e1b828d 100644 (file)
@@ -16,8 +16,8 @@
 #include "ietf/ietf_attr.h"
 #include "ita/ita_attr.h"
 
-#include <utils.h>
 #include <utils/debug.h>
+#include <utils/utils.h>
 #include <pen/pen.h>
 
 #include <syslog.h>
index 47470c3..c7c5d4b 100644 (file)
@@ -30,7 +30,7 @@ pen/pen.c plugins/plugin_loader.c plugins/plugin_feature.c processing/jobs/job.c
 processing/jobs/callback_job.c processing/processor.c processing/scheduler.c \
 selectors/traffic_selector.c threading/thread.c threading/thread_value.c \
 threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \
-utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.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
 
index 2aed071..56e28d7 100644 (file)
@@ -28,7 +28,7 @@ pen/pen.c plugins/plugin_loader.c plugins/plugin_feature.c processing/jobs/job.c
 processing/jobs/callback_job.c processing/processor.c processing/scheduler.c \
 selectors/traffic_selector.c threading/thread.c threading/thread_value.c \
 threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \
-utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.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
 
@@ -69,7 +69,7 @@ processing/scheduler.h selectors/traffic_selector.h \
 threading/thread.h threading/thread_value.h \
 threading/mutex.h threading/condvar.h threading/spinlock.h threading/semaphore.h \
 threading/rwlock.h threading/rwlock_condvar.h threading/lock_profiler.h \
-utils.h utils/chunk.h utils/debug.h utils/enum.h utils/identification.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
 endif
index 900c973..299373a 100644 (file)
@@ -23,7 +23,7 @@
 
 typedef struct enumerator_t enumerator_t;
 
-#include "../utils.h"
+#include <utils/utils.h>
 
 /**
  * Enumerator interface, allows enumeration over collections.
index e547c7e..43c6b33 100644 (file)
@@ -80,9 +80,9 @@
 # error config.h not included, pass "-include [...]/config.h" to gcc
 #endif
 
-/* make sure we include printf_hook.h first */
+/* make sure we include printf_hook.h and utils.h first */
 #include "utils/printf_hook.h"
-#include "utils.h"
+#include "utils/utils.h"
 #include "networking/host_resolver.h"
 #include "processing/processor.h"
 #include "processing/scheduler.h"
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
deleted file mode 100644 (file)
index bf0224c..0000000
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Copyright (C) 2008-2012 Tobias Brunner
- * Copyright (C) 2005-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 "utils.h"
-
-#include <sys/stat.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <limits.h>
-#include <dirent.h>
-#include <time.h>
-#include <pthread.h>
-
-#include "collections/enumerator.h"
-#include "utils/debug.h"
-
-ENUM(status_names, SUCCESS, NEED_MORE,
-       "SUCCESS",
-       "FAILED",
-       "OUT_OF_RES",
-       "ALREADY_DONE",
-       "NOT_SUPPORTED",
-       "INVALID_ARG",
-       "NOT_FOUND",
-       "PARSE_ERROR",
-       "VERIFY_ERROR",
-       "INVALID_STATE",
-       "DESTROY_ME",
-       "NEED_MORE",
-);
-
-/**
- * Described in header.
- */
-void *clalloc(void * pointer, size_t size)
-{
-       void *data;
-       data = malloc(size);
-
-       memcpy(data, pointer, size);
-
-       return (data);
-}
-
-/**
- * Described in header.
- */
-void memxor(u_int8_t dst[], u_int8_t src[], size_t n)
-{
-       int m, i;
-
-       /* byte wise XOR until dst aligned */
-       for (i = 0; (uintptr_t)&dst[i] % sizeof(long) && i < n; i++)
-       {
-               dst[i] ^= src[i];
-       }
-       /* try to use words if src shares an aligment with dst */
-       switch (((uintptr_t)&src[i] % sizeof(long)))
-       {
-               case 0:
-                       for (m = n - sizeof(long); i <= m; i += sizeof(long))
-                       {
-                               *(long*)&dst[i] ^= *(long*)&src[i];
-                       }
-                       break;
-               case sizeof(int):
-                       for (m = n - sizeof(int); i <= m; i += sizeof(int))
-                       {
-                               *(int*)&dst[i] ^= *(int*)&src[i];
-                       }
-                       break;
-               case sizeof(short):
-                       for (m = n - sizeof(short); i <= m; i += sizeof(short))
-                       {
-                               *(short*)&dst[i] ^= *(short*)&src[i];
-                       }
-                       break;
-               default:
-                       break;
-       }
-       /* byte wise XOR of the rest */
-       for (; i < n; i++)
-       {
-               dst[i] ^= src[i];
-       }
-}
-
-/**
- * Described in header.
- */
-void memwipe_noinline(void *ptr, size_t n)
-{
-       memwipe_inline(ptr, n);
-}
-
-/**
- * Described in header.
- */
-void *memstr(const void *haystack, const char *needle, size_t n)
-{
-       unsigned const char *pos = haystack;
-       size_t l = strlen(needle);
-       for (; n >= l; ++pos, --n)
-       {
-               if (memeq(pos, needle, l))
-               {
-                       return (void*)pos;
-               }
-       }
-       return NULL;
-}
-
-/**
- * Described in header.
- */
-char* translate(char *str, const char *from, const char *to)
-{
-       char *pos = str;
-       if (strlen(from) != strlen(to))
-       {
-               return str;
-       }
-       while (pos && *pos)
-       {
-               char *match;
-               if ((match = strchr(from, *pos)) != NULL)
-               {
-                       *pos = to[match - from];
-               }
-               pos++;
-       }
-       return str;
-}
-
-/**
- * Described in header.
- */
-bool mkdir_p(const char *path, mode_t mode)
-{
-       int len;
-       char *pos, full[PATH_MAX];
-       pos = full;
-       if (!path || *path == '\0')
-       {
-               return TRUE;
-       }
-       len = snprintf(full, sizeof(full)-1, "%s", path);
-       if (len < 0 || len >= sizeof(full)-1)
-       {
-               DBG1(DBG_LIB, "path string %s too long", path);
-               return FALSE;
-       }
-       /* ensure that the path ends with a '/' */
-       if (full[len-1] != '/')
-       {
-               full[len++] = '/';
-               full[len] = '\0';
-       }
-       /* skip '/' at the beginning */
-       while (*pos == '/')
-       {
-               pos++;
-       }
-       while ((pos = strchr(pos, '/')))
-       {
-               *pos = '\0';
-               if (access(full, F_OK) < 0)
-               {
-                       if (mkdir(full, mode) < 0)
-                       {
-                               DBG1(DBG_LIB, "failed to create directory %s", full);
-                               return FALSE;
-                       }
-               }
-               *pos = '/';
-               pos++;
-       }
-       return TRUE;
-}
-
-
-/**
- * The size of the thread-specific error buffer
- */
-#define STRERROR_BUF_LEN 256
-
-/**
- * Key to store thread-specific error buffer
- */
-static pthread_key_t strerror_buf_key;
-
-/**
- * Only initialize the key above once
- */
-static pthread_once_t strerror_buf_key_once = PTHREAD_ONCE_INIT;
-
-/**
- * Create the key used for the thread-specific error buffer
- */
-static void create_strerror_buf_key()
-{
-       pthread_key_create(&strerror_buf_key, free);
-}
-
-/**
- * Retrieve the error buffer assigned to the current thread (or create it)
- */
-static inline char *get_strerror_buf()
-{
-       char *buf;
-
-       pthread_once(&strerror_buf_key_once, create_strerror_buf_key);
-       buf = pthread_getspecific(strerror_buf_key);
-       if (!buf)
-       {
-               buf = malloc(STRERROR_BUF_LEN);
-               pthread_setspecific(strerror_buf_key, buf);
-       }
-       return buf;
-}
-
-#ifdef HAVE_STRERROR_R
-/*
- * Described in header.
- */
-const char *safe_strerror(int errnum)
-{
-       char *buf = get_strerror_buf(), *msg;
-
-#ifdef STRERROR_R_CHAR_P
-       /* char* version which may or may not return the original buffer */
-       msg = strerror_r(errnum, buf, STRERROR_BUF_LEN);
-#else
-       /* int version returns 0 on success */
-       msg = strerror_r(errnum, buf, STRERROR_BUF_LEN) ? "Unknown error" : buf;
-#endif
-       return msg;
-}
-#else /* HAVE_STRERROR_R */
-/* we actually wan't to call strerror(3) below */
-#undef strerror
-/*
- * Described in header.
- */
-const char *safe_strerror(int errnum)
-{
-       static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-       char *buf = get_strerror_buf();
-
-       /* use a mutex to ensure calling strerror(3) is thread-safe */
-       pthread_mutex_lock(&mutex);
-       strncpy(buf, strerror(errnum), STRERROR_BUF_LEN);
-       pthread_mutex_unlock(&mutex);
-       buf[STRERROR_BUF_LEN - 1] = '\0';
-       return buf;
-}
-#endif /* HAVE_STRERROR_R */
-
-
-#ifndef HAVE_CLOSEFROM
-/**
- * Described in header.
- */
-void closefrom(int lowfd)
-{
-       char fd_dir[PATH_MAX];
-       int maxfd, fd, len;
-
-       /* try to close only open file descriptors on Linux... */
-       len = snprintf(fd_dir, sizeof(fd_dir), "/proc/%u/fd", getpid());
-       if (len > 0 && len < sizeof(fd_dir) && access(fd_dir, F_OK) == 0)
-       {
-               enumerator_t *enumerator = enumerator_create_directory(fd_dir);
-               if (enumerator)
-               {
-                       char *rel;
-                       while (enumerator->enumerate(enumerator, &rel, NULL, NULL))
-                       {
-                               fd = atoi(rel);
-                               if (fd >= lowfd)
-                               {
-                                       close(fd);
-                               }
-                       }
-                       enumerator->destroy(enumerator);
-                       return;
-               }
-       }
-
-       /* ...fall back to closing all fds otherwise */
-       maxfd = (int)sysconf(_SC_OPEN_MAX);
-       if (maxfd < 0)
-       {
-               maxfd = 256;
-       }
-       for (fd = lowfd; fd < maxfd; fd++)
-       {
-               close(fd);
-       }
-}
-#endif /* HAVE_CLOSEFROM */
-
-/**
- * Return monotonic time
- */
-time_t time_monotonic(timeval_t *tv)
-{
-#if defined(HAVE_CLOCK_GETTIME) && \
-       (defined(HAVE_CONDATTR_CLOCK_MONOTONIC) || \
-        defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC))
-       /* as we use time_monotonic() for condvar operations, we use the
-        * monotonic time source only if it is also supported by pthread. */
-       timespec_t ts;
-
-       if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
-       {
-               if (tv)
-               {
-                       tv->tv_sec = ts.tv_sec;
-                       tv->tv_usec = ts.tv_nsec / 1000;
-               }
-               return ts.tv_sec;
-       }
-#endif /* HAVE_CLOCK_GETTIME && (...) */
-       /* Fallback to non-monotonic timestamps:
-        * On MAC OS X, creating monotonic timestamps is rather difficult. We
-        * could use mach_absolute_time() and catch sleep/wakeup notifications.
-        * We stick to the simpler (non-monotonic) gettimeofday() for now.
-        * But keep in mind: we need the same time source here as in condvar! */
-       if (!tv)
-       {
-               return time(NULL);
-       }
-       if (gettimeofday(tv, NULL) != 0)
-       {       /* should actually never fail if passed pointers are valid */
-               return -1;
-       }
-       return tv->tv_sec;
-}
-
-/**
- * return null
- */
-void *return_null()
-{
-       return NULL;
-}
-
-/**
- * returns TRUE
- */
-bool return_true()
-{
-       return TRUE;
-}
-
-/**
- * returns FALSE
- */
-bool return_false()
-{
-       return FALSE;
-}
-
-/**
- * returns FAILED
- */
-status_t return_failed()
-{
-       return FAILED;
-}
-
-/**
- * nop operation
- */
-void nop()
-{
-}
-
-#ifndef HAVE_GCC_ATOMIC_OPERATIONS
-
-/**
- * We use a single mutex for all refcount variables.
- */
-static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/**
- * Increase refcount
- */
-void ref_get(refcount_t *ref)
-{
-       pthread_mutex_lock(&ref_mutex);
-       (*ref)++;
-       pthread_mutex_unlock(&ref_mutex);
-}
-
-/**
- * Decrease refcount
- */
-bool ref_put(refcount_t *ref)
-{
-       bool more_refs;
-
-       pthread_mutex_lock(&ref_mutex);
-       more_refs = --(*ref) > 0;
-       pthread_mutex_unlock(&ref_mutex);
-       return !more_refs;
-}
-
-/**
- * Single mutex for all compare and swap operations.
- */
-static pthread_mutex_t cas_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/**
- * Compare and swap if equal to old value
- */
-#define _cas_impl(name, type) \
-bool cas_##name(type *ptr, type oldval, type newval) \
-{ \
-       bool swapped; \
-       pthread_mutex_lock(&cas_mutex); \
-       if ((swapped = (*ptr == oldval))) { *ptr = newval; } \
-       pthread_mutex_unlock(&cas_mutex); \
-       return swapped; \
-}
-
-_cas_impl(bool, bool)
-_cas_impl(ptr, void*)
-
-#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
-
-/**
- * Described in header.
- */
-int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
-                                        const void *const *args)
-{
-       static const char* months[] = {
-               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-       };
-       time_t *time = *((time_t**)(args[0]));
-       bool utc = *((bool*)(args[1]));;
-       struct tm t;
-
-       if (time == UNDEFINED_TIME)
-       {
-               return print_in_hook(data, "--- -- --:--:--%s----",
-                                                        utc ? " UTC " : " ");
-       }
-       if (utc)
-       {
-               gmtime_r(time, &t);
-       }
-       else
-       {
-               localtime_r(time, &t);
-       }
-       return print_in_hook(data, "%s %02d %02d:%02d:%02d%s%04d",
-                                                months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,
-                                                t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
-}
-
-/**
- * Described in header.
- */
-int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
-                                                  const void *const *args)
-{
-       char* unit = "second";
-       time_t *arg1 = *((time_t**)(args[0]));
-       time_t *arg2 = *((time_t**)(args[1]));
-       u_int64_t delta = llabs(*arg1 - *arg2);
-
-       if (delta > 2 * 60 * 60 * 24)
-       {
-               delta /= 60 * 60 * 24;
-               unit = "day";
-       }
-       else if (delta > 2 * 60 * 60)
-       {
-               delta /= 60 * 60;
-               unit = "hour";
-       }
-       else if (delta > 2 * 60)
-       {
-               delta /= 60;
-               unit = "minute";
-       }
-       return print_in_hook(data, "%" PRIu64 " %s%s", delta, unit,
-                                                (delta == 1) ? "" : "s");
-}
-
-/**
- * Number of bytes per line to dump raw data
- */
-#define BYTES_PER_LINE 16
-
-static char hexdig_upper[] = "0123456789ABCDEF";
-
-/**
- * Described in header.
- */
-int mem_printf_hook(printf_hook_data_t *data,
-                                       printf_hook_spec_t *spec, const void *const *args)
-{
-       char *bytes = *((void**)(args[0]));
-       u_int len = *((int*)(args[1]));
-
-       char buffer[BYTES_PER_LINE * 3];
-       char ascii_buffer[BYTES_PER_LINE + 1];
-       char *buffer_pos = buffer;
-       char *bytes_pos  = bytes;
-       char *bytes_roof = bytes + len;
-       int line_start = 0;
-       int i = 0;
-       int written = 0;
-
-       written += print_in_hook(data, "=> %u bytes @ %p", len, bytes);
-
-       while (bytes_pos < bytes_roof)
-       {
-               *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
-               *buffer_pos++ = hexdig_upper[ *bytes_pos       & 0xF];
-
-               ascii_buffer[i++] =
-                               (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
-
-               if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE)
-               {
-                       int padding = 3 * (BYTES_PER_LINE - i);
-
-                       while (padding--)
-                       {
-                               *buffer_pos++ = ' ';
-                       }
-                       *buffer_pos++ = '\0';
-                       ascii_buffer[i] = '\0';
-
-                       written += print_in_hook(data, "\n%4d: %s  %s",
-                                                                        line_start, buffer, ascii_buffer);
-
-                       buffer_pos = buffer;
-                       line_start += BYTES_PER_LINE;
-                       i = 0;
-               }
-               else
-               {
-                       *buffer_pos++ = ' ';
-               }
-       }
-       return written;
-}
diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h
deleted file mode 100644 (file)
index 1da71af..0000000
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2008-2012 Tobias Brunner
- * Copyright (C) 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 utils utils
- * @{ @ingroup libstrongswan
- */
-
-#ifndef UTILS_H_
-#define UTILS_H_
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include <string.h>
-
-#include "utils/enum.h"
-
-/**
- * strongSwan program return codes
- */
-#define SS_RC_LIBSTRONGSWAN_INTEGRITY  64
-#define SS_RC_DAEMON_INTEGRITY                 65
-#define SS_RC_INITIALIZATION_FAILED            66
-
-#define SS_RC_FIRST    SS_RC_LIBSTRONGSWAN_INTEGRITY
-#define SS_RC_LAST     SS_RC_INITIALIZATION_FAILED
-
-/**
- * Number of bits in a byte
- */
-#define BITS_PER_BYTE 8
-
-/**
- * Default length for various auxiliary text buffers
- */
-#define BUF_LEN 512
-
-/**
- * General purpose boolean type.
- */
-#ifdef HAVE_STDBOOL_H
-# include <stdbool.h>
-#else
-# ifndef HAVE__BOOL
-#  define _Bool signed char
-# endif /* HAVE__BOOL */
-# define bool _Bool
-# define false 0
-# define true 1
-# define __bool_true_false_are_defined 1
-#endif /* HAVE_STDBOOL_H */
-#ifndef FALSE
-# define FALSE false
-#endif /* FALSE */
-#ifndef TRUE
-# define TRUE  true
-#endif /* TRUE */
-
-/**
- * Helper function that compares two strings for equality
- */
-static inline bool streq(const char *x, const char *y)
-{
-       return strcmp(x, y) == 0;
-}
-
-/**
- * Macro compares two strings for equality, length limited
- */
-#define strneq(x,y,len) (strncmp(x, y, len) == 0)
-
-/**
- * Helper function that compares two strings for equality ignoring case
- */
-static inline bool strcaseeq(const char *x, const char *y)
-{
-       return strcasecmp(x, y) == 0;
-}
-
-/**
- * Macro compares two strings for equality ignoring case, length limited
- */
-#define strncaseeq(x,y,len) (strncasecmp(x, y, len) == 0)
-
-/**
- * NULL-safe strdup variant
- */
-static inline char *strdupnull(const char *s)
-{
-       return s ? strdup(s) : NULL;
-}
-
-/**
- * Macro compares two binary blobs for equality
- */
-#define memeq(x,y,len) (memcmp(x, y, len) == 0)
-
-/**
- * Macro gives back larger of two values.
- */
-#define max(x,y) ({ \
-       typeof(x) _x = (x); \
-       typeof(y) _y = (y); \
-       _x > _y ? _x : _y; })
-
-
-/**
- * Macro gives back smaller of two values.
- */
-#define min(x,y) ({ \
-       typeof(x) _x = (x); \
-       typeof(y) _y = (y); \
-       _x < _y ? _x : _y; })
-
-/**
- * Call destructor of an object, if object != NULL
- */
-#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
-
-/**
- * Call offset destructor of an object, if object != NULL
- */
-#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
-
-/**
- * Call function destructor of an object, if object != NULL
- */
-#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
-
-/**
- * Debug macro to follow control flow
- */
-#define POS printf("%s, line %d\n", __FILE__, __LINE__)
-
-/**
- * Object allocation/initialization macro, using designated initializer.
- */
-#define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \
-                                                  *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
-
-/**
- * Method declaration/definition macro, providing private and public interface.
- *
- * Defines a method name with this as first parameter and a return value ret,
- * and an alias for this method with a _ prefix, having the this argument
- * safely casted to the public interface iface.
- * _name is provided a function pointer, but will get optimized out by GCC.
- */
-#define METHOD(iface, name, ret, this, ...) \
-       static ret name(union {iface *_public; this;} \
-       __attribute__((transparent_union)), ##__VA_ARGS__); \
-       static typeof(name) *_##name = (typeof(name)*)name; \
-       static ret name(this, ##__VA_ARGS__)
-
-/**
- * Same as METHOD(), but is defined for two public interfaces.
- */
-#define METHOD2(iface1, iface2, name, ret, this, ...) \
-       static ret name(union {iface1 *_public1; iface2 *_public2; this;} \
-       __attribute__((transparent_union)), ##__VA_ARGS__); \
-       static typeof(name) *_##name = (typeof(name)*)name; \
-       static ret name(this, ##__VA_ARGS__)
-
-/**
- * Architecture independent bitfield definition helpers (at least with GCC).
- *
- * Defines a bitfield with a type t and a fixed size of bitfield members, e.g.:
- * BITFIELD2(u_int8_t,
- *     low: 4,
- *     high: 4,
- * ) flags;
- * The member defined first placed at bit 0.
- */
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define BITFIELD2(t, a, b,...)                 struct { t a; t b; __VA_ARGS__}
-#define BITFIELD3(t, a, b, c,...)              struct { t a; t b; t c; __VA_ARGS__}
-#define BITFIELD4(t, a, b, c, d,...)   struct { t a; t b; t c; t d; __VA_ARGS__}
-#define BITFIELD5(t, a, b, c, d, e,...)        struct { t a; t b; t c; t d; t e; __VA_ARGS__}
-#elif BYTE_ORDER == BIG_ENDIAN
-#define BITFIELD2(t, a, b,...)                 struct { t b; t a; __VA_ARGS__}
-#define BITFIELD3(t, a, b, c,...)              struct { t c; t b; t a; __VA_ARGS__}
-#define BITFIELD4(t, a, b, c, d,...)   struct { t d; t c; t b; t a; __VA_ARGS__}
-#define BITFIELD5(t, a, b, c, d, e,...)        struct { t e; t d; t c; t b; t a; __VA_ARGS__}
-#endif
-
-/**
- * Macro to allocate a sized type.
- */
-#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
-
-/**
- * Get the number of elements in an array
- */
-#define countof(array) (sizeof(array)/sizeof(array[0]))
-
-/**
- * Ignore result of functions tagged with warn_unused_result attributes
- */
-#define ignore_result(call) { if(call){}; }
-
-/**
- * Assign a function as a class method
- */
-#define ASSIGN(method, function) (method = (typeof(method))function)
-
-/**
- * time_t not defined
- */
-#define UNDEFINED_TIME 0
-
-/**
- * Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038
- */
-#define TIME_32_BIT_SIGNED_MAX 0x7fffffff
-
-/**
- * define some missing fixed width int types on OpenSolaris.
- * TODO: since the uintXX_t types are defined by the C99 standard we should
- * probably use those anyway
- */
-#ifdef __sun
-        #include <stdint.h>
-        typedef uint8_t         u_int8_t;
-        typedef uint16_t        u_int16_t;
-        typedef uint32_t        u_int32_t;
-        typedef uint64_t        u_int64_t;
-#endif
-
-typedef enum status_t status_t;
-
-/**
- * Return values of function calls.
- */
-enum status_t {
-       /**
-        * Call succeeded.
-        */
-       SUCCESS,
-
-       /**
-        * Call failed.
-        */
-       FAILED,
-
-       /**
-        * Out of resources.
-        */
-       OUT_OF_RES,
-
-       /**
-        * The suggested operation is already done
-        */
-       ALREADY_DONE,
-
-       /**
-        * Not supported.
-        */
-       NOT_SUPPORTED,
-
-       /**
-        * One of the arguments is invalid.
-        */
-       INVALID_ARG,
-
-       /**
-        * Something could not be found.
-        */
-       NOT_FOUND,
-
-       /**
-        * Error while parsing.
-        */
-       PARSE_ERROR,
-
-       /**
-        * Error while verifying.
-        */
-       VERIFY_ERROR,
-
-       /**
-        * Object in invalid state.
-        */
-       INVALID_STATE,
-
-       /**
-        * Destroy object which called method belongs to.
-        */
-       DESTROY_ME,
-
-       /**
-        * Another call to the method is required.
-        */
-       NEED_MORE,
-};
-
-/**
- * enum_names for type status_t.
- */
-extern enum_name_t *status_names;
-
-/**
- * deprecated pluto style return value:
- * error message, NULL for success
- */
-typedef const char *err_t;
-
-/**
- * Handle struct timeval like an own type.
- */
-typedef struct timeval timeval_t;
-
-/**
- * Handle struct timespec like an own type.
- */
-typedef struct timespec timespec_t;
-
-/**
- * Handle struct chunk_t like an own type.
- */
-typedef struct sockaddr sockaddr_t;
-
-/**
- * Clone a data to a newly allocated buffer
- */
-void *clalloc(void *pointer, size_t size);
-
-/**
- * Same as memcpy, but XORs src into dst instead of copy
- */
-void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
-
-/**
- * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
- */
-void memwipe_noinline(void *ptr, size_t n);
-
-/**
- * Safely overwrite n bytes of memory at ptr with zero, inlining variant.
- */
-static inline void memwipe_inline(void *ptr, size_t n)
-{
-       volatile char *c = (volatile char*)ptr;
-       size_t m, i;
-
-       /* byte wise until long aligned */
-       for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
-       {
-               c[i] = 0;
-       }
-       /* word wise */
-       if (n >= sizeof(long))
-       {
-               for (m = n - sizeof(long); i <= m; i += sizeof(long))
-               {
-                       *(volatile long*)&c[i] = 0;
-               }
-       }
-       /* byte wise of the rest */
-       for (; i < n; i++)
-       {
-               c[i] = 0;
-       }
-}
-
-/**
- * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
- */
-static inline void memwipe(void *ptr, size_t n)
-{
-       if (__builtin_constant_p(n))
-       {
-               memwipe_inline(ptr, n);
-       }
-       else
-       {
-               memwipe_noinline(ptr, n);
-       }
-}
-
-/**
- * A variant of strstr with the characteristics of memchr, where haystack is not
- * a null-terminated string but simply a memory area of length n.
- */
-void *memstr(const void *haystack, const char *needle, size_t n);
-
-/**
- * Translates the characters in the given string, searching for characters
- * in 'from' and mapping them to characters in 'to'.
- * The two characters sets 'from' and 'to' must contain the same number of
- * characters.
- */
-char *translate(char *str, const char *from, const char *to);
-
-/**
- * Creates a directory and all required parent directories.
- *
- * @param path         path to the new directory
- * @param mode         permissions of the new directory/directories
- * @return                     TRUE on success
- */
-bool mkdir_p(const char *path, mode_t mode);
-
-/**
- * Thread-safe wrapper around strerror and strerror_r.
- *
- * This is required because the first is not thread-safe (on some platforms)
- * and the second uses two different signatures (POSIX/GNU) and is impractical
- * to use anyway.
- *
- * @param errnum       error code (i.e. errno)
- * @return                     error message
- */
-const char *safe_strerror(int errnum);
-
-/**
- * Replace usages of strerror(3) with thread-safe variant.
- */
-#define strerror(errnum) safe_strerror(errnum)
-
-#ifndef HAVE_CLOSEFROM
-/**
- * Close open file descriptors greater than or equal to lowfd.
- *
- * @param lowfd                start closing file descriptoros from here
- */
-void closefrom(int lowfd);
-#endif
-
-/**
- * Get a timestamp from a monotonic time source.
- *
- * While the time()/gettimeofday() functions are affected by leap seconds
- * and system time changes, this function returns ever increasing monotonic
- * time stamps.
- *
- * @param tv           timeval struct receiving monotonic timestamps, or NULL
- * @return                     monotonic timestamp in seconds
- */
-time_t time_monotonic(timeval_t *tv);
-
-/**
- * Add the given number of milliseconds to the given timeval struct
- *
- * @param tv           timeval struct to modify
- * @param ms           number of milliseconds
- */
-static inline void timeval_add_ms(timeval_t *tv, u_int ms)
-{
-       tv->tv_usec += ms * 1000;
-       while (tv->tv_usec > 1000000 /* 1s */)
-       {
-               tv->tv_usec -= 1000000;
-               tv->tv_sec++;
-       }
-}
-
-/**
- * returns null
- */
-void *return_null();
-
-/**
- * No-Operation function
- */
-void nop();
-
-/**
- * returns TRUE
- */
-bool return_true();
-
-/**
- * returns FALSE
- */
-bool return_false();
-
-/**
- * returns FAILED
- */
-status_t return_failed();
-
-/**
- * Write a 16-bit host order value in network order to an unaligned address.
- *
- * @param host         host order 16-bit value
- * @param network      unaligned address to write network order value to
- */
-static inline void htoun16(void *network, u_int16_t host)
-{
-       char *unaligned = (char*)network;
-
-       host = htons(host);
-       memcpy(unaligned, &host, sizeof(host));
-}
-
-/**
- * Write a 32-bit host order value in network order to an unaligned address.
- *
- * @param host         host order 32-bit value
- * @param network      unaligned address to write network order value to
- */
-static inline void htoun32(void *network, u_int32_t host)
-{
-       char *unaligned = (char*)network;
-
-       host = htonl(host);
-       memcpy((char*)unaligned, &host, sizeof(host));
-}
-
-/**
- * Write a 64-bit host order value in network order to an unaligned address.
- *
- * @param host         host order 64-bit value
- * @param network      unaligned address to write network order value to
- */
-static inline void htoun64(void *network, u_int64_t host)
-{
-       char *unaligned = (char*)network;
-
-#ifdef be64toh
-       host = htobe64(host);
-       memcpy((char*)unaligned, &host, sizeof(host));
-#else
-       u_int32_t high_part, low_part;
-
-       high_part = host >> 32;
-       high_part = htonl(high_part);
-       low_part  = host & 0xFFFFFFFFLL;
-       low_part  = htonl(low_part);
-
-       memcpy(unaligned, &high_part, sizeof(high_part));
-       unaligned += sizeof(high_part);
-       memcpy(unaligned, &low_part, sizeof(low_part));
-#endif
-}
-
-/**
- * Read a 16-bit value in network order from an unaligned address to host order.
- *
- * @param network      unaligned address to read network order value from
- * @return                     host order value
- */
-static inline u_int16_t untoh16(void *network)
-{
-       char *unaligned = (char*)network;
-       u_int16_t tmp;
-
-       memcpy(&tmp, unaligned, sizeof(tmp));
-       return ntohs(tmp);
-}
-
-/**
- * Read a 32-bit value in network order from an unaligned address to host order.
- *
- * @param network      unaligned address to read network order value from
- * @return                     host order value
- */
-static inline u_int32_t untoh32(void *network)
-{
-       char *unaligned = (char*)network;
-       u_int32_t tmp;
-
-       memcpy(&tmp, unaligned, sizeof(tmp));
-       return ntohl(tmp);
-}
-
-/**
- * Read a 64-bit value in network order from an unaligned address to host order.
- *
- * @param network      unaligned address to read network order value from
- * @return                     host order value
- */
-static inline u_int64_t untoh64(void *network)
-{
-       char *unaligned = (char*)network;
-
-#ifdef be64toh
-       u_int64_t tmp;
-
-       memcpy(&tmp, unaligned, sizeof(tmp));
-       return be64toh(tmp);
-#else
-       u_int32_t high_part, low_part;
-
-       memcpy(&high_part, unaligned, sizeof(high_part));
-       unaligned += sizeof(high_part);
-       memcpy(&low_part, unaligned, sizeof(low_part));
-
-       high_part = ntohl(high_part);
-       low_part  = ntohl(low_part);
-
-       return (((u_int64_t)high_part) << 32) + low_part;
-#endif
-}
-
-/**
- * Special type to count references
- */
-typedef volatile u_int refcount_t;
-
-
-#ifdef HAVE_GCC_ATOMIC_OPERATIONS
-
-#define ref_get(ref) {__sync_fetch_and_add(ref, 1); }
-#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
-
-#define cas_bool(ptr, oldval, newval) \
-                                       (__sync_bool_compare_and_swap(ptr, oldval, newval))
-#define cas_ptr(ptr, oldval, newval) \
-                                       (__sync_bool_compare_and_swap(ptr, oldval, newval))
-
-#else /* !HAVE_GCC_ATOMIC_OPERATIONS */
-
-/**
- * Get a new reference.
- *
- * Increments the reference counter atomic.
- *
- * @param ref  pointer to ref counter
- */
-void ref_get(refcount_t *ref);
-
-/**
- * Put back a unused reference.
- *
- * Decrements the reference counter atomic and
- * says if more references available.
- *
- * @param ref  pointer to ref counter
- * @return             TRUE if no more references counted
- */
-bool ref_put(refcount_t *ref);
-
-/**
- * Atomically replace value of ptr with newval if it currently equals oldval.
- *
- * @param ptr          pointer to variable
- * @param oldval       old value of the variable
- * @param newval       new value set if possible
- * @return                     TRUE if value equaled oldval and newval was written
- */
-bool cas_bool(bool *ptr, bool oldval, bool newval);
-
-/**
- * Atomically replace value of ptr with newval if it currently equals oldval.
- *
- * @param ptr          pointer to variable
- * @param oldval       old value of the variable
- * @param newval       new value set if possible
- * @return                     TRUE if value equaled oldval and newval was written
- */
-bool cas_ptr(void **ptr, void *oldval, void *newval);
-
-#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
-
-/**
- * printf hook for time_t.
- *
- * Arguments are:
- *     time_t* time, bool utc
- */
-int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
-                                        const void *const *args);
-
-/**
- * printf hook for time_t deltas.
- *
- * Arguments are:
- *     time_t* begin, time_t* end
- */
-int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
-                                                  const void *const *args);
-
-/**
- * printf hook for memory areas.
- *
- * Arguments are:
- *     u_char *ptr, u_int len
- */
-int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
-                                       const void *const *args);
-
-#endif /** UTILS_H_ @}*/
index 865c1b8..67848ee 100644 (file)
@@ -42,7 +42,7 @@ struct chunk_t {
        size_t len;
 };
 
-#include "../utils.h"
+#include "utils.h"
 
 /**
  * A { NULL, 0 }-chunk handy for initialization.
index f999b9a..afaa114 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef INTEGRITY_CHECKER_H_
 #define INTEGRITY_CHECKER_H_
 
-#include "../utils.h"
+#include "utils.h"
 
 typedef struct integrity_checker_t integrity_checker_t;
 typedef struct integrity_checksum_t integrity_checksum_t;
index ae4e719..a861325 100644 (file)
@@ -24,7 +24,7 @@
 
 typedef struct settings_t settings_t;
 
-#include "../utils.h"
+#include "utils.h"
 #include "collections/enumerator.h"
 
 /**
diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c
new file mode 100644 (file)
index 0000000..bf0224c
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2005-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 "utils.h"
+
+#include <sys/stat.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <limits.h>
+#include <dirent.h>
+#include <time.h>
+#include <pthread.h>
+
+#include "collections/enumerator.h"
+#include "utils/debug.h"
+
+ENUM(status_names, SUCCESS, NEED_MORE,
+       "SUCCESS",
+       "FAILED",
+       "OUT_OF_RES",
+       "ALREADY_DONE",
+       "NOT_SUPPORTED",
+       "INVALID_ARG",
+       "NOT_FOUND",
+       "PARSE_ERROR",
+       "VERIFY_ERROR",
+       "INVALID_STATE",
+       "DESTROY_ME",
+       "NEED_MORE",
+);
+
+/**
+ * Described in header.
+ */
+void *clalloc(void * pointer, size_t size)
+{
+       void *data;
+       data = malloc(size);
+
+       memcpy(data, pointer, size);
+
+       return (data);
+}
+
+/**
+ * Described in header.
+ */
+void memxor(u_int8_t dst[], u_int8_t src[], size_t n)
+{
+       int m, i;
+
+       /* byte wise XOR until dst aligned */
+       for (i = 0; (uintptr_t)&dst[i] % sizeof(long) && i < n; i++)
+       {
+               dst[i] ^= src[i];
+       }
+       /* try to use words if src shares an aligment with dst */
+       switch (((uintptr_t)&src[i] % sizeof(long)))
+       {
+               case 0:
+                       for (m = n - sizeof(long); i <= m; i += sizeof(long))
+                       {
+                               *(long*)&dst[i] ^= *(long*)&src[i];
+                       }
+                       break;
+               case sizeof(int):
+                       for (m = n - sizeof(int); i <= m; i += sizeof(int))
+                       {
+                               *(int*)&dst[i] ^= *(int*)&src[i];
+                       }
+                       break;
+               case sizeof(short):
+                       for (m = n - sizeof(short); i <= m; i += sizeof(short))
+                       {
+                               *(short*)&dst[i] ^= *(short*)&src[i];
+                       }
+                       break;
+               default:
+                       break;
+       }
+       /* byte wise XOR of the rest */
+       for (; i < n; i++)
+       {
+               dst[i] ^= src[i];
+       }
+}
+
+/**
+ * Described in header.
+ */
+void memwipe_noinline(void *ptr, size_t n)
+{
+       memwipe_inline(ptr, n);
+}
+
+/**
+ * Described in header.
+ */
+void *memstr(const void *haystack, const char *needle, size_t n)
+{
+       unsigned const char *pos = haystack;
+       size_t l = strlen(needle);
+       for (; n >= l; ++pos, --n)
+       {
+               if (memeq(pos, needle, l))
+               {
+                       return (void*)pos;
+               }
+       }
+       return NULL;
+}
+
+/**
+ * Described in header.
+ */
+char* translate(char *str, const char *from, const char *to)
+{
+       char *pos = str;
+       if (strlen(from) != strlen(to))
+       {
+               return str;
+       }
+       while (pos && *pos)
+       {
+               char *match;
+               if ((match = strchr(from, *pos)) != NULL)
+               {
+                       *pos = to[match - from];
+               }
+               pos++;
+       }
+       return str;
+}
+
+/**
+ * Described in header.
+ */
+bool mkdir_p(const char *path, mode_t mode)
+{
+       int len;
+       char *pos, full[PATH_MAX];
+       pos = full;
+       if (!path || *path == '\0')
+       {
+               return TRUE;
+       }
+       len = snprintf(full, sizeof(full)-1, "%s", path);
+       if (len < 0 || len >= sizeof(full)-1)
+       {
+               DBG1(DBG_LIB, "path string %s too long", path);
+               return FALSE;
+       }
+       /* ensure that the path ends with a '/' */
+       if (full[len-1] != '/')
+       {
+               full[len++] = '/';
+               full[len] = '\0';
+       }
+       /* skip '/' at the beginning */
+       while (*pos == '/')
+       {
+               pos++;
+       }
+       while ((pos = strchr(pos, '/')))
+       {
+               *pos = '\0';
+               if (access(full, F_OK) < 0)
+               {
+                       if (mkdir(full, mode) < 0)
+                       {
+                               DBG1(DBG_LIB, "failed to create directory %s", full);
+                               return FALSE;
+                       }
+               }
+               *pos = '/';
+               pos++;
+       }
+       return TRUE;
+}
+
+
+/**
+ * The size of the thread-specific error buffer
+ */
+#define STRERROR_BUF_LEN 256
+
+/**
+ * Key to store thread-specific error buffer
+ */
+static pthread_key_t strerror_buf_key;
+
+/**
+ * Only initialize the key above once
+ */
+static pthread_once_t strerror_buf_key_once = PTHREAD_ONCE_INIT;
+
+/**
+ * Create the key used for the thread-specific error buffer
+ */
+static void create_strerror_buf_key()
+{
+       pthread_key_create(&strerror_buf_key, free);
+}
+
+/**
+ * Retrieve the error buffer assigned to the current thread (or create it)
+ */
+static inline char *get_strerror_buf()
+{
+       char *buf;
+
+       pthread_once(&strerror_buf_key_once, create_strerror_buf_key);
+       buf = pthread_getspecific(strerror_buf_key);
+       if (!buf)
+       {
+               buf = malloc(STRERROR_BUF_LEN);
+               pthread_setspecific(strerror_buf_key, buf);
+       }
+       return buf;
+}
+
+#ifdef HAVE_STRERROR_R
+/*
+ * Described in header.
+ */
+const char *safe_strerror(int errnum)
+{
+       char *buf = get_strerror_buf(), *msg;
+
+#ifdef STRERROR_R_CHAR_P
+       /* char* version which may or may not return the original buffer */
+       msg = strerror_r(errnum, buf, STRERROR_BUF_LEN);
+#else
+       /* int version returns 0 on success */
+       msg = strerror_r(errnum, buf, STRERROR_BUF_LEN) ? "Unknown error" : buf;
+#endif
+       return msg;
+}
+#else /* HAVE_STRERROR_R */
+/* we actually wan't to call strerror(3) below */
+#undef strerror
+/*
+ * Described in header.
+ */
+const char *safe_strerror(int errnum)
+{
+       static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+       char *buf = get_strerror_buf();
+
+       /* use a mutex to ensure calling strerror(3) is thread-safe */
+       pthread_mutex_lock(&mutex);
+       strncpy(buf, strerror(errnum), STRERROR_BUF_LEN);
+       pthread_mutex_unlock(&mutex);
+       buf[STRERROR_BUF_LEN - 1] = '\0';
+       return buf;
+}
+#endif /* HAVE_STRERROR_R */
+
+
+#ifndef HAVE_CLOSEFROM
+/**
+ * Described in header.
+ */
+void closefrom(int lowfd)
+{
+       char fd_dir[PATH_MAX];
+       int maxfd, fd, len;
+
+       /* try to close only open file descriptors on Linux... */
+       len = snprintf(fd_dir, sizeof(fd_dir), "/proc/%u/fd", getpid());
+       if (len > 0 && len < sizeof(fd_dir) && access(fd_dir, F_OK) == 0)
+       {
+               enumerator_t *enumerator = enumerator_create_directory(fd_dir);
+               if (enumerator)
+               {
+                       char *rel;
+                       while (enumerator->enumerate(enumerator, &rel, NULL, NULL))
+                       {
+                               fd = atoi(rel);
+                               if (fd >= lowfd)
+                               {
+                                       close(fd);
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+                       return;
+               }
+       }
+
+       /* ...fall back to closing all fds otherwise */
+       maxfd = (int)sysconf(_SC_OPEN_MAX);
+       if (maxfd < 0)
+       {
+               maxfd = 256;
+       }
+       for (fd = lowfd; fd < maxfd; fd++)
+       {
+               close(fd);
+       }
+}
+#endif /* HAVE_CLOSEFROM */
+
+/**
+ * Return monotonic time
+ */
+time_t time_monotonic(timeval_t *tv)
+{
+#if defined(HAVE_CLOCK_GETTIME) && \
+       (defined(HAVE_CONDATTR_CLOCK_MONOTONIC) || \
+        defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC))
+       /* as we use time_monotonic() for condvar operations, we use the
+        * monotonic time source only if it is also supported by pthread. */
+       timespec_t ts;
+
+       if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+       {
+               if (tv)
+               {
+                       tv->tv_sec = ts.tv_sec;
+                       tv->tv_usec = ts.tv_nsec / 1000;
+               }
+               return ts.tv_sec;
+       }
+#endif /* HAVE_CLOCK_GETTIME && (...) */
+       /* Fallback to non-monotonic timestamps:
+        * On MAC OS X, creating monotonic timestamps is rather difficult. We
+        * could use mach_absolute_time() and catch sleep/wakeup notifications.
+        * We stick to the simpler (non-monotonic) gettimeofday() for now.
+        * But keep in mind: we need the same time source here as in condvar! */
+       if (!tv)
+       {
+               return time(NULL);
+       }
+       if (gettimeofday(tv, NULL) != 0)
+       {       /* should actually never fail if passed pointers are valid */
+               return -1;
+       }
+       return tv->tv_sec;
+}
+
+/**
+ * return null
+ */
+void *return_null()
+{
+       return NULL;
+}
+
+/**
+ * returns TRUE
+ */
+bool return_true()
+{
+       return TRUE;
+}
+
+/**
+ * returns FALSE
+ */
+bool return_false()
+{
+       return FALSE;
+}
+
+/**
+ * returns FAILED
+ */
+status_t return_failed()
+{
+       return FAILED;
+}
+
+/**
+ * nop operation
+ */
+void nop()
+{
+}
+
+#ifndef HAVE_GCC_ATOMIC_OPERATIONS
+
+/**
+ * We use a single mutex for all refcount variables.
+ */
+static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Increase refcount
+ */
+void ref_get(refcount_t *ref)
+{
+       pthread_mutex_lock(&ref_mutex);
+       (*ref)++;
+       pthread_mutex_unlock(&ref_mutex);
+}
+
+/**
+ * Decrease refcount
+ */
+bool ref_put(refcount_t *ref)
+{
+       bool more_refs;
+
+       pthread_mutex_lock(&ref_mutex);
+       more_refs = --(*ref) > 0;
+       pthread_mutex_unlock(&ref_mutex);
+       return !more_refs;
+}
+
+/**
+ * Single mutex for all compare and swap operations.
+ */
+static pthread_mutex_t cas_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Compare and swap if equal to old value
+ */
+#define _cas_impl(name, type) \
+bool cas_##name(type *ptr, type oldval, type newval) \
+{ \
+       bool swapped; \
+       pthread_mutex_lock(&cas_mutex); \
+       if ((swapped = (*ptr == oldval))) { *ptr = newval; } \
+       pthread_mutex_unlock(&cas_mutex); \
+       return swapped; \
+}
+
+_cas_impl(bool, bool)
+_cas_impl(ptr, void*)
+
+#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
+
+/**
+ * Described in header.
+ */
+int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
+                                        const void *const *args)
+{
+       static const char* months[] = {
+               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+       };
+       time_t *time = *((time_t**)(args[0]));
+       bool utc = *((bool*)(args[1]));;
+       struct tm t;
+
+       if (time == UNDEFINED_TIME)
+       {
+               return print_in_hook(data, "--- -- --:--:--%s----",
+                                                        utc ? " UTC " : " ");
+       }
+       if (utc)
+       {
+               gmtime_r(time, &t);
+       }
+       else
+       {
+               localtime_r(time, &t);
+       }
+       return print_in_hook(data, "%s %02d %02d:%02d:%02d%s%04d",
+                                                months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,
+                                                t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
+}
+
+/**
+ * Described in header.
+ */
+int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
+                                                  const void *const *args)
+{
+       char* unit = "second";
+       time_t *arg1 = *((time_t**)(args[0]));
+       time_t *arg2 = *((time_t**)(args[1]));
+       u_int64_t delta = llabs(*arg1 - *arg2);
+
+       if (delta > 2 * 60 * 60 * 24)
+       {
+               delta /= 60 * 60 * 24;
+               unit = "day";
+       }
+       else if (delta > 2 * 60 * 60)
+       {
+               delta /= 60 * 60;
+               unit = "hour";
+       }
+       else if (delta > 2 * 60)
+       {
+               delta /= 60;
+               unit = "minute";
+       }
+       return print_in_hook(data, "%" PRIu64 " %s%s", delta, unit,
+                                                (delta == 1) ? "" : "s");
+}
+
+/**
+ * Number of bytes per line to dump raw data
+ */
+#define BYTES_PER_LINE 16
+
+static char hexdig_upper[] = "0123456789ABCDEF";
+
+/**
+ * Described in header.
+ */
+int mem_printf_hook(printf_hook_data_t *data,
+                                       printf_hook_spec_t *spec, const void *const *args)
+{
+       char *bytes = *((void**)(args[0]));
+       u_int len = *((int*)(args[1]));
+
+       char buffer[BYTES_PER_LINE * 3];
+       char ascii_buffer[BYTES_PER_LINE + 1];
+       char *buffer_pos = buffer;
+       char *bytes_pos  = bytes;
+       char *bytes_roof = bytes + len;
+       int line_start = 0;
+       int i = 0;
+       int written = 0;
+
+       written += print_in_hook(data, "=> %u bytes @ %p", len, bytes);
+
+       while (bytes_pos < bytes_roof)
+       {
+               *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
+               *buffer_pos++ = hexdig_upper[ *bytes_pos       & 0xF];
+
+               ascii_buffer[i++] =
+                               (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
+
+               if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE)
+               {
+                       int padding = 3 * (BYTES_PER_LINE - i);
+
+                       while (padding--)
+                       {
+                               *buffer_pos++ = ' ';
+                       }
+                       *buffer_pos++ = '\0';
+                       ascii_buffer[i] = '\0';
+
+                       written += print_in_hook(data, "\n%4d: %s  %s",
+                                                                        line_start, buffer, ascii_buffer);
+
+                       buffer_pos = buffer;
+                       line_start += BYTES_PER_LINE;
+                       i = 0;
+               }
+               else
+               {
+                       *buffer_pos++ = ' ';
+               }
+       }
+       return written;
+}
diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h
new file mode 100644 (file)
index 0000000..7b1beb9
--- /dev/null
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 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 utils_i utils
+ * @{ @ingroup utils
+ */
+
+#ifndef UTILS_H_
+#define UTILS_H_
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "enum.h"
+
+/**
+ * strongSwan program return codes
+ */
+#define SS_RC_LIBSTRONGSWAN_INTEGRITY  64
+#define SS_RC_DAEMON_INTEGRITY                 65
+#define SS_RC_INITIALIZATION_FAILED            66
+
+#define SS_RC_FIRST    SS_RC_LIBSTRONGSWAN_INTEGRITY
+#define SS_RC_LAST     SS_RC_INITIALIZATION_FAILED
+
+/**
+ * Number of bits in a byte
+ */
+#define BITS_PER_BYTE 8
+
+/**
+ * Default length for various auxiliary text buffers
+ */
+#define BUF_LEN 512
+
+/**
+ * General purpose boolean type.
+ */
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# ifndef HAVE__BOOL
+#  define _Bool signed char
+# endif /* HAVE__BOOL */
+# define bool _Bool
+# define false 0
+# define true 1
+# define __bool_true_false_are_defined 1
+#endif /* HAVE_STDBOOL_H */
+#ifndef FALSE
+# define FALSE false
+#endif /* FALSE */
+#ifndef TRUE
+# define TRUE  true
+#endif /* TRUE */
+
+/**
+ * Helper function that compares two strings for equality
+ */
+static inline bool streq(const char *x, const char *y)
+{
+       return strcmp(x, y) == 0;
+}
+
+/**
+ * Macro compares two strings for equality, length limited
+ */
+#define strneq(x,y,len) (strncmp(x, y, len) == 0)
+
+/**
+ * Helper function that compares two strings for equality ignoring case
+ */
+static inline bool strcaseeq(const char *x, const char *y)
+{
+       return strcasecmp(x, y) == 0;
+}
+
+/**
+ * Macro compares two strings for equality ignoring case, length limited
+ */
+#define strncaseeq(x,y,len) (strncasecmp(x, y, len) == 0)
+
+/**
+ * NULL-safe strdup variant
+ */
+static inline char *strdupnull(const char *s)
+{
+       return s ? strdup(s) : NULL;
+}
+
+/**
+ * Macro compares two binary blobs for equality
+ */
+#define memeq(x,y,len) (memcmp(x, y, len) == 0)
+
+/**
+ * Macro gives back larger of two values.
+ */
+#define max(x,y) ({ \
+       typeof(x) _x = (x); \
+       typeof(y) _y = (y); \
+       _x > _y ? _x : _y; })
+
+
+/**
+ * Macro gives back smaller of two values.
+ */
+#define min(x,y) ({ \
+       typeof(x) _x = (x); \
+       typeof(y) _y = (y); \
+       _x < _y ? _x : _y; })
+
+/**
+ * Call destructor of an object, if object != NULL
+ */
+#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
+
+/**
+ * Call offset destructor of an object, if object != NULL
+ */
+#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
+
+/**
+ * Call function destructor of an object, if object != NULL
+ */
+#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
+
+/**
+ * Debug macro to follow control flow
+ */
+#define POS printf("%s, line %d\n", __FILE__, __LINE__)
+
+/**
+ * Object allocation/initialization macro, using designated initializer.
+ */
+#define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \
+                                                  *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
+
+/**
+ * Method declaration/definition macro, providing private and public interface.
+ *
+ * Defines a method name with this as first parameter and a return value ret,
+ * and an alias for this method with a _ prefix, having the this argument
+ * safely casted to the public interface iface.
+ * _name is provided a function pointer, but will get optimized out by GCC.
+ */
+#define METHOD(iface, name, ret, this, ...) \
+       static ret name(union {iface *_public; this;} \
+       __attribute__((transparent_union)), ##__VA_ARGS__); \
+       static typeof(name) *_##name = (typeof(name)*)name; \
+       static ret name(this, ##__VA_ARGS__)
+
+/**
+ * Same as METHOD(), but is defined for two public interfaces.
+ */
+#define METHOD2(iface1, iface2, name, ret, this, ...) \
+       static ret name(union {iface1 *_public1; iface2 *_public2; this;} \
+       __attribute__((transparent_union)), ##__VA_ARGS__); \
+       static typeof(name) *_##name = (typeof(name)*)name; \
+       static ret name(this, ##__VA_ARGS__)
+
+/**
+ * Architecture independent bitfield definition helpers (at least with GCC).
+ *
+ * Defines a bitfield with a type t and a fixed size of bitfield members, e.g.:
+ * BITFIELD2(u_int8_t,
+ *     low: 4,
+ *     high: 4,
+ * ) flags;
+ * The member defined first placed at bit 0.
+ */
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define BITFIELD2(t, a, b,...)                 struct { t a; t b; __VA_ARGS__}
+#define BITFIELD3(t, a, b, c,...)              struct { t a; t b; t c; __VA_ARGS__}
+#define BITFIELD4(t, a, b, c, d,...)   struct { t a; t b; t c; t d; __VA_ARGS__}
+#define BITFIELD5(t, a, b, c, d, e,...)        struct { t a; t b; t c; t d; t e; __VA_ARGS__}
+#elif BYTE_ORDER == BIG_ENDIAN
+#define BITFIELD2(t, a, b,...)                 struct { t b; t a; __VA_ARGS__}
+#define BITFIELD3(t, a, b, c,...)              struct { t c; t b; t a; __VA_ARGS__}
+#define BITFIELD4(t, a, b, c, d,...)   struct { t d; t c; t b; t a; __VA_ARGS__}
+#define BITFIELD5(t, a, b, c, d, e,...)        struct { t e; t d; t c; t b; t a; __VA_ARGS__}
+#endif
+
+/**
+ * Macro to allocate a sized type.
+ */
+#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
+
+/**
+ * Get the number of elements in an array
+ */
+#define countof(array) (sizeof(array)/sizeof(array[0]))
+
+/**
+ * Ignore result of functions tagged with warn_unused_result attributes
+ */
+#define ignore_result(call) { if(call){}; }
+
+/**
+ * Assign a function as a class method
+ */
+#define ASSIGN(method, function) (method = (typeof(method))function)
+
+/**
+ * time_t not defined
+ */
+#define UNDEFINED_TIME 0
+
+/**
+ * Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038
+ */
+#define TIME_32_BIT_SIGNED_MAX 0x7fffffff
+
+/**
+ * define some missing fixed width int types on OpenSolaris.
+ * TODO: since the uintXX_t types are defined by the C99 standard we should
+ * probably use those anyway
+ */
+#ifdef __sun
+        #include <stdint.h>
+        typedef uint8_t         u_int8_t;
+        typedef uint16_t        u_int16_t;
+        typedef uint32_t        u_int32_t;
+        typedef uint64_t        u_int64_t;
+#endif
+
+typedef enum status_t status_t;
+
+/**
+ * Return values of function calls.
+ */
+enum status_t {
+       /**
+        * Call succeeded.
+        */
+       SUCCESS,
+
+       /**
+        * Call failed.
+        */
+       FAILED,
+
+       /**
+        * Out of resources.
+        */
+       OUT_OF_RES,
+
+       /**
+        * The suggested operation is already done
+        */
+       ALREADY_DONE,
+
+       /**
+        * Not supported.
+        */
+       NOT_SUPPORTED,
+
+       /**
+        * One of the arguments is invalid.
+        */
+       INVALID_ARG,
+
+       /**
+        * Something could not be found.
+        */
+       NOT_FOUND,
+
+       /**
+        * Error while parsing.
+        */
+       PARSE_ERROR,
+
+       /**
+        * Error while verifying.
+        */
+       VERIFY_ERROR,
+
+       /**
+        * Object in invalid state.
+        */
+       INVALID_STATE,
+
+       /**
+        * Destroy object which called method belongs to.
+        */
+       DESTROY_ME,
+
+       /**
+        * Another call to the method is required.
+        */
+       NEED_MORE,
+};
+
+/**
+ * enum_names for type status_t.
+ */
+extern enum_name_t *status_names;
+
+/**
+ * deprecated pluto style return value:
+ * error message, NULL for success
+ */
+typedef const char *err_t;
+
+/**
+ * Handle struct timeval like an own type.
+ */
+typedef struct timeval timeval_t;
+
+/**
+ * Handle struct timespec like an own type.
+ */
+typedef struct timespec timespec_t;
+
+/**
+ * Handle struct chunk_t like an own type.
+ */
+typedef struct sockaddr sockaddr_t;
+
+/**
+ * Clone a data to a newly allocated buffer
+ */
+void *clalloc(void *pointer, size_t size);
+
+/**
+ * Same as memcpy, but XORs src into dst instead of copy
+ */
+void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
+
+/**
+ * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
+ */
+void memwipe_noinline(void *ptr, size_t n);
+
+/**
+ * Safely overwrite n bytes of memory at ptr with zero, inlining variant.
+ */
+static inline void memwipe_inline(void *ptr, size_t n)
+{
+       volatile char *c = (volatile char*)ptr;
+       size_t m, i;
+
+       /* byte wise until long aligned */
+       for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
+       {
+               c[i] = 0;
+       }
+       /* word wise */
+       if (n >= sizeof(long))
+       {
+               for (m = n - sizeof(long); i <= m; i += sizeof(long))
+               {
+                       *(volatile long*)&c[i] = 0;
+               }
+       }
+       /* byte wise of the rest */
+       for (; i < n; i++)
+       {
+               c[i] = 0;
+       }
+}
+
+/**
+ * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
+ */
+static inline void memwipe(void *ptr, size_t n)
+{
+       if (__builtin_constant_p(n))
+       {
+               memwipe_inline(ptr, n);
+       }
+       else
+       {
+               memwipe_noinline(ptr, n);
+       }
+}
+
+/**
+ * A variant of strstr with the characteristics of memchr, where haystack is not
+ * a null-terminated string but simply a memory area of length n.
+ */
+void *memstr(const void *haystack, const char *needle, size_t n);
+
+/**
+ * Translates the characters in the given string, searching for characters
+ * in 'from' and mapping them to characters in 'to'.
+ * The two characters sets 'from' and 'to' must contain the same number of
+ * characters.
+ */
+char *translate(char *str, const char *from, const char *to);
+
+/**
+ * Creates a directory and all required parent directories.
+ *
+ * @param path         path to the new directory
+ * @param mode         permissions of the new directory/directories
+ * @return                     TRUE on success
+ */
+bool mkdir_p(const char *path, mode_t mode);
+
+/**
+ * Thread-safe wrapper around strerror and strerror_r.
+ *
+ * This is required because the first is not thread-safe (on some platforms)
+ * and the second uses two different signatures (POSIX/GNU) and is impractical
+ * to use anyway.
+ *
+ * @param errnum       error code (i.e. errno)
+ * @return                     error message
+ */
+const char *safe_strerror(int errnum);
+
+/**
+ * Replace usages of strerror(3) with thread-safe variant.
+ */
+#define strerror(errnum) safe_strerror(errnum)
+
+#ifndef HAVE_CLOSEFROM
+/**
+ * Close open file descriptors greater than or equal to lowfd.
+ *
+ * @param lowfd                start closing file descriptoros from here
+ */
+void closefrom(int lowfd);
+#endif
+
+/**
+ * Get a timestamp from a monotonic time source.
+ *
+ * While the time()/gettimeofday() functions are affected by leap seconds
+ * and system time changes, this function returns ever increasing monotonic
+ * time stamps.
+ *
+ * @param tv           timeval struct receiving monotonic timestamps, or NULL
+ * @return                     monotonic timestamp in seconds
+ */
+time_t time_monotonic(timeval_t *tv);
+
+/**
+ * Add the given number of milliseconds to the given timeval struct
+ *
+ * @param tv           timeval struct to modify
+ * @param ms           number of milliseconds
+ */
+static inline void timeval_add_ms(timeval_t *tv, u_int ms)
+{
+       tv->tv_usec += ms * 1000;
+       while (tv->tv_usec > 1000000 /* 1s */)
+       {
+               tv->tv_usec -= 1000000;
+               tv->tv_sec++;
+       }
+}
+
+/**
+ * returns null
+ */
+void *return_null();
+
+/**
+ * No-Operation function
+ */
+void nop();
+
+/**
+ * returns TRUE
+ */
+bool return_true();
+
+/**
+ * returns FALSE
+ */
+bool return_false();
+
+/**
+ * returns FAILED
+ */
+status_t return_failed();
+
+/**
+ * Write a 16-bit host order value in network order to an unaligned address.
+ *
+ * @param host         host order 16-bit value
+ * @param network      unaligned address to write network order value to
+ */
+static inline void htoun16(void *network, u_int16_t host)
+{
+       char *unaligned = (char*)network;
+
+       host = htons(host);
+       memcpy(unaligned, &host, sizeof(host));
+}
+
+/**
+ * Write a 32-bit host order value in network order to an unaligned address.
+ *
+ * @param host         host order 32-bit value
+ * @param network      unaligned address to write network order value to
+ */
+static inline void htoun32(void *network, u_int32_t host)
+{
+       char *unaligned = (char*)network;
+
+       host = htonl(host);
+       memcpy((char*)unaligned, &host, sizeof(host));
+}
+
+/**
+ * Write a 64-bit host order value in network order to an unaligned address.
+ *
+ * @param host         host order 64-bit value
+ * @param network      unaligned address to write network order value to
+ */
+static inline void htoun64(void *network, u_int64_t host)
+{
+       char *unaligned = (char*)network;
+
+#ifdef be64toh
+       host = htobe64(host);
+       memcpy((char*)unaligned, &host, sizeof(host));
+#else
+       u_int32_t high_part, low_part;
+
+       high_part = host >> 32;
+       high_part = htonl(high_part);
+       low_part  = host & 0xFFFFFFFFLL;
+       low_part  = htonl(low_part);
+
+       memcpy(unaligned, &high_part, sizeof(high_part));
+       unaligned += sizeof(high_part);
+       memcpy(unaligned, &low_part, sizeof(low_part));
+#endif
+}
+
+/**
+ * Read a 16-bit value in network order from an unaligned address to host order.
+ *
+ * @param network      unaligned address to read network order value from
+ * @return                     host order value
+ */
+static inline u_int16_t untoh16(void *network)
+{
+       char *unaligned = (char*)network;
+       u_int16_t tmp;
+
+       memcpy(&tmp, unaligned, sizeof(tmp));
+       return ntohs(tmp);
+}
+
+/**
+ * Read a 32-bit value in network order from an unaligned address to host order.
+ *
+ * @param network      unaligned address to read network order value from
+ * @return                     host order value
+ */
+static inline u_int32_t untoh32(void *network)
+{
+       char *unaligned = (char*)network;
+       u_int32_t tmp;
+
+       memcpy(&tmp, unaligned, sizeof(tmp));
+       return ntohl(tmp);
+}
+
+/**
+ * Read a 64-bit value in network order from an unaligned address to host order.
+ *
+ * @param network      unaligned address to read network order value from
+ * @return                     host order value
+ */
+static inline u_int64_t untoh64(void *network)
+{
+       char *unaligned = (char*)network;
+
+#ifdef be64toh
+       u_int64_t tmp;
+
+       memcpy(&tmp, unaligned, sizeof(tmp));
+       return be64toh(tmp);
+#else
+       u_int32_t high_part, low_part;
+
+       memcpy(&high_part, unaligned, sizeof(high_part));
+       unaligned += sizeof(high_part);
+       memcpy(&low_part, unaligned, sizeof(low_part));
+
+       high_part = ntohl(high_part);
+       low_part  = ntohl(low_part);
+
+       return (((u_int64_t)high_part) << 32) + low_part;
+#endif
+}
+
+/**
+ * Special type to count references
+ */
+typedef volatile u_int refcount_t;
+
+
+#ifdef HAVE_GCC_ATOMIC_OPERATIONS
+
+#define ref_get(ref) {__sync_fetch_and_add(ref, 1); }
+#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
+
+#define cas_bool(ptr, oldval, newval) \
+                                       (__sync_bool_compare_and_swap(ptr, oldval, newval))
+#define cas_ptr(ptr, oldval, newval) \
+                                       (__sync_bool_compare_and_swap(ptr, oldval, newval))
+
+#else /* !HAVE_GCC_ATOMIC_OPERATIONS */
+
+/**
+ * Get a new reference.
+ *
+ * Increments the reference counter atomic.
+ *
+ * @param ref  pointer to ref counter
+ */
+void ref_get(refcount_t *ref);
+
+/**
+ * Put back a unused reference.
+ *
+ * Decrements the reference counter atomic and
+ * says if more references available.
+ *
+ * @param ref  pointer to ref counter
+ * @return             TRUE if no more references counted
+ */
+bool ref_put(refcount_t *ref);
+
+/**
+ * Atomically replace value of ptr with newval if it currently equals oldval.
+ *
+ * @param ptr          pointer to variable
+ * @param oldval       old value of the variable
+ * @param newval       new value set if possible
+ * @return                     TRUE if value equaled oldval and newval was written
+ */
+bool cas_bool(bool *ptr, bool oldval, bool newval);
+
+/**
+ * Atomically replace value of ptr with newval if it currently equals oldval.
+ *
+ * @param ptr          pointer to variable
+ * @param oldval       old value of the variable
+ * @param newval       new value set if possible
+ * @return                     TRUE if value equaled oldval and newval was written
+ */
+bool cas_ptr(void **ptr, void *oldval, void *newval);
+
+#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
+
+/**
+ * printf hook for time_t.
+ *
+ * Arguments are:
+ *     time_t* time, bool utc
+ */
+int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
+                                        const void *const *args);
+
+/**
+ * printf hook for time_t deltas.
+ *
+ * Arguments are:
+ *     time_t* begin, time_t* end
+ */
+int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
+                                                  const void *const *args);
+
+/**
+ * printf hook for memory areas.
+ *
+ * Arguments are:
+ *     u_char *ptr, u_int len
+ */
+int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
+                                       const void *const *args);
+
+#endif /** UTILS_H_ @}*/