reducing capabilities of the threads to a minimum
[strongswan.git] / src / libstrongswan / library.c
index 0394f32..9f96d11 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * @file library.c
  *
- * @brief Library (de-)initialization.
+ * @brief Helper functions and definitions.
  *
  */
 
  * for more details.
  */
 
-#include <stdarg.h>
+#include <string.h>
+#include <time.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <pthread.h>
 
 #include "library.h"
 
+#include <printf_hook.h>
+
+ENUM(status_names, SUCCESS, DESTROY_ME,
+       "SUCCESS",
+       "FAILED",
+       "OUT_OF_RES",
+       "ALREADY_DONE",
+       "NOT_SUPPORTED",
+       "INVALID_ARG",
+       "NOT_FOUND",
+       "PARSE_ERROR",
+       "VERIFY_ERROR",
+       "INVALID_STATE",
+       "DESTROY_ME",
+       "NEED_MORE",
+);
+
 /**
- * default dbg function which printf all to stderr
+ * Described in header.
  */
-static void dbg_stderr(int level, char *fmt, ...)
+void *clalloc(void * pointer, size_t size)
 {
-       va_list args;
+       void *data;
+       data = malloc(size);
+       
+       memcpy(data, pointer,size);
        
-       va_start(args, fmt);
-       vfprintf(stderr, fmt, args);
-       fprintf(stderr, "\n");
-       va_end(args);
+       return (data);
 }
 
-void (*dbg) (int level, char *fmt, ...) = dbg_stderr;
+/**
+ * Described in header.
+ */
+void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
+{
+       size_t i;
+       for (i = 0; i < n; i++)
+       {
+               dest[i] ^= src[i];
+       }
+}
+
+/**
+ * We use a single mutex for all refcount variables. This
+ * is not optimal for performance, but the critical section
+ * is not that long...
+ * TODO: Consider to include a mutex in each refcount_t variable.
+ */
+static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Described in header.
+ * 
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+void ref_get(refcount_t *ref)
+{
+       pthread_mutex_lock(&ref_mutex);
+       (*ref)++;
+       pthread_mutex_unlock(&ref_mutex);
+}
+
+/**
+ * Described in header.
+ * 
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+bool ref_put(refcount_t *ref)
+{
+       bool more_refs;
+       
+       pthread_mutex_lock(&ref_mutex);
+       more_refs = --(*ref);
+       pthread_mutex_unlock(&ref_mutex);
+       return !more_refs;
+}
+
+/**
+ * output handler in printf() for time_t
+ */
+static int print_time(FILE *stream, const struct printf_info *info,
+                                         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 = TRUE;
+       struct tm t;
+       
+       if (info->alt)
+       {
+               utc = *((bool*)(args[1]));
+       }
+       if (time == UNDEFINED_TIME)
+       {
+               return fprintf(stream, "--- -- --:--:--%s----",
+                                          info->alt ? " UTC " : " ");
+       }
+       if (utc)
+       {
+               gmtime_r(time, &t);
+       }
+       else
+       {
+               localtime_r(time, &t);
+       }
+       return fprintf(stream, "%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);
+}
+
+/**
+ * output handler in printf() for time deltas
+ */
+static int print_time_delta(FILE *stream, const struct printf_info *info,
+                                                       const void *const *args)
+{
+       time_t *start = *((time_t**)(args[0]));
+       time_t *end   = *((time_t**)(args[1]));
+       u_int delta   = abs(*end - *start);
+
+       char* unit = "second";
+
+       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 fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s");
+}
+
+/**
+ * register printf() handlers for time_t
+ */
+static void __attribute__ ((constructor))print_register()
+{
+       register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int);
+       register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_ptr);
+}