]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
Merge branch 'utils-split'
authorMartin Willi <martin@revosec.ch>
Thu, 16 Apr 2015 14:50:27 +0000 (16:50 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 16 Apr 2015 14:50:27 +0000 (16:50 +0200)
Split up the almighty utils.[ch] to separate files in the utils/utils subfolder.
These are not meant to include manually, but bring back some order to all
this functionality included through utils.h.

Additionally give some love to apidoc generation.

26 files changed:
Doxyfile.in
Makefile.am
src/libstrongswan/Android.mk
src/libstrongswan/Makefile.am
src/libstrongswan/utils/utils.c
src/libstrongswan/utils/utils.h
src/libstrongswan/utils/utils/align.c [new file with mode: 0644]
src/libstrongswan/utils/utils/align.h [new file with mode: 0644]
src/libstrongswan/utils/utils/atomics.c [new file with mode: 0644]
src/libstrongswan/utils/utils/atomics.h [new file with mode: 0644]
src/libstrongswan/utils/utils/byteorder.h [new file with mode: 0644]
src/libstrongswan/utils/utils/memory.c [new file with mode: 0644]
src/libstrongswan/utils/utils/memory.h [new file with mode: 0644]
src/libstrongswan/utils/utils/object.h [new file with mode: 0644]
src/libstrongswan/utils/utils/path.c [new file with mode: 0644]
src/libstrongswan/utils/utils/path.h [new file with mode: 0644]
src/libstrongswan/utils/utils/status.c [new file with mode: 0644]
src/libstrongswan/utils/utils/status.h [new file with mode: 0644]
src/libstrongswan/utils/utils/strerror.h
src/libstrongswan/utils/utils/string.c [new file with mode: 0644]
src/libstrongswan/utils/utils/string.h [new file with mode: 0644]
src/libstrongswan/utils/utils/time.c [new file with mode: 0644]
src/libstrongswan/utils/utils/time.h [new file with mode: 0644]
src/libstrongswan/utils/utils/tty.c [new file with mode: 0644]
src/libstrongswan/utils/utils/tty.h [new file with mode: 0644]
src/libstrongswan/utils/utils/types.h [new file with mode: 0644]

index eaf02d7de84fc2d6d5fe2e5a9f67c8df414c6789..7608ffef1b0f0b4d3809cbdf75f89f8af1fcc31d 100644 (file)
@@ -416,7 +416,7 @@ EXTRACT_PACKAGE        = NO
 # included in the documentation.
 # The default value is: NO.
 
-EXTRACT_STATIC         = NO
+EXTRACT_STATIC         = YES
 
 # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
 # locally in source files will be included in the documentation. If set to NO
@@ -683,7 +683,7 @@ CITE_BIB_FILES         =
 # messages are off.
 # The default value is: NO.
 
-QUIET                  = NO
+QUIET                  = YES
 
 # The WARNINGS tag can be used to turn on/off the warning messages that are
 # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
index bea4ba7c0290e2041f007fa6a5500c8a9fea55b2..f9e6452a2c10862a7074fa26eabe3f884e525b3f 100644 (file)
@@ -38,7 +38,9 @@ Doxyfile :    Doxyfile.in
                $(srcdir)/$@.in > $@
 
 apidoc :       Doxyfile
-               doxygen
+               @test -d apidoc || doxygen
+               @! find Doxyfile src/ -name '*.h' -o -name '*.md' , -newer apidoc | \
+                       grep -q '' || doxygen && touch apidoc
 
 cov-reset-common:
                @rm -rf $(top_builddir)/coverage
@@ -75,4 +77,4 @@ clean-local: cov-reset-common
                @find $(top_builddir)/src $(top_builddir)/scripts -name "*.gcno" -delete
                @rm -rf apidoc
 
-.PHONY: cov-reset-common cov-reset cov-report coverage
+.PHONY: cov-reset-common cov-reset cov-report coverage apidoc
index b137b73f9c87e6f30175b348c3f82a28c8f5424b..d019d96e121355a8ab9333d63c9173c914bb32c2 100644 (file)
@@ -39,7 +39,10 @@ selectors/traffic_selector.c settings/settings.c settings/settings_types.c \
 settings/settings_parser.c settings/settings_lexer.c utils/cpu_feature.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/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c
+utils/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c \
+utils/utils/atomics.c utils/utils/string.c utils/utils/memory.c \
+utils/utils/tty.c utils/utils/path.c utils/utils/status.c utils/utils/time.c \
+utils/utils/align.c
 
 libstrongswan_la_SOURCES += \
     threading/thread.c \
index 462c34bb218a643edd406307b8a4827bf161a5d8..b3636cfb897be668bdd2ecf8e971d9002bfc7e86 100644 (file)
@@ -37,7 +37,10 @@ selectors/traffic_selector.c settings/settings.c settings/settings_types.c \
 settings/settings_parser.y settings/settings_lexer.l utils/cpu_feature.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/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c
+utils/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c \
+utils/utils/atomics.c utils/utils/string.c utils/utils/memory.c \
+utils/utils/tty.c utils/utils/path.c utils/utils/status.c utils/utils/time.c \
+utils/utils/align.c
 
 if !USE_WINDOWS
   libstrongswan_la_SOURCES += \
@@ -106,7 +109,10 @@ utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
 utils/cpu_feature.h utils/leak_detective.h utils/printf_hook/printf_hook.h \
 utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
 utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
-utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h
+utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h \
+utils/utils/atomics.h utils/utils/types.h utils/utils/byteorder.h \
+utils/utils/string.h utils/utils/memory.h utils/utils/tty.h utils/utils/path.h \
+utils/utils/status.h utils/utils/object.h utils/utils/time.h utils/utils/align.h
 endif
 
 library.lo :   $(top_builddir)/config.status
index 119c6563a88fdc57e6ce163cf7d620f8257170fd..9b516accd411b9593f3a4e603746d8423819ec63 100644 (file)
  * for more details.
  */
 
-#define _GNU_SOURCE /* for memrchr */
-#ifdef WIN32
-/* for GetTickCount64, Windows 7 */
-# define _WIN32_WINNT 0x0601
-#endif
-
 #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>
 #ifndef WIN32
 # include <signal.h>
 #endif
 
 #include <library.h>
-#include <utils/debug.h>
-#include <utils/chunk.h>
 #include <collections/enumerator.h>
-#include <threading/spinlock.h>
-#include <threading/mutex.h>
-#include <threading/condvar.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* malloc_align(size_t size, u_int8_t align)
-{
-       u_int8_t pad;
-       void *ptr;
-
-       if (align == 0)
-       {
-               align = 1;
-       }
-       ptr = malloc(align + sizeof(pad) + size);
-       if (!ptr)
-       {
-               return NULL;
-       }
-       /* store padding length just before data, down to the allocation boundary
-        * to do some verification during free_align() */
-       pad = align - ((uintptr_t)ptr % align);
-       memset(ptr, pad, pad);
-       return ptr + pad;
-}
-
-/**
- * Described in header.
- */
-void free_align(void *ptr)
-{
-       u_int8_t pad, *pos;
-
-       pos = ptr - 1;
-       /* verify padding to check any corruption */
-       for (pad = *pos; (void*)pos >= ptr - pad; pos--)
-       {
-               if (*pos != pad)
-               {
-                       DBG1(DBG_LIB, "!!!! invalid free_align() !!!!");
-                       return;
-               }
-       }
-       free(ptr - pad);
-}
-
-/**
- * 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.
- */
-bool memeq_const(const void *x, const void *y, size_t len)
-{
-       const u_char *a, *b;
-       u_int bad = 0;
-       size_t i;
-
-       a = (const u_char*)x;
-       b = (const u_char*)y;
-
-       for (i = 0; i < len; i++)
-       {
-               bad |= a[i] != b[i];
-       }
-       return !bad;
-}
-
-/**
- * Described in header.
- */
-void *memstr(const void *haystack, const char *needle, size_t n)
-{
-       const u_char *pos = haystack;
-       size_t l;
-
-       if (!haystack || !needle || (l = strlen(needle)) == 0)
-       {
-               return NULL;
-       }
-       for (; n >= l; ++pos, --n)
-       {
-               if (memeq(pos, needle, l))
-               {
-                       return (void*)pos;
-               }
-       }
-       return NULL;
-}
-
-/**
- * Described in header.
- */
-void *utils_memrchr(const void *s, int c, size_t n)
-{
-       const u_char *pos;
-
-       if (!s || !n)
-       {
-               return NULL;
-       }
-
-       for (pos = s + n - 1; pos >= (u_char*)s; pos--)
-       {
-               if (*pos == (u_char)c)
-               {
-                       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.
- */
-char* strreplace(const char *str, const char *search, const char *replace)
-{
-       size_t len, slen, rlen, count = 0;
-       char *res, *pos, *found, *dst;
-
-       if (!str || !*str || !search || !*search || !replace)
-       {
-               return (char*)str;
-       }
-       slen = strlen(search);
-       rlen = strlen(replace);
-       if (slen != rlen)
-       {
-               for (pos = (char*)str; (pos = strstr(pos, search)); pos += slen)
-               {
-                       found = pos;
-                       count++;
-               }
-               if (!count)
-               {
-                       return (char*)str;
-               }
-               len = (found - str) + strlen(found) + count * (rlen - slen);
-       }
-       else
-       {
-               len = strlen(str);
-       }
-       found = strstr(str, search);
-       if (!found)
-       {
-               return (char*)str;
-       }
-       dst = res = malloc(len + 1);
-       pos = (char*)str;
-       do
-       {
-               len = found - pos;
-               memcpy(dst, pos, len);
-               dst += len;
-               memcpy(dst, replace, rlen);
-               dst += rlen;
-               pos = found + slen;
-       }
-       while ((found = strstr(pos, search)));
-       strcpy(dst, pos);
-       return res;
-}
 
 #ifdef WIN32
 
+#include <threading/mutex.h>
+#include <threading/condvar.h>
+
 /**
  * Flag to indicate signaled wait_sigint()
  */
@@ -368,216 +106,6 @@ void wait_sigint()
 
 #endif
 
-/**
- * Described in header.
- */
-char* path_dirname(const char *path)
-{
-       char *pos;
-
-       pos = path ? strrchr(path, DIRECTORY_SEPARATOR[0]) : NULL;
-
-       if (pos && !pos[1])
-       {       /* if path ends with slashes we have to look beyond them */
-               while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
-               {       /* skip trailing slashes */
-                       pos--;
-               }
-               pos = memrchr(path, DIRECTORY_SEPARATOR[0], pos - path + 1);
-       }
-       if (!pos)
-       {
-#ifdef WIN32
-               if (path && strlen(path))
-               {
-                       if ((isalpha(path[0]) && path[1] == ':'))
-                       {       /* if just a drive letter given, return that as dirname */
-                               return chunk_clone(chunk_from_chars(path[0], ':', 0)).ptr;
-                       }
-               }
-#endif
-               return strdup(".");
-       }
-       while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
-       {       /* skip superfluous slashes */
-               pos--;
-       }
-       return strndup(path, pos - path + 1);
-}
-
-/**
- * Described in header.
- */
-char* path_basename(const char *path)
-{
-       char *pos, *trail = NULL;
-
-       if (!path || !*path)
-       {
-               return strdup(".");
-       }
-       pos = strrchr(path, DIRECTORY_SEPARATOR[0]);
-       if (pos && !pos[1])
-       {       /* if path ends with slashes we have to look beyond them */
-               while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
-               {       /* skip trailing slashes */
-                       pos--;
-               }
-               if (pos == path && *pos == DIRECTORY_SEPARATOR[0])
-               {       /* contains only slashes */
-                       return strdup(DIRECTORY_SEPARATOR);
-               }
-               trail = pos + 1;
-               pos = memrchr(path, DIRECTORY_SEPARATOR[0], trail - path);
-       }
-       pos = pos ? pos + 1 : (char*)path;
-       return trail ? strndup(pos, trail - pos) : strdup(pos);
-}
-
-/**
- * Described in header.
- */
-bool path_absolute(const char *path)
-{
-       if (!path)
-       {
-               return FALSE;
-       }
-#ifdef WIN32
-       if (strpfx(path, "\\\\"))
-       {       /* UNC */
-               return TRUE;
-       }
-       if (strlen(path) && isalpha(path[0]) && path[1] == ':')
-       {       /* drive letter */
-               return TRUE;
-       }
-#else /* !WIN32 */
-       if (path[0] == DIRECTORY_SEPARATOR[0])
-       {
-               return TRUE;
-       }
-#endif
-       return FALSE;
-}
-
-/**
- * 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)
-               {
-#ifdef WIN32
-                       if (_mkdir(full) < 0)
-#else
-                       if (mkdir(full, mode) < 0)
-#endif
-                       {
-                               DBG1(DBG_LIB, "failed to create directory %s", full);
-                               return FALSE;
-                       }
-               }
-               *pos = '/';
-               pos++;
-       }
-       return TRUE;
-}
-
-ENUM(tty_color_names, TTY_RESET, TTY_BG_DEF,
-       "\e[0m",
-       "\e[1m",
-       "\e[4m",
-       "\e[5m",
-       "\e[30m",
-       "\e[31m",
-       "\e[32m",
-       "\e[33m",
-       "\e[34m",
-       "\e[35m",
-       "\e[36m",
-       "\e[37m",
-       "\e[39m",
-       "\e[40m",
-       "\e[41m",
-       "\e[42m",
-       "\e[43m",
-       "\e[44m",
-       "\e[45m",
-       "\e[46m",
-       "\e[47m",
-       "\e[49m",
-);
-
-/**
- * Get the escape string for a given TTY color, empty string on non-tty FILE
- */
-char* tty_escape_get(int fd, tty_escape_t escape)
-{
-       if (!isatty(fd))
-       {
-               return "";
-       }
-       switch (escape)
-       {
-               case TTY_RESET:
-               case TTY_BOLD:
-               case TTY_UNDERLINE:
-               case TTY_BLINKING:
-#ifdef WIN32
-                       return "";
-#endif
-               case TTY_FG_BLACK:
-               case TTY_FG_RED:
-               case TTY_FG_GREEN:
-               case TTY_FG_YELLOW:
-               case TTY_FG_BLUE:
-               case TTY_FG_MAGENTA:
-               case TTY_FG_CYAN:
-               case TTY_FG_WHITE:
-               case TTY_FG_DEF:
-               case TTY_BG_BLACK:
-               case TTY_BG_RED:
-               case TTY_BG_GREEN:
-               case TTY_BG_YELLOW:
-               case TTY_BG_BLUE:
-               case TTY_BG_MAGENTA:
-               case TTY_BG_CYAN:
-               case TTY_BG_WHITE:
-               case TTY_BG_DEF:
-                       return enum_to_name(tty_color_names, escape);
-               /* warn if a escape code is missing */
-       }
-       return "";
-}
-
 #ifndef HAVE_CLOSEFROM
 /**
  * Described in header.
@@ -625,58 +153,6 @@ void closefrom(int lowfd)
 }
 #endif /* HAVE_CLOSEFROM */
 
-/**
- * Return monotonic time
- */
-time_t time_monotonic(timeval_t *tv)
-{
-#ifdef WIN32
-       ULONGLONG ms;
-       time_t s;
-
-       ms = GetTickCount64();
-       s = ms / 1000;
-       if (tv)
-       {
-               tv->tv_sec = s;
-               tv->tv_usec = (ms - (s * 1000)) * 1000;
-       }
-       return s;
-#else /* !WIN32 */
-#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;
-#endif /* !WIN32 */
-}
-
 /**
  * return null
  */
@@ -701,22 +177,6 @@ bool return_false()
        return FALSE;
 }
 
-/**
- * returns FAILED
- */
-status_t return_failed()
-{
-       return FAILED;
-}
-
-/**
- * returns SUCCESS
- */
-status_t return_success()
-{
-       return SUCCESS;
-}
-
 /**
  * nop operation
  */
@@ -724,122 +184,6 @@ void nop()
 {
 }
 
-#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
-
-/**
- * Spinlock for ref_get/put
- */
-static spinlock_t *ref_lock;
-
-/**
- * Increase refcount
- */
-refcount_t ref_get(refcount_t *ref)
-{
-       refcount_t current;
-
-       ref_lock->lock(ref_lock);
-       current = ++(*ref);
-       ref_lock->unlock(ref_lock);
-
-       return current;
-}
-
-/**
- * Decrease refcount
- */
-bool ref_put(refcount_t *ref)
-{
-       bool more_refs;
-
-       ref_lock->lock(ref_lock);
-       more_refs = --(*ref) > 0;
-       ref_lock->unlock(ref_lock);
-       return !more_refs;
-}
-
-/**
- * Current refcount
- */
-refcount_t ref_cur(refcount_t *ref)
-{
-       refcount_t current;
-
-       ref_lock->lock(ref_lock);
-       current = *ref;
-       ref_lock->unlock(ref_lock);
-
-       return current;
-}
-
-/**
- * Spinlock for all compare and swap operations.
- */
-static spinlock_t *cas_lock;
-
-/**
- * Compare and swap if equal to old value
- */
-#define _cas_impl(name, type) \
-bool cas_##name(type *ptr, type oldval, type newval) \
-{ \
-       bool swapped; \
-       cas_lock->lock(cas_lock); \
-       if ((swapped = (*ptr == oldval))) { *ptr = newval; } \
-       cas_lock->unlock(cas_lock); \
-       return swapped; \
-}
-
-_cas_impl(bool, bool)
-_cas_impl(ptr, void*)
-
-#endif /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */
-
-
-#ifdef HAVE_FMEMOPEN_FALLBACK
-
-static int fmemread(chunk_t *cookie, char *buf, int size)
-{
-       int len;
-
-       len = min(size, cookie->len);
-       memcpy(buf, cookie->ptr, len);
-       *cookie = chunk_skip(*cookie, len);
-
-       return len;
-}
-
-static int fmemwrite(chunk_t *cookie, const char *buf, int size)
-{
-       int len;
-
-       len = min(size, cookie->len);
-       memcpy(cookie->ptr, buf, len);
-       *cookie = chunk_skip(*cookie, len);
-
-       return len;
-}
-
-static int fmemclose(void *cookie)
-{
-       free(cookie);
-       return 0;
-}
-
-FILE *fmemopen(void *buf, size_t size, const char *mode)
-{
-       chunk_t *cookie;
-
-       INIT(cookie,
-               .ptr = buf,
-               .len = size,
-       );
-
-       return funopen(cookie, (void*)fmemread, (void*)fmemwrite, NULL, fmemclose);
-}
-
-#endif /* FMEMOPEN fallback*/
-
 /**
  * See header
  */
@@ -848,12 +192,7 @@ void utils_init()
 #ifdef WIN32
        windows_init();
 #endif
-
-#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
-       ref_lock = spinlock_create();
-       cas_lock = spinlock_create();
-#endif
-
+       atomics_init();
        strerror_init();
 }
 
@@ -865,137 +204,6 @@ void utils_deinit()
 #ifdef WIN32
        windows_deinit();
 #endif
-
-#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
-       ref_lock->destroy(ref_lock);
-       cas_lock->destroy(cas_lock);
-#endif
-
+       atomics_deinit();
        strerror_deinit();
 }
-
-/**
- * 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 = *((int*)(args[1]));
-       struct tm t, *ret = NULL;
-
-       if (*time != UNDEFINED_TIME)
-       {
-               if (utc)
-               {
-                       ret = gmtime_r(time, &t);
-               }
-               else
-               {
-                       ret = localtime_r(time, &t);
-               }
-       }
-       if (ret == NULL)
-       {
-               return print_in_hook(data, "--- -- --:--:--%s----",
-                                                        utc ? " UTC " : " ");
-       }
-       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;
-}
index c42f88168700670f819aec2befadb5deeb0e3d97..acc15c42a8c6ebdafffc22fd6e1c21bf65328316 100644 (file)
 # include <poll.h>
 #endif
 
+#include "utils/types.h"
+#include "enum.h"
+#include "utils/atomics.h"
+#include "utils/align.h"
+#include "utils/byteorder.h"
+#include "utils/string.h"
+#include "utils/memory.h"
+#include "utils/strerror.h"
+#include "utils/status.h"
+#include "utils/object.h"
+#include "utils/path.h"
+#include "utils/time.h"
+#include "utils/tty.h"
+#ifdef __APPLE__
+# include "compat/apple.h"
+#endif
+
+/**
+ * Initialize utility functions
+ */
+void utils_init();
+
+/**
+ * Deinitialize utility functions
+ */
+void utils_deinit();
+
 /**
  * strongSwan program return codes
  */
 #define BUILD_ASSERT_ARRAY(a) \
                BUILD_ASSERT(!__builtin_types_compatible_p(typeof(a), typeof(&(a)[0])))
 
-/**
- * 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 */
-
-#include "enum.h"
-#include "utils/strerror.h"
-#ifdef __APPLE__
-# include "compat/apple.h"
-#endif
-
-/**
- * Directory separator character in paths on this platform
- */
-#ifdef WIN32
-# define DIRECTORY_SEPARATOR "\\"
-#else
-# define DIRECTORY_SEPARATOR "/"
-#endif
-
-/**
- * Initialize utility functions
- */
-void utils_init();
-
-/**
- * Deinitialize utility functions
- */
-void utils_deinit();
-
-/**
- * Helper function that compares two strings for equality
- */
-static inline bool streq(const char *x, const char *y)
-{
-       return strcmp(x, y) == 0;
-}
-
-/**
- * Helper function that compares two strings for equality, length limited
- */
-static inline bool strneq(const char *x, const char *y, size_t len)
-{
-       return strncmp(x, y, len) == 0;
-}
-
-/**
- * Helper function that checks if a string starts with a given prefix
- */
-static inline bool strpfx(const char *x, const char *prefix)
-{
-       return strneq(x, prefix, strlen(prefix));
-}
-
-/**
- * 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;
-}
-
-/**
- * Helper function that compares two strings for equality ignoring case, length limited
- */
-static inline bool strncaseeq(const char *x, const char *y, size_t len)
-{
-       return strncasecmp(x, y, len) == 0;
-}
-
-/**
- * Helper function that checks if a string starts with a given prefix
- */
-static inline bool strcasepfx(const char *x, const char *prefix)
-{
-       return strncaseeq(x, prefix, strlen(prefix));
-}
-
-/**
- * NULL-safe strdup variant
- */
-static inline char *strdupnull(const char *s)
-{
-       return s ? strdup(s) : NULL;
-}
-
-/**
- * Helper function that compares two binary blobs for equality
- */
-static inline bool memeq(const void *x, const void *y, size_t len)
-{
-       return memcmp(x, y, len) == 0;
-}
-
-/**
- * Same as memeq(), but with a constant runtime, safe for cryptographic use.
- */
-bool memeq_const(const void *x, const void *y, size_t len);
-
-/**
- * Calling memcpy() with NULL pointers, even with n == 0, results in undefined
- * behavior according to the C standard.  This version is guaranteed to not
- * access the pointers if n is 0.
- */
-static inline void *memcpy_noop(void *dst, const void *src, size_t n)
-{
-       return n ? memcpy(dst, src, n) : dst;
-}
-#ifdef memcpy
-# undef memcpy
-#endif
-#define memcpy(d,s,n) memcpy_noop(d,s,n)
-
-/**
- * Calling memmove() with NULL pointers, even with n == 0, results in undefined
- * behavior according to the C standard.  This version is guaranteed to not
- * access the pointers if n is 0.
- */
-static inline void *memmove_noop(void *dst, const void *src, size_t n)
-{
-       return n ? memmove(dst, src, n) : dst;
-}
-#ifdef memmove
-# undef memmove
-#endif
-#define memmove(d,s,n) memmove_noop(d,s,n)
-
-/**
- * Calling memset() with a NULL pointer, even with n == 0, results in undefined
- * behavior according to the C standard.  This version is guaranteed to not
- * access the pointer if n is 0.
- */
-static inline void *memset_noop(void *s, int c, size_t n)
-{
-       return n ? memset(s, c, n) : s;
-}
-#ifdef memset
-# undef memset
-#endif
-#define memset(s,c,n) memset_noop(s,c,n)
-
-/**
- * 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__ }; }
-
-/**
- * Aligning version of INIT().
- *
- * The returned pointer must be freed using free_align(), not free().
- *
- * @param this         object to allocate/initialize
- * @param align                alignment for allocation, in bytes
- * @param ...          initializer
- */
-#define INIT_ALIGN(this, align, ...) { \
-                                               (this) = malloc_align(sizeof(*(this)), align); \
-                                               *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
-
-/**
- * Object allocation/initialization macro, with extra allocated bytes at tail.
- *
- * The extra space gets zero-initialized.
- *
- * @param this         pointer to object to allocate memory for
- * @param extra                number of bytes to allocate at end of this
- * @param ...          initializer
- */
-#define INIT_EXTRA(this, extra, ...) { \
-                                               typeof(extra) _extra = (extra); \
-                                               (this) = malloc(sizeof(*(this)) + _extra); \
-                                               *(this) = (typeof(*(this))){ __VA_ARGS__ }; \
-                                               memset((this) + 1, 0, _extra); }
-
-/**
- * Aligning version of INIT_EXTRA().
- *
- * The returned pointer must be freed using free_align(), not free().
- *
- * @param this         object to allocate/initialize
- * @param extra                number of bytes to allocate at end of this
- * @param align                alignment for allocation, in bytes
- * @param ...          initializer
- */
-#define INIT_EXTRA_ALIGN(this, extra, align, ...) { \
-                                               typeof(extra) _extra = (extra); \
-                                               (this) = malloc_align(sizeof(*(this)) + _extra, align); \
-                                               *(this) = (typeof(*(this))){ __VA_ARGS__ }; \
-                                               memset((this) + 1, 0, _extra); }
-
-/**
- * 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__)
-
-/**
- * Callback declaration/definition macro, allowing casted first parameter.
- *
- * This is very similar to METHOD, but instead of casting the first parameter
- * to a public interface, it uses a void*. This allows type safe definition
- * of a callback function, while using the real type for the first parameter.
- */
-#define CALLBACK(name, ret, param1, ...) \
-       static ret _cb_##name(union {void *_generic; param1;} \
-       __attribute__((transparent_union)), ##__VA_ARGS__); \
-       static typeof(_cb_##name) *name = (typeof(_cb_##name)*)_cb_##name; \
-       static ret _cb_##name(param1, ##__VA_ARGS__)
-
 /**
  * This macro allows counting the number of arguments passed to a macro.
  * Combined with the VA_ARGS_DISPATCH() macro this can be used to implement
@@ -379,28 +132,6 @@ static inline void *memset_noop(void *s, int c, size_t n)
 #define _VA_ARGS_DISPATCH(func, num) __VA_ARGS_DISPATCH(func, num)
 #define __VA_ARGS_DISPATCH(func, num) func ## num
 
-/**
- * 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.
  */
@@ -417,349 +148,11 @@ static inline void *memset_noop(void *s, int c, size_t n)
  */
 #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
- */
-#if defined __sun || defined WIN32
-        #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
-
-#ifdef HAVE_INT128
-/**
- * 128 bit wide signed integer, if supported
- */
-typedef __int128 int128_t;
-/**
- * 128 bit wide unsigned integer, if supported
- */
-typedef unsigned __int128 u_int128_t;
-
-# define MAX_INT_TYPE int128_t
-# define MAX_UINT_TYPE u_int128_t
-#else
-# define MAX_INT_TYPE int64_t
-# define MAX_UINT_TYPE 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;
-
-typedef enum tty_escape_t tty_escape_t;
-
-/**
- * Excape codes for tty colors
- */
-enum tty_escape_t {
-       /** text properties */
-       TTY_RESET,
-       TTY_BOLD,
-       TTY_UNDERLINE,
-       TTY_BLINKING,
-
-       /** foreground colors */
-       TTY_FG_BLACK,
-       TTY_FG_RED,
-       TTY_FG_GREEN,
-       TTY_FG_YELLOW,
-       TTY_FG_BLUE,
-       TTY_FG_MAGENTA,
-       TTY_FG_CYAN,
-       TTY_FG_WHITE,
-       TTY_FG_DEF,
-
-       /** background colors */
-       TTY_BG_BLACK,
-       TTY_BG_RED,
-       TTY_BG_GREEN,
-       TTY_BG_YELLOW,
-       TTY_BG_BLUE,
-       TTY_BG_MAGENTA,
-       TTY_BG_CYAN,
-       TTY_BG_WHITE,
-       TTY_BG_DEF,
-};
-
-/**
- * Get the escape string for a given TTY color, empty string on non-tty fd
- */
-char* tty_escape_get(int fd, tty_escape_t escape);
-
-/**
- * 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;
-
-/**
- * malloc(), but returns aligned memory.
- *
- * The returned pointer must be freed using free_align(), not free().
- *
- * @param size                 size of allocated data
- * @param align                        alignment, up to 255 bytes, usually a power of 2
- * @return                             allocated hunk, aligned to align bytes
- */
-void* malloc_align(size_t size, u_int8_t align);
-
-/**
- * Free a hunk allocated by malloc_align().
- *
- * @param ptr                  hunk to free
- */
-void free_align(void *ptr);
-
-/**
- * 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 (!ptr)
-       {
-               return;
-       }
-       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);
-
-/**
- * Replacement for memrchr(3) if it is not provided by the C library.
- *
- * @param s            start of the memory area to search
- * @param c            character to search
- * @param n            length of memory area to search
- * @return             pointer to the found character or NULL
- */
-void *utils_memrchr(const void *s, int c, size_t n);
-
-#ifndef HAVE_MEMRCHR
-#define memrchr(s,c,n) utils_memrchr(s,c,n)
-#endif
-
-/**
- * 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);
-
-/**
- * Replaces all occurrences of search in the given string with replace.
- *
- * Allocates memory only if anything is replaced in the string.  The original
- * string is also returned if any of the arguments are invalid (e.g. if search
- * is empty or any of them are NULL).
- *
- * @param str          original string
- * @param search       string to search for and replace
- * @param replace      string to replace found occurrences with
- * @return                     allocated string, if anything got replaced, str otherwise
- */
-char *strreplace(const char *str, const char *search, const char *replace);
-
 /**
  * Portable function to wait for SIGINT/SIGTERM (or equivalent).
  */
 void wait_sigint();
 
-/**
- * Like dirname(3) returns the directory part of the given null-terminated
- * pathname, up to but not including the final '/' (or '.' if no '/' is found).
- * Trailing '/' are not counted as part of the pathname.
- *
- * The difference is that it does this in a thread-safe manner (i.e. it does not
- * use static buffers) and does not modify the original path.
- *
- * @param path         original pathname
- * @return                     allocated directory component
- */
-char *path_dirname(const char *path);
-
-/**
- * Like basename(3) returns the filename part of the given null-terminated path,
- * i.e. the part following the final '/' (or '.' if path is empty or NULL).
- * Trailing '/' are not counted as part of the pathname.
- *
- * The difference is that it does this in a thread-safe manner (i.e. it does not
- * use static buffers) and does not modify the original path.
- *
- * @param path         original pathname
- * @return                     allocated filename component
- */
-char *path_basename(const char *path);
-
-/**
- * Check if a given path is absolute.
- *
- * @param path         path to check
- * @return                     TRUE if absolute, FALSE if relative
- */
-bool path_absolute(const char *path);
-
-/**
- * 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);
-
 #ifndef HAVE_CLOSEFROM
 /**
  * Close open file descriptors greater than or equal to lowfd.
@@ -769,34 +162,6 @@ bool mkdir_p(const char *path, mode_t mode);
 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
  */
@@ -817,294 +182,4 @@ bool return_true();
  */
 bool return_false();
 
-/**
- * returns FAILED
- */
-status_t return_failed();
-
-/**
- * returns SUCCESS
- */
-status_t return_success();
-
-/**
- * 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
-}
-
-/**
- * Get the padding required to make size a multiple of alignment
- */
-static inline size_t pad_len(size_t size, size_t alignment)
-{
-       size_t remainder;
-
-       remainder = size % alignment;
-       return remainder ? alignment - remainder : 0;
-}
-
-/**
- * Round up size to be multiple of alignment
- */
-static inline size_t round_up(size_t size, size_t alignment)
-{
-       return size + pad_len(size, alignment);
-}
-
-/**
- * Round down size to be a multiple of alignment
- */
-static inline size_t round_down(size_t size, size_t alignment)
-{
-       return size - (size % alignment);
-}
-
-/**
- * Special type to count references
- */
-typedef u_int refcount_t;
-
-/* use __atomic* built-ins with GCC 4.7 and newer */
-#ifdef __GNUC__
-# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
-#  define HAVE_GCC_ATOMIC_OPERATIONS
-# endif
-#endif
-
-#ifdef HAVE_GCC_ATOMIC_OPERATIONS
-
-#define ref_get(ref) __atomic_add_fetch(ref, 1, __ATOMIC_RELAXED)
-/* The relaxed memory model works fine for increments as these (usually) don't
- * change the state of refcounted objects.  But here we have to ensure that we
- * free the right stuff if ref counted objects are mutable.  So we have to sync
- * with other threads that call ref_put().  It would be sufficient to use
- * __ATOMIC_RELEASE here and then call __atomic_thread_fence() with
- * __ATOMIC_ACQUIRE if we reach 0, but since we don't have control over the use
- * of ref_put() we have to make sure. */
-#define ref_put(ref) (!__atomic_sub_fetch(ref, 1, __ATOMIC_ACQ_REL))
-#define ref_cur(ref) __atomic_load_n(ref, __ATOMIC_RELAXED)
-
-#define _cas_impl(ptr, oldval, newval) ({ typeof(oldval) _old = oldval; \
-                       __atomic_compare_exchange_n(ptr, &_old, newval, FALSE, \
-                                                                               __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); })
-#define cas_bool(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
-#define cas_ptr(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
-
-#elif defined(HAVE_GCC_SYNC_OPERATIONS)
-
-#define ref_get(ref) __sync_add_and_fetch(ref, 1)
-#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
-#define ref_cur(ref) __sync_fetch_and_add(ref, 0)
-
-#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 && !HAVE_GCC_SYNC_OPERATIONS */
-
-/**
- * Get a new reference.
- *
- * Increments the reference counter atomically.
- *
- * @param ref  pointer to ref counter
- * @return             new value of ref
- */
-refcount_t ref_get(refcount_t *ref);
-
-/**
- * Put back a unused reference.
- *
- * Decrements the reference counter atomically 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);
-
-/**
- * Get the current value of the reference counter.
- *
- * @param ref  pointer to ref counter
- * @return             current value of ref
- */
-refcount_t ref_cur(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 */
-
-#ifndef HAVE_FMEMOPEN
-# ifdef HAVE_FUNOPEN
-#  define HAVE_FMEMOPEN
-#  define HAVE_FMEMOPEN_FALLBACK
-#  include <stdio.h>
-/**
- * fmemopen(3) fallback using BSD funopen.
- *
- * We could also provide one using fopencookie(), but should we have it we
- * most likely have fmemopen().
- *
- * fseek() is currently not supported.
- */
-FILE *fmemopen(void *buf, size_t size, const char *mode);
-# endif /* FUNOPEN */
-#endif /* FMEMOPEN */
-
-/**
- * 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_ @}*/
diff --git a/src/libstrongswan/utils/utils/align.c b/src/libstrongswan/utils/utils/align.c
new file mode 100644 (file)
index 0000000..29f110f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008-2014 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/utils.h>
+#include <utils/debug.h>
+
+/**
+ * Described in header.
+ */
+void* malloc_align(size_t size, u_int8_t align)
+{
+       u_int8_t pad;
+       void *ptr;
+
+       if (align == 0)
+       {
+               align = 1;
+       }
+       ptr = malloc(align + sizeof(pad) + size);
+       if (!ptr)
+       {
+               return NULL;
+       }
+       /* store padding length just before data, down to the allocation boundary
+        * to do some verification during free_align() */
+       pad = align - ((uintptr_t)ptr % align);
+       memset(ptr, pad, pad);
+       return ptr + pad;
+}
+
+/**
+ * Described in header.
+ */
+void free_align(void *ptr)
+{
+       u_int8_t pad, *pos;
+
+       pos = ptr - 1;
+       /* verify padding to check any corruption */
+       for (pad = *pos; (void*)pos >= ptr - pad; pos--)
+       {
+               if (*pos != pad)
+               {
+                       DBG1(DBG_LIB, "!!!! invalid free_align() !!!!");
+                       return;
+               }
+       }
+       free(ptr - pad);
+}
diff --git a/src/libstrongswan/utils/utils/align.h b/src/libstrongswan/utils/utils/align.h
new file mode 100644 (file)
index 0000000..39cde10
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008-2014 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 align_i align
+ * @{ @ingroup utils_i
+ */
+
+#ifndef ALIGN_H_
+#define ALIGN_H_
+
+/**
+ * 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; })
+
+/**
+ * Get the padding required to make size a multiple of alignment
+ */
+static inline size_t pad_len(size_t size, size_t alignment)
+{
+       size_t remainder;
+
+       remainder = size % alignment;
+       return remainder ? alignment - remainder : 0;
+}
+
+/**
+ * Round up size to be multiple of alignment
+ */
+static inline size_t round_up(size_t size, size_t alignment)
+{
+       return size + pad_len(size, alignment);
+}
+
+/**
+ * Round down size to be a multiple of alignment
+ */
+static inline size_t round_down(size_t size, size_t alignment)
+{
+       return size - (size % alignment);
+}
+
+/**
+ * malloc(), but returns aligned memory.
+ *
+ * The returned pointer must be freed using free_align(), not free().
+ *
+ * @param size                 size of allocated data
+ * @param align                        alignment, up to 255 bytes, usually a power of 2
+ * @return                             allocated hunk, aligned to align bytes
+ */
+void* malloc_align(size_t size, u_int8_t align);
+
+/**
+ * Free a hunk allocated by malloc_align().
+ *
+ * @param ptr                  hunk to free
+ */
+void free_align(void *ptr);
+
+#endif /** ALIGN_H_ @} */
diff --git a/src/libstrongswan/utils/utils/atomics.c b/src/libstrongswan/utils/utils/atomics.c
new file mode 100644 (file)
index 0000000..17e823e
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008-2014 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/utils.h>
+
+#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
+
+#include <threading/spinlock.h>
+
+/**
+ * Spinlock for ref_get/put
+ */
+static spinlock_t *ref_lock;
+
+/**
+ * Increase refcount
+ */
+refcount_t ref_get(refcount_t *ref)
+{
+       refcount_t current;
+
+       ref_lock->lock(ref_lock);
+       current = ++(*ref);
+       ref_lock->unlock(ref_lock);
+
+       return current;
+}
+
+/**
+ * Decrease refcount
+ */
+bool ref_put(refcount_t *ref)
+{
+       bool more_refs;
+
+       ref_lock->lock(ref_lock);
+       more_refs = --(*ref) > 0;
+       ref_lock->unlock(ref_lock);
+       return !more_refs;
+}
+
+/**
+ * Current refcount
+ */
+refcount_t ref_cur(refcount_t *ref)
+{
+       refcount_t current;
+
+       ref_lock->lock(ref_lock);
+       current = *ref;
+       ref_lock->unlock(ref_lock);
+
+       return current;
+}
+
+/**
+ * Spinlock for all compare and swap operations.
+ */
+static spinlock_t *cas_lock;
+
+/**
+ * Compare and swap if equal to old value
+ */
+#define _cas_impl(name, type) \
+bool cas_##name(type *ptr, type oldval, type newval) \
+{ \
+       bool swapped; \
+       cas_lock->lock(cas_lock); \
+       if ((swapped = (*ptr == oldval))) { *ptr = newval; } \
+       cas_lock->unlock(cas_lock); \
+       return swapped; \
+}
+
+_cas_impl(bool, bool)
+_cas_impl(ptr, void*)
+
+#endif /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */
+
+/**
+ * See header
+ */
+void atomics_init()
+{
+#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
+       ref_lock = spinlock_create();
+       cas_lock = spinlock_create();
+#endif
+}
+
+/**
+ * See header
+ */
+void atomics_deinit()
+{
+#if !defined(HAVE_GCC_ATOMIC_OPERATIONS) && !defined(HAVE_GCC_SYNC_OPERATIONS)
+       ref_lock->destroy(ref_lock);
+       cas_lock->destroy(cas_lock);
+#endif
+}
diff --git a/src/libstrongswan/utils/utils/atomics.h b/src/libstrongswan/utils/utils/atomics.h
new file mode 100644 (file)
index 0000000..e5db0a1
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2008-2014 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 atomics_i atomics
+ * @{ @ingroup utils_i
+ */
+
+#ifndef ATOMICS_H_
+#define ATOMICS_H_
+
+/**
+ * Special type to count references
+ */
+typedef u_int refcount_t;
+
+/* use __atomic* built-ins with GCC 4.7 and newer */
+#ifdef __GNUC__
+# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
+#  define HAVE_GCC_ATOMIC_OPERATIONS
+# endif
+#endif
+
+#ifdef HAVE_GCC_ATOMIC_OPERATIONS
+
+#define ref_get(ref) __atomic_add_fetch(ref, 1, __ATOMIC_RELAXED)
+/* The relaxed memory model works fine for increments as these (usually) don't
+ * change the state of refcounted objects.  But here we have to ensure that we
+ * free the right stuff if ref counted objects are mutable.  So we have to sync
+ * with other threads that call ref_put().  It would be sufficient to use
+ * __ATOMIC_RELEASE here and then call __atomic_thread_fence() with
+ * __ATOMIC_ACQUIRE if we reach 0, but since we don't have control over the use
+ * of ref_put() we have to make sure. */
+#define ref_put(ref) (!__atomic_sub_fetch(ref, 1, __ATOMIC_ACQ_REL))
+#define ref_cur(ref) __atomic_load_n(ref, __ATOMIC_RELAXED)
+
+#define _cas_impl(ptr, oldval, newval) ({ typeof(oldval) _old = oldval; \
+                       __atomic_compare_exchange_n(ptr, &_old, newval, FALSE, \
+                                                                               __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); })
+#define cas_bool(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
+#define cas_ptr(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
+
+#elif defined(HAVE_GCC_SYNC_OPERATIONS)
+
+#define ref_get(ref) __sync_add_and_fetch(ref, 1)
+#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
+#define ref_cur(ref) __sync_fetch_and_add(ref, 0)
+
+#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 && !HAVE_GCC_SYNC_OPERATIONS */
+
+/**
+ * Get a new reference.
+ *
+ * Increments the reference counter atomically.
+ *
+ * @param ref  pointer to ref counter
+ * @return             new value of ref
+ */
+refcount_t ref_get(refcount_t *ref);
+
+/**
+ * Put back a unused reference.
+ *
+ * Decrements the reference counter atomically 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);
+
+/**
+ * Get the current value of the reference counter.
+ *
+ * @param ref  pointer to ref counter
+ * @return             current value of ref
+ */
+refcount_t ref_cur(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 */
+
+/**
+ * Initialize atomics utility functions
+ */
+void atomics_init();
+
+/**
+ * Clean up atomics utility functions
+ */
+void atomics_deinit();
+
+#endif /** ATOMICS_H_ @} */
diff --git a/src/libstrongswan/utils/utils/byteorder.h b/src/libstrongswan/utils/utils/byteorder.h
new file mode 100644 (file)
index 0000000..48cf1d5
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008-2014 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 byteorder_i byteorder
+ * @{ @ingroup utils_i
+ */
+
+#ifndef BYTEORDER_H_
+#define BYTEORDER_H_
+
+/**
+ * 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
+
+/**
+ * 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
+}
+
+#endif /** BYTEORDER_H_ @} */
diff --git a/src/libstrongswan/utils/utils/memory.c b/src/libstrongswan/utils/utils/memory.c
new file mode 100644 (file)
index 0000000..a153715
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2008-2014 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/utils.h>
+#include <utils/chunk.h>
+
+/**
+ * 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.
+ */
+bool memeq_const(const void *x, const void *y, size_t len)
+{
+       const u_char *a, *b;
+       u_int bad = 0;
+       size_t i;
+
+       a = (const u_char*)x;
+       b = (const u_char*)y;
+
+       for (i = 0; i < len; i++)
+       {
+               bad |= a[i] != b[i];
+       }
+       return !bad;
+}
+
+/**
+ * Described in header.
+ */
+void *memstr(const void *haystack, const char *needle, size_t n)
+{
+       const u_char *pos = haystack;
+       size_t l;
+
+       if (!haystack || !needle || (l = strlen(needle)) == 0)
+       {
+               return NULL;
+       }
+       for (; n >= l; ++pos, --n)
+       {
+               if (memeq(pos, needle, l))
+               {
+                       return (void*)pos;
+               }
+       }
+       return NULL;
+}
+
+/**
+ * Described in header.
+ */
+void *utils_memrchr(const void *s, int c, size_t n)
+{
+       const u_char *pos;
+
+       if (!s || !n)
+       {
+               return NULL;
+       }
+
+       for (pos = s + n - 1; pos >= (u_char*)s; pos--)
+       {
+               if (*pos == (u_char)c)
+               {
+                       return (void*)pos;
+               }
+       }
+       return NULL;
+}
+
+#ifdef HAVE_FMEMOPEN_FALLBACK
+
+static int fmemread(chunk_t *cookie, char *buf, int size)
+{
+       int len;
+
+       len = min(size, cookie->len);
+       memcpy(buf, cookie->ptr, len);
+       *cookie = chunk_skip(*cookie, len);
+
+       return len;
+}
+
+static int fmemwrite(chunk_t *cookie, const char *buf, int size)
+{
+       int len;
+
+       len = min(size, cookie->len);
+       memcpy(cookie->ptr, buf, len);
+       *cookie = chunk_skip(*cookie, len);
+
+       return len;
+}
+
+static int fmemclose(void *cookie)
+{
+       free(cookie);
+       return 0;
+}
+
+FILE *fmemopen(void *buf, size_t size, const char *mode)
+{
+       chunk_t *cookie;
+
+       INIT(cookie,
+               .ptr = buf,
+               .len = size,
+       );
+
+       return funopen(cookie, (void*)fmemread, (void*)fmemwrite, NULL, fmemclose);
+}
+
+#endif /* FMEMOPEN fallback*/
+
+/**
+ * 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/memory.h b/src/libstrongswan/utils/utils/memory.h
new file mode 100644 (file)
index 0000000..aef318f
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2008-2014 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 memory_i memory
+ * @{ @ingroup utils_i
+ */
+
+#ifndef MEMORY_H_
+#define MEMORY_H_
+
+/**
+ * Helper function that compares two binary blobs for equality
+ */
+static inline bool memeq(const void *x, const void *y, size_t len)
+{
+       return memcmp(x, y, len) == 0;
+}
+
+/**
+ * Same as memeq(), but with a constant runtime, safe for cryptographic use.
+ */
+bool memeq_const(const void *x, const void *y, size_t len);
+
+/**
+ * Calling memcpy() with NULL pointers, even with n == 0, results in undefined
+ * behavior according to the C standard.  This version is guaranteed to not
+ * access the pointers if n is 0.
+ */
+static inline void *memcpy_noop(void *dst, const void *src, size_t n)
+{
+       return n ? memcpy(dst, src, n) : dst;
+}
+#ifdef memcpy
+# undef memcpy
+#endif
+#define memcpy(d,s,n) memcpy_noop(d,s,n)
+
+/**
+ * Calling memmove() with NULL pointers, even with n == 0, results in undefined
+ * behavior according to the C standard.  This version is guaranteed to not
+ * access the pointers if n is 0.
+ */
+static inline void *memmove_noop(void *dst, const void *src, size_t n)
+{
+       return n ? memmove(dst, src, n) : dst;
+}
+#ifdef memmove
+# undef memmove
+#endif
+#define memmove(d,s,n) memmove_noop(d,s,n)
+
+/**
+ * Calling memset() with a NULL pointer, even with n == 0, results in undefined
+ * behavior according to the C standard.  This version is guaranteed to not
+ * access the pointer if n is 0.
+ */
+static inline void *memset_noop(void *s, int c, size_t n)
+{
+       return n ? memset(s, c, n) : s;
+}
+#ifdef memset
+# undef memset
+#endif
+#define memset(s,c,n) memset_noop(s,c,n)
+
+/**
+ * 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 (!ptr)
+       {
+               return;
+       }
+       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);
+
+/**
+ * Replacement for memrchr(3) if it is not provided by the C library.
+ *
+ * @param s            start of the memory area to search
+ * @param c            character to search
+ * @param n            length of memory area to search
+ * @return             pointer to the found character or NULL
+ */
+void *utils_memrchr(const void *s, int c, size_t n);
+
+#ifndef HAVE_MEMRCHR
+#define memrchr(s,c,n) utils_memrchr(s,c,n)
+#endif
+
+#ifndef HAVE_FMEMOPEN
+# ifdef HAVE_FUNOPEN
+#  define HAVE_FMEMOPEN
+#  define HAVE_FMEMOPEN_FALLBACK
+#  include <stdio.h>
+/**
+ * fmemopen(3) fallback using BSD funopen.
+ *
+ * We could also provide one using fopencookie(), but should we have it we
+ * most likely have fmemopen().
+ *
+ * fseek() is currently not supported.
+ */
+FILE *fmemopen(void *buf, size_t size, const char *mode);
+# endif /* FUNOPEN */
+#endif /* FMEMOPEN */
+
+/**
+ * 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 /** MEMORY_H_ @} */
diff --git a/src/libstrongswan/utils/utils/object.h b/src/libstrongswan/utils/utils/object.h
new file mode 100644 (file)
index 0000000..301fb66
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008-2014 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 object_i object
+ * @{ @ingroup utils_i
+ */
+
+#ifndef OBJECT_H_
+#define OBJECT_H_
+
+/**
+ * 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);
+
+/**
+ * Object allocation/initialization macro, using designated initializer.
+ */
+#define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \
+                                                  *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
+
+/**
+ * Aligning version of INIT().
+ *
+ * The returned pointer must be freed using free_align(), not free().
+ *
+ * @param this         object to allocate/initialize
+ * @param align                alignment for allocation, in bytes
+ * @param ...          initializer
+ */
+#define INIT_ALIGN(this, align, ...) { \
+                                               (this) = malloc_align(sizeof(*(this)), align); \
+                                               *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
+
+/**
+ * Object allocation/initialization macro, with extra allocated bytes at tail.
+ *
+ * The extra space gets zero-initialized.
+ *
+ * @param this         pointer to object to allocate memory for
+ * @param extra                number of bytes to allocate at end of this
+ * @param ...          initializer
+ */
+#define INIT_EXTRA(this, extra, ...) { \
+                                               typeof(extra) _extra = (extra); \
+                                               (this) = malloc(sizeof(*(this)) + _extra); \
+                                               *(this) = (typeof(*(this))){ __VA_ARGS__ }; \
+                                               memset((this) + 1, 0, _extra); }
+
+/**
+ * Aligning version of INIT_EXTRA().
+ *
+ * The returned pointer must be freed using free_align(), not free().
+ *
+ * @param this         object to allocate/initialize
+ * @param extra                number of bytes to allocate at end of this
+ * @param align                alignment for allocation, in bytes
+ * @param ...          initializer
+ */
+#define INIT_EXTRA_ALIGN(this, extra, align, ...) { \
+                                               typeof(extra) _extra = (extra); \
+                                               (this) = malloc_align(sizeof(*(this)) + _extra, align); \
+                                               *(this) = (typeof(*(this))){ __VA_ARGS__ }; \
+                                               memset((this) + 1, 0, _extra); }
+
+/**
+ * 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__)
+
+/**
+ * Callback declaration/definition macro, allowing casted first parameter.
+ *
+ * This is very similar to METHOD, but instead of casting the first parameter
+ * to a public interface, it uses a void*. This allows type safe definition
+ * of a callback function, while using the real type for the first parameter.
+ */
+#define CALLBACK(name, ret, param1, ...) \
+       static ret _cb_##name(union {void *_generic; param1;} \
+       __attribute__((transparent_union)), ##__VA_ARGS__); \
+       static typeof(_cb_##name) *name = (typeof(_cb_##name)*)_cb_##name; \
+       static ret _cb_##name(param1, ##__VA_ARGS__)
+
+#endif /** OBJECT_H_ @} */
diff --git a/src/libstrongswan/utils/utils/path.c b/src/libstrongswan/utils/utils/path.c
new file mode 100644 (file)
index 0000000..3abbe77
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2008-2014 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.
+ */
+
+#define _GNU_SOURCE /* for memrchr */
+#include <utils/utils.h>
+#include <utils/debug.h>
+#include <utils/chunk.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+/**
+ * Described in header.
+ */
+char* path_dirname(const char *path)
+{
+       char *pos;
+
+       pos = path ? strrchr(path, DIRECTORY_SEPARATOR[0]) : NULL;
+
+       if (pos && !pos[1])
+       {       /* if path ends with slashes we have to look beyond them */
+               while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
+               {       /* skip trailing slashes */
+                       pos--;
+               }
+               pos = memrchr(path, DIRECTORY_SEPARATOR[0], pos - path + 1);
+       }
+       if (!pos)
+       {
+#ifdef WIN32
+               if (path && strlen(path))
+               {
+                       if ((isalpha(path[0]) && path[1] == ':'))
+                       {       /* if just a drive letter given, return that as dirname */
+                               return chunk_clone(chunk_from_chars(path[0], ':', 0)).ptr;
+                       }
+               }
+#endif
+               return strdup(".");
+       }
+       while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
+       {       /* skip superfluous slashes */
+               pos--;
+       }
+       return strndup(path, pos - path + 1);
+}
+
+/**
+ * Described in header.
+ */
+char* path_basename(const char *path)
+{
+       char *pos, *trail = NULL;
+
+       if (!path || !*path)
+       {
+               return strdup(".");
+       }
+       pos = strrchr(path, DIRECTORY_SEPARATOR[0]);
+       if (pos && !pos[1])
+       {       /* if path ends with slashes we have to look beyond them */
+               while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
+               {       /* skip trailing slashes */
+                       pos--;
+               }
+               if (pos == path && *pos == DIRECTORY_SEPARATOR[0])
+               {       /* contains only slashes */
+                       return strdup(DIRECTORY_SEPARATOR);
+               }
+               trail = pos + 1;
+               pos = memrchr(path, DIRECTORY_SEPARATOR[0], trail - path);
+       }
+       pos = pos ? pos + 1 : (char*)path;
+       return trail ? strndup(pos, trail - pos) : strdup(pos);
+}
+
+/**
+ * Described in header.
+ */
+bool path_absolute(const char *path)
+{
+       if (!path)
+       {
+               return FALSE;
+       }
+#ifdef WIN32
+       if (strpfx(path, "\\\\"))
+       {       /* UNC */
+               return TRUE;
+       }
+       if (strlen(path) && isalpha(path[0]) && path[1] == ':')
+       {       /* drive letter */
+               return TRUE;
+       }
+#else /* !WIN32 */
+       if (path[0] == DIRECTORY_SEPARATOR[0])
+       {
+               return TRUE;
+       }
+#endif
+       return FALSE;
+}
+
+/**
+ * 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)
+               {
+#ifdef WIN32
+                       if (_mkdir(full) < 0)
+#else
+                       if (mkdir(full, mode) < 0)
+#endif
+                       {
+                               DBG1(DBG_LIB, "failed to create directory %s", full);
+                               return FALSE;
+                       }
+               }
+               *pos = '/';
+               pos++;
+       }
+       return TRUE;
+}
diff --git a/src/libstrongswan/utils/utils/path.h b/src/libstrongswan/utils/utils/path.h
new file mode 100644 (file)
index 0000000..838ce73
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008-2014 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 path_i path
+ * @{ @ingroup utils_i
+ */
+
+#ifndef PATH_H_
+#define PATH_H_
+
+/**
+ * Directory separator character in paths on this platform
+ */
+#ifdef WIN32
+# define DIRECTORY_SEPARATOR "\\"
+#else
+# define DIRECTORY_SEPARATOR "/"
+#endif
+
+/**
+ * Like dirname(3) returns the directory part of the given null-terminated
+ * pathname, up to but not including the final '/' (or '.' if no '/' is found).
+ * Trailing '/' are not counted as part of the pathname.
+ *
+ * The difference is that it does this in a thread-safe manner (i.e. it does not
+ * use static buffers) and does not modify the original path.
+ *
+ * @param path         original pathname
+ * @return                     allocated directory component
+ */
+char *path_dirname(const char *path);
+
+/**
+ * Like basename(3) returns the filename part of the given null-terminated path,
+ * i.e. the part following the final '/' (or '.' if path is empty or NULL).
+ * Trailing '/' are not counted as part of the pathname.
+ *
+ * The difference is that it does this in a thread-safe manner (i.e. it does not
+ * use static buffers) and does not modify the original path.
+ *
+ * @param path         original pathname
+ * @return                     allocated filename component
+ */
+char *path_basename(const char *path);
+
+/**
+ * Check if a given path is absolute.
+ *
+ * @param path         path to check
+ * @return                     TRUE if absolute, FALSE if relative
+ */
+bool path_absolute(const char *path);
+
+/**
+ * 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);
+
+#endif /** PATH_H_ @} */
diff --git a/src/libstrongswan/utils/utils/status.c b/src/libstrongswan/utils/utils/status.c
new file mode 100644 (file)
index 0000000..4a97d84
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008-2014 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/utils.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",
+);
+
+/**
+ * returns FAILED
+ */
+status_t return_failed()
+{
+       return FAILED;
+}
+
+/**
+ * returns SUCCESS
+ */
+status_t return_success()
+{
+       return SUCCESS;
+}
diff --git a/src/libstrongswan/utils/utils/status.h b/src/libstrongswan/utils/utils/status.h
new file mode 100644 (file)
index 0000000..c96eebd
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008-2014 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 status_i status
+ * @{ @ingroup utils_i
+ */
+
+#ifndef STATUS_H_
+#define STATUS_H_
+
+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;
+
+/**
+ * returns FAILED
+ */
+status_t return_failed();
+
+/**
+ * returns SUCCESS
+ */
+status_t return_success();
+
+#endif /** STATUS_H_ @} */
index e1b0638422b3c6214ffa2f6b84d58c4556999989..f59649c2acf1c17d357773f9b9054191ae56c680 100644 (file)
@@ -14,7 +14,8 @@
  */
 
 /**
- * @{ @ingroup utils
+ * @defgroup strerror_i strerror
+ * @{ @ingroup utils_i
  */
 
 #ifndef STRERROR_H_
diff --git a/src/libstrongswan/utils/utils/string.c b/src/libstrongswan/utils/utils/string.c
new file mode 100644 (file)
index 0000000..14087e7
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008-2014 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/utils.h>
+
+/**
+ * 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.
+ */
+char* strreplace(const char *str, const char *search, const char *replace)
+{
+       size_t len, slen, rlen, count = 0;
+       char *res, *pos, *found, *dst;
+
+       if (!str || !*str || !search || !*search || !replace)
+       {
+               return (char*)str;
+       }
+       slen = strlen(search);
+       rlen = strlen(replace);
+       if (slen != rlen)
+       {
+               for (pos = (char*)str; (pos = strstr(pos, search)); pos += slen)
+               {
+                       found = pos;
+                       count++;
+               }
+               if (!count)
+               {
+                       return (char*)str;
+               }
+               len = (found - str) + strlen(found) + count * (rlen - slen);
+       }
+       else
+       {
+               len = strlen(str);
+       }
+       found = strstr(str, search);
+       if (!found)
+       {
+               return (char*)str;
+       }
+       dst = res = malloc(len + 1);
+       pos = (char*)str;
+       do
+       {
+               len = found - pos;
+               memcpy(dst, pos, len);
+               dst += len;
+               memcpy(dst, replace, rlen);
+               dst += rlen;
+               pos = found + slen;
+       }
+       while ((found = strstr(pos, search)));
+       strcpy(dst, pos);
+       return res;
+}
diff --git a/src/libstrongswan/utils/utils/string.h b/src/libstrongswan/utils/utils/string.h
new file mode 100644 (file)
index 0000000..60eaaae
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008-2014 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 string_i string
+ * @{ @ingroup utils_i
+ */
+
+#ifndef STRING_H_
+#define STRING_H_
+
+/**
+ * Helper function that compares two strings for equality
+ */
+static inline bool streq(const char *x, const char *y)
+{
+       return strcmp(x, y) == 0;
+}
+
+/**
+ * Helper function that compares two strings for equality, length limited
+ */
+static inline bool strneq(const char *x, const char *y, size_t len)
+{
+       return strncmp(x, y, len) == 0;
+}
+
+/**
+ * Helper function that checks if a string starts with a given prefix
+ */
+static inline bool strpfx(const char *x, const char *prefix)
+{
+       return strneq(x, prefix, strlen(prefix));
+}
+
+/**
+ * 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;
+}
+
+/**
+ * Helper function that compares two strings for equality ignoring case, length limited
+ */
+static inline bool strncaseeq(const char *x, const char *y, size_t len)
+{
+       return strncasecmp(x, y, len) == 0;
+}
+
+/**
+ * Helper function that checks if a string starts with a given prefix
+ */
+static inline bool strcasepfx(const char *x, const char *prefix)
+{
+       return strncaseeq(x, prefix, strlen(prefix));
+}
+
+/**
+ * NULL-safe strdup variant
+ */
+static inline char *strdupnull(const char *s)
+{
+       return s ? strdup(s) : NULL;
+}
+
+/**
+ * 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);
+
+/**
+ * Replaces all occurrences of search in the given string with replace.
+ *
+ * Allocates memory only if anything is replaced in the string.  The original
+ * string is also returned if any of the arguments are invalid (e.g. if search
+ * is empty or any of them are NULL).
+ *
+ * @param str          original string
+ * @param search       string to search for and replace
+ * @param replace      string to replace found occurrences with
+ * @return                     allocated string, if anything got replaced, str otherwise
+ */
+char *strreplace(const char *str, const char *search, const char *replace);
+
+#endif /** STRING_H_ @} */
diff --git a/src/libstrongswan/utils/utils/time.c b/src/libstrongswan/utils/utils/time.c
new file mode 100644 (file)
index 0000000..c67ae93
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2008-2014 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.
+ */
+
+#ifdef WIN32
+/* for GetTickCount64, Windows 7 */
+# define _WIN32_WINNT 0x0601
+#endif
+
+#define _GNU_SOURCE
+#include <utils/utils.h>
+
+#include <inttypes.h>
+#include <time.h>
+
+/**
+ * Return monotonic time
+ */
+time_t time_monotonic(timeval_t *tv)
+{
+#ifdef WIN32
+       ULONGLONG ms;
+       time_t s;
+
+       ms = GetTickCount64();
+       s = ms / 1000;
+       if (tv)
+       {
+               tv->tv_sec = s;
+               tv->tv_usec = (ms - (s * 1000)) * 1000;
+       }
+       return s;
+#else /* !WIN32 */
+#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;
+#endif /* !WIN32 */
+}
+
+/**
+ * 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 = *((int*)(args[1]));
+       struct tm t, *ret = NULL;
+
+       if (*time != UNDEFINED_TIME)
+       {
+               if (utc)
+               {
+                       ret = gmtime_r(time, &t);
+               }
+               else
+               {
+                       ret = localtime_r(time, &t);
+               }
+       }
+       if (ret == NULL)
+       {
+               return print_in_hook(data, "--- -- --:--:--%s----",
+                                                        utc ? " UTC " : " ");
+       }
+       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");
+}
diff --git a/src/libstrongswan/utils/utils/time.h b/src/libstrongswan/utils/utils/time.h
new file mode 100644 (file)
index 0000000..2626d9a
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008-2014 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 time_i time
+ * @{ @ingroup utils_i
+ */
+
+#ifndef TIME_H_
+#define TIME_H_
+
+/**
+ * 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
+
+/**
+ * Handle struct timeval like an own type.
+ */
+typedef struct timeval timeval_t;
+
+/**
+ * Handle struct timespec like an own type.
+ */
+typedef struct timespec timespec_t;
+
+/**
+ * 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++;
+       }
+}
+
+/**
+ * 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);
+
+#endif /** TIME_H_ @} */
diff --git a/src/libstrongswan/utils/utils/tty.c b/src/libstrongswan/utils/utils/tty.c
new file mode 100644 (file)
index 0000000..7cce71d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008-2014 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/utils.h>
+
+#include <unistd.h>
+
+ENUM(tty_color_names, TTY_RESET, TTY_BG_DEF,
+       "\e[0m",
+       "\e[1m",
+       "\e[4m",
+       "\e[5m",
+       "\e[30m",
+       "\e[31m",
+       "\e[32m",
+       "\e[33m",
+       "\e[34m",
+       "\e[35m",
+       "\e[36m",
+       "\e[37m",
+       "\e[39m",
+       "\e[40m",
+       "\e[41m",
+       "\e[42m",
+       "\e[43m",
+       "\e[44m",
+       "\e[45m",
+       "\e[46m",
+       "\e[47m",
+       "\e[49m",
+);
+
+/**
+ * Get the escape string for a given TTY color, empty string on non-tty FILE
+ */
+char* tty_escape_get(int fd, tty_escape_t escape)
+{
+       if (!isatty(fd))
+       {
+               return "";
+       }
+       switch (escape)
+       {
+               case TTY_RESET:
+               case TTY_BOLD:
+               case TTY_UNDERLINE:
+               case TTY_BLINKING:
+#ifdef WIN32
+                       return "";
+#endif
+               case TTY_FG_BLACK:
+               case TTY_FG_RED:
+               case TTY_FG_GREEN:
+               case TTY_FG_YELLOW:
+               case TTY_FG_BLUE:
+               case TTY_FG_MAGENTA:
+               case TTY_FG_CYAN:
+               case TTY_FG_WHITE:
+               case TTY_FG_DEF:
+               case TTY_BG_BLACK:
+               case TTY_BG_RED:
+               case TTY_BG_GREEN:
+               case TTY_BG_YELLOW:
+               case TTY_BG_BLUE:
+               case TTY_BG_MAGENTA:
+               case TTY_BG_CYAN:
+               case TTY_BG_WHITE:
+               case TTY_BG_DEF:
+                       return enum_to_name(tty_color_names, escape);
+               /* warn if a escape code is missing */
+       }
+       return "";
+}
diff --git a/src/libstrongswan/utils/utils/tty.h b/src/libstrongswan/utils/utils/tty.h
new file mode 100644 (file)
index 0000000..6cd285a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008-2014 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 tty_i tty
+ * @{ @ingroup utils_i
+ */
+
+#ifndef TTY_H_
+#define TTY_H_
+
+typedef enum tty_escape_t tty_escape_t;
+
+/**
+ * Excape codes for tty colors
+ */
+enum tty_escape_t {
+       /** text properties */
+       TTY_RESET,
+       TTY_BOLD,
+       TTY_UNDERLINE,
+       TTY_BLINKING,
+
+       /** foreground colors */
+       TTY_FG_BLACK,
+       TTY_FG_RED,
+       TTY_FG_GREEN,
+       TTY_FG_YELLOW,
+       TTY_FG_BLUE,
+       TTY_FG_MAGENTA,
+       TTY_FG_CYAN,
+       TTY_FG_WHITE,
+       TTY_FG_DEF,
+
+       /** background colors */
+       TTY_BG_BLACK,
+       TTY_BG_RED,
+       TTY_BG_GREEN,
+       TTY_BG_YELLOW,
+       TTY_BG_BLUE,
+       TTY_BG_MAGENTA,
+       TTY_BG_CYAN,
+       TTY_BG_WHITE,
+       TTY_BG_DEF,
+};
+
+/**
+ * Get the escape string for a given TTY color, empty string on non-tty fd
+ */
+char* tty_escape_get(int fd, tty_escape_t escape);
+
+#endif /** TTY_H_ @} */
diff --git a/src/libstrongswan/utils/utils/types.h b/src/libstrongswan/utils/utils/types.h
new file mode 100644 (file)
index 0000000..056c2e0
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008-2014 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 types_i types
+ * @{ @ingroup utils_i
+ */
+
+#ifndef TYPES_H_
+#define TYPES_H_
+
+/**
+ * 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 */
+
+/**
+ * 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
+ */
+#if defined __sun || defined WIN32
+#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
+
+#ifdef HAVE_INT128
+/**
+ * 128 bit wide signed integer, if supported
+ */
+typedef __int128 int128_t;
+/**
+ * 128 bit wide unsigned integer, if supported
+ */
+typedef unsigned __int128 u_int128_t;
+
+# define MAX_INT_TYPE int128_t
+# define MAX_UINT_TYPE u_int128_t
+#else
+# define MAX_INT_TYPE int64_t
+# define MAX_UINT_TYPE u_int64_t
+#endif
+
+/**
+ * deprecated pluto style return value:
+ * error message, NULL for success
+ */
+typedef const char *err_t;
+
+/**
+ * Handle struct sockaddr as a simpler sockaddr_t type.
+ */
+typedef struct sockaddr sockaddr_t;
+
+#endif /** TYPES_H_ @} */