gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r3024 - in GNUnet: . src/applications src/applications/stat


From: grothoff
Subject: [GNUnet-SVN] r3024 - in GNUnet: . src/applications src/applications/state src/include src/util src/util/crypto src/util/disk src/util/getopt src/util/loggers src/util/network src/util/os src/util/string src/util/threads
Date: Thu, 22 Jun 2006 10:51:11 -0700 (PDT)

Author: grothoff
Date: 2006-06-22 10:50:56 -0700 (Thu, 22 Jun 2006)
New Revision: 3024

Added:
   GNUnet/src/applications/state/
   GNUnet/src/applications/state/Makefile.am
   GNUnet/src/applications/state/state.c
   GNUnet/src/applications/state/statetest.c
   GNUnet/src/util/disk/
   GNUnet/src/util/disk/Makefile.am
   GNUnet/src/util/disk/storage.c
   GNUnet/src/util/disk/storagetest.c
   GNUnet/src/util/network/
   GNUnet/src/util/network/Makefile.am
   GNUnet/src/util/network/endian.c
   GNUnet/src/util/network/io.c
   GNUnet/src/util/network/ipcheck.c
   GNUnet/src/util/network/port.c
   GNUnet/src/util/network/tcp_return.c
   GNUnet/src/util/network/tcpio.c
   GNUnet/src/util/network/tcpiotest.c
   GNUnet/src/util/os/
   GNUnet/src/util/os/Makefile.am
   GNUnet/src/util/os/daemon.c
   GNUnet/src/util/os/daemontest.c
   GNUnet/src/util/os/dso.c
   GNUnet/src/util/os/osconfig.c
   GNUnet/src/util/os/statuscalls.c
   GNUnet/src/util/os/statuscallstest.c
   GNUnet/src/util/threads/
   GNUnet/src/util/threads/Makefile.am
   GNUnet/src/util/threads/mutex.c
   GNUnet/src/util/threads/pthread.c
   GNUnet/src/util/threads/semaphore.c
   GNUnet/src/util/threads/semaphoretest.c
   GNUnet/src/util/threads/shutdown.c
   GNUnet/src/util/threads/shutdowntest.c
   GNUnet/src/util/threads/timertest.c
   GNUnet/src/util/time.c
Removed:
   GNUnet/src/util/cron.c
   GNUnet/src/util/crontest.c
   GNUnet/src/util/daemon.c
   GNUnet/src/util/daemontest.c
   GNUnet/src/util/dso.c
   GNUnet/src/util/endian.c
   GNUnet/src/util/io.c
   GNUnet/src/util/ipcheck.c
   GNUnet/src/util/osconfig.c
   GNUnet/src/util/port.c
   GNUnet/src/util/printhelp.c
   GNUnet/src/util/semaphore.c
   GNUnet/src/util/semaphoretest.c
   GNUnet/src/util/shutdown.c
   GNUnet/src/util/shutdowntest.c
   GNUnet/src/util/state.c
   GNUnet/src/util/statetest.c
   GNUnet/src/util/statuscalls.c
   GNUnet/src/util/statuscallstest.c
   GNUnet/src/util/storage.c
   GNUnet/src/util/storagetest.c
   GNUnet/src/util/tcp_return.c
   GNUnet/src/util/tcpio.c
   GNUnet/src/util/tcpiotest.c
   GNUnet/src/util/timer.c
   GNUnet/src/util/timertest.c
Modified:
   GNUnet/configure.ac
   GNUnet/src/applications/Makefile.am
   GNUnet/src/include/Makefile.am
   GNUnet/src/include/gnunet_util.h
   GNUnet/src/include/gnunet_util_crypto.h
   GNUnet/src/include/gnunet_util_error.h
   GNUnet/src/include/gnunet_util_error_loggers.h
   GNUnet/src/util/Makefile.am
   GNUnet/src/util/README
   GNUnet/src/util/crypto/locking_gcrypt.c
   GNUnet/src/util/getopt/Makefile
   GNUnet/src/util/getopt/Makefile.in
   GNUnet/src/util/getopt/getopt.c
   GNUnet/src/util/getopt/printhelp.c
   GNUnet/src/util/getopt/setoption.c
   GNUnet/src/util/loggers/file.c
   GNUnet/src/util/string/string.c
   GNUnet/todo
Log:
Denver

Modified: GNUnet/configure.ac
===================================================================
--- GNUnet/configure.ac 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/configure.ac 2006-06-22 17:50:56 UTC (rev 3024)
@@ -539,6 +539,7 @@
 src/applications/session/Makefile
 src/applications/sqstore_mysql/Makefile
 src/applications/sqstore_sqlite/Makefile
+src/applications/state/Makefile
 src/applications/stats/Makefile
 src/applications/tbench/Makefile
 src/applications/testbed/Makefile
@@ -556,9 +557,16 @@
 src/util/config/Makefile
 src/util/config_impl/Makefile
 src/util/containers/Makefile
+src/util/cron/Makefile
 src/util/crypto/Makefile
+src/util/disk/Makefile
 src/util/error/Makefile
+src/util/getopt/Makefile
 src/util/loggers/Makefile
+src/util/network/Makefile
+src/util/os/Makefile
+src/util/string/Makefile
+src/util/threads/Makefile
 src/util/win/Makefile
 ])
 AC_OUTPUT

Modified: GNUnet/src/applications/Makefile.am
===================================================================
--- GNUnet/src/applications/Makefile.am 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/applications/Makefile.am 2006-06-22 17:50:56 UTC (rev 3024)
@@ -21,6 +21,7 @@
  fragmentation \
  getoption \
  fs \
+ state \
  stats \
  gap \
  identity \

Added: GNUnet/src/applications/state/Makefile.am
===================================================================
--- GNUnet/src/applications/state/Makefile.am   2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/applications/state/Makefile.am   2006-06-22 17:50:56 UTC (rev 
3024)
@@ -0,0 +1,33 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la 
+
+plugindir = $(libdir)/GNUnet
+
+plugin_LTLIBRARIES = \
+  libgnunetmodule_state.la
+
+lib_LTLIBRARIES = \
+  libgnunetstate_api.la
+
+bin_PROGRAMS = \
+ gnunet-stats
+
+libgnunetmodule_state_la_SOURCES = \
+  state.c
+libgnunetmodule_state_la_LIBADD = \
+  $(top_builddir)/src/util/libgnunetutil.la
+libgnunetmodule_state_la_LDFLAGS = \
+  -export-dynamic -avoid-version -module
+
+check_PROGRAMS = \
+ statetest
+
+TESTS = $(check_PROGRAMS)
+
+statetest_SOURCES = \
+ statetest.c
+statetest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  
+

Added: GNUnet/src/applications/state/state.c
===================================================================
--- GNUnet/src/applications/state/state.c       2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/applications/state/state.c       2006-06-22 17:50:56 UTC (rev 
3024)
@@ -0,0 +1,271 @@
+/*
+     This file is part of GNUnet.
+     (C) 2002, 2003, 2004, 2006 Christian Grothoff (and other contributing 
authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/disk/state.c
+ * @brief tiny, stateful database too keep track of internal state
+ *
+ * Directory based implementation of a tiny, stateful database
+ * to keep track of GNUnet _internal_ configuration parameters
+ * that users are not supposed to see (e.g. *previous* quota,
+ * previous database type for AFS, etc.)
+ *
+ *
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util_disk.h"
+#include "platform.h"
+
+#include <sys/stat.h>
+
+#define STATE_DEBUG NO
+
+#define DIR_EXT "state.sdb"
+
+static char * handle = NULL;
+
+/**
+ * Initialize the Directory module, expand filename
+ * @param dir the directory where content is configured to be stored (e.g. 
~/.gnunet/data/content).
+ */
+static char * getDirectory(char * dir) {
+  char * result;
+  char * tmp;
+  size_t n;
+
+#if STATE_DEBUG
+  LOG(LOG_DEBUG,
+      "Database (state): %s\n",
+      dir);
+#endif
+  n = strlen(dir) + strlen(DIR_EXT) + 5;
+  tmp = MALLOC(n);
+  SNPRINTF(tmp, n, "%s/%s/", dir, DIR_EXT);
+  result = expandFileName(tmp);
+  FREE(tmp);
+  return result;
+}
+
+void initState() {
+  char * dbh;
+  char * dir;
+  char * base;
+  char * baseSect;
+
+  if (testConfigurationString("GNUNETD",
+                             "_MAGIC_",
+                             "YES")) {
+    base = "GNUNETD_HOME";
+    baseSect = "GNUNETD";
+       }
+  else {
+    base = "GNUNET_HOME";
+    baseSect = "GNUNET";
+  }
+  dir = getFileName(baseSect,
+                   base,
+                   _("Configuration file must specify a directory"
+                     " for GNUnet to store per-peer data under %s\\%s.\n"));
+  dbh = getDirectory(dir);
+  FREE(dir);
+  GNUNET_ASSERT(dbh != NULL);
+  mkdirp(dbh);
+  handle = dbh;
+}
+
+/**
+ * Clean shutdown of the storage module (not used at the moment)
+ */
+void doneState() {
+  if (handle == NULL)
+    return; /* bogus call! */
+  FREE(handle);
+  handle = NULL;
+}
+
+/**
+ * Read the contents of a bucket to a buffer.
+ *
+ * @param name the hashcode representing the entry
+ * @param result the buffer to write the result to
+ *        (*result should be NULL, sufficient space is allocated)
+ * @return the number of bytes read on success, -1 on failure
+ */
+int stateReadContent(const char * name,
+                    void ** result) {
+  /* open file, must exist, open read only */
+  char * dbh = handle;
+  int fd;
+  int size;
+  char * fil;
+  unsigned long long fsize;
+  size_t n;
+
+  GNUNET_ASSERT(handle != NULL);
+  if (result == NULL)
+    return -1;
+  n = strlen(dbh) + strlen(name) + 2;
+  fil = MALLOC(n);
+  SNPRINTF(fil,
+          n,
+          "%s/%s",
+          dbh,
+          name);
+  if (OK != getFileSize(fil,
+                       &fsize)) {
+    FREE(fil);
+    return -1;
+  }
+  fd = fileopen(fil,
+           O_RDONLY,
+           S_IRUSR);
+  if (fd == -1) {
+    FREE(fil);
+    return -1;
+  }
+  FREE(fil);
+  if (fsize == 0) { /* also invalid! */
+    closefile(fd);
+    return -1;
+  }
+
+  *result = xmalloc_unchecked_(fsize, __FILE__, __LINE__);
+  size = READ(fd,
+             *result,
+             fsize);
+  closefile(fd);
+  if (size == -1) {
+    FREE(*result);
+    *result = NULL;
+  }
+  return size;
+}
+
+
+/**
+ * Append content to file.
+ *
+ * @param name the key for the entry
+ * @param len the number of bytes in block
+ * @param block the data to store
+ * @return SYSERR on error, OK if ok.
+ */
+int stateAppendContent(const char * name,
+                      int len,
+                      const void * block) {
+  char * dbh = handle;
+  char * fil;
+  int fd;
+  size_t n;
+
+  GNUNET_ASSERT(handle != NULL);
+  n = strlen(dbh) + strlen(name) + 2;
+  fil = MALLOC(n);
+  SNPRINTF(fil,
+          n,
+          "%s/%s",
+          dbh,
+          name);
+  fd = fileopen(fil,
+               O_RDWR|O_CREAT,
+               S_IRUSR|S_IWUSR);
+  if (fd == -1) {
+    LOG_FILE_STRERROR(LOG_WARNING, "open", fil);
+    FREE(fil);
+    return SYSERR; /* failed! */
+  }
+  FREE(fil);
+  lseek(fd,
+       0,
+       SEEK_END);
+  WRITE(fd,
+       block,
+       len);
+  closefile(fd);
+  return OK;
+}
+
+/**
+ * Write content to a file.
+ *
+ * @param name the key for the entry
+ * @param len the number of bytes in block
+ * @param block the data to store
+ * @return SYSERR on error, OK if ok.
+ */
+int stateWriteContent(const char * name,
+                     int len,
+                     const void * block) {
+  char * dbh = handle;
+  char * fil;
+  int fd;
+  size_t n;
+
+  GNUNET_ASSERT(handle != NULL);
+  n = strlen(dbh) + strlen(name) + 2;
+  fil = MALLOC(n);
+  SNPRINTF(fil,
+          n,
+          "%s/%s",
+          dbh,
+          name);
+  fd = fileopen(fil,
+           O_RDWR|O_CREAT,
+           S_IRUSR|S_IWUSR);
+  if (fd == -1) {
+    LOG_FILE_STRERROR(LOG_WARNING, "open", fil);
+    FREE(fil);
+    return SYSERR; /* failed! */
+  }
+  WRITE(fd,
+       block,
+       len);
+  if (0 != ftruncate(fd, len))
+    LOG_FILE_STRERROR(LOG_WARNING, "ftruncate", fil);
+  closefile(fd);
+  FREE(fil);
+  return OK;
+}
+
+/**
+ * Free space in the database by removing one file
+ * @param name the hashcode representing the name of the file
+ *        (without directory)
+ */
+int stateUnlinkFromDB(const char * name) {
+  char * dbh = handle;
+  char * fil;
+  size_t n;
+
+  GNUNET_ASSERT(handle != NULL);
+  n = strlen(dbh) + strlen(name) + 2;
+  fil = MALLOC(n);
+  SNPRINTF(fil,
+          n,
+          "%s/%s",
+          dbh,
+          name);
+  UNLINK(fil);
+  FREE(fil);
+  return OK;
+}
+
+/* end of state.c */

Added: GNUnet/src/applications/state/statetest.c
===================================================================
--- GNUnet/src/applications/state/statetest.c   2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/applications/state/statetest.c   2006-06-22 17:50:56 UTC (rev 
3024)
@@ -0,0 +1,81 @@
+/**
+ * @file test/storagetest.c
+ * @brief testcase for the state module
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+/**
+ * Perform option parsing from the command line.
+ */
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  char c;
+
+  while (1) {
+    int option_index = 0;
+    static struct GNoption long_options[] = {
+      { "config",  1, 0, 'c' },
+      { 0,0,0,0 }
+    };
+
+    c = GNgetopt_long(argc,
+                     argv,
+                     "c:",
+                     long_options,
+                     &option_index);
+
+    if (c == -1)
+      break;  /* No more flags to process */
+
+    switch(c) {
+    case 'c':
+      FREENONNULL(setConfigurationString("FILES",
+                                        "gnunet.conf",
+                                        GNoptarg));
+      break;
+    } /* end of parsing commandline */
+  }
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGLEVEL",
+                                    "NOTHING"));
+  return OK;
+}
+
+#define TH "TestHandle"
+
+int testState() {
+  char * testString = "Hello World";
+  char * ret;
+
+  stateUnlinkFromDB(TH); /* go to defined state */
+  if (SYSERR == stateWriteContent(TH,
+                                 5,
+                                 testString))
+    return 1;
+  if (SYSERR == stateAppendContent(TH,
+                                  6,
+                                  &testString[5]))
+    return 2;
+  ret = NULL;
+  if (SYSERR == stateReadContent(TH,
+                                (void**)&ret))
+    return 3;
+  if (0 != strncmp(ret, testString, 11))
+    return 4;
+  FREE(ret);
+  if (OK != stateUnlinkFromDB(TH))
+    return 5;
+  return 0;
+}
+
+int main(int argc, char * argv[]) {
+  int ret = 0;
+  initUtil(argc, argv, &parseCommandLine);
+  ret = testState();
+
+  doneUtil();
+  return ret;
+} /* end of main */

Modified: GNUnet/src/include/Makefile.am
===================================================================
--- GNUnet/src/include/Makefile.am      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/include/Makefile.am      2006-06-22 17:50:56 UTC (rev 3024)
@@ -44,7 +44,13 @@
   gnunet_util_config.h \
   gnunet_util_config_impl.h \
   gnunet_util_containers.h \
+  gnunet_util_cron.h \
   gnunet_util_crypto.h \
+  gnunet_util_disk.h \
   gnunet_util_error.h \
-  gnunet_util_error.h \
   gnunet_util_error_loggers.h 
+  gnunet_util_getopt.h \
+  gnunet_util_network.h \
+  gnunet_util_os.h \
+  gnunet_util_string.h \
+  gnunet_util_threads.h 

Modified: GNUnet/src/include/gnunet_util.h
===================================================================
--- GNUnet/src/include/gnunet_util.h    2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/include/gnunet_util.h    2006-06-22 17:50:56 UTC (rev 3024)
@@ -56,8 +56,15 @@
    unconditionally available... */
 #include <stdlib.h>
 
-/* add error and config prototypes */
+/* add prototypes of sublibraries */
+#include "gnunet_util_error.h"
 #include "gnunet_util_config.h"
+#include "gnunet_util_string.h"
+#include "gnunet_util_disk.h"
+#include "gnunet_util_threads.h"
+#include "gnunet_util_getopt.h"
+#include "gnunet_util_network.h"
+#include "gnunet_util_os.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -67,12 +74,18 @@
 #endif
 
 
-/* **************** constants ****************** */
+#define DEFAULT_CLIENT_CONFIG_FILE "~/.gnunet/gnunet.conf"
+#define DEFAULT_DAEMON_DIR         "/etc"
+#define DEFAULT_DAEMON_CONFIG_FILE DEFAULT_DAEMON_DIR"/gnunetd.conf"
+#define VAR_DIRECTORY              "/var/lib"
+#define VAR_DAEMON_DIRECTORY       VAR_DIRECTORY"/gnunet"
+#define VAR_DAEMON_CONFIG_FILE     VAR_DAEMON_DIRECTORY"/gnunetd.conf"
+#define GNUNET_HOME_DIRECTORY      "~/.gnunet"
+#define HOME_DAEMON_CONFIG_FILE    GNUNET_HOME_DIRECTORY"/gnunetd.conf"
 
-/* do not turn this on unless you know what you
-   are doing, you'll get a ton of output... */
-#define DEBUG_LOCKING 0
 
+/* **************** constants ****************** */
+
 /**
  * Just the version number of GNUnet-util implementation.
  * Encoded as
@@ -87,743 +100,18 @@
  */
 #define GNUNET_UTIL_VERSION 0x00070004
 
-/**
- * We use an unsigned short in the protocol header, thus:
- */
-#define MAX_BUFFER_SIZE 65536
+/* CHRISTIAN: move this to gnunet_core.h or _protocols.h ? */
 
 /**
  * Highest legal priority or trust value
  */
 #define MAX_PRIO 0x7FFFFFFF
 
-/**
- * Named constants for return values.  The following
- * invariants hold: "NO == 0" (to allow "if (NO)")
- * "OK != SYSERR", "OK != NO", "NO != SYSERR"
- * and finally "YES != NO".
- */
-#define OK      1
-#define SYSERR -1
-#define YES     1
-#define NO      0
 
-#define STRONG YES
-#define WEAK NO
+/* NILS: I would love to see the 
+   next two methods in PLIBC */
 
 /**
- * @brief constants to specify time
- */
-#define cronMILLIS ((cron_t)1)
-#define cronSECONDS ((cron_t)(1000 * cronMILLIS))
-#define cronMINUTES ((cron_t) (60 * cronSECONDS))
-#define cronHOURS ((cron_t)(60 * cronMINUTES))
-#define cronDAYS ((cron_t)(24 * cronHOURS))
-#define cronWEEKS ((cron_t)(7 * cronDAYS))
-#define cronMONTHS ((cron_t)(30 * cronDAYS))
-#define cronYEARS ((cron_t)(365 * cronDAYS))
-
-/**
- * @brief Default names of the configuration files.
- */
-#define DEFAULT_CLIENT_CONFIG_FILE "~/.gnunet/gnunet.conf"
-#define DEFAULT_DAEMON_DIR "/etc"
-#define DEFAULT_DAEMON_CONFIG_FILE "/etc/gnunetd.conf"
-#define VAR_DIRECTORY       "/var/lib"
-#define VAR_DAEMON_DIRECTORY       "/var/lib/GNUnet"
-#define VAR_DAEMON_CONFIG_FILE     "/var/lib/GNUnet/gnunetd.conf"
-#define HOME_DAEMON_CONFIG_FILE    "~/.gnunet/gnunetd.conf"
-#define GNUNET_HOME_DIRECTORY    "~/.gnunet/"
-
-#define HELP_HELP \
-  { 'h', "help", NULL,                         \
-    gettext_noop("print this help") }
-#define HELP_LOGLEVEL \
-  { 'L', "loglevel", "LEVEL",                  \
-    gettext_noop("set verbosity to LEVEL") }
-#define HELP_CONFIG \
-  { 'c', "config", "FILENAME",                 \
-    gettext_noop("use configuration file FILENAME") }
-#define HELP_HOSTNAME \
-  { 'H', "host", "HOSTNAME",                   \
-    gettext_noop("specify host on which gnunetd is running") }
-#define HELP_VERSION \
-  { 'v', "version", NULL,                      \
-    gettext_noop("print the version number") }
-#define HELP_VERBOSE \
-  { 'V', "verbose", NULL,                      \
-    gettext_noop("be verbose") }
-#define HELP_END \
-    { 0, NULL, NULL, NULL, }
-
-/**
- * Default "long" version of the options, use
- * "vhdc:L:H:" in the short option argument
- * to getopt_long for now.
- */
-#define LONG_DEFAULT_OPTIONS \
-      { "config",        1, 0, 'c' }, \
-      { "version",       0, 0, 'v' }, \
-      { "help",          0, 0, 'h' }, \
-      { "debug",         0, 0, 'd' }, \
-      { "loglevel",      1, 0, 'L' }, \
-      { "host",          1, 0, 'H' }
-
-/* **************** structs ****************** */
-
-/**
- * @brief 512-bit hashcode
- */
-typedef struct {
-  unsigned int bits[512 / 8 / sizeof(unsigned int)]; /* = 16 */
-} HashCode512;
-
-/**
- * Header for all Client-Server communications.
- */
-typedef struct {
-  /**
-   * The length of the struct (in bytes, including the length field itself)
-   */
-  unsigned short size;
-
-  /**
-   * The type of the message (XX_CS_PROTO_XXXX)
-   */
-  unsigned short type;
-
-} CS_MESSAGE_HEADER;
-
-/**
- * CS communication: simple return value
- */
-typedef struct {
-  /**
-   * The CS header (values: sizeof(CS_returnvalue_MESSAGE), 
CS_PROTO_RETURN_VALUE)
-   */
-  CS_MESSAGE_HEADER header;
-
-  /**
-   * The return value (network byte order)
-   */
-  int return_value;
-} CS_returnvalue_MESSAGE;
-
-/**
- * p2p message part header
- */
-typedef struct {
-  /**
-   * size of this MESSAGE_PART (network byte order)
-   */
-  unsigned short size;
-
-  /**
-   * type of the request, XX_p2p_PROTO_XXX (network byte order)
-   */
-  unsigned short type;
-} P2P_MESSAGE_HEADER;
-
-typedef void (*NotifyConfigurationUpdateCallback)(void);
-
-/**
- * Type of a cron-job method.
- */
-typedef void (*CronJob)(void *);
-
-/**
- * Time for absolute times used by cron (64 bit)
- */
-typedef unsigned long long cron_t;
-
-/**
- * 32-bit timer value.
- */
-typedef unsigned int TIME_T;
-
-/* Describe the long-named options requested by the application.
-   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
-   of `struct GNoption' terminated by an element containing a name which is
-   zero.
-
-   The field `has_arg' is:
-   no_argument         (or 0) if the option does not take an argument,
-   required_argument   (or 1) if the option requires an argument,
-   optional_argument   (or 2) if the option takes an optional argument.
-
-   If the field `flag' is not NULL, it points to a variable that is set
-   to the value given in the field `val' when the option is found, but
-   left unchanged if the option is not found.
-
-   To have a long-named option do something other than set an `int' to
-   a compiled-in constant, such as set a value from `GNoptarg', set the
-   option's `flag' field to zero and its `val' field to a nonzero
-   value (the equivalent single-letter option character, if there is
-   one).  For long options that have a zero `flag' field, `getopt'
-   returns the contents of the `val' field.  */
-
-struct GNoption {
-  const char *name;
-  /* has_arg can't be an enum because some compilers complain about
-     type mismatches in all the code that assumes it is an int.  */
-  int has_arg;
-  int *flag;
-  int val;
-};
-
-/**
- * @brief an IPv4 address
- */
-typedef struct {
-  unsigned int addr; /* struct in_addr */
-} IPaddr;
-
-/**
- * @brief IPV4 network in CIDR notation.
- */
-struct CIDRNetwork;
-
-/**
- * @brief an IPV6 address.
- */
-typedef struct {
-  unsigned int addr[4]; /* struct in6_addr addr; */
-} IP6addr;
-
-/**
- * @brief IPV6 network in CIDR notation.
- */
-struct CIDR6Network;
-
-/**
- * Main method of a thread.
- */
-typedef void * (*PThreadMain)(void*);
-
-/**
- * Encapsulation of a pthread handle.
- */
-typedef struct PTHREAD_T {
-  void * internal;
-} PTHREAD_T;
-
-/**
- * The identity of the host (basically the SHA-512 hashcode of
- * it's public key).
- */
-typedef struct {
-  HashCode512 hashPubKey;
-} PeerIdentity;
-
-/**
- * @brief Structure for MUTual EXclusion (Mutex).
- *
- * Essentially a wrapper around pthread_mutex_t.
- */
-typedef struct Mutex {
-  void * internal;
-} Mutex;
-
-/**
- * @brief Semaphore abstraction implemented with pthreads
- */
-typedef struct Semaphore {
-  int v;
-  Mutex mutex;
-  /**
-   * Wrapper for pthread condition variable.
-   */
-  void * cond;
-} Semaphore;
-
-/**
- * @brief Inter-process semaphore.
- */
-typedef struct IPC_Semaphore{
-  void * platform;
-} IPC_Semaphore;
-
-/**
- * Struct to refer to a GNUnet TCP connection.
- * This is more than just a socket because if the server
- * drops the connection, the client automatically tries
- * to reconnect (and for that needs connection information).
- */
-typedef struct GNUNET_TCP_SOCKET {
-
-  /**
-   * the socket handle, -1 if invalid / not life
-   */
-  int socket;
-
-  /**
-   * the following is the IP for the remote host for client-sockets,
-   * as returned by gethostbyname("hostname"); server sockets should
-   * use 0.
-   */
-  IPaddr ip;
-
-  /**
-   * the port number, in host byte order
-   */
-  unsigned short port;
-
-  /**
-   * Write buffer length for non-blocking writes.
-   */
-  unsigned int outBufLen;
-
-  /**
-   * Write buffer for non-blocking writes.
-   */
-  void * outBufPending;
-
-  Mutex readlock;
-  Mutex writelock;
-
-} GNUNET_TCP_SOCKET;
-
-/**
- * Method to parse the command line. The results
- * are to be stored in the configuration module.
- * @param argc the number of arguments
- * @param argv the command line arguments
- * @return OK on success, SYSERR if we should abort the
- *   initialization sequence and exit the program
- */
-typedef int (*CommandLineParser)(int argc, char * argv[]);
-
-/**
- * Function called on each file in a directory.
- * @return OK to continue to iterate,
- *  SYSERR to abort iteration with error!
- */
-typedef int (*DirectoryEntryCallback)(const char * filename,
-                                     const char * dirName,
-                                     void * data);
-
-/**
- * @brief description of a command line option (helptext)
- */
-typedef struct {
-  char shortArg;
-  char * longArg;
-  char * mandatoryArg;
-  char * description;
-} Help;
-
-
-/* **************** Functions and Macros ************* */
-
-/**
- * Convert a long-long to host-byte-order.
- * @param n the value in network byte order
- * @return the same value in host byte order
- */
-unsigned long long ntohll(unsigned long long n);
-
-/**
- * Convert a long long to network-byte-order.
- * @param n the value in host byte order
- * @return the same value in network byte order
- */
-unsigned long long htonll(unsigned long long n);
-
-/**
- * Convert the len characters long character sequence
- * given in input that is in the given charset
- * to UTF-8.
- * @return the converted string (0-terminated)
- */
-char * convertToUtf8(const char * input,
-                    size_t len,
-                    const char * charset);
-
-/**
- * Expand an expression of the form
- * "$FOO/BAR" to "DIRECTORY/BAR" where
- * either in the current section or
- * globally FOO is set to DIRECTORY.
- */
-char * expandDollar(const char * section,
-         char * orig);
-
-/**
- * Start the cron jobs.
- */
-void startCron(void);
-
-/**
- * Stop the cron service.
- */
-void stopCron(void);
-
-/**
- * Stop running cron-jobs for a short time.  This method may only be
- * called by a thread that is not holding any locks.  It will cause
- * a deadlock if this method is called from within a cron-job.
- * Use with caution.
- */
-void suspendCron(void);
-
-/**
- * Resume running cron-jobs.
- */
-void resumeCron(void);
-
-/**
- * Is the cron-thread currently running?
- */
-int isCronRunning(void);
-
-/**
- * Like suspendCron, but does nothing if called from
- * within a cron-job.
- */
-void suspendIfNotCron(void);
-
-/**
- * Like resumeCron, but does nothing if called from
- * within a cron-job.
- */
-void resumeIfNotCron(void);
-
-/**
- * Get the current time (works just as "time", just
- * that we use the unit of time that the cron-jobs use).
- * @param setme will set the current time if non-null
- * @return the current time
- */
-cron_t cronTime(cron_t * setme);
-
-/**
- * Add a cron-job to the delta list.
- * @param method which method should we run
- * @param delta how many milliseconds until we run the method
- * @param deltaRepeat if this is a periodic, the time between
- *        the runs, otherwise 0.
- * @param data argument to pass to the method
- */
-void addCronJob(CronJob method,
-               unsigned int delta,
-               unsigned int deltaRepeat,
-               void * data);
-
-/**
- * If the specified cron-job exists in th delta-list, move it to the
- * head of the list.  If it is running, do nothing.  If it is does not
- * exist and is not running, add it to the list to run it next.
- *
- * @param method which method should we run
- * @param deltaRepeat if this is a periodic, the time between
- *        the runs, otherwise 0.
- * @param data extra argument to calls to method, freed if
- *        non-null and cron is shutdown before the job is
- *        run and/or delCronJob is called
- */
-void advanceCronJob(CronJob method,
-                  unsigned int deltaRepeat,
-                  void * data);
-/**
- * Remove all matching cron-jobs from the list. This method should
- * only be called while cron is suspended or stopped, or from a cron
- * job that deletes another cron job.  If cron is not suspended or
- * stopped, it may be running the method that is to be deleted, which
- * could be bad (in this case, the deletion will not affect the
- * running job and may return before the running job has terminated).
- *
- * @param method which method is listed?
- * @param repeat which repeat factor was chosen?
- * @param data what was the data given to the method
- * @return the number of jobs removed
- */
-int delCronJob(CronJob method,
-              unsigned int repeat,
-              void * data);
-
-/**
- * Sleep for the specified time interval.
- * A signal interrupts the sleep.  Caller
- * is responsible to check that the sleep was
- * long enough.
- *
- * @return 0 if there was no interrupt, 1 if there was, -1 on error.
- */
-int gnunet_util_sleep(cron_t delay);
-
-/**
- * Load dynamic library
- */
-void * loadDynamicLibrary(const char * libprefix,
-                         const char * dsoname);
-
-void * bindDynamicMethod(void * libhandle,
-                        const char * methodprefix,
-                        const char * dsoname);
-
-void * trybindDynamicMethod(void * libhandle,
-                           const char * methodprefix,
-                           const char * dsoname);
-
-void unloadDynamicLibrary(void * libhandle);
-
-/* For communication from `getopt' to the caller.
-   When `getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when `ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-extern char *GNoptarg;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to `getopt'.
-
-   On entry to `getopt', zero means this is the first call; initialize.
-
-   When `getopt' returns -1, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, `GNoptind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-extern int GNoptind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
-   for unrecognized options.  */
-
-extern int GNopterr;
-
-/* Set to an option character which was unrecognized.  */
-
-extern int GNoptopt;
-
-
-int GNgetopt_long (int argc,
-                  char *const *argv,
-                  const char *shortopts,
-                  const struct GNoption *longopts,
-                  int *longind);
-
-
-/**
- * Parse a network specification. The argument specifies
- * a list of networks. The format is
- * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
- * with a semicolon). The network must be given in dotted-decimal
- * notation. The netmask can be given in CIDR notation (/16) or
- * in dotted-decimal (/255.255.0.0).
- * <p>
- * @param routeList a string specifying the forbidden networks
- * @return the converted list, NULL if the synatx is flawed
- */
-struct CIDRNetwork * parseRoutes(const char * routeList);
-
-
-/**
- * Check if the given IP address is in the list of
- * IP addresses.
- * @param list a list of networks
- * @param ip the IP to check (in network byte order)
- * @return NO if the IP is not in the list, YES if it it is
- */
-int checkIPListed(const struct CIDRNetwork * list,
-                 IPaddr ip);
-
-/**
- * Check if the given IP address is in the list of
- * IP addresses.
- * @param list a list of networks
- * @param ip the IP to check (in network byte order)
- * @return NO if the IP is not in the list, YES if it it is
- */
-int checkIP6Listed(const struct CIDR6Network * list,
-                  const IP6addr * ip);
-
-/**
- * Parse a network specification. The argument specifies
- * a list of networks. The format is
- * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
- * with a semicolon). The network must be given in dotted-decimal
- * notation. The netmask can be given in CIDR notation (/16) or
- * in dotted-decimal (/255.255.0.0).
- * <p>
- * @param routeList a string specifying the forbidden networks
- * @return the converted list, NULL if the synatx is flawed
- */
-struct CIDR6Network * parseRoutes6(const char * routeList);
-
-#define PRIP(ip) (unsigned int)(((unsigned int)(ip))>>24), (unsigned 
int)((((unsigned)(ip)))>>16 & 255), (unsigned int)((((unsigned int)(ip)))>>8 & 
255), (unsigned int)((((unsigned int)(ip))) & 255)
-
-/**
- * Allocate memory. Checks the return value, aborts if no more
- * memory is available.  Don't use xmalloc_ directly. Use the
- * MALLOC macro.
- */
-void * xmalloc_(size_t size,
-               const char * filename,
-               const int linenumber);
-
-/**
- * Allocate memory.  This function does not check if the
- * allocation request is within reasonable bounds, allowing
- * allocations larger than 40 MB.  If you don't expect the
- * possibility of very large allocations, use MALLOC instead.
- */
-void * xmalloc_unchecked_(size_t size,
-                         const char * filename,
-                         const int linenumber);
-
-/**
- * Wrapper around malloc. Allocates size bytes of memory.
- * @param size the number of bytes to allocate
- * @return pointer to size bytes of memory
- */
-#define MALLOC(size) xmalloc_(size, __FILE__,__LINE__)
-
-/**
- * Reallocate memory. Checks the return value, aborts if no more
- * memory is available.
- */
-void * xrealloc_(void * ptr,
-                const size_t n,
-                const char * filename,
-                const int linenumber);
-
-/**
- * Wrapper around realloc. Rellocates size bytes of memory.
- * @param ptr the pointer to reallocate
- * @param size the number of bytes to reallocate
- * @return pointer to size bytes of memory
- */
-#define REALLOC(ptr, size) xrealloc_(ptr, size, __FILE__,__LINE__)
-
-/**
- * Free memory. Merely a wrapper for the case that we
- * want to keep track of allocations.  Don't use xfree_
- * directly. Use the FREE macro.
- */
-void xfree_(void * ptr,
-           const char * filename,
-           const int linenumber);
-
-/**
- * Wrapper around free. Frees the memory referred to by ptr.
- * Note that is is generally better to free memory that was
- * allocated with GROW using GROW(mem, size, 0) instead of FREE.
- *
- * @param ptr location where to free the memory. ptr must have
- *     been returned by STRDUP, MALLOC or GROW earlier.
- */
-#define FREE(ptr) xfree_(ptr, __FILE__, __LINE__)
-
-/**
- * Free the memory pointed to by ptr if ptr is not NULL.
- * Equivalent to if (ptr!=null)FREE(ptr).
- * @param ptr the location in memory to free
- */
-#define FREENONNULL(ptr) do { void * __x__ = ptr; if (__x__ != NULL) { 
FREE(__x__); } } while(0)
-
-/**
- * Dup a string. Don't call xstrdup_ directly. Use the STRDUP macro.
- */
-char * xstrdup_(const char * str,
-               const char * filename,
-               const int linenumber);
-
-/**
- * Wrapper around STRDUP.  Makes a copy of the zero-terminated string
- * pointed to by a.
- * @param a pointer to a zero-terminated string
- * @return a copy of the string including zero-termination
- */
-#define STRDUP(a) xstrdup_(a,__FILE__,__LINE__)
-
-/**
- * Dup a string. Don't call xstrdup_ directly. Use the STRDUP macro.
- *
- * @param str the string to dup
- * @param n the maximum number of characters to copy (+1 for 0-termination)
- * @param filename where in the code was the call to GROW
- * @param linenumber where in the code was the call to GROW
- * @return strdup(str)
- */
-char * xstrndup_(const char * str,
-                const size_t n,
-                const char * filename,
-                const int linenumber);
-
-/**
- * Wrapper around STRNDUP.  Makes a copy of the zero-terminated string
- * pointed to by a.
- * @param a pointer to a zero-terminated string
- * @param n the maximum number of characters to copy (+1 for 0-termination)
- * @return a copy of the string including zero-termination
- */
-#define STRNDUP(a,n) xstrndup_(a,n,__FILE__,__LINE__)
-
-/**
- * Grow an array, the new elements are zeroed out.
- * Grows old by (*oldCount-newCount)*elementSize
- * bytes and sets *oldCount to newCount.
- *
- * Don't call xgrow_ directly. Use the GROW macro.
- *
- * @param old address of the pointer to the array
- *        *old may be NULL
- * @param elementSize the size of the elements of the array
- * @param oldCount address of the number of elements in the *old array
- * @param newCount number of elements in the new array, may be 0 (then *old 
will be NULL afterwards)
- */
-void xgrow_(void ** old,
-           size_t elementSize,
-           unsigned int * oldCount,
-           unsigned int newCount,
-           const char * filename,
-           const int linenumber);
-
-/**
- * Grow a well-typed (!) array.  This is a convenience
- * method to grow a vector <tt>arr</tt> of size <tt>size</tt>
- * to the new (target) size <tt>tsize</tt>.
- * <p>
- *
- * Example (simple, well-typed stack):
- *
- * <pre>
- * static struct foo * myVector = NULL;
- * static int myVecLen = 0;
- *
- * static void push(struct foo * elem) {
- *   GROW(myVector, myVecLen, myVecLen+1);
- *   memcpy(&myVector[myVecLen-1], elem, sizeof(struct foo));
- * }
- *
- * static void pop(struct foo * elem) {
- *   if (myVecLen == 0) die();
- *   memcpy(elem, myVector[myVecLen-1], sizeof(struct foo));
- *   GROW(myVector, myVecLen, myVecLen-1);
- * }
- * </pre>
- *
- * @param arr base-pointer of the vector, may be NULL if size is 0;
- *        will be updated to reflect the new address. The TYPE of
- *        arr is important since size is the number of elements and
- *        not the size in bytes
- * @param size the number of elements in the existing vector (number
- *        of elements to copy over)
- * @param tsize the target size for the resulting vector, use 0 to
- *        free the vector (then, arr will be NULL afterwards).
- */
-#define GROW(arr,size,tsize) xgrow_((void**)&arr, sizeof(arr[0]), &size, 
tsize, __FILE__, __LINE__)
-
-/**
- * Append an element to a list (growing the 
- * list by one).
- */
-#define APPEND(arr,size,element) GROW(arr,size,size+1); arr[size-1] = (element)
-
-/**
  * TIME prototype. "man time".
  */
 TIME_T TIME(TIME_T * t);
@@ -835,171 +123,17 @@
  */
 char * GN_CTIME(const TIME_T * t);
 
-/**
- * Get the IP address of the given host.
- * @return OK on success, SYSERR on error
- */
-int GN_getHostByName(const char * hostname,
-                    IPaddr * ip);
+/** NILS: the next one should be removed from gnunetutil --
+    we should not have anything win32 specific in here! */
 
 /**
- * Give relative time in human-readable fancy format.
+ * @brief Format a Windows specific error code
  */
-char * timeIntervalToFancyString(cron_t delta);
+char *winErrorStr(const char *prefix, 
+                 int dwErr);
 
-/**
- * Convert a given filesize into a fancy human-readable format.
- */
-char * fileSizeToFancyString(unsigned long long size);
 
-#define SEMAPHORE_NEW(value) semaphore_new_(value, __FILE__, __LINE__)
-#define SEMAPHORE_FREE(s) semaphore_free_(s, __FILE__, __LINE__)
-#define SEMAPHORE_DOWN(s) semaphore_down_(s, __FILE__, __LINE__)
-#define SEMAPHORE_DOWN_NONBLOCKING(s) semaphore_down_nonblocking_(s, __FILE__, 
__LINE__)
-#define SEMAPHORE_UP(s) semaphore_up_(s, __FILE__, __LINE__)
-
-#if DEBUG_LOCKING
-#define MUTEX_CREATE(a) do { \
-  fprintf(stderr, \
-          "Creating mutex %x at line %d in file %s\n", \
-          (int) a, __LINE__, __FILE__); \
-  create_mutex_(a); \
-}\
-while(0)
-#define MUTEX_CREATE_RECURSIVE(a) do { \
-  fprintf(stderr, \
-          "Creating recursive mutex %x at line %d in file %s\n", \
-          (int) a, __LINE__, __FILE__); \
-  create_recursive_mutex_(a); \
-}\
-while(0)
-#define MUTEX_DESTROY(a) do { \
-  fprintf(stderr, \
-          "Destroying mutex %x at line %d in file %s\n", \
-          (int) a, __LINE__, __FILE__); \
-  destroy_mutex_(a); \
-}\
-while(0)
-#define MUTEX_LOCK(a) do { \
-  fprintf(stderr, \
-          "Aquireing lock %x at %s:%d\n", \
-          (int)a, __FILE__, __LINE__); \
-  mutex_lock_(a, __FILE__, __LINE__); \
-}\
-while (0)
-#define MUTEX_UNLOCK(a) do { \
-  fprintf(stderr, \
-         "Releasing lock %x at %s:%d\n", \
-       (int)a, __FILE__, __LINE__); \
-  mutex_unlock_(a, __FILE__, __LINE__); \
-}\
-while (0)
-#else
-#define MUTEX_LOCK(a) mutex_lock_(a, __FILE__, __LINE__)
-#define MUTEX_UNLOCK(a) mutex_unlock_(a, __FILE__, __LINE__)
-#define MUTEX_CREATE(a) create_mutex_(a)
-#define MUTEX_CREATE_RECURSIVE(a) create_recursive_mutex_(a)
-#define MUTEX_DESTROY(a) destroy_mutex_(a)
-#endif
-
 /**
- * Returns YES if pt is the handle for THIS thread.
- */
-int PTHREAD_SELF_TEST(PTHREAD_T * pt);
-
-/**
- * Get the handle for THIS thread.
- */
-void PTHREAD_GET_SELF(PTHREAD_T * pt);
-
-/**
- * Release handle for a thread (should have been
- * obtained using PTHREAD_GET_SELF).
- */
-void PTHREAD_REL_SELF(PTHREAD_T * pt);
-
-/**
- * Create a thread. Use this method instead of pthread_create since
- * BSD may only give a 1k stack otherwise.
- *
- * @param handle handle to the pthread (for detaching, join)
- * @param main the main method of the thread
- * @param arg the argument to main
- * @param stackSize the size of the stack of the thread in bytes.
- *        Note that if the stack overflows, some OSes (seen under BSD)
- *        will just segfault and gdb will give a messed-up stacktrace.
- * @return see pthread_create
- */
-int PTHREAD_CREATE(PTHREAD_T * handle,
-                  PThreadMain main,
-                  void * arg,
-                  size_t stackSize);
-
-void PTHREAD_JOIN(PTHREAD_T * handle,
-                 void ** ret);
-
-void PTHREAD_KILL(PTHREAD_T * handle,
-                 int signal);
-
-void PTHREAD_DETACH(PTHREAD_T * handle);
-
-#define IPC_SEMAPHORE_NEW(name,value) ipc_semaphore_new_(name, value, 
__FILE__, __LINE__)
-#define IPC_SEMAPHORE_FREE(s) ipc_semaphore_free_(s, __FILE__, __LINE__)
-#define IPC_SEMAPHORE_DOWN(s) ipc_semaphore_down_(s, __FILE__, __LINE__)
-#define IPC_SEMAPHORE_UP(s) ipc_semaphore_up_(s, __FILE__, __LINE__)
-
-IPC_Semaphore * ipc_semaphore_new_(const char * basename,
-                                  const unsigned int initialValue,
-                                  const char * filename,
-                                  const int linenumber);
-
-void ipc_semaphore_up_(IPC_Semaphore * sem,
-                      const char * filename,
-                      const int linenumber);
-
-void ipc_semaphore_down_(IPC_Semaphore * sem,
-                        const char * filename,
-                        const int linenumber);
-
-
-void ipc_semaphore_free_(IPC_Semaphore * sem,
-                        const char * filename,
-                        const int linenumber);
-
-/**
- * While we must define these globally to make the
- * compiler happy, always use the macros in the sources
- * instead!
- */
-void create_mutex_(Mutex * mutex);
-void create_recursive_mutex_(Mutex * mutex);
-void create_fast_mutex_(Mutex * mutex);
-void destroy_mutex_(Mutex * mutex);
-void mutex_lock_(Mutex * mutex,
-                const char * filename,
-                const int linenumber);
-void mutex_unlock_(Mutex * mutex,
-                  const char * filename,
-                  const int linenumber);
-Semaphore * semaphore_new_(int value,
-                          const char * filename,
-                          const int linenumber);
-void semaphore_free_(Semaphore * s,
-                    const char * filename,
-                    const int linenumber);
-int semaphore_down_(Semaphore * s,
-                   const char * filename,
-                   const int linenumber);
-int semaphore_down_nonblocking_(Semaphore * s,
-                               const char * filename,
-                               const int linenumber);
-int semaphore_up_(Semaphore * s,
-                 const char * filename,
-                 const int linenumber);                
-
-
-
-/**
  * Initialize the util module.
  * @param argc the number of arguments
  * @param argv the command line arguments
@@ -1023,609 +157,6 @@
  */
 void doneUtil(void);
 
-/**
- * Configuration: get the GNUnet port for the client to
- * connect to (via TCP).
- */
-unsigned short getGNUnetPort(void);
-
-/**
- * Get a GNUnet TCP socket that is connected to gnunetd.
- */
-GNUNET_TCP_SOCKET * getClientSocket(void);
-
-/**
- * Free a Client socket.
- */
-void releaseClientSocket(GNUNET_TCP_SOCKET * sock);
-
-/**
- * Read the contents of a bucket to a buffer.
- *
- * @param fn the hashcode representing the entry
- * @param result the buffer to write the result to
- *        (*result should be NULL, sufficient space is allocated)
- * @return the number of bytes read on success, -1 on failure
- */
-int stateReadContent(const char * name,
-                    void ** result);
-
-/**
- * Append content to file.
- *
- * @param fn the key for the entry
- * @param len the number of bytes in block
- * @param block the data to store
- * @return SYSERR on error, OK if ok.
- */
-int stateAppendContent(const char * name,
-                      int len,
-                      const void * block);
-
-/**
- * Write content to a file.
- *
- * @param fn the key for the entry
- * @param len the number of bytes in block
- * @param block the data to store
- * @return SYSERR on error, OK if ok.
- */
-int stateWriteContent(const char * name,
-                     int len,
-                     const void * block);
-
-/**
- * Free space in the database by removing one file
- * @param name the hashcode representing the name of the file
- *        (without directory)
- */
-int stateUnlinkFromDB(const char * name);
-
-/**
- * Initialize a GNUnet client socket.
- *
- * @param port the portnumber in host byte order
- * @param hostname the name of the host to connect to
- * @param result the SOCKET (filled in)
- * @return OK if successful, SYSERR on failure
- */
-int initGNUnetClientSocket(unsigned short port,
-                          const char * hostname,
-                          GNUNET_TCP_SOCKET * result);
-
-/**
- * Initialize a GNUnet client socket.
- *
- * @param port the portnumber in host byte order
- * @param ip IP of the host to connect to
- * @param result the SOCKET (filled in)
- * @return OK if successful, SYSERR on failure
- */
-int initGNUnetClientSocketIP(unsigned short port,
-                            IPaddr ip,
-                            GNUNET_TCP_SOCKET * result);
-
-/**
- * Initialize a GNUnet server socket.
- * @param sock the open socket
- * @param result the SOCKET (filled in)
- * @return OK (always successful)
- */
-int initGNUnetServerSocket(int socket,
-                          GNUNET_TCP_SOCKET * result);
-
-/**
- * Check if a socket is open. Will ALWAYS return 'true'
- * for a valid client socket (even if the connection is
- * closed), but will return false for a closed server socket.
- * @return 1 if open, 0 if closed
- */
-int isOpenConnection(GNUNET_TCP_SOCKET * sock);
-
-/**
- * Check a socket, open and connect if it is closed and it is a
- * client-socket.
- */
-int checkSocket(GNUNET_TCP_SOCKET * sock);
-
-/**
- * Read from a GNUnet TCP socket.
- * @param sock the socket
- * @param buffer the buffer to write data to;
- *        if NULL == *buffer, *buffer is allocated (caller frees)
- * @return OK if the read was successful, SYSERR if the socket
- *         was closed by the other side (if the socket is a
- *         client socket and is used again, tcpio will attempt
- *         to re-establish the connection [temporary error]).
- */
-int readFromSocket(GNUNET_TCP_SOCKET * sock,
-                  CS_MESSAGE_HEADER ** buffer);
-
-/**
- * Write to a GNUnet TCP socket.
- * @param sock the socket to write to
- * @param buffer the buffer to write
- * @return OK if the write was sucessful, otherwise SYSERR.
- */
-int writeToSocket(GNUNET_TCP_SOCKET * sock,
-                 const CS_MESSAGE_HEADER * buffer);
-
-/**
- * Write to a GNUnet TCP socket non-blocking.
- * @param sock the socket to write to
- * @param buffer the buffer to write
- * @return OK if the write was sucessful, NO if it would have blocked and was 
not performed,
- *         otherwise SYSERR.
- */
-int writeToSocketNonBlocking(GNUNET_TCP_SOCKET * sock,
-                            const CS_MESSAGE_HEADER * buffer);
-
-/**
- * Close a GNUnet TCP socket for now (use to temporarily close
- * a TCP connection that will probably not be used for a long
- * time; the socket will still be auto-reopened by the
- * readFromSocket/writeToSocket methods if it is a client-socket).
- */
-void closeSocketTemporarily(GNUNET_TCP_SOCKET * sock);
-
-/**
- * Destroy a socket for good. If you use this socket afterwards,
- * you must first invoke initializeSocket, otherwise the operation
- * will fail.
- */
-void destroySocket(GNUNET_TCP_SOCKET * sock);
-
-
-/**
- * Obtain a return value from a remote call from
- * TCP.
- * @param sock the TCP socket
- * @param ret the return value from TCP
- * @return SYSERR on error, OK if the return value was
- *         read successfully
- */
-int readTCPResult(GNUNET_TCP_SOCKET * sock,
-                 int * ret);
-
-/**
- * Send a return value to the caller of a remote call via
- * TCP.
- * @param sock the TCP socket
- * @param ret the return value to send via TCP
- * @return SYSERR on error, OK if the return value was
- *         send successfully
- */
-int sendTCPResult(GNUNET_TCP_SOCKET * sock,
-                 int ret);
-
-/**
- * Get the load of the CPU relative to what is allowed.
- *
- * @return the CPU load as a percentage of allowed
- *        (100 is equivalent to full load)
- */
-int getCPULoad(void);
-
-/**
- * Get the load of the network relative to what is allowed.
- * The only difference to networkUsageUp is that
- * this function averages the values over time.
- *
- * @return the network load as a percentage of allowed
- *        (100 is equivalent to full load)
- */
-int getNetworkLoadUp(void);
-
-/**
- * Get the load of the network relative to what is allowed.
- * The only difference to networkUsageDown is that
- * this function averages the values over time.
- *
- * @return the network load as a percentage of allowed
- *        (100 is equivalent to full load)
- */
-int getNetworkLoadDown(void);
-
-/**
- * Tell statuscalls to increment the number of bytes sent
- */
-void incrementBytesSent(unsigned long long delta);
-
-/**
- * Tell statuscalls to increment the number of bytes received
- */
-void incrementBytesReceived(unsigned long long delta);
-
-/**
- * Get the size of the file (or directory)
- * of the given file (in bytes).
- *
- * @return OK on success, SYSERR on error
- */
-int getFileSize(const char * filename,
-               unsigned long long * size);
-
-/**
- * Get the size of the file (or directory) without
- * counting symlinks.
- *
- * @return OK on success, SYSERR on error
- */
-int getFileSizeWithoutSymlinks(const char * filename,
-                              unsigned long long * size);
-
-/**
- * Get the number of blocks that are left on the partition that
- * contains the given file (for normal users).
- *
- * @param part a file on the partition to check
- * @return -1 on errors, otherwise the number of free blocks
- */
-long getBlocksLeftOnDrive(const char * part);
-
-/**
- * Assert that fil corresponds to a filename
- * (of a file that exists and that is not a directory).
- * @returns 1 if yes, 0 if not (will print an error
- * message in that case, too).
- */
-int assertIsFile(const char * fil);
-
-/**
- * Complete filename (a la shell) from abbrevition.
- * @param fil the name of the file, may contain ~/ or
- *        be relative to the current directory
- * @returns the full file name,
- *          NULL is returned on error
- */
-char * expandFileName(const char * fil);
-
-/**
- * Implementation of "mkdir -p"
- * @param dir the directory to create
- * @returns SYSERR on failure, OK otherwise
- */
-int mkdirp(const char * dir);
-
-/**
- * Read the contents of a binary file into a buffer.
- * @param fileName the name of the file, not freed,
- *        must already be expanded!
- * @param len the maximum number of bytes to read
- * @param result the buffer to write the result to
- * @return the number of bytes read on success, -1 on failure
- */
-int readFile(const char * fileName,
-            int len,
-            void * result);
-
-/**
- * Write a buffer to a file.
- * @param fileName the name of the file, NOT freed!
- * @param buffer the data to write
- * @param n number of bytes to write
- * @param mode the mode for file permissions
- * @return OK on success, SYSERR on error
- */
-int writeFile(const char * fileName,
-             const void * buffer,
-             unsigned int n,
-             const char * mode);
-
-/**
- * Copy a file.
- * @return OK on success, SYSERR on error
- */
-int copyFile(const char * src,
-            const char * dst);
-
-/**
- * Scan a directory for files. The name of the directory
- * must be expanded first (!).
- * @param dirName the name of the directory
- * @param callback the method to call for each file
- * @param data argument to pass to callback
- * @return the number of files found, -1 on error
- */
-int scanDirectory(const char * dirName,
-                 DirectoryEntryCallback callback,
-                 void * data);
-
-/**
- * Test if fil is a directory.
- * @returns YES if yes, NO if not
- */
-int isDirectory(const char * fil);
-
-/**
- * Remove all files in a directory (rm -rf). Call with
- * caution.
- *
- *
- * @param fileName the file to remove
- * @return OK on success, SYSERR on error
- */
-int rm_minus_rf(const char * fileName);
-
-/**
- * Stop the application.
- * @param signum is ignored
- */
-void run_shutdown(int signum);
-
-/**
- * Test if the shutdown has been initiated.
- * @return YES if we are shutting down, NO otherwise
- */
-int testShutdown(void);
-
-/**
- * Initialize the signal handlers, etc.
- */
-void initializeShutdownHandlers(void);
-
-/**
- * Wait until the shutdown has been initiated.
- */
-void wait_for_shutdown(void);
-
-void doneShutdownHandlers(void);
-
-/**
- * Print output of --help in GNU format.
- */
-void formatHelp(const char * general,
-               const char * description,
-               const Help * opt);
-
-/**
- * Parse the default set of options and set
- * options in the configuration accordingly.
- * This does not include --help or --version.
- * @return YES if the option was a default option
- *  that was successfully processed
- */
-int parseDefaultOptions(char c,
-                       char * optarg);
-
-/**
- * Depending on doBlock, enable or disable the nonblocking mode
- * of socket s.
- *
- * @return Upon successful completion, it returns zero.
- * @return Otherwise -1 is returned.
- */
-int setBlocking(int s, int doBlock);
-
-/**
- * Check whether the socket is blocking
- * @param s the socket
- * @return YES if blocking, NO non-blocking
- */
-int isSocketBlocking(int s);
-
-/**
- * Do a NONBLOCKING read on the given socket.  Note that in order to
- * avoid blocking, the caller MUST have done a select call before
- * calling this function. Though the caller must be prepared to the
- * fact that this function may fail with EWOULDBLOCK in any case (Win32).
- *
- * @brief Reads at most max bytes to buf. Interrupts are IGNORED.
- * @param s socket
- * @param buf buffer
- * @param max maximum number of bytes to read
- * @param read number of bytes actually read.
- *             0 is returned if no more bytes can be read
- * @return SYSERR on error, YES on success or NO if the operation
- *         would have blocked
- */
-int RECV_NONBLOCKING(int s,
-                    void * buf,
-                    size_t max,
-                    size_t *read);
-
-
-/**
- * Do a BLOCKING read on the given socket.  Read len bytes (if needed
- * try multiple reads).  Interrupts are ignored.
- *
- * @return SYSERR if len bytes could not be read,
- *   otherwise the number of bytes read (must be len)
- */
-int RECV_BLOCKING_ALL(int s,
-                     void * buf,
-                     size_t len);
-
-
-/**
- * Do a NONBLOCKING write on the given socket.
- * Write at most max bytes from buf.
- * Interrupts are ignored (cause a re-try).
- *
- * The caller must be prepared to the fact that this function
- * may fail with EWOULDBLOCK in any case (Win32).
- *
- * @param s socket
- * @param buf buffer to send
- * @param max maximum number of bytes to send
- * @param sent number of bytes actually sent
- * @return SYSERR on error, YES on success or
- *         NO if the operation would have blocked.
- */
-int SEND_NONBLOCKING(int s,
-                    const void * buf,
-                    size_t max,
-                    size_t *sent);
-
-
-/**
- * Do a BLOCKING write on the given socket.  Write len bytes (if
- * needed do multiple write).  Interrupts are ignored (cause a
- * re-try).
- *
- * @return SYSERR if len bytes could not be send,
- *   otherwise the number of bytes transmitted (must be len)
- */
-int SEND_BLOCKING_ALL(int s,
-                     const void * buf,
-                     size_t len);
-
-/**
- * Check if socket is valid
- * @return 1 if valid, 0 otherwise
- */
-int isSocketValid(int s);
-
-/**
- * Like snprintf, just aborts if the buffer is of insufficient size.
- */
-int SNPRINTF(char * buf,
-            size_t size,
-            const char * format,
-            ...);
-
-/**
- * open() a file
- */
-int fileopen(const char *filename, int oflag, ...);
-
-/**
- * String functions
- */
-#if !HAVE_STRLCPY
-size_t strlcpy(char *dest, const char *src, size_t size);
-#endif
-#if !HAVE_STRLCAT
-size_t strlcat(char *dest, const char *src, size_t count);
-#endif
-
-/**
- * @brief Get human-readable filesizes from byte numbers
- * @param size_n the size in bytes
- */
-char * getHumanSize (unsigned long long int size_n);
-
-/**
- * @brief Enumerate all network interfaces
- * @param callback the callback function
- */
-void enumNetworkIfs(void (*callback) (const char *, int, void *), void * cls);
-
-/**
- * @brief Checks if we can start GNUnet automatically
- * @return 1 if yes, 0 otherwise
- */
-int isOSAutostartCapable(void);
-
-/**
- * @brief Make GNUnet start automatically
- * @param doAutoStart true to enable autostart, false to disable it
- * @param username name of the user account to use
- * @param groupname name of the group to use
- * @return 0 on success
- */
-int autostartService(int doAutoStart, 
-                    const char *username, 
-                    const char *groupname);
-
-/**
- * @brief Checks if we can add an user for the GNUnet service
- * @return 1 if yes, 0 otherwise
- * @todo support for useradd(8)
- */
-int isOSUserAddCapable(void);
-
-/**
- * @brief Checks if we can add a group for the GNUnet service
- * @return 1 if yes, 0 otherwise
- * @todo support for groupadd(8)
- */
-int isOSGroupAddCapable(void);
-
-/**
- * @brief Add a service account for GNUnet
- * @param group the group of the new user
- * @param name the name of the new user
- * @return 0 on success
- */
-int createGroupUser(const char *group_name, 
-                   const char *user_name);
-
-/**
- * @brief Format a Windows specific error code
- */
-char *winErrorStr(const char *prefix, int dwErr);
-
-/**
- * Checks if gnunetd is running
- *
- * Uses CS_PROTO_traffic_COUNT query to determine if gnunetd is
- * running.
- *
- * @return OK if gnunetd is running, SYSERR if not
- */
-int checkGNUnetDaemonRunning(void);
-
-/**
- * Start gnunetd process
- *
- * @param daemonize YES if gnunetd should be daemonized
- * @return pid_t of gnunetd if NOT daemonized, 0 if
- *  daemonized sucessfully, -1 on error
- */
-int startGNUnetDaemon(int daemonize);
-
-
-/**
- * Stop gnunetd
- *
- * Note that returning an error does NOT mean that
- * gnunetd will continue to run (it may have been
- * shutdown by something else in the meantime or
- * crashed).  Call checkDaemonRunning() frequently
- * to check the status of gnunetd.
- *
- * Furthermore, note that this WILL potentially kill
- * gnunetd processes on remote machines that cannot
- * be restarted with startGNUnetDaemon!
- *
- * This function does NOT need the PID and will also
- * kill daemonized gnunetd's.
- *
- * @return OK successfully stopped, SYSERR: error
- */
-int stopGNUnetDaemon(void);
-
-
-/**
- * Wait until the gnunet daemon is
- * running.
- *
- * @param timeout how long to wait at most
- * @return OK if gnunetd is now running
- */
-int waitForGNUnetDaemonRunning(cron_t timeout);
-
-
-/**
- * Wait until the gnunet daemon (or any other CHILD process for that
- * matter) with the given PID has terminated.  Assumes that
- * the daemon was started with startGNUnetDaemon in no-daemonize mode.
- * On arbitrary PIDs, this function may fail unexpectedly.
- *
- * @return YES if gnunetd shutdown with
- *  return value 0, SYSERR if waitpid
- *  failed, NO if gnunetd shutdown with
- *  some error
- */
-int waitForGNUnetDaemonTermination(int pid);
-
-/**
- * @brief Terminate a process
- * @return YES on success, NO otherwise
- */
-int termProcess(int pid);
-
 #if 0 /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: GNUnet/src/include/gnunet_util_crypto.h
===================================================================
--- GNUnet/src/include/gnunet_util_crypto.h     2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/include/gnunet_util_crypto.h     2006-06-22 17:50:56 UTC (rev 
3024)
@@ -41,6 +41,9 @@
 #endif
 #endif
 
+#define STRONG YES
+#define WEAK NO
+
 /**
  * @brief length of the sessionkey in bytes (256 BIT sessionkey)
  */

Modified: GNUnet/src/include/gnunet_util_error.h
===================================================================
--- GNUnet/src/include/gnunet_util_error.h      2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/include/gnunet_util_error.h      2006-06-22 17:50:56 UTC (rev 
3024)
@@ -38,6 +38,19 @@
 #endif
 
 /**
+ * Named constants for return values.  The following
+ * invariants hold: "NO == 0" (to allow "if (NO)")
+ * "OK != SYSERR", "OK != NO", "NO != SYSERR"
+ * and finally "YES != NO".
+ */
+#define OK      1
+#define SYSERR -1
+#define YES     1
+#define NO      0
+
+
+
+/**
  * Context required to log messages.
  */
 struct GE_Context;
@@ -49,10 +62,11 @@
   GE_NOTHING   = 0x00000000,
   /* type of event */
   GE_DEBUG     = 0x00000001, /* DEBUG/CRON/EVERYTHING */
-  GE_STATUS    = 0x00000002, /* INFO/MESSAGE */
-  GE_WARNING   = 0x00000004,
-  GE_ERROR     = 0x00000008,
-  GE_FATAL     = 0x00000010, /* FATAL/FAILURE/NOTHING */
+  GE_STATUS    = 0x00000002, /* status message */
+  GE_INFO      = 0x00000004, /* normal program response */
+  GE_WARNING   = 0x00000008,
+  GE_ERROR     = 0x00000010,
+  GE_FATAL     = 0x00000020, /* FATAL/FAILURE/NOTHING */
   GE_EVENTKIND = 0x000000FF, /* bitmask */
 
   /* who should see the message? */
@@ -112,8 +126,10 @@
 
 /**
  * Does the given event match the mask?
+ *
  * @param have the event type
  * @param mask the filter mask
+ * @return YES or NO
  */
 int GE_applies(GE_KIND have,
               GE_KIND mask);
@@ -121,8 +137,10 @@
 /**
  * Would an event of this kind be possibly 
  * processed by the logger?
+ *
  * @param ctx the logger
  * @param have the kind of event
+ * @return YES or NO
  */
 int GE_isLogged(struct GE_Context * ctx,
                GE_KIND kind);
@@ -155,7 +173,7 @@
 
 #define GE_ASSERT(ctx, cond) do { if (! (cond)) { GE_LOG(ctx, GE_DEVELOPER | 
GE_USER | GE_FATAL | GE_IMMEDIATE, _("Assertion failed at %s:%d in %s.\n"), 
__FILE__, __LINE__, __FUNCTION__); abort(); } } while(0);
 
-#define GE_ASSERT_FLF(ctx, cond, file, line, function) do { if (! (cond)) { 
GE_LOG(_(ctx, GE_DEVELOPER | GE_USER | GE_FATAL | GE_IMMEDIATE, "Assertion 
failed at %s:%d in %s.\n"), file, line, function); abort(); } } while(0);
+#define GE_ASSERT_FLF(ctx, cond, file, line, function) do { if (! (cond)) { 
GE_LOG(ctx, GE_DEVELOPER | GE_USER | GE_FATAL | GE_IMMEDIATE, _("Assertion 
failed at %s:%d in %s.\n"), file, line, function); abort(); } } while(0);
 
 #define GE_BREAK(ctx, cond)  do { if (! (cond)) { GE_LOG(ctx, GE_DEVELOPER | 
GE_USER | GE_FATAL | GE_IMMEDIATE, _("Assertion failed at %s:%d in %s.\n"), 
__FILE__, __LINE__, __FUNCTION__); } } while(0);
 
@@ -180,6 +198,13 @@
  * a failure of the command 'cmd' with the message given
  * by strerror(errno).
  */
+#define GE_DIE_STRERROR_FLF(ctx, level, cmd, file, line, function) do { 
GE_LOG(ctx, level, _("`%s' failed at %s:%d in %s with error: %s\n"), cmd, file, 
line, function, STRERROR(errno)); abort(); } while(0);
+
+/**
+ * Log an error message at log-level 'level' that indicates
+ * a failure of the command 'cmd' with the message given
+ * by strerror(errno).
+ */
 #define GE_LOG_STRERROR_FLF(ctx, level, cmd, file, line, function) do { 
GE_LOG(ctx, level, _("`%s' failed at %s:%d in %s with error: %s\n"), cmd, file, 
line, function, STRERROR(errno)); } while(0);
 
 /**
@@ -190,8 +215,6 @@
 #define GE_LOG_STRERROR_FILE(ctx, level, cmd, filename) do { GE_LOG(ctx, 
level, _("`%s' failed on file `%s' at %s:%d in %s with error: %s\n"), cmd, 
filename,__FILE__, __LINE__, __FUNCTION__, STRERROR(errno)); } while(0);
 
 
-
-
 #if 0 /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: GNUnet/src/include/gnunet_util_error_loggers.h
===================================================================
--- GNUnet/src/include/gnunet_util_error_loggers.h      2006-06-22 17:39:19 UTC 
(rev 3023)
+++ GNUnet/src/include/gnunet_util_error_loggers.h      2006-06-22 17:50:56 UTC 
(rev 3024)
@@ -69,6 +69,15 @@
                         GE_KIND mask);
 
 /**
+ * Create a logger that writes events to stderr
+ * 
+ * @param mask which events should be logged?
+ */
+struct GE_Context * 
+GE_create_context_stdout(int logDate,
+                        GE_KIND mask);
+
+/**
  * Create a logger that keeps events in memory (to be
  * queried later in bulk).
  */

Modified: GNUnet/src/util/Makefile.am
===================================================================
--- GNUnet/src/util/Makefile.am 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/Makefile.am 2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,4 +1,9 @@
-SUBDIRS = $(WINSUBDIRS) $(CYGSUBDIRS) error string config getopt . config_impl 
loggers crypto containers
+SUBDIRS = $(WINSUBDIRS) $(CYGSUBDIRS) \
+  error string config \
+  getopt disk threads \
+  os network . \
+  config_impl loggers \
+  crypto cron containers
 
 INCLUDES = -I$(top_srcdir)/src/include
 
@@ -34,11 +39,16 @@
 lib_LTLIBRARIES = libgnunetutil.la
 
 libgnunetutil_la_LIBADD = $(GCLIBADD) $(CYGLIBADD) $(WINLIBADD) \
- error/liberror.la \
  config/libconfig.la \
+ disk/libdisk.la \
+ error/liberror.la \
+ getopt/libgetopt.la \
  string/libstring.la \
- getopt/libgetopt.la
+ network/libnetwork.la \
+ os/libos.la \
+ threads/libthreads.la
 
+
 EXTRA_DIST = \
   testconfig.conf \
   check.conf
@@ -48,86 +58,5 @@
  -version-info 1:0:0
 
 libgnunetutil_la_SOURCES = \
- cron.c \
- daemon.c \
- dso.c \
- endian.c \
- getopt.c \
- initialize.c \
- io.c \
- ipcheck.c \
- osconfig.c \
- printhelp.c \
- port.c \
- semaphore.c \
- shutdown.c \
- state.c \
- statuscalls.c \
- storage.c \
- tcp_return.c \
- tcpio.c \
- timer.c
+ initialize.c time.c
 
-################################
-# TESTCASES 
-################################
-
-check_PROGRAMS = \
- crontest \
- daemontest \
- semaphoretest \
- shutdowntest \
- statetest \
- statuscallstest \
- storagetest \
- tcpiotest \
- timertest 
-
-TESTS = $(check_PROGRAMS)
-
-daemontest_SOURCES = \
- daemontest.c 
-daemontest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-statetest_SOURCES = \
- statetest.c
-statetest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-shutdowntest_SOURCES = \
- shutdowntest.c
-shutdowntest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-timertest_SOURCES = \
- timertest.c
-timertest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-tcpiotest_SOURCES = \
- tcpiotest.c
-tcpiotest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-crontest_SOURCES = \
- crontest.c
-crontest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-storagetest_SOURCES = \
- storagetest.c
-storagetest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-statuscallstest_SOURCES = \
- statuscallstest.c
-statuscallstest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-semaphoretest_SOURCES = \
- semaphoretest.c
-semaphoretest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la  
-
-

Modified: GNUnet/src/util/README
===================================================================
--- GNUnet/src/util/README      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/README      2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,12 +1,22 @@
-Util is now structured as follows:
+util/ is now structured as follows:
 
 util/error: basic error handling functions (lowest layer)
 util/win: win32 portability (lowest layer)
-util/string: string and memory abstraction (depends on error)
-util/config: configuration handling (depends on error)
-util/getopt: command line parsing (depends on config)
-util: main utility library (depends on error/, win/ and config/, string/ and 
getopt/)
-      => these are linked into gnunetutil.so
+ util/string: string and memory abstraction (depends on error)
+  util/disk  : disk IO abstractions (depends on string)
+ util/config: configuration handling (depends on error)
+  util/getopt: command line parsing (depends on config)
+ util/threads: pthread abstractions (depends on error)
+
+-------- TODO ----------
+  util/network: network IO abstractions (depends on threads, config)
+  util/os    : process and system abstractions (depends on threads, config)
+
+util: main utility library (depends on all of the above)
+      => these are all statically linked into gnunetutil.so
+
+util/cron: periodic job execution (depends on gnunetutil.so)
+      => linked to gnunetutil_cron.so
 util/loggers: specific logging implementations (depends on gnunetutil.so)
       => linked to gnunetutil_logging.so
 util/config_impl: implementation of config API (depends on gnunetutil.so)

Deleted: GNUnet/src/util/cron.c
===================================================================
--- GNUnet/src/util/cron.c      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/cron.c      2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,708 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other 
contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/cron.c
- * @author Christian Grothoff
- *
- * @brief Module for periodic background (cron) jobs.
- *
- * The module only uses one thread, thus every cron-job must be
- * short-lived, should never block for an indefinite amount of
- * time. Specified deadlines are only a guide-line, the 10ms
- * timer-resolution is only an upper-bound on the possible precision,
- * in practice it will be worse (depending on the other cron-jobs).
- *
- * If you need to schedule a long-running or blocking cron-job,
- * run a function that will start another thread that will
- * then run the actual job.
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#define DEBUG_CRON NO
-
-#if DEBUG_CRON
-#define HAVE_PRINT_CRON_TAB 1
-#else
-#define HAVE_PRINT_CRON_TAB 0
-#endif
-
-/**
- * The initial size of the cron-job table
- */
-#define INIT_CRON_JOBS 16
-
-/**
- * how long do we sleep at most? In some systems, the
- * signal-interrupted sleep does not work nicely, so to ensure
- * progress, we should rather wake up periodically. (But we don't want
- * to burn too much CPU time doing busy waiting; every 2s strikes a
- * good balance)
- */
-#define MAXSLEEP 2000
-
-#define CHECK_ASSERTS 1
-
-/**
- * The Delta-list for the cron jobs.
- */
-typedef struct {
-  /** The start-time for this event (in milliseconds). */
-  cron_t delta;
-  /** The method to call at that point. */
-  CronJob method;
-  /** for cron-jobs: when this should be repeated
-      automatically, 0 if this was a once-only job */
-  unsigned int deltaRepeat;
-  /** The index of the next entry in the delta list
-      after this one */
-  int next;
-  /** data ptr (argument to the method) */
-  void * data;
-} UTIL_cron_DeltaListEntry;
-
-/**
- * The delta-list of waiting tasks.
- */
-static UTIL_cron_DeltaListEntry * deltaList_;
-
-/**
- * The current size of the DeltaList.
- */
-static unsigned int deltaListSize_;
-
-/**
- * The lock for the delta-list.
- */
-static Mutex deltaListLock_;
-
-/**
- * The currently running job.
- */
-static CronJob runningJob_;
-static unsigned int runningRepeat_;
-static void * runningData_;
-
-/**
- * The first empty slot in the delta-list.
- */
-static int firstFree_;
-
-/**
- * The first empty slot in the delta-list.
- */
-static int firstUsed_;
-
-/**
- * The cron thread.
- */
-static int cron_shutdown = YES;
-static Semaphore * cron_signal = NULL;
-static Semaphore * cron_signal_up = NULL;
-
-static PTHREAD_T cron_handle;
-
-
-/* don't do anything, we use SIGALRM to abort
-   the nanosleep */
-#ifndef WINDOWS
-static void sigalrmHandler(int sig) {
-}
-#endif
-
-static Mutex inBlockLock_;
-
-
-/**
- * Initialize the cron service.
- */
-void initCron() {
-  unsigned int i;
-#ifndef MINGW
-  static struct sigaction sig;
-  static struct sigaction old;
-#endif
-
-  deltaListSize_ = INIT_CRON_JOBS;
-  deltaList_
-    = MALLOC(sizeof(UTIL_cron_DeltaListEntry) * deltaListSize_);
-  for (i=0;i<deltaListSize_;i++)
-    deltaList_[i].next = i-1;
-  firstFree_ = deltaListSize_-1;
-  MUTEX_CREATE_RECURSIVE(&deltaListLock_);
-  MUTEX_CREATE(&inBlockLock_);
-  runningJob_ = NULL;
-  firstUsed_  = -1;
-  /* SA_NODEFER == SA_NOMASK but is available on linux */
-
-#ifndef WINDOWS /* We don't use signals under Windows */
-  memset(&sig, 0, sizeof(struct sigaction));
-  memset(&old, 0, sizeof(struct sigaction));
-  sig.sa_flags = SA_NODEFER;
-  sig.sa_handler =  &sigalrmHandler; 
-  sigaction(SIGALRM, &sig, &old);
-#endif
-  cron_signal_up = SEMAPHORE_NEW(0);
-}
-
-static void noJob(void * unused) {
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "In noJob.\n");
-#endif
-}
-
-/**
- * Stop the cron service.
- */
-void stopCron() {
-  void * unused;
-
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "Stopping cron\n");
-#endif
-  cron_shutdown = YES;
-  addCronJob(&noJob, 0, 0, NULL);
-  SEMAPHORE_DOWN(cron_signal);
-  SEMAPHORE_FREE(cron_signal);
-  cron_signal = NULL;
-  PTHREAD_JOIN(&cron_handle, &unused);
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "Cron stopped\n");
-#endif
-}
-
-static int inBlock = 0;
-
-/**
- * CronJob to suspend the cron thread
- * until it is resumed.
- */
-static void block(void * sem) {
-  Semaphore * sig = sem;
-  int ok = SYSERR;
-
-  if (sig != NULL)
-    SEMAPHORE_UP(sig);
-  while (ok == SYSERR) {
-    SEMAPHORE_DOWN(cron_signal_up);
-    MUTEX_LOCK(&inBlockLock_);
-    inBlock--;
-    if (inBlock == 0)
-      ok = OK;
-    MUTEX_UNLOCK(&inBlockLock_);
-  }
-}
-                               
-/**
- * Stop running cron-jobs for a short time.  This method may only be
- * called by a thread that is not holding any locks (otherwise
- * there is the danger of a deadlock).
- */
-void suspendCron() {
-  Semaphore * blockSignal;
-
-  GE_ASSERT(NULL, cron_shutdown == NO);
-  GE_ASSERT(NULL, NO == PTHREAD_SELF_TEST(&cron_handle));
-  MUTEX_LOCK(&inBlockLock_);
-  inBlock++;
-  if (inBlock == 1) {
-    blockSignal = SEMAPHORE_NEW(0);
-    addCronJob(&block,
-              0,
-              0,
-              blockSignal);
-    SEMAPHORE_DOWN(blockSignal);
-    SEMAPHORE_FREE(blockSignal);
-  }
-  MUTEX_UNLOCK(&inBlockLock_);
-}
-
-int isCronRunning() {
-  if ( (NO == cron_shutdown) || (inBlock > 0) )
-    return YES;
-  else
-    return NO;
-}
-
-/**
- * Resume running cron-jobs.
- */
-void resumeCron() {
-  GE_ASSERT(NULL, inBlock > 0);
-  SEMAPHORE_UP(cron_signal_up);
-}
-
-void suspendIfNotCron() {
-  if (NO == PTHREAD_SELF_TEST(&cron_handle))
-    suspendCron();
-}
-
-void resumeIfNotCron() {
-  if (NO == PTHREAD_SELF_TEST(&cron_handle))
-    resumeCron();
-}
-
-static void abortSleep() {
-  if (cron_signal == NULL)
-    return; /* cron_handle not valid */
-  PTHREAD_KILL(&cron_handle, SIGALRM);
-}
-
-
-#if HAVE_PRINT_CRON_TAB
-/**
- * Print the cron-tab.
- */
-void printCronTab() {
-  int jobId;
-  UTIL_cron_DeltaListEntry * tab;
-  cron_t now;
-
-  cronTime(&now);
-  MUTEX_LOCK(&deltaListLock_);
-
-  jobId = firstUsed_;
-  while (jobId != -1) {
-    tab = &deltaList_[jobId];
-    GE_LOG(NULL,
-          GE_STATUS | GE_DEVELOPER | GE_BULK,
-          "%3u: delta %8lld CU --- method %p --- repeat %8u CU\n",
-          jobId,
-          tab->delta - now,
-          (int)tab->method,
-          tab->deltaRepeat);
-    jobId = tab->next;
-  }
-  MUTEX_UNLOCK(&deltaListLock_);
-}
-#endif
-
-
-/**
- * If the specified cron-job exists in th delta-list, move it to the
- * head of the list.  If it is running, do nothing.  If it is does not
- * exist and is not running, add it to the list to run it next.
- *
- * @param method which method should we run
- * @param deltaRepeat if this is a periodic, the time between
- *        the runs, otherwise 0.
- * @param data extra argument to calls to method, freed if
- *        non-null and cron is shutdown before the job is
- *        run and/or delCronJob is called
- */
-void advanceCronJob(CronJob method,
-                   unsigned int deltaRepeat,
-                   void * data) {
-  UTIL_cron_DeltaListEntry * job;
-  UTIL_cron_DeltaListEntry * last;
-  int jobId;
-
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "Advancing job %p-%p\n",
-        method,
-        data);
-#endif
-  MUTEX_LOCK(&deltaListLock_);
-  jobId = firstUsed_;
-  if (jobId == -1) {
-    /* not in queue; add if not running */
-    if ( (method != runningJob_) ||
-         (data != runningData_) ||
-        (deltaRepeat != runningRepeat_) ) {
-      GE_LOG(NULL,
-            GE_ERROR | GE_USER | GE_DEVELOPER | GE_BULK,
-            _("`%s' called with cron job not in queue, adding.  This may not 
be what you want.\n"),
-            __FUNCTION__);
-      addCronJob(method,
-                0,
-                deltaRepeat,
-                data);
-    }
-    MUTEX_UNLOCK(&deltaListLock_);
-    return;
-  }
-  last = NULL;
-  job = &deltaList_[jobId];
-  while ( (job->method != method) ||
-         (job->data != data) ||
-         (job->deltaRepeat != deltaRepeat) ) {
-    last = job;
-    if (job->next == -1) {
-      /* not in queue; add if not running */
-      if ( (method != runningJob_) ||
-          (data != runningData_) ||
-          (deltaRepeat != runningRepeat_) ) {
-       addCronJob(method,
-                  0,
-                  deltaRepeat,
-                  data);
-      }
-      MUTEX_UNLOCK(&deltaListLock_);
-      return;
-    }
-    jobId = job->next;
-    job = &deltaList_[jobId];
-  }
-  /* ok, found it; remove, re-add with time 0 */
-  delCronJob(method,
-            deltaRepeat,
-            data);
-  addCronJob(method,
-            0,
-            deltaRepeat,
-            data);
-  MUTEX_UNLOCK(&deltaListLock_);
-}
-
-/**
- * Add a cron-job to the delta list.
- *
- * @param method which method should we run
- * @param delta how many milliseconds until we run the method
- * @param deltaRepeat if this is a periodic, the time between
- *        the runs, otherwise 0.
- * @param data extra argument to calls to method, freed if
- *        non-null and cron is shutdown before the job is
- *        run and/or delCronJob is called
- */
-void addCronJob(CronJob method,
-               unsigned int delta,
-               unsigned int deltaRepeat,
-               void * data) {
-  UTIL_cron_DeltaListEntry * entry;
-  UTIL_cron_DeltaListEntry * pos;
-  int last;
-  int current;
-
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "Adding job %p-%p to fire in %d CU\n",
-        method,
-        data,
-        delta);
-#endif
-
-  MUTEX_LOCK(&deltaListLock_);
-  if (firstFree_ == -1) { /* need to grow */
-    unsigned int i;
-
-    GROW(deltaList_,
-        deltaListSize_,
-        deltaListSize_ * 2);
-    for (i=deltaListSize_/2;i<deltaListSize_;i++)
-      deltaList_[i].next = i-1;
-    deltaList_[deltaListSize_/2].next = -1;
-    firstFree_ = deltaListSize_-1;
-  }
-  entry = &deltaList_[firstFree_];
-  entry->method = method;
-  entry->data = data;
-  entry->deltaRepeat = deltaRepeat;
-  entry->delta = cronTime(NULL) + delta;
-  if (firstUsed_ == -1) {
-    firstUsed_
-      = firstFree_;
-    firstFree_
-      = entry->next;
-    entry->next = -1; /* end of list */
-    MUTEX_UNLOCK(&deltaListLock_);
-    /* interrupt sleeping cron-thread! */
-    abortSleep();
-    return;
-  }
-  /* no, there are jobs waiting */
-  last = -1;
-  current = firstUsed_;
-  pos = &deltaList_[current];
-
-  while (entry->delta > pos->delta) {
-    if (pos->next != -1) {
-      last = current;
-      current = pos->next;
-      pos = &deltaList_[current];
-    } else { /* append */
-      pos->next = firstFree_;
-      firstFree_
-       = entry->next;
-      entry->next = -1;
-      MUTEX_UNLOCK(&deltaListLock_);
-#if HAVE_PRINT_CRON_TAB
-      printCronTab();
-#endif
-      return;
-    }
-  }
-  /* insert before pos */
-  if (last == -1) {
-    firstUsed_ = firstFree_;
-    abortSleep();
-  } else {
-    deltaList_[last].next = firstFree_;
-#if HAVE_PRINT_CRON_TAB
-    printCronTab();
-#endif
-  }
-  firstFree_
-    = entry->next;
-  entry->next = current;
-  MUTEX_UNLOCK(&deltaListLock_);
-}
-
-/**
- * Process the cron-job at the beginning of the waiting queue, that
- * is, remove, invoke, and re-insert if it is a periodical job. Make
- * sure the cron job is held when calling this method, but
- * note that it will be released briefly for the time
- * where the job is running (the job to run may add other
- * jobs!)
- */
-static void runJob() {
-  UTIL_cron_DeltaListEntry * job;
-  int jobId;
-  CronJob method;
-  void * data;
-  unsigned int repeat;
-
-  jobId = firstUsed_;
-  if (jobId == -1)
-    return; /* no job to be done */
-  job    = &deltaList_[jobId];
-  method = job->method;
-  runningJob_ = method;
-  data   = job->data;
-  runningData_ = data;
-  repeat = job->deltaRepeat;
-  runningRepeat_ = repeat;
-  /* remove from queue */
-  firstUsed_
-    = job->next;
-  job->next
-    = firstFree_;
-  firstFree_ = jobId;
-  MUTEX_UNLOCK(&deltaListLock_);
-  /* re-insert */
-  if (repeat > 0) {
-#if DEBUG_CRON
-    GE_LOG(NULL,
-          GE_STATUS | GE_DEVELOPER | GE_BULK,
-          "adding periodic job %p-%p to run again in %u\n",
-          method,
-          data,
-          repeat);
-#endif
-    addCronJob(method, repeat, repeat, data);
-  }
-  /* run */
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "running job %p-%p\n",
-        method,
-        data);
-#endif
-  method(data);
-  MUTEX_LOCK(&deltaListLock_);
-  runningJob_ = NULL;
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "job %p-%p done\n",
-        method,
-        data);
-#endif
-}
-
-/**
- * The main-method of cron.
- */
-static void * cron(void * unused) {
-  cron_t now;
-  cron_t next;
-
-  while (cron_shutdown == NO) {
-#if HAVE_PRINT_CRON_TAB
-    printCronTab();
-#endif
-    cronTime(&now);
-    next = now + 0xFFFFFFFF;
-    MUTEX_LOCK(&deltaListLock_);
-    while (firstUsed_ != -1) {
-      cronTime(&now);
-      next = deltaList_[firstUsed_].delta;
-      if (next <= now) {
-#if DEBUG_CRON
-       LOG(LOG_CRON,
-           "running cron job, table is\n");
-       printCronTab();
-#endif
-       runJob();
-#if DEBUG_CRON
-       GE_LOG(NULL,
-              GE_STATUS | GE_DEVELOPER | GE_BULK,
-              "job run, new table is\n");
-       printCronTab();
-#endif
-      } else
-       break;
-    }
-    MUTEX_UNLOCK(&deltaListLock_);
-    next = next - now; /* how long to sleep */
-#if DEBUG_CRON
-    GE_LOG(NULL,
-          GE_STATUS | GE_DEVELOPER | GE_BULK,
-          "Sleeping at %llu for %llu CU (%llu s, %llu CU)\n",
-          now,
-          next,
-          next / cronSECONDS,
-          next);
-#endif
-    if (next > MAXSLEEP)
-      next = MAXSLEEP;
-    if (cron_shutdown == NO) 
-      gnunet_util_sleep(next);
-#if DEBUG_CRON
-    GE_LOG(NULL,
-          GE_STATUS | GE_DEVELOPER | GE_BULK,
-          "woke up at  %llu - %lld CS late\n",
-          cronTime(NULL),
-          cronTime(NULL)-(now+next));
-#endif
-  }
-  SEMAPHORE_UP(cron_signal);
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "Cron thread exits.\n");
-  printCronTab();
-#endif
-  return NULL;
-}
-
-
-/**
- * Make sure to call stopCron before calling this method!
- */
-void doneCron() {
-  int i;
-
-  i = firstUsed_;
-  while (i != -1) {
-    FREENONNULL(deltaList_[i].data);
-    i = deltaList_[i].next;
-  }
-  MUTEX_DESTROY(&deltaListLock_);
-  MUTEX_DESTROY(&inBlockLock_);
-  FREE(deltaList_);
-  SEMAPHORE_FREE(cron_signal_up);
-  deltaList_ = NULL;
-}
-
-/**
- * Start the cron jobs.
- */
-void startCron() {
-  GE_ASSERT(NULL, cron_signal == NULL);
-  cron_shutdown = NO;
-  cron_signal = SEMAPHORE_NEW(0);
-  /* large stack, we don't know for sure
-     what the cron jobs may be doing */
-  if (0 != PTHREAD_CREATE(&cron_handle,
-                         &cron,
-                         NULL,
-                         256 * 1024))
-    GE_DIE_STRERROR(NULL, 
-                   GE_FATAL | GE_ADMIN | GE_USER | GE_BULK, 
-                   "pthread_create");
-}
-
-
-/**
- * Remove all matching cron-jobs from the list. This method should
- * only be called while cron is suspended or stopped, or from a cron
- * job that deletes another cron job.  If cron is not suspended or
- * stopped, it may be running the method that is to be deleted, which
- * could be bad (in this case, the deletion will not affect the
- * running job and may return before the running job has terminated).
- *
- * @param method which method is listed?
- * @param repeat which repeat factor was chosen?
- * @param data what was the data given to the method
- * @return the number of jobs removed
- */
-int delCronJob(CronJob method,
-              unsigned int repeat,
-              void * data) {
-  UTIL_cron_DeltaListEntry * job;
-  UTIL_cron_DeltaListEntry * last;
-  int jobId;
-
-#if DEBUG_CRON
-  GE_LOG(NULL,
-        GE_STATUS | GE_DEVELOPER | GE_BULK,
-        "deleting job %p-%p\n",
-        method,
-        data);
-#endif
-  MUTEX_LOCK(&deltaListLock_);
-  jobId = firstUsed_;
-  if (jobId == -1) {
-    MUTEX_UNLOCK(&deltaListLock_);
-    return 0;
-  }
-  last = NULL;
-  job = &deltaList_[jobId];
-  while ( (job->method != method) ||
-         (job->data != data) ||
-         (job->deltaRepeat != repeat) ) {
-    last = job;
-    if (job->next == -1) {
-      MUTEX_UNLOCK(&deltaListLock_);
-      return 0;
-    }
-    jobId = job->next;
-    job = &deltaList_[jobId];
-  }
-  if (last != NULL)
-    last->next = job->next;
-  else
-    firstUsed_ = job->next;
-  job->next
-    = firstFree_;
-  firstFree_ = jobId;
-  job->method = NULL;
-  job->data = NULL;
-  job->deltaRepeat = 0;
-  MUTEX_UNLOCK(&deltaListLock_);
-  /* ok, there may be more matches, go again! */
-  return 1 + delCronJob(method, repeat, data);
-}
-
-/* end of cron.c */

Deleted: GNUnet/src/util/crontest.c
===================================================================
--- GNUnet/src/util/crontest.c  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/crontest.c  2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,105 +0,0 @@
-/**
- * @file test/crontest.c
- * @brief Testcase for cron.
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-static int global;
-static int global2;
-static int global3;
-
-/**
- * Initialize controlThread.
- */
-void initCron();
-
-/**
- * Make sure to call stopCron before calling this method!
- */
-void doneCron();
-
-/**
- * Process the cron-job at the beginning of the waiting
- * queue, that is, remove, invoke, and re-insert if
- * it is a periodical job. Make sure the sync is down
- * while the job is running (it may add other jobs!)
- */
-void runJob();
-
-static void cronJob(void * unused) {
-  global++;
-}
-static void cronJob2(void * unused) {
-  global2++;
-}
-static void cronJob3(void * unused) {
-  global3++;
-}
-
-int testCron() {
-  int i;
-
-  global = -1;
-  global2 = -1;
-  global3 = -1;
-  addCronJob(&cronJob, cronSECONDS*1, cronSECONDS*1, NULL);
-  addCronJob(&cronJob2, cronSECONDS*4, cronSECONDS*4, NULL);
-  addCronJob(&cronJob3, cronSECONDS*16, cronSECONDS*16, NULL);
-  for (i=0;i<10;i++) {
-    /*    fprintf(stderr,"."); */
-    sleep(1);
-    if (((global-i) * (global-i)) > 9) {
-      fprintf(stderr,"1: Expected %d got %d\n", i, global);
-      return 1;
-    }
-    if (((global2-(i>>2)) * (global2-(i>>2))) > 9) {
-      fprintf(stderr,"2: Expected %d got %d\n", i>>2, global2);
-      return 1;
-    }
-    if (((global3-(i>>4)) * (global3-(i>>4))) > 9) {
-      fprintf(stderr,"3: Expected %d got %d\n", i>>4, global3);
-      return 1;
-    }
-  }
-  delCronJob(&cronJob, cronSECONDS*1, NULL);
-  delCronJob(&cronJob2, cronSECONDS*4, NULL);
-  delCronJob(&cronJob3, cronSECONDS*16, NULL);
-  return 0;
-}
-
-static void delJob() {
-  delCronJob(&cronJob, 42, NULL);
-}
-
-static int testDelCron() {
-  global = 0;
-  addCronJob(&cronJob, cronSECONDS*1, 42, NULL);
-  addCronJob(&delJob, 500 * cronMILLIS, 0, NULL);
-  sleep(1);
-  if (global != 0) {
-    fprintf(stderr,
-           "cron job was supposed to be deleted, but ran anyway!\n");
-    return 1;
-  } else
-    return 0;
-}
-
-int main(int argc, char * argv[]) {
-  int failureCount = 0;
-
-  initCron();
-  startCron();
-  failureCount += testCron();
-  failureCount += testDelCron();
-  stopCron();
-  doneCron();
-  if (failureCount == 0)
-    return 0;
-  else {
-    printf("\n\n%d TESTS FAILED!\n\n",failureCount);
-    return -1;
-  }
-} /* end of main */

Modified: GNUnet/src/util/crypto/locking_gcrypt.c
===================================================================
--- GNUnet/src/util/crypto/locking_gcrypt.c     2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/util/crypto/locking_gcrypt.c     2006-06-22 17:50:56 UTC (rev 
3024)
@@ -39,7 +39,7 @@
   MUTEX_UNLOCK(&gcrypt_shared_lock);
 }
 
-void __attribute__ ((constructor)) gnunet_crypto_ltdl_init(void) {
+void __attribute__ ((constructor)) gnunet_crypto_ltdl_init() {
   MUTEX_CREATE_RECURSIVE(&gcrypt_shared_lock);
   gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
   if (! gcry_check_version(GCRYPT_VERSION)) {
@@ -56,6 +56,6 @@
 #endif
 }
 
-void __attribute__ ((destructor)) gnunet_crypto_ltdl_fini(void) {
+void __attribute__ ((destructor)) gnunet_crypto_ltdl_fini() {
   MUTEX_DESTROY(&gcrypt_shared_lock);
 }

Deleted: GNUnet/src/util/daemon.c
===================================================================
--- GNUnet/src/util/daemon.c    2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/daemon.c    2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,336 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2005 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file src/util/daemon.c
- * @brief code for client-gnunetd interaction (start, stop, waitpid, check 
running)
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_util.h"
-#include "gnunet_protocols.h"
-
-
-/**
- * Checks if gnunetd is running
- *
- * Uses CS_PROTO_traffic_COUNT query to determine if gnunetd is
- * running.
- *
- * @return OK if gnunetd is running, SYSERR if not
- */
-int checkGNUnetDaemonRunning(struct GE_Context * ectx) {
-  GNUNET_TCP_SOCKET * sock;
-  CS_MESSAGE_HEADER csHdr;
-  int ret;
-
-  sock = getClientSocket(ectx);
-  if (sock == NULL) 
-    return SYSERR;
-
-  csHdr.size
-    = htons(sizeof(CS_MESSAGE_HEADER));
-  csHdr.type
-    = htons(CS_PROTO_traffic_COUNT);
-  if (SYSERR == writeToSocket(sock,
-                              &csHdr)) {
-    releaseClientSocket(sock);
-    return SYSERR;
-  }
-  if (SYSERR == readTCPResult(sock,
-                             &ret)) {
-    releaseClientSocket(sock);
-    return SYSERR;
-  }
-  releaseClientSocket(sock);
-  return OK;
-}
-
-
-#if LINUX || OSX || SOLARIS || SOMEBSD
-/**
- * Fork a gnunetd process
- *
- * @param daemonize YES if gnunetd should be daemonized
- * @return pid_t of gnunetd if NOT daemonized, 0 if
- *  daemonized sucessfully, -1 on error
- */
-static pid_t launchWithExec(int daemonize) {
-  pid_t pid;
-
-  pid = fork();
-  if (pid == 0) {
-    char * args[5];
-    char * path;
-    char * cp;
-
-    path = NULL;
-    cp = getConfigurationString("MAIN",
-                               "ARGV[0]");
-    if (cp != NULL) {
-      int i = strlen(cp);
-      while ( (i >= 0) &&
-             (cp[i] != DIR_SEPARATOR) )
-       i--;
-      if ( i != -1 ) {
-       cp[i+1] = '\0';
-       path = MALLOC(i+2+strlen("gnunetd"));
-       strcpy(path, cp);
-       strcat(path, "gnunetd");
-       if (ACCESS(path, X_OK) == 0) {
-         args[0] = path;
-       } else {
-         FREE(path);
-         path = NULL;
-         args[0] = "gnunetd";
-       }
-       FREE(cp);
-      } else {
-       args[0] = "gnunetd";
-      }
-    }
-    cp = getConfigurationString("GNUNET",
-                               "GNUNETD-CONFIG");
-    if (cp != NULL) {
-      args[1] = "-c";
-      args[2] = cp;
-      if (NO == daemonize) {
-       args[3] = "-d";
-       args[4] = NULL;
-      } else
-       args[3] = NULL;
-    } else {
-      if (NO == daemonize) {
-       args[1] = "-d";
-       args[2] = NULL;
-      } else
-       args[1] = NULL;
-    }
-    errno = 0;
-    nice(10); /* return value is not well-defined */
-    if (errno != 0)
-      LOG_STRERROR(LOG_WARNING, "nice");
-    if (path != NULL)
-      execv(path,
-           args);
-    else
-      execvp("gnunetd",
-            args);
-    LOG_STRERROR(LOG_FAILURE, "exec");
-    LOG(LOG_FAILURE,
-       _("Attempted path to `%s' was `%s'.\n"),
-       "gnunetd",
-       (path == NULL) ? "gnunetd" : path);
-    FREENONNULL(path); /* yeah, right, like we're likely to get
-                         here... */
-    _exit(-1);
-  } else if (daemonize) {
-    pid_t ret;
-    int status;
-
-    ret = waitpid(pid, &status, 0);
-    if (ret == -1) {
-      LOG_STRERROR(LOG_ERROR, "waitpid");
-      return SYSERR;
-    }
-    if ( (WIFEXITED(status) &&
-         (0 != WEXITSTATUS(status)) ) ) {
-      return SYSERR;
-    }
-#ifdef WCOREDUMP
-    if (WCOREDUMP(status)) {
-      return SYSERR;
-    }
-#endif
-    if (WIFSIGNALED(status) ||
-       WTERMSIG(status) ) {
-      return SYSERR;
-    }
-    return 0;
-  }
-  return pid;
-}
-#endif
-
-/**
- * Start gnunetd process
- *
- * @param daemonize YES if gnunetd should be daemonized
- * @return pid_t of gnunetd if NOT daemonized, 0 if
- *  daemonized sucessfully, -1 on error
- */
-int startGNUnetDaemon(int daemonize) {
-#if LINUX || OSX || SOLARIS || SOMEBSD
-  return launchWithExec(daemonize);
-#elif MINGW
-  char szCall[_MAX_PATH + 1], szWd[_MAX_PATH + 1], szCWd[_MAX_PATH + 1];
-  char *args[1], *cp = NULL;
-  int pid;
-  int idx = 0;
-
-  plibc_conv_to_win_path("/bin/gnunetd.exe", szCall);
-  plibc_conv_to_win_path("/bin", szWd);
-  _getcwd(szCWd, _MAX_PATH);
-
-  chdir(szWd);
-
-  if (daemonize == NO) {
-       args[0] = "-d";
-               idx = 1;
-
-    cp = getConfigurationString("GNUNET",
-                               "GNUNETD-CONFIG");
-               if (cp) {
-                       args[1] = "-c";
-                       args[2] = cp;
-                       idx=3;
-               }               
-  }
-
-  args[idx] = NULL;
-  pid = spawnvp(_P_NOWAIT, szCall, (const char *const *) args);
-  chdir(szCWd);
-
-  FREENONNULL(cp);
-
-  return (daemonize == NO) ? pid : 0;
-#else
-  /* any system out there that does not support THIS!? */
-  system("gnunetd"); /* we may not have nice,
-                       so let's be minimalistic here. */
-  return 0;
-#endif
-}
-
-
-/**
- * Stop gnunetd
- *
- * Note that returning an error does NOT mean that
- * gnunetd will continue to run (it may have been
- * shutdown by something else in the meantime or
- * crashed).  Call checkDaemonRunning() frequently
- * to check the status of gnunetd.
- *
- * Furthermore, note that this WILL potentially kill
- * gnunetd processes on remote machines that cannot
- * be restarted with startGNUnetDaemon!
- *
- * This function does NOT need the PID and will also
- * kill daemonized gnunetd's.
- *
- * @return OK successfully stopped, SYSERR: error
- */
-int stopGNUnetDaemon() {
-  GNUNET_TCP_SOCKET * sock;
-  CS_MESSAGE_HEADER csHdr;
-  int ret;
-
-  sock = getClientSocket();
-  if (sock == NULL)
-    return SYSERR;
-  csHdr.size
-    = htons(sizeof(CS_MESSAGE_HEADER));
-  csHdr.type
-    = htons(CS_PROTO_SHUTDOWN_REQUEST);
-  if (SYSERR == writeToSocket(sock,
-                             &csHdr)) {
-    releaseClientSocket(sock);
-    return SYSERR;
-  }
-  if (SYSERR == readTCPResult(sock,
-                             &ret)) {
-    releaseClientSocket(sock);
-    return SYSERR;
-  }
-  releaseClientSocket(sock);
-  return ret;
-}
-
-/**
- * Wait until the gnunet daemon is
- * running.
- *
- * @param timeout how long to wait at most
- * @return OK if gnunetd is now running
- */
-int waitForGNUnetDaemonRunning(cron_t timeout) {
-  timeout += cronTime(NULL);
-  while (OK != checkGNUnetDaemonRunning()) {
-    gnunet_util_sleep(100 * cronMILLIS);
-    if (timeout < cronTime(NULL))
-      return checkGNUnetDaemonRunning();
-  }
-  return OK;
-}
-
-/**
- * Wait until the gnunet daemon (or any other CHILD process for that
- * matter) with the given PID has terminated.  Assumes that
- * the daemon was started with startGNUnetDaemon in no-daemonize mode.
- * On arbitrary PIDs, this function may fail unexpectedly.
- *
- * @return YES if gnunetd shutdown with
- *  return value 0, SYSERR if waitpid
- *  failed, NO if gnunetd shutdown with
- *  some error
- */
-int waitForGNUnetDaemonTermination(int pid) {
-  pid_t p;
-  int status;
-
-  p = pid;
-  if (p != WAITPID(p, &status, 0)) {
-    LOG_STRERROR(LOG_ERROR, "waitpid");
-    return SYSERR;
-  }
-  if (WEXITSTATUS(status) == 0)
-    return YES;
-  else
-    return NO;
-}
-
-int termProcess(int pid) {
-#ifndef MINGW
-  return kill(pid, SIGTERM) == 0;
-#else
-  int ret;
-  DWORD dwExitCode = 0;
-  
-  HANDLE hProc = OpenProcess(1, 0, pid);
-  GenerateConsoleCtrlEvent(CTRL_C_EVENT, pid);
-  
-  WaitForSingleObject(hProc, 3000);
-  
-  GetExitCodeProcess(hProc, &dwExitCode);
-  if(dwExitCode == STILL_ACTIVE) {
-    ret = TerminateProcess(hProc, 0);
-  }
-  else
-    ret = 1;
-  
-  CloseHandle(hProc);
-  
-  return ret;
-#endif
-}
-
-/* end of daemon.c */

Deleted: GNUnet/src/util/daemontest.c
===================================================================
--- GNUnet/src/util/daemontest.c        2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/daemontest.c        2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,61 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2005 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-/**
- * @file test/daemontest.c
- * @brief Testcase for the daemon functions
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "_MAGIC_",
-                                    "NO"));
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGFILE",
-                                    NULL));
-  FREENONNULL(setConfigurationString("GNUNET",
-                                    "LOGLEVEL",
-                                    "NOTHING"));
-  FREENONNULL(setConfigurationString("GNUNET",
-                                    "GNUNETD-CONFIG",
-                                    "check.conf"));
-  return OK;
-}
-
-int main(int argc, char *argv[]) {
-  int daemon;
-
-  if (OK != initUtil(argc,
-                    argv,
-                    &parseCommandLine))
-    return -1;
-  daemon = startGNUnetDaemon(NO);
-  GNUNET_ASSERT(daemon > 0);
-  GNUNET_ASSERT(OK == waitForGNUnetDaemonRunning(30 * cronSECONDS));
-  GNUNET_ASSERT(OK == stopGNUnetDaemon());
-  GNUNET_ASSERT(OK == waitForGNUnetDaemonTermination(daemon));
-  doneUtil();
-  return 0;
-}
-
-/* end of deamontest.c */

Added: GNUnet/src/util/disk/Makefile.am
===================================================================
--- GNUnet/src/util/disk/Makefile.am    2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/disk/Makefile.am    2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,18 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+SUBDIRS = .
+
+noinst_LTLIBRARIES = \
+  libdisk.la
+
+libdisk_la_SOURCES = \
+  storage.c
+
+check_PROGRAMS = \
+ storagetest 
+
+storagetest_SOURCES = \
+ storagetest.c
+storagetest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  
+

Added: GNUnet/src/util/disk/storage.c
===================================================================
--- GNUnet/src/util/disk/storage.c      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/disk/storage.c      2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,695 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2005, 2006 Christian Grothoff (and other contributing 
authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/disk/storage.c
+ * @brief disk IO convenience methods
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util_string.h"
+#include "gnunet_util_disk.h"
+
+
+
+#if LINUX || CYGWIN
+#include <sys/vfs.h>
+#else
+#ifdef SOMEBSD
+#include <sys/param.h>
+#include <sys/mount.h>
+#else
+#ifdef OSX
+#include <sys/param.h>
+#include <sys/mount.h>
+#else
+#ifdef SOLARIS
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#else
+#ifdef MINGW
+#define                _IFMT           0170000 /* type of file */
+#define                _IFLNK          0120000 /* symbolic link */
+#define        S_ISLNK(m)      (((m)&_IFMT) == _IFLNK)
+#else
+#error PORT-ME: need to port statfs (how much space is left on the drive?)
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#ifndef SOMEBSD
+ #ifndef WINDOWS
+  #ifndef OSX
+   #include <wordexp.h>
+  #endif
+ #endif
+#endif
+
+typedef struct {
+  struct GE_Context * ectx;
+  unsigned long long total;
+  int include_sym_links;
+} GetFileSizeData;
+
+static int getSizeRec(const char * filename,
+                     const char * dirname,
+                     void * ptr) {
+  GetFileSizeData * gfsd = ptr;
+#ifdef HAVE_STAT64
+  struct stat64 buf;
+#else
+  struct stat buf;
+#endif
+  char * fn;
+
+  GE_ASSERT(gfsd->ectx, filename != NULL);
+  if ( (dirname != NULL) &&
+       (strlen(dirname) > 0) ) {
+    fn = MALLOC(strlen(filename) + strlen(dirname) + 3);
+    if (strlen(dirname) > 0) {
+      strcpy(fn, dirname);
+      if (dirname[strlen(dirname)-1] != DIR_SEPARATOR)
+       strcat(fn, DIR_SEPARATOR_STR); /* add tailing / if needed */
+    }
+    /* Windows paths don't start with / */
+#ifndef MINGW
+    else
+      strcpy(fn, DIR_SEPARATOR_STR);
+#endif
+    if (filename[0] == DIR_SEPARATOR)
+      /* if filename starts with a "/", don't copy it */
+      strcat(fn, &filename[1]);
+    else
+      strcat(fn, filename);
+  } else
+    fn = STRDUP(filename);
+
+#ifdef HAVE_STAT64
+  if (0 != STAT64(fn, &buf)) {
+#else
+  if (0 != STAT(fn, &buf)) {
+#endif
+    GE_LOG_STRERROR_FILE(gfsd->ectx,
+                        GE_WARNING | GE_USER | GE_REQUEST,
+                        "stat",
+                        fn);
+    FREE(fn);
+    return SYSERR;
+  }
+  if ( (! S_ISLNK(buf.st_mode)) ||
+       (gfsd->include_sym_links == YES) )
+    gfsd->total += buf.st_size;
+  if ( (S_ISDIR(buf.st_mode)) &&
+       ( (!S_ISLNK(buf.st_mode)) ||
+        (gfsd->include_sym_links == YES) ) ) {
+    if (SYSERR ==
+       disk_directory_scan(gfsd->ectx,
+                           fn,
+                           &getSizeRec,
+                           gfsd)) {
+      FREE(fn);
+      return SYSERR;
+    }
+  }
+  FREE(fn);
+  return OK;
+}
+
+/**
+ * Get the size of the file (or directory)
+ * of the given file (in bytes).
+ *
+ * @return SYSERR on error, OK on success
+ */
+int disk_file_size(struct GE_Context * ectx,
+                  const char * filename,
+                  unsigned long long * size,
+                  int includeSymLinks) {
+  GetFileSizeData gfsd;
+  int ret;
+
+  GE_ASSERT(ectx, size != NULL);
+  gfsd.ectx = ectx;
+  gfsd.total = 0;
+  gfsd.include_sym_links = includeSymLinks;
+  ret = getSizeRec(filename, "", &gfsd);
+  *size = gfsd.total;
+  return ret;
+}
+
+/**
+ * Get the number of blocks that are left on the partition that
+ * contains the given file (for normal users).
+ *
+ * @param part a file on the partition to check
+ * @return -1 on errors, otherwise the number of free blocks
+ */
+long disk_get_blocks_available(struct GE_Context * ectx,
+                              const char * part) {
+#ifdef SOLARIS
+  struct statvfs buf;
+
+  if (0 != statvfs(part, &buf)) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_ADMIN | GE_BULK, 
+                        "statfs",
+                        part);
+    return -1;
+  }
+  return buf.f_bavail;
+#elif MINGW
+  DWORD dwDummy;
+  DWORD dwBlocks;
+  char szDrive[4];
+
+  memcpy(szDrive, part, 3);
+  szDrive[3] = 0;
+  if (!GetDiskFreeSpace(szDrive, 
+                       &dwDummy,
+                       &dwDummy, 
+                       &dwBlocks,
+                       &dwDummy)) {
+    GE_LOG(ectx,
+          GE_WARNING | GE_USER | GE_ADMIN | GE_BULK,
+          _("`%s' failed for drive `%s': %u\n"),
+          "GetDiskFreeSpace",
+          szDrive, 
+          GetLastError());
+
+    return -1;
+  }
+  return dwBlocks;
+#else
+  struct statfs s;
+  if (0 != statfs(part, &s)) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_ADMIN | GE_BULK,
+                        "statfs",
+                        part);
+    return -1;
+  }
+  return s.f_bavail;
+#endif
+}
+
+/**
+ * Test if fil is a directory.
+ *
+ * @return YES if yes, NO if not, SYSERR if it 
+ *   does not exist
+ */
+int disk_directory_test(struct GE_Context * ectx,
+                       const char * fil) {
+  struct stat filestat;
+  int ret;
+
+  ret = STAT(fil, &filestat);
+  if (ret != 0) {
+    if (errno != ENOENT) {
+      GE_LOG_STRERROR_FILE(ectx,
+                          GE_WARNING | GE_USER | GE_ADMIN | GE_REQUEST, 
+                          "stat",
+                          fil);
+      return SYSERR;
+    }
+    return NO;
+  }
+  if (!S_ISDIR(filestat.st_mode)) {
+    GE_LOG(ectx,
+          GE_WARNING | GE_USER | GE_ADMIN | GE_REQUEST, 
+          _("Expected `%s' to be a directory\n"),
+          fil);
+    return SYSERR;
+  }
+  if (ACCESS(fil, R_OK | X_OK) < 0 ) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_ADMIN | GE_REQUEST, 
+                        "access", 
+                        fil);
+    return SYSERR;
+  }
+  return YES;
+}
+
+/**
+ * Assert that fil corresponds to a filename
+ * (of a file that exists and that is not a directory).
+ * @returns 1 if yes, 0 if not (will print an error
+ * message in that case, too).
+ */
+int disk_file_test(struct GE_Context * ectx,
+                  const char * fil) {
+  struct stat filestat;
+  int ret;
+
+  ret = STAT(fil, &filestat);
+  if (ret != 0) {
+    if (errno != ENOENT) {
+      GE_LOG_STRERROR_FILE(ectx,
+                          GE_WARNING | GE_USER | GE_ADMIN | GE_REQUEST, 
+                          "stat",
+                          fil);
+      return SYSERR;
+    }
+    return NO;
+  }
+  if (!S_ISREG(filestat.st_mode)) {
+    GE_LOG(ectx,
+          GE_WARNING | GE_USER | GE_ADMIN | GE_REQUEST, 
+          _("Expected `%s' to be a regular file\n"),
+          fil);
+    return SYSERR;
+  }
+  if (ACCESS(fil, R_OK) < 0 ) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_ADMIN | GE_REQUEST, 
+                        "access", 
+                        fil);
+    return SYSERR;
+  }
+  return YES;
+}
+
+/**
+ * Implementation of "mkdir -p"
+ * @param dir the directory to create
+ * @returns OK on success, SYSERR on failure
+ */
+int disk_directory_create(struct GE_Context * ectx,
+                         const char * dir) {
+  char * rdir;
+  int len;
+  int pos;
+  int ret = OK;
+
+  rdir = string_expandFileName(ectx,
+                              dir);
+  if (rdir == NULL)
+    return SYSERR;
+  len = strlen(rdir);
+#ifndef MINGW
+  pos = 1; /* skip heading '/' */
+#else
+  /* Local or Network path? */
+  if (strncmp(rdir, "\\\\", 2) == 0) {
+    pos = 2;
+    while (rdir[pos]) {
+      if (rdir[pos] == '\\') {
+        pos++;
+        break;
+      }
+      pos++;
+    }
+  } else {
+    pos = 3;  /* strlen("C:\\") */
+  }
+#endif
+  while (pos <= len) {
+    if ( (rdir[pos] == DIR_SEPARATOR) ||
+        (pos == len) ) {
+      rdir[pos] = '\0';
+      ret = disk_directory_test(ectx, rdir);
+      if (ret == SYSERR) {
+       FREE(rdir);
+       return SYSERR;
+      }
+      if (ret == NO) {
+#ifndef MINGW
+       ret = mkdir(rdir,
+                   S_IRUSR | S_IWUSR |
+                   S_IXUSR | S_IRGRP |
+                   S_IXGRP | S_IROTH |
+                   S_IXOTH); /* 755 */
+#else
+       ret = mkdir(rdir);
+#endif
+       if ( (ret != 0) &&
+            (errno != EEXIST) ) {
+         GE_LOG_STRERROR_FILE(ectx,
+                              GE_ERROR | GE_USER | GE_BULK, 
+                              "mkdir", 
+                              rdir);
+         FREE(rdir);
+         return SYSERR;
+       }
+       rdir[pos] = DIR_SEPARATOR;
+      }
+    }
+    pos++;
+  }
+  FREE(rdir);
+  return ret;
+}
+
+/**
+ * Read the contents of a binary file into a buffer.
+ * @param fileName the name of the file, not freed,
+ *        must already be expanded!
+ * @param len the maximum number of bytes to read
+ * @param result the buffer to write the result to
+ * @return the number of bytes read on success, -1 on failure
+ */
+int disk_file_read(struct GE_Context * ectx,
+                  const char * fileName,
+                  int  len,
+                  void * result) {
+  /* open file, must exist, open read only */
+  int handle;
+  int size;
+
+  GE_ASSERT(ectx, fileName != NULL);
+  if (len == 0)
+    return 0;
+  GE_ASSERT(ectx, result != NULL);
+  handle = disk_file_open(ectx,
+                         fileName,
+                         O_RDONLY,
+                         S_IRUSR);
+  if (handle < 0)
+    return -1;
+  size = READ(handle, result, len);
+  disk_file_close(ectx, fileName, handle);
+  return size;
+}
+
+
+/**
+ * Convert string to value ('755' for chmod-call)
+ */
+static int atoo(const char *s) {
+  int n = 0;
+
+  while ( ('0' <= *s) && (*s < '8') ) {
+    n <<= 3;
+    n += *s++ - '0';
+  }
+  return n;
+}
+
+/**
+ * Write a buffer to a file.
+ * @param fileName the name of the file, NOT freed!
+ * @param buffer the data to write
+ * @param n number of bytes to write
+ * @param mode permissions to set on the file
+ * @return OK on success, SYSERR on error
+ */
+int disk_file_write(struct GE_Context * ectx,
+                   const char * fileName,
+                   const void * buffer,
+                   unsigned int n,
+                   const char * mode) {
+  int handle;
+
+  /* open file, open with 600, create if not
+     present, otherwise overwrite */
+  GE_ASSERT(ectx, fileName != NULL);
+
+  handle = disk_file_open(ectx,
+                         fileName,
+                         O_CREAT | O_WRONLY,
+                         S_IRUSR | S_IWUSR);
+  if (handle == -1)
+    return SYSERR;
+  GE_ASSERT(ectx, 
+           (n == 0) || (buffer != NULL));
+  /* write the buffer take length from the beginning */
+  if (n != WRITE(handle, buffer, n)) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_IMMEDIATE,
+                        "write",
+                        fileName);
+    disk_file_close(ectx, fileName, handle);
+    return SYSERR;
+  }
+  disk_file_close(ectx, fileName, handle);
+  if (0 != CHMOD(fileName,
+                atoo(mode))) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_BULK,
+                        "chmod",
+                        fileName);
+  }
+  return OK;
+}
+
+/**
+ * Scan a directory for files. The name of the directory
+ * must be expanded first (!).
+ * @param dirName the name of the directory
+ * @param callback the method to call for each file,
+ *        can be NULL, in that case, we only count
+ * @param data argument to pass to callback
+ * @return the number of files found, SYSERR on error or
+ *         ieration aborted by callback returning SYSERR
+ */
+int disk_directory_scan(struct GE_Context * ectx,
+                       const char * dirName,
+                       DirectoryEntryCallback callback,
+                       void * data) {
+  DIR * dinfo;
+  struct dirent *finfo;
+  struct stat istat;
+  int count = 0;
+
+  GE_ASSERT(ectx, dirName != NULL);
+  if (0 != STAT(dirName, &istat)) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_BULK,
+                        "stat",
+                        dirName);
+    return SYSERR;
+  }
+  if (!S_ISDIR(istat.st_mode)) {
+    GE_LOG(ectx,
+          GE_WARNING | GE_USER | GE_BULK,
+          _("expected `%s' to be a directory!\n"),
+          dirName);
+    return SYSERR;
+  }
+  errno = 0;
+  dinfo = OPENDIR(dirName);
+  if ( (errno == EACCES) || (dinfo == NULL)) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_BULK,
+                        "opendir",
+                        dirName);
+    return SYSERR;
+  }
+  while ((finfo = readdir(dinfo)) != NULL) {
+    if (finfo->d_name[0] == '.')
+      continue;
+    if (callback != NULL) {
+      if (OK != callback(finfo->d_name,
+                        dirName,
+                        data)) {
+       closedir(dinfo);
+       return SYSERR;
+      }
+    }  
+    count++;
+  }
+  closedir(dinfo);
+  return count;
+}
+
+/**
+ * Callback for disk_directory_remove
+ */
+static int rmHelper(const char * fil,
+                   const char * dir,
+                   void * ctx) {
+  struct GE_Context * ectx = ctx;
+  char * fn;
+  size_t n;
+
+  n = strlen(dir) + strlen(fil) + 2;
+  fn = MALLOC(n);
+  SNPRINTF(fn,
+          n,
+          "%s/%s",
+          dir,
+          fil);
+  if (SYSERR == disk_directory_remove(ectx,
+                                     fn)) {
+    FREE(fn);
+    return SYSERR;
+  }
+  FREE(fn);
+  return OK;
+}
+
+/**
+ * Remove all files in a directory (rm -rf). Call with
+ * caution.
+ *
+ *
+ * @param fileName the file to remove
+ * @return OK on success, SYSERR on error
+ */
+int disk_directory_remove(struct GE_Context * ectx,
+                         const char * fileName) {
+  if (UNLINK(fileName) == 0) 
+    return OK;
+  if ( (errno != EISDIR) &&
+       /* EISDIR is not sufficient in all cases, e.g.
+         sticky /tmp directory may result in EPERM on BSD.
+         So we also explicitly check "isDirectory" */
+       (YES != disk_directory_test(ectx, fileName)) ) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_ADMIN | GE_BULK,
+                        "rmdir",
+                        fileName);
+    return SYSERR;
+  }
+  if (SYSERR == disk_directory_scan(ectx,
+                                   fileName,
+                                   &rmHelper,
+                                   ectx)) 
+    return SYSERR;
+  if (0 != RMDIR(fileName)) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_ADMIN | GE_BULK,
+                        "rmdir",
+                        fileName);
+    return SYSERR;
+  }
+  return OK;
+}
+
+void disk_file_close(struct GE_Context * ectx,
+                    const char * filename,
+                    int fd) {
+  if (0 != CLOSE(fd)) 
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_BULK,
+                        "close",
+                        filename);
+}
+
+int disk_file_open(struct GE_Context * ectx,
+                  const char * filename,
+                  int oflag,
+                  ...) {
+  const char * fn;
+  int mode;
+  int ret;
+#ifdef MINGW
+  char szFile[_MAX_PATH + 1];
+  long lRet;
+
+  if ((lRet = plibc_conv_to_win_path(filename, 
+                                    szFile)) != ERROR_SUCCESS) {
+    errno = ENOENT;
+    SetLastError(lRet);
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_DEVELOPER | GE_ADMIN | 
GE_BULK,
+                        "plibc_conv_to_win_path",
+                        filename);
+    return -1;
+  }
+  fn = szFile;
+#else
+  fn = filename;
+#endif
+  if (oflag & O_CREAT) {
+    va_list arg;
+    va_start(arg, oflag);
+    mode = va_arg(arg, int);
+    va_end(arg);
+  } else {
+    mode = 0;
+  }
+#ifdef MINGW
+  /* set binary mode */
+  oflag |= O_BINARY;
+#endif
+  ret = open(fn, oflag, mode);
+  if (ret == -1) 
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_BULK,
+                        "open",
+                        filename);
+  return ret;
+}
+
+#define COPY_BLK_SIZE 65536
+
+/**
+ * Copy a file.
+ * @return OK on success, SYSERR on error
+ */
+int disk_file_copy(struct GE_Context * ectx,
+                  const char * src,
+                  const char * dst) {
+  char * buf;
+  unsigned long long pos;
+  unsigned long long size;
+  unsigned long long len;
+  int in;
+  int out;
+
+  if (OK != disk_file_size(ectx,
+                          src,
+                          &size,
+                          YES)) 
+    return SYSERR;
+  pos = 0;
+  in = disk_file_open(ectx,
+                     src,
+                     O_RDONLY | O_LARGEFILE);
+  if (in == -1) 
+    return SYSERR;
+  out = disk_file_open(ectx,
+                      dst,
+                      O_LARGEFILE | O_WRONLY | O_CREAT | O_EXCL,
+                      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+  if (out == -1) {
+    disk_file_close(ectx,
+                   src,
+                   in);
+    return SYSERR;
+  }
+  buf = MALLOC(COPY_BLK_SIZE);
+  while (pos < size) {
+    len = COPY_BLK_SIZE;
+    if (len > size - pos)
+      len = size - pos;
+    if (len != READ(in, buf, len))
+      goto FAIL;
+    if (len != WRITE(out, buf, len))
+      goto FAIL;
+    pos += len;
+  }
+  FREE(buf);
+  disk_file_close(ectx, src, in);
+  disk_file_close(ectx, dst, out);
+  return OK;
+ FAIL:
+  FREE(buf);
+  disk_file_close(ectx, src, in);
+  disk_file_close(ectx, dst, out);
+  return SYSERR;
+}
+
+/* end of storage.c */

Added: GNUnet/src/util/disk/storagetest.c
===================================================================
--- GNUnet/src/util/disk/storagetest.c  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/disk/storagetest.c  2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,54 @@
+/**
+ * @file test/storagetest.c
+ * @brief testcase for the storage module
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+#define TESTSTRING "Hello World\0"
+
+/**
+ * Perform option parsing from the command line.
+ */
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  return OK;
+}
+
+static int testReadWrite() {
+  HashCode512 ha;
+  EncName filename;
+  char tmp[100];
+
+  hash(TESTSTRING,
+       strlen(TESTSTRING),
+       &ha);
+  hash2enc(&ha, &filename);
+  writeFile((char*)&filename, TESTSTRING, strlen(TESTSTRING), "644");
+  tmp[readFile((char*)&filename, 100, tmp)] = '\0';
+  if (memcmp(tmp,TESTSTRING,strlen(TESTSTRING)+1) == 0)
+    return 0;
+  else {
+    fprintf(stderr,
+           "Error in testReadWrite: *%s* != *%s* for file %s\n",
+           tmp,TESTSTRING,(char*)&filename);
+    return 1;
+  }
+}
+
+int main(int argc, char * argv[]) {
+  int failureCount = 0;
+
+  initUtil(argc, argv, &parseCommandLine);
+  failureCount += testReadWrite();
+  doneUtil();
+  if (failureCount == 0)
+    return 0;
+  else {
+    fprintf(stderr,
+            "\n\n%d TESTS FAILED!\n\n",failureCount);
+    return -1;
+  }
+} /* end of main */

Deleted: GNUnet/src/util/dso.c
===================================================================
--- GNUnet/src/util/dso.c       2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/dso.c       2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,160 +0,0 @@
-/*
-     This file is part of GNUnet
-     (C) 2002, 2003, 2004, 2005 Christian Grothoff (and other contributing 
authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/dso.c
- * @brief Methods to access dynamic shared objects (DSOs).
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_util.h"
-
-static int using_valgrind;
-
-static char * old_dlsearchpath = NULL;
-
-/* using libtool, needs init! */
-void __attribute__ ((constructor)) gnc_ltdl_init(void) {
-  int err;
-
-  err = lt_dlinit ();
-  if (err > 0)
-    {
-#if DEBUG
-      fprintf(stderr,
-             _("Initialization of plugin mechanism failed: %s!\n"),
-             lt_dlerror());
-#endif
-      return;
-    }
-  if (lt_dlgetsearchpath() != NULL)
-    old_dlsearchpath = strdup(lt_dlgetsearchpath());
-  if (lt_dlgetsearchpath () == NULL)
-    lt_dladdsearchdir ("/usr/lib/GNUnet");
-  else if (strstr (lt_dlgetsearchpath (), "/usr/lib/GNUnet") == NULL)
-    lt_dladdsearchdir ("/usr/lib/GNUnet");
-  if (strstr (lt_dlgetsearchpath (), "/usr/local/lib/GNUnet") == NULL)
-    lt_dladdsearchdir ("/usr/local/lib/GNUnet");
-#ifdef PLUGIN_PATH
-  if (strstr (lt_dlgetsearchpath (), PLUGIN_PATH) == NULL)
-    lt_dladdsearchdir (PLUGIN_PATH);
-#endif
-}
-
-void __attribute__ ((destructor)) gnc_ltdl_fini(void) {
-  lt_dlsetsearchpath(old_dlsearchpath);
-  if (old_dlsearchpath != NULL) {
-    free(old_dlsearchpath);
-    old_dlsearchpath = NULL;
-  }
-  if (0 != using_valgrind)
-    lt_dlexit ();
-}
-
-
-static char * buildLibName(const char * prefix,
-                          const char * dso) {
-  char * libname;
-
-  libname = MALLOC(strlen(dso) +
-                  strlen(prefix) + 1);
-  libname[0] = '\0';
-  strcat(libname, prefix);
-  strcat(libname, dso);
-  return libname;
-}
-
-void * loadDynamicLibrary(const char * libprefix,
-                         const char * dsoname) {
-  void * libhandle;
-  char * libname;
-
-  if (0 != lt_dlinit())
-    DIE_STRERROR("lt_dlinit");
-  /* finally, load the library */
-  libname = buildLibName(libprefix,
-                        dsoname);
-  libhandle = lt_dlopenext(libname);
-  if (libhandle == NULL) {
-    LOG(LOG_ERROR,
-       _("`%s' failed for library `%s' at %s:%d with error: %s\n"),
-       "lt_dlopenext",
-       libname,
-       __FILE__, __LINE__,
-       lt_dlerror());
-  }
-  FREE(libname);
-  return libhandle;
-}
-
-void unloadDynamicLibrary(void * libhandle) {
-  /* when valgrinding, comment out these lines
-     to get decent traces for memory leaks on exit */
-  if (0 != getConfigurationInt("GNUNETD",
-                              "VALGRIND")) {
-    lt_dlclose(libhandle);
-    if (0 != lt_dlexit())
-      LOG_STRERROR(LOG_WARNING, "lt_dlexit");
-  } else
-    using_valgrind = 1;
-}
-
-void * trybindDynamicMethod(void * libhandle,
-                           const char * methodprefix,
-                           const char * dsoname) {
-  char * initName;
-  void * mptr;
-
-  initName = MALLOC(strlen(dsoname) +
-                   strlen(methodprefix) + 2);
-  initName[0] = '\0';
-  strcat(initName, "_");
-  strcat(initName, methodprefix);
-  strcat(initName, dsoname);
-  mptr = lt_dlsym(libhandle, &initName[1]);
-  if (mptr == NULL) {
-    /* try again with "_" prefix; some systems use that
-       variant. */
-    mptr = lt_dlsym(libhandle, initName);
-  }
-  FREE(initName);
-  return mptr;
-}
-
-void * bindDynamicMethod(void * libhandle,
-                        const char * methodprefix,
-                        const char * dsoname) {
-  void * mptr;
-
-  mptr = trybindDynamicMethod(libhandle,
-                             methodprefix,
-                             dsoname);
-  if (mptr == NULL)
-    LOG(LOG_ERROR,
-       _("`%s' failed to resolve method '%s%s' at %s:%d with error: %s\n"),
-       "lt_dlsym",
-       methodprefix, dsoname,
-       __FILE__, __LINE__,
-       lt_dlerror());
-  return mptr;
-}
-
-/* end of dso.c */                     

Deleted: GNUnet/src/util/endian.c
===================================================================
--- GNUnet/src/util/endian.c    2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/endian.c    2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,48 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2006 Christian Grothoff (and other 
contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/endian.c
- * @brief endian conversion helpers
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_util.h"
-
-unsigned long long ntohll(unsigned long long n) {
-#if __BYTE_ORDER == __BIG_ENDIAN
-  return n;
-#else
-  return (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32);
-#endif
-}
-
-unsigned long long htonll(unsigned long long n) {
-#if __BYTE_ORDER == __BIG_ENDIAN
-  return n;
-#else
-  return (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32);
-#endif
-}
-
-
-
-/* end of endian.c */

Modified: GNUnet/src/util/getopt/Makefile
===================================================================
--- GNUnet/src/util/getopt/Makefile     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/getopt/Makefile     2006-06-22 17:50:56 UTC (rev 3024)
@@ -14,7 +14,7 @@
 
 
 
-SOURCES = $(liberror_la_SOURCES)
+SOURCES = $(libgetopt_la_SOURCES)
 
 srcdir = .
 top_srcdir = ../../..
@@ -54,13 +54,17 @@
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-liberror_la_LIBADD =
-am_liberror_la_OBJECTS = error.lo
-liberror_la_OBJECTS = $(am_liberror_la_OBJECTS)
+libgetopt_la_LIBADD =
+am_libgetopt_la_OBJECTS = getopt.lo setoption.lo printhelp.lo \
+       printversion.lo
+libgetopt_la_OBJECTS = $(am_libgetopt_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
-DEP_FILES = ./$(DEPDIR)/error.Plo
+DEP_FILES = ./$(DEPDIR)/getopt.Plo \
+       ./$(DEPDIR)/printhelp.Plo \
+       ./$(DEPDIR)/printversion.Plo \
+       ./$(DEPDIR)/setoption.Plo
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
@@ -69,8 +73,8 @@
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(liberror_la_SOURCES)
-DIST_SOURCES = $(liberror_la_SOURCES)
+SOURCES = $(libgetopt_la_SOURCES)
+DIST_SOURCES = $(libgetopt_la_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
        html-recursive info-recursive install-data-recursive \
        install-exec-recursive install-info-recursive \
@@ -248,10 +252,13 @@
 INCLUDES = -I$(top_srcdir)/src/include
 SUBDIRS = .
 noinst_LTLIBRARIES = \
-  liberror.la
+  libgetopt.la
 
-liberror_la_SOURCES = \
-  error.c
+libgetopt_la_SOURCES = \
+  getopt.c \
+  setoption.c \
+  printhelp.c \
+  printversion.c 
 
 all: all-recursive
 
@@ -295,8 +302,8 @@
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-liberror.la: $(liberror_la_OBJECTS) $(liberror_la_DEPENDENCIES) 
-       $(LINK)  $(liberror_la_LDFLAGS) $(liberror_la_OBJECTS) 
$(liberror_la_LIBADD) $(LIBS)
+libgetopt.la: $(libgetopt_la_OBJECTS) $(libgetopt_la_DEPENDENCIES) 
+       $(LINK)  $(libgetopt_la_LDFLAGS) $(libgetopt_la_OBJECTS) 
$(libgetopt_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -304,7 +311,10 @@
 distclean-compile:
        -rm -f *.tab.c
 
-include ./$(DEPDIR)/error.Plo
+include ./$(DEPDIR)/getopt.Plo
+include ./$(DEPDIR)/printhelp.Plo
+include ./$(DEPDIR)/printversion.Plo
+include ./$(DEPDIR)/setoption.Plo
 
 .c.o:
        if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \

Modified: GNUnet/src/util/getopt/Makefile.in
===================================================================
--- GNUnet/src/util/getopt/Makefile.in  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/getopt/Makefile.in  2006-06-22 17:50:56 UTC (rev 3024)
@@ -14,7 +14,7 @@
 
 @SET_MAKE@
 
-SOURCES = $(liberror_la_SOURCES)
+SOURCES = $(libgetopt_la_SOURCES)
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -54,13 +54,17 @@
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-liberror_la_LIBADD =
-am_liberror_la_OBJECTS = error.lo
-liberror_la_OBJECTS = $(am_liberror_la_OBJECTS)
+libgetopt_la_LIBADD =
+am_libgetopt_la_OBJECTS = getopt.lo setoption.lo printhelp.lo \
+       printversion.lo
+libgetopt_la_OBJECTS = $(am_libgetopt_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
address@hidden@DEP_FILES = ./$(DEPDIR)/error.Plo
address@hidden@DEP_FILES = ./$(DEPDIR)/getopt.Plo \
address@hidden@ ./$(DEPDIR)/printhelp.Plo \
address@hidden@ ./$(DEPDIR)/printversion.Plo \
address@hidden@ ./$(DEPDIR)/setoption.Plo
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
@@ -69,8 +73,8 @@
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(liberror_la_SOURCES)
-DIST_SOURCES = $(liberror_la_SOURCES)
+SOURCES = $(libgetopt_la_SOURCES)
+DIST_SOURCES = $(libgetopt_la_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
        html-recursive info-recursive install-data-recursive \
        install-exec-recursive install-info-recursive \
@@ -248,10 +252,13 @@
 INCLUDES = -I$(top_srcdir)/src/include
 SUBDIRS = .
 noinst_LTLIBRARIES = \
-  liberror.la
+  libgetopt.la
 
-liberror_la_SOURCES = \
-  error.c
+libgetopt_la_SOURCES = \
+  getopt.c \
+  setoption.c \
+  printhelp.c \
+  printversion.c 
 
 all: all-recursive
 
@@ -295,8 +302,8 @@
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-liberror.la: $(liberror_la_OBJECTS) $(liberror_la_DEPENDENCIES) 
-       $(LINK)  $(liberror_la_LDFLAGS) $(liberror_la_OBJECTS) 
$(liberror_la_LIBADD) $(LIBS)
+libgetopt.la: $(libgetopt_la_OBJECTS) $(libgetopt_la_DEPENDENCIES) 
+       $(LINK)  $(libgetopt_la_LDFLAGS) $(libgetopt_la_OBJECTS) 
$(libgetopt_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -304,7 +311,10 @@
 distclean-compile:
        -rm -f *.tab.c
 
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 
 .c.o:
 @am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c 
-o $@ $<; \

Modified: GNUnet/src/util/getopt/getopt.c
===================================================================
--- GNUnet/src/util/getopt/getopt.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/getopt/getopt.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -32,8 +32,14 @@
 /**
  * @file util/getopt/getopt.c
  * @brief GNU style option parsing
+ *
+ * TODO: get rid of statics (make reentrant) and
+ * replace main GNU getopt parser with one that
+ * actually fits our API.
  */
 
+#include "gnunet_util_error.h"
+#include "gnunet_util_string.h"
 #include "gnunet_util_getopt.h"
 #include "platform.h"
 
@@ -147,7 +153,7 @@
    If this is zero, or a null string, it means resume the scan
    by advancing to the next ARGV-element.  */
 
-static static char *nextchar;
+static char *nextchar;
 
 /* Callers store zero here to inhibit the error message
    for unrecognized options.  */
@@ -966,25 +972,22 @@
   }
 }
 
-
 static int
-GNgetopt_long (argc, argv, options, long_options, opt_index)
-     int argc;
-     char *const *argv;
-     const char *options;
-     const struct GNoption *long_options;
-     int *opt_index;
-{
-  return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
+GNgetopt_long(int argc, 
+             const char ** argv, 
+             const char * options, 
+             const struct GNoption * long_options,
+             int * opt_index) {
+  return GN_getopt_internal(argc,
+                           argv, 
+                           options, 
+                           long_options,
+                           opt_index,
+                           0);
 }
 
-
 /* ******************** now the GNUnet specific modifications... 
********************* */
 
-
-
-
-
 /**
  * Parse the command line.
  *
@@ -994,8 +997,8 @@
  * @param allOptions defined options and handlers
  * @param argc number of arguments 
  * @param argv actual arguments
- * @return OK on success, SYSERR on error (bad options
- *   or command line handlers signal abort).
+ * @return index into argv with first non-option
+ *   argument, or -1 on error
  */
 int gnunet_parse_options(const char * binaryName,
                         struct GE_Context * ectx,
@@ -1004,12 +1007,21 @@
                         unsigned int argc,
                         const char ** argv) {
   struct GNoption * long_options;
+  CommandLineProcessorContext clpc;
   int count;
   int i;
   char * shorts;
   int spos;
   int cont;
+  int c;
 
+  GE_ASSERT(ectx, argc > 0);
+  clpc.binaryName = argv[0];
+  clpc.allOptions = allOptions;
+  clpc.argv = argv;
+  clpc.argc = argc;
+  clpc.ectx = ectx;
+  clpc.cfg  = cfg;
   count = 0;
   while (allOptions[count].name != NULL)
     count++;
@@ -1041,12 +1053,13 @@
                      long_options,
                      &option_index);
 
-    if (c == -1)
+    if (c == SYSERR)
       break;  /* No more flags to process */
     
     for (i=0;i<count;i++) {
-      if (c == allOptions[i].shortName) {
-       cont = allOptions[i].processor(mctx,
+      clpc.currentArgument = GNoptind - 1;
+      if ((char)c == allOptions[i].shortName) {
+       cont = allOptions[i].processor(&clpc,
                                       allOptions[i].scls,
                                       allOptions[i].name,
                                       GNoptarg);
@@ -1055,7 +1068,7 @@
     }
     if (i == count) {
       GE_LOG(ectx,
-            LOG_FAILURE | GE_USER | GE_IMMEDIATE,
+            GE_INFO | GE_USER | GE_IMMEDIATE,
             _("Use --help to get a list of options.\n"));
       cont = SYSERR;
     } 
@@ -1063,29 +1076,7 @@
 
   FREE(shorts);
   FREE(long_options);
-
-  if (GNoptind < argc) {
-    LOG(LOG_WARNING,
-       _("Invalid command-line arguments:\n"));
-    while (GNoptind < argc) {
-      LOG(LOG_WARNING,
-         _("Argument %d: `%s'\n"),
-         GNoptind+1,
-         argv[GNoptind]);
-      GNoptind++;
-    }
-    LOG(LOG_FATAL,
-       _("Invalid command-line arguments.\n"));
-    return SYSERR;
-  }
-
+  return GNoptind;
 }
 
-
-
-
-
-
-
-
 /* end of getopt.c */

Modified: GNUnet/src/util/getopt/printhelp.c
===================================================================
--- GNUnet/src/util/getopt/printhelp.c  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/getopt/printhelp.c  2006-06-22 17:50:56 UTC (rev 3024)
@@ -42,7 +42,7 @@
   int p;
   char * scp;
   const char * trans;
-  struct CommandLineOption * opt;
+  const struct CommandLineOption * opt;
        
   printf("%s",
         gettext(about));
@@ -55,7 +55,7 @@
       printf("      ");
     else
       printf("  -%c, ",
-            opt[i].shortArg);
+            opt[i].shortName);
     printf("--%s",
           opt[i].name);
     slen = 8 + strlen(opt[i].name);

Modified: GNUnet/src/util/getopt/setoption.c
===================================================================
--- GNUnet/src/util/getopt/setoption.c  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/getopt/setoption.c  2006-06-22 17:50:56 UTC (rev 3024)
@@ -32,7 +32,7 @@
 
 int gnunet_getopt_configure_set_option(CommandLineProcessorContext * ctx,
                                       void * scls,
-                                      const char * option,
+                                      const char * cmdLineOption,
                                       const char * value) {
   char * section = STRDUP(scls);
   struct GC_Configuration * cfg = ctx->cfg;
@@ -55,7 +55,7 @@
 
 int gnunet_getopt_configure_increment_value(CommandLineProcessorContext * ctx,
                                            void * scls,
-                                           const char * option,
+                                           const char * cmdLineOption,
                                            const char * value) {
   char * section = STRDUP(scls);
   struct GC_Configuration * cfg = ctx->cfg;

Deleted: GNUnet/src/util/io.c
===================================================================
--- GNUnet/src/util/io.c        2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/io.c        2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,359 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2003 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/io.c
- * @brief (network) input/output operations
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-/* some systems send us signals, so we'd better
-   catch them (& ignore) */
-#ifndef LINUX
-static void catcher(int sig) {
-  LOG(LOG_INFO,
-      _("Caught signal %d.\n"),
-      sig);
-  /* re-install signal handler! */
-  signal(sig, catcher);
-}
-
-
-#endif
-
-void gnunet_util_initIO() {
-#if ! (defined(LINUX) || defined(MINGW))
-  if ( SIG_ERR == signal(SIGPIPE, SIG_IGN))
-    if ( SIG_ERR == signal(SIGPIPE, catcher))
-      LOG_STRERROR(LOG_WARNING, "signal");
-#endif
-}
-
-void gnunet_util_doneIO() {
-}
-
-/**
- * Depending on doBlock, enable or disable the nonblocking mode
- * of socket s.
- *
- * @param doBlock use YES to change the socket to blocking, NO to non-blocking
- * @return Upon successful completion, it returns zero, otherwise -1
- */
-int setBlocking(int s, int doBlock) {
-#if MINGW
-  u_long l = !doBlock;
-  if (ioctlsocket(s, FIONBIO, &l) == SOCKET_ERROR) {
-    SetErrnoFromWinsockError(WSAGetLastError());
-
-    return -1;
-  } else {
-    /* store the blocking mode */
-    __win_SetHandleBlockingMode(s, doBlock);
-    return 0;
-  }
-#else
-  int flags = fcntl(s, F_GETFL);
-  if (doBlock)
-    flags &= ~O_NONBLOCK;
-  else
-    flags |= O_NONBLOCK;
-
-  return fcntl(s,
-              F_SETFL,
-              flags);
-#endif
-}
-
-/**
- * Check whether the socket is blocking
- * @param s the socket
- * @return YES if blocking, NO non-blocking
- */
-int isSocketBlocking(int s)
-{
-#ifndef MINGW
- return (fcntl(s, F_GETFL) & O_NONBLOCK) ? NO : YES;
-#else
-  return __win_IsHandleMarkedAsBlocking(s);
-#endif
-}
-
-/* recv wrappers */
-
-/**
- * Do a NONBLOCKING read on the given socket.  Note that in order to
- * avoid blocking, the caller MUST have done a select call before
- * calling this function. Though the caller must be prepared to the
- * fact that this function may fail with EWOULDBLOCK in any case (Win32).
- *
- * @brief Reads at most max bytes to buf. Interrupts are IGNORED.
- * @param s socket
- * @param buf buffer
- * @param max maximum number of bytes to read
- * @param read number of bytes actually read.
- *             0 is returned if no more bytes can be read
- * @return SYSERR on error, YES on success or NO if the operation
- *         would have blocked
- */
-int RECV_NONBLOCKING(int s,
-                    void * buf,
-                    size_t max,
-                    size_t *read) {
-  int flags;
-
-  setBlocking(s, NO);
-
-#ifdef CYGWIN
-    flags = MSG_NOSIGNAL;
-#elif OSX
-    flags = 0;
-#elif SOMEBSD || SOLARIS
-    flags = MSG_DONTWAIT;
-#elif LINUX
-    flags = MSG_DONTWAIT | MSG_NOSIGNAL;
-#else
-    /* good luck */
-    flags = 0;
-#endif
-
-  do {
-    *read = (size_t) RECV(s,
-                         buf,
-                         max,
-                         flags);
-  } while ( ( *read == -1) && ( errno == EINTR) );
-
-  setBlocking(s, YES);
-
-  if (*read == SYSERR && (errno == EWOULDBLOCK || errno == EAGAIN))
-    return NO;
-  else if ( (*read < 0) || (*read > max) )
-    return SYSERR;
-
-  return YES;
-}
-
-/**
- * Do a BLOCKING read on the given socket.  Read len bytes (if needed
- * try multiple reads).  Interrupts are ignored.
- *
- * @return SYSERR if len bytes could not be read,
- *   otherwise the number of bytes read (must be len)
- */
-int RECV_BLOCKING_ALL(int s,
-                     void * buf,
-                     size_t len) {
-  size_t pos;
-  int i, flags;
-
-  pos = 0;
-  setBlocking(s, YES);
-
-  while (pos < len) {
-#if LINUX || CYGWIN
-    flags = MSG_NOSIGNAL;
-#else
-    flags = 0;
-#endif
-
-    i = RECV(s,
-            &((char*)buf)[pos],
-            len - pos,
-            flags);
-
-    if ( (i == -1) && (errno == EINTR) )
-      continue;
-    if (i <= 0)
-    {
-      setBlocking(s, NO);
-      return SYSERR;
-    }
-    pos += i;
-  }
-  GNUNET_ASSERT(pos == len);
-
-  setBlocking(s, NO);
-
-  return pos;
-}
-
-/**
- * Do a NONBLOCKING write on the given socket.
- * Write at most max bytes from buf.
- * Interrupts are ignored (cause a re-try).
- *
- * The caller must be prepared to the fact that this function
- * may fail with EWOULDBLOCK in any case (Win32).
- *
- * @param s socket
- * @param buf buffer to send
- * @param max maximum number of bytes to send
- * @param sent number of bytes actually sent
- * @return SYSERR on error, YES on success or
- *         NO if the operation would have blocked.
- */
-int SEND_NONBLOCKING(int s,
-                    const void * buf,
-                    size_t max,
-                    size_t * sent) {
-  int flags;
-
-  setBlocking(s, NO);
-
-#ifdef SOMEBSD
-    flags = MSG_DONTWAIT;
-#elif SOLARIS
-    flags = MSG_DONTWAIT;
-#elif OSX
-    /* As braindead as Win32? */
-    flags = 0;
-#elif CYGWIN
-       flags = MSG_NOSIGNAL;
-#elif LINUX
-       flags = MSG_DONTWAIT | MSG_NOSIGNAL;
-#else
-    /* pray */
-       flags = 0;
-#endif
-
-  do {
-    *sent = (size_t) SEND(s,
-                         buf,
-                         max,
-                         flags);
-
-  } while ( (*sent == -1) &&
-           (errno == EINTR) );
-
-  setBlocking(s, YES);
-
-  if (*sent == SYSERR && (errno == EWOULDBLOCK || errno == EAGAIN))
-    return NO;
-  else if ( (*sent < 0) || (*sent > max) )
-    return SYSERR;
-
-  return YES;
-}
-
-/**
- * Do a BLOCKING write on the given socket.  Write len bytes (if
- * needed do multiple write).  Interrupts are ignored (cause a
- * re-try).
- *
- * @return SYSERR if len bytes could not be send,
- *   otherwise the number of bytes transmitted (must be len)
- */
-int SEND_BLOCKING_ALL(int s,
-                     const void * buf,
-                     size_t len) {
-  size_t pos;
-  int i, flags;
-
-  pos = 0;
-  setBlocking(s, YES);
-  while (pos < len) {
-#if CYGWIN || LINUX
-    flags = MSG_NOSIGNAL;
-#else
-    flags = 0;
-#endif
-    i = SEND(s,
-            &((char*)buf)[pos],
-            len - pos,
-            flags);
-
-    if ( (i == -1) &&
-        (errno == EINTR) )
-      continue; /* ingnore interrupts */
-    if (i <= 0) {
-      if (i == -1)
-       LOG_STRERROR(LOG_WARNING, "send");
-      return SYSERR;
-    }
-    pos += i;
-  }
-  setBlocking(s, NO);
-  GNUNET_ASSERT(pos == len);
-  return pos;
-}
-
-/**
- * Check if socket is valid
- * @return 1 if valid, 0 otherwise
- */
-int isSocketValid(int s)
-{
-#ifndef MINGW
-  struct stat buf;
-  return -1 != fstat(s, &buf);
-#else
-  long l;
-  return ioctlsocket(s, FIONREAD, &l) != SOCKET_ERROR;
-#endif
-}
-
-/**
- * Open a file
- */
-int fileopen(const char *filename, int oflag, ...)
-{
-  int mode;
-  char *fn;
-
-#ifdef MINGW
-  char szFile[_MAX_PATH + 1];
-  long lRet;
-
-  if ((lRet = plibc_conv_to_win_path(filename, szFile)) != ERROR_SUCCESS)
-  {
-    errno = ENOENT;
-    SetLastError(lRet);
-
-    return -1;
-  }
-  fn = szFile;
-#else
-  fn = (char *) filename;
-#endif
-
-  if (oflag & O_CREAT)
-  {
-    va_list arg;
-    va_start(arg, oflag);
-    mode = va_arg(arg, int);
-    va_end(arg);
-  }
-  else
-  {
-    mode = 0;
-  }
-
-#ifdef MINGW
-  /* Set binary mode */
-  oflag |= O_BINARY;
-#endif
-
-  return open(fn, oflag, mode);
-}
-
-/* end of io.c */

Deleted: GNUnet/src/util/ipcheck.c
===================================================================
--- GNUnet/src/util/ipcheck.c   2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/ipcheck.c   2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,325 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004 Christian Grothoff (and other contributing 
authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/ipcheck.c
- * @brief test if an IP matches a given subnet
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-/**
- * @brief IPV4 network in CIDR notation.
- */
-typedef struct CIDRNetwork {
-  IPaddr network;
-  IPaddr netmask;
-} CIDRNetwork;
-
-/**
- * @brief network in CIDR notation for IPV6.
- */
-typedef struct CIDR6Network {
-  IP6addr network;
-  IP6addr netmask;
-} CIDR6Network;
-
-
-/**
- * Parse a network specification. The argument specifies
- * a list of networks. The format is
- * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
- * with a semicolon). The network must be given in dotted-decimal
- * notation. The netmask can be given in CIDR notation (/16) or
- * in dotted-decimal (/255.255.0.0).
- * <p>
- * @param routeList a string specifying the forbidden networks
- * @return the converted list, NULL if the synatx is flawed
- */
-CIDRNetwork * parseRoutes(const char * routeList) {
-  unsigned int count;
-  unsigned int i;
-  unsigned int j;
-  unsigned int len;
-  int cnt;
-  unsigned int pos;
-  unsigned int temps[8];
-  int slash;
-  CIDRNetwork * result;
-
-  if (routeList == NULL)
-    return NULL;
-  len = strlen(routeList);
-  if (len == 0)
-    return NULL;
-  count = 0;
-  for (i=0;i<len;i++)
-    if (routeList[i] == ';')
-      count++;
-  result = MALLOC(sizeof(CIDRNetwork) * (count+1));
-  /* add termination */
-  memset(result,
-        0,
-        sizeof(CIDRNetwork)*(count+1));
-  i=0;
-  pos = 0;
-  while (i < count) {
-    cnt = sscanf(&routeList[pos],
-                "%u.%u.%u.%u/%u.%u.%u.%u;",
-                &temps[0],
-                &temps[1],
-                &temps[2],
-                &temps[3],
-                &temps[4],
-                &temps[5],
-                &temps[6],
-                &temps[7]);
-    if (cnt == 8) {
-      for (j=0;j<8;j++)
-       if (temps[j] > 0xFF) {
-         LOG(LOG_ERROR,
-             _("Invalid format for IP: `%s'\n"),
-             &routeList[pos]);
-         FREE(result);
-         return NULL;
-       }
-      result[i].network.addr
-       = htonl((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + 
temps[3]);
-      result[i].netmask.addr
-       = htonl((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) + 
temps[7]);
-      while (routeList[pos] != ';')
-       pos++;
-      pos++;
-      i++;
-      continue;
-    }
-    /* try second notation */
-    cnt = sscanf(&routeList[pos],
-                "%u.%u.%u.%u/%u;",
-                &temps[0],
-                &temps[1],
-                &temps[2],
-                &temps[3],
-                &slash);
-    if (cnt == 5) {
-      for (j=0;j<4;j++)
-       if (temps[j] > 0xFF) {
-         LOG(LOG_ERROR,
-             "wrong format for IP: %s\n",
-             &routeList[pos]);
-         FREE(result);
-         return NULL;
-       }
-      result[i].network.addr
-       = htonl((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + 
temps[3]);
-      if ( (slash <= 32) && (slash > 0) ) {
-       result[i].netmask.addr = 0;
-       while (slash > 0) {
-         result[i].netmask.addr
-           = (result[i].netmask.addr >> 1) + 0x80000000;
-         slash--;
-       }
-       result[i].netmask.addr
-         = htonl(result[i].netmask.addr);
-       while (routeList[pos] != ';')
-         pos++;
-       pos++;
-       i++;
-       continue;
-      } else {
-       LOG(LOG_ERROR,
-           _("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
-           slash);
-       FREE(result);
-       return NULL; /* error */
-      }
-    }
-    LOG(LOG_ERROR,
-       "invalid network notation: >>%s<<",
-       &routeList[pos]);
-    FREE(result);
-    return NULL; /* error */
-  }
-  if (pos < strlen(routeList)) {
-    LOG(LOG_ERROR,
-       _("Invalid network notation (additional characters: `%s')."),
-       &routeList[pos]);
-    FREE(result);
-    return NULL; /* oops */
-  }
-  return result; /* ok */
-}
-
-
-
-/**
- * Check if the given IP address is in the list of IP addresses.
- *
- * @param list a list of networks
- * @param ip the IP to check (in network byte order)
- * @return NO if the IP is not in the list, YES if it it is
- */
-int checkIPListed(const CIDRNetwork * list,
-                 IPaddr ip) {
-  int i;
-  IPaddr add;
-
-  add = ip;
-  i=0;
-  if (list == NULL)
-    return NO;
-
-  while ( (list[i].network.addr != 0) ||
-         (list[i].netmask.addr != 0) ) {
-    if ( (add.addr & list[i].netmask.addr) ==
-        (list[i].network.addr & list[i].netmask.addr) )
-      return YES;
-    i++;
-  }
-  return NO;
-}
-
-/**
- * Parse a network specification. The argument specifies
- * a list of networks. The format is
- * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
- * with a semicolon). The network must be given in colon-hex
- * notation.  The netmask must be given in CIDR notation (/16) or
- * can be omitted to specify a single host.
- * <p>
- * @param routeList a string specifying the forbidden networks
- * @return the converted list, NULL if the synatx is flawed
- */
-CIDR6Network * parseRoutes6(const char * routeListX) {
-  unsigned int count;
-  unsigned int i;
-  unsigned int len;
-  unsigned int pos;
-  int start;
-  int slash;
-  int ret;
-  char * routeList;
-  CIDR6Network * result;
-
-  if (routeListX == NULL)
-    return NULL;
-  len = strlen(routeListX);
-  if (len == 0)
-    return NULL;
-  routeList = STRDUP(routeListX);
-  count = 0;
-  for (i=0;i<len;i++)
-    if (routeList[i] == ';')
-      count++;
-  if (routeList[len-1] != ';') {
-    LOG(LOG_ERROR,
-       _("Invalid network notation (does not end with ';': `%s')\n"),
-       routeList);
-    FREE(routeList);
-    return NULL;
-  }
-
-  result = MALLOC(sizeof(CIDR6Network) * (count+1));
-  memset(result,
-        0,
-        sizeof(CIDR6Network) * (count+1));
-  i=0;
-  pos = 0;
-  while (i < count) {
-    start = pos;
-    while (routeList[pos] != ';')
-      pos++;
-    slash = pos;
-    while ( (slash >= start) &&
-           (routeList[slash] != '/') )
-      slash--;
-    if (slash < start) {
-      memset(&result[i].netmask,
-            0xFF,
-            sizeof(IP6addr));  
-      slash = pos;
-    } else {
-      routeList[pos] = '\0';
-      ret = inet_pton(AF_INET6,
-                     &routeList[slash+1],
-                     &result[i].netmask);
-      if (ret <= 0) {
-       LOG(LOG_ERROR,
-           _("Wrong format `%s' for netmask: %s\n"),
-           &routeList[slash+1],
-           STRERROR(errno));
-       FREE(result);
-       FREE(routeList);
-       return NULL;
-      }
-    }
-    routeList[slash] = '\0';
-    ret = inet_pton(AF_INET6,
-                   &routeList[start],
-                   &result[i].network);
-    if (ret <= 0) {
-      LOG(LOG_ERROR,
-         _("Wrong format `%s' for network: %s\n"),
-         &routeList[slash+1],
-         STRERROR(errno));
-      FREE(result);
-      FREE(routeList);
-      return NULL;
-    }
-    pos++;
-  }
-  FREE(routeList);
-  return result;
-}
-
-/**
- * Check if the given IP address is in the list of IP addresses.
- *
- * @param list a list of networks
- * @param ip the IP to check (in network byte order)
- * @return NO if the IP is not in the list, YES if it it is
- */
-int checkIP6Listed(const CIDR6Network * list,
-                  const IP6addr * ip) {
-  unsigned int i;
-  unsigned int j;
-  struct in6_addr zero;
-
-  i=0;
-  if (list == NULL)
-    return NO;
-
-  memset(&zero, 0, sizeof(struct in6_addr));
-  while ( (memcmp(&zero, &list[i].network, sizeof(struct in6_addr)) != 0) ||
-         (memcmp(&zero, &list[i].netmask, sizeof(struct in6_addr)) != 0) ) {
-    for (j=0;j<sizeof(struct in6_addr)/sizeof(int);j++)
-      if ( ((((int*)ip)[j] & ((int*)&list[i].netmask)[j])) !=
-          (((int*)&list[i].network)[j] & ((int*)&list[i].netmask)[j]) ) {
-      i++;
-      continue;
-    }
-    return YES;
-  }
-  return NO;
-}
-
-/* end of ipcheck.c */

Modified: GNUnet/src/util/loggers/file.c
===================================================================
--- GNUnet/src/util/loggers/file.c      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/loggers/file.c      2006-06-22 17:50:56 UTC (rev 3024)
@@ -249,6 +249,7 @@
   FREENONNULL(fctx->filename);
   FREENONNULL(fctx->basename);
   if ( (fctx->handle != stderr) &&
+       (fctx->handle != stdout) &&
        (0 != fclose(fctx->handle)) )
     GE_LOG_STRERROR(fctx->ectx,
                    GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE | GE_BULK,
@@ -332,3 +333,29 @@
                                    &fileclose);
 
 }
+
+/**
+ * Create a logger that writes events to stderr
+ * 
+ * @param mask which events should be logged?
+ */
+struct GE_Context * 
+GE_create_context_stdout(int logDate,
+                        GE_KIND mask) {
+  FileContext * fctx;
+
+  fctx = MALLOC(sizeof(FileContext));
+  fctx->ectx = NULL;
+  fctx->logdate = logDate;
+  fctx->logrotate = 0;
+  fctx->handle = stdout;
+  fctx->filename = NULL;
+  fctx->basename = NULL;
+  fctx->logstart = 0;
+  MUTEX_CREATE_RECURSIVE(&fctx->lock);
+  return GE_create_context_callback(mask,
+                                   &filelogger,
+                                   fctx,
+                                   &fileclose);
+
+}

Added: GNUnet/src/util/network/Makefile.am
===================================================================
--- GNUnet/src/util/network/Makefile.am 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/network/Makefile.am 2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,27 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+SUBDIRS = .
+
+noinst_LTLIBRARIES = \
+  libnetwork.la
+
+libnetwork_la_SOURCES = \
+ endian.c \
+ io.c \
+ ipcheck.c \
+ port.c \
+ tcp_return.c \
+ tcpio.c 
+
+check_PROGRAMS = \
+ tcpiotest 
+
+TESTS = $(check_PROGRAMS)
+
+tcpiotest_SOURCES = \
+ tcpiotest.c
+tcpiotest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  
+
+
+

Added: GNUnet/src/util/network/endian.c
===================================================================
--- GNUnet/src/util/network/endian.c    2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/network/endian.c    2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,48 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004, 2006 Christian Grothoff (and other 
contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/endian.c
+ * @brief endian conversion helpers
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util.h"
+
+unsigned long long ntohll(unsigned long long n) {
+#if __BYTE_ORDER == __BIG_ENDIAN
+  return n;
+#else
+  return (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32);
+#endif
+}
+
+unsigned long long htonll(unsigned long long n) {
+#if __BYTE_ORDER == __BIG_ENDIAN
+  return n;
+#else
+  return (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32);
+#endif
+}
+
+
+
+/* end of endian.c */

Added: GNUnet/src/util/network/io.c
===================================================================
--- GNUnet/src/util/network/io.c        2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/network/io.c        2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,315 @@
+/*
+     This file is part of GNUnet.
+     (C) 2003 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/io.c
+ * @brief (network) input/output operations
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+/* some systems send us signals, so we'd better
+   catch them (& ignore) */
+#ifndef LINUX
+static void catcher(int sig) {
+  LOG(LOG_INFO,
+      _("Caught signal %d.\n"),
+      sig);
+  /* re-install signal handler! */
+  signal(sig, catcher);
+}
+
+
+#endif
+
+void gnunet_util_initIO() {
+#if ! (defined(LINUX) || defined(MINGW))
+  if ( SIG_ERR == signal(SIGPIPE, SIG_IGN))
+    if ( SIG_ERR == signal(SIGPIPE, catcher))
+      LOG_STRERROR(LOG_WARNING, "signal");
+#endif
+}
+
+void gnunet_util_doneIO() {
+}
+
+/**
+ * Depending on doBlock, enable or disable the nonblocking mode
+ * of socket s.
+ *
+ * @param doBlock use YES to change the socket to blocking, NO to non-blocking
+ * @return Upon successful completion, it returns zero, otherwise -1
+ */
+int setBlocking(int s, int doBlock) {
+#if MINGW
+  u_long l = !doBlock;
+  if (ioctlsocket(s, FIONBIO, &l) == SOCKET_ERROR) {
+    SetErrnoFromWinsockError(WSAGetLastError());
+
+    return -1;
+  } else {
+    /* store the blocking mode */
+    __win_SetHandleBlockingMode(s, doBlock);
+    return 0;
+  }
+#else
+  int flags = fcntl(s, F_GETFL);
+  if (doBlock)
+    flags &= ~O_NONBLOCK;
+  else
+    flags |= O_NONBLOCK;
+
+  return fcntl(s,
+              F_SETFL,
+              flags);
+#endif
+}
+
+/**
+ * Check whether the socket is blocking
+ * @param s the socket
+ * @return YES if blocking, NO non-blocking
+ */
+int isSocketBlocking(int s)
+{
+#ifndef MINGW
+ return (fcntl(s, F_GETFL) & O_NONBLOCK) ? NO : YES;
+#else
+  return __win_IsHandleMarkedAsBlocking(s);
+#endif
+}
+
+/* recv wrappers */
+
+/**
+ * Do a NONBLOCKING read on the given socket.  Note that in order to
+ * avoid blocking, the caller MUST have done a select call before
+ * calling this function. Though the caller must be prepared to the
+ * fact that this function may fail with EWOULDBLOCK in any case (Win32).
+ *
+ * @brief Reads at most max bytes to buf. Interrupts are IGNORED.
+ * @param s socket
+ * @param buf buffer
+ * @param max maximum number of bytes to read
+ * @param read number of bytes actually read.
+ *             0 is returned if no more bytes can be read
+ * @return SYSERR on error, YES on success or NO if the operation
+ *         would have blocked
+ */
+int RECV_NONBLOCKING(int s,
+                    void * buf,
+                    size_t max,
+                    size_t *read) {
+  int flags;
+
+  setBlocking(s, NO);
+
+#ifdef CYGWIN
+    flags = MSG_NOSIGNAL;
+#elif OSX
+    flags = 0;
+#elif SOMEBSD || SOLARIS
+    flags = MSG_DONTWAIT;
+#elif LINUX
+    flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+#else
+    /* good luck */
+    flags = 0;
+#endif
+
+  do {
+    *read = (size_t) RECV(s,
+                         buf,
+                         max,
+                         flags);
+  } while ( ( *read == -1) && ( errno == EINTR) );
+
+  setBlocking(s, YES);
+
+  if (*read == SYSERR && (errno == EWOULDBLOCK || errno == EAGAIN))
+    return NO;
+  else if ( (*read < 0) || (*read > max) )
+    return SYSERR;
+
+  return YES;
+}
+
+/**
+ * Do a BLOCKING read on the given socket.  Read len bytes (if needed
+ * try multiple reads).  Interrupts are ignored.
+ *
+ * @return SYSERR if len bytes could not be read,
+ *   otherwise the number of bytes read (must be len)
+ */
+int RECV_BLOCKING_ALL(int s,
+                     void * buf,
+                     size_t len) {
+  size_t pos;
+  int i, flags;
+
+  pos = 0;
+  setBlocking(s, YES);
+
+  while (pos < len) {
+#if LINUX || CYGWIN
+    flags = MSG_NOSIGNAL;
+#else
+    flags = 0;
+#endif
+
+    i = RECV(s,
+            &((char*)buf)[pos],
+            len - pos,
+            flags);
+
+    if ( (i == -1) && (errno == EINTR) )
+      continue;
+    if (i <= 0)
+    {
+      setBlocking(s, NO);
+      return SYSERR;
+    }
+    pos += i;
+  }
+  GNUNET_ASSERT(pos == len);
+
+  setBlocking(s, NO);
+
+  return pos;
+}
+
+/**
+ * Do a NONBLOCKING write on the given socket.
+ * Write at most max bytes from buf.
+ * Interrupts are ignored (cause a re-try).
+ *
+ * The caller must be prepared to the fact that this function
+ * may fail with EWOULDBLOCK in any case (Win32).
+ *
+ * @param s socket
+ * @param buf buffer to send
+ * @param max maximum number of bytes to send
+ * @param sent number of bytes actually sent
+ * @return SYSERR on error, YES on success or
+ *         NO if the operation would have blocked.
+ */
+int SEND_NONBLOCKING(int s,
+                    const void * buf,
+                    size_t max,
+                    size_t * sent) {
+  int flags;
+
+  setBlocking(s, NO);
+
+#ifdef SOMEBSD
+    flags = MSG_DONTWAIT;
+#elif SOLARIS
+    flags = MSG_DONTWAIT;
+#elif OSX
+    /* As braindead as Win32? */
+    flags = 0;
+#elif CYGWIN
+       flags = MSG_NOSIGNAL;
+#elif LINUX
+       flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+#else
+    /* pray */
+       flags = 0;
+#endif
+
+  do {
+    *sent = (size_t) SEND(s,
+                         buf,
+                         max,
+                         flags);
+
+  } while ( (*sent == -1) &&
+           (errno == EINTR) );
+
+  setBlocking(s, YES);
+
+  if (*sent == SYSERR && (errno == EWOULDBLOCK || errno == EAGAIN))
+    return NO;
+  else if ( (*sent < 0) || (*sent > max) )
+    return SYSERR;
+
+  return YES;
+}
+
+/**
+ * Do a BLOCKING write on the given socket.  Write len bytes (if
+ * needed do multiple write).  Interrupts are ignored (cause a
+ * re-try).
+ *
+ * @return SYSERR if len bytes could not be send,
+ *   otherwise the number of bytes transmitted (must be len)
+ */
+int SEND_BLOCKING_ALL(int s,
+                     const void * buf,
+                     size_t len) {
+  size_t pos;
+  int i, flags;
+
+  pos = 0;
+  setBlocking(s, YES);
+  while (pos < len) {
+#if CYGWIN || LINUX
+    flags = MSG_NOSIGNAL;
+#else
+    flags = 0;
+#endif
+    i = SEND(s,
+            &((char*)buf)[pos],
+            len - pos,
+            flags);
+
+    if ( (i == -1) &&
+        (errno == EINTR) )
+      continue; /* ingnore interrupts */
+    if (i <= 0) {
+      if (i == -1)
+       LOG_STRERROR(LOG_WARNING, "send");
+      return SYSERR;
+    }
+    pos += i;
+  }
+  setBlocking(s, NO);
+  GNUNET_ASSERT(pos == len);
+  return pos;
+}
+
+/**
+ * Check if socket is valid
+ * @return 1 if valid, 0 otherwise
+ */
+int isSocketValid(int s)
+{
+#ifndef MINGW
+  struct stat buf;
+  return -1 != fstat(s, &buf);
+#else
+  long l;
+  return ioctlsocket(s, FIONREAD, &l) != SOCKET_ERROR;
+#endif
+}
+
+/* end of io.c */

Added: GNUnet/src/util/network/ipcheck.c
===================================================================
--- GNUnet/src/util/network/ipcheck.c   2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/network/ipcheck.c   2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,325 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004 Christian Grothoff (and other contributing 
authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/ipcheck.c
+ * @brief test if an IP matches a given subnet
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+/**
+ * @brief IPV4 network in CIDR notation.
+ */
+typedef struct CIDRNetwork {
+  IPaddr network;
+  IPaddr netmask;
+} CIDRNetwork;
+
+/**
+ * @brief network in CIDR notation for IPV6.
+ */
+typedef struct CIDR6Network {
+  IP6addr network;
+  IP6addr netmask;
+} CIDR6Network;
+
+
+/**
+ * Parse a network specification. The argument specifies
+ * a list of networks. The format is
+ * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
+ * with a semicolon). The network must be given in dotted-decimal
+ * notation. The netmask can be given in CIDR notation (/16) or
+ * in dotted-decimal (/255.255.0.0).
+ * <p>
+ * @param routeList a string specifying the forbidden networks
+ * @return the converted list, NULL if the synatx is flawed
+ */
+CIDRNetwork * parseRoutes(const char * routeList) {
+  unsigned int count;
+  unsigned int i;
+  unsigned int j;
+  unsigned int len;
+  int cnt;
+  unsigned int pos;
+  unsigned int temps[8];
+  int slash;
+  CIDRNetwork * result;
+
+  if (routeList == NULL)
+    return NULL;
+  len = strlen(routeList);
+  if (len == 0)
+    return NULL;
+  count = 0;
+  for (i=0;i<len;i++)
+    if (routeList[i] == ';')
+      count++;
+  result = MALLOC(sizeof(CIDRNetwork) * (count+1));
+  /* add termination */
+  memset(result,
+        0,
+        sizeof(CIDRNetwork)*(count+1));
+  i=0;
+  pos = 0;
+  while (i < count) {
+    cnt = sscanf(&routeList[pos],
+                "%u.%u.%u.%u/%u.%u.%u.%u;",
+                &temps[0],
+                &temps[1],
+                &temps[2],
+                &temps[3],
+                &temps[4],
+                &temps[5],
+                &temps[6],
+                &temps[7]);
+    if (cnt == 8) {
+      for (j=0;j<8;j++)
+       if (temps[j] > 0xFF) {
+         LOG(LOG_ERROR,
+             _("Invalid format for IP: `%s'\n"),
+             &routeList[pos]);
+         FREE(result);
+         return NULL;
+       }
+      result[i].network.addr
+       = htonl((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + 
temps[3]);
+      result[i].netmask.addr
+       = htonl((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) + 
temps[7]);
+      while (routeList[pos] != ';')
+       pos++;
+      pos++;
+      i++;
+      continue;
+    }
+    /* try second notation */
+    cnt = sscanf(&routeList[pos],
+                "%u.%u.%u.%u/%u;",
+                &temps[0],
+                &temps[1],
+                &temps[2],
+                &temps[3],
+                &slash);
+    if (cnt == 5) {
+      for (j=0;j<4;j++)
+       if (temps[j] > 0xFF) {
+         LOG(LOG_ERROR,
+             "wrong format for IP: %s\n",
+             &routeList[pos]);
+         FREE(result);
+         return NULL;
+       }
+      result[i].network.addr
+       = htonl((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + 
temps[3]);
+      if ( (slash <= 32) && (slash > 0) ) {
+       result[i].netmask.addr = 0;
+       while (slash > 0) {
+         result[i].netmask.addr
+           = (result[i].netmask.addr >> 1) + 0x80000000;
+         slash--;
+       }
+       result[i].netmask.addr
+         = htonl(result[i].netmask.addr);
+       while (routeList[pos] != ';')
+         pos++;
+       pos++;
+       i++;
+       continue;
+      } else {
+       LOG(LOG_ERROR,
+           _("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
+           slash);
+       FREE(result);
+       return NULL; /* error */
+      }
+    }
+    LOG(LOG_ERROR,
+       "invalid network notation: >>%s<<",
+       &routeList[pos]);
+    FREE(result);
+    return NULL; /* error */
+  }
+  if (pos < strlen(routeList)) {
+    LOG(LOG_ERROR,
+       _("Invalid network notation (additional characters: `%s')."),
+       &routeList[pos]);
+    FREE(result);
+    return NULL; /* oops */
+  }
+  return result; /* ok */
+}
+
+
+
+/**
+ * Check if the given IP address is in the list of IP addresses.
+ *
+ * @param list a list of networks
+ * @param ip the IP to check (in network byte order)
+ * @return NO if the IP is not in the list, YES if it it is
+ */
+int checkIPListed(const CIDRNetwork * list,
+                 IPaddr ip) {
+  int i;
+  IPaddr add;
+
+  add = ip;
+  i=0;
+  if (list == NULL)
+    return NO;
+
+  while ( (list[i].network.addr != 0) ||
+         (list[i].netmask.addr != 0) ) {
+    if ( (add.addr & list[i].netmask.addr) ==
+        (list[i].network.addr & list[i].netmask.addr) )
+      return YES;
+    i++;
+  }
+  return NO;
+}
+
+/**
+ * Parse a network specification. The argument specifies
+ * a list of networks. The format is
+ * <tt>[network/netmask;]*</tt> (no whitespace, must be terminated
+ * with a semicolon). The network must be given in colon-hex
+ * notation.  The netmask must be given in CIDR notation (/16) or
+ * can be omitted to specify a single host.
+ * <p>
+ * @param routeList a string specifying the forbidden networks
+ * @return the converted list, NULL if the synatx is flawed
+ */
+CIDR6Network * parseRoutes6(const char * routeListX) {
+  unsigned int count;
+  unsigned int i;
+  unsigned int len;
+  unsigned int pos;
+  int start;
+  int slash;
+  int ret;
+  char * routeList;
+  CIDR6Network * result;
+
+  if (routeListX == NULL)
+    return NULL;
+  len = strlen(routeListX);
+  if (len == 0)
+    return NULL;
+  routeList = STRDUP(routeListX);
+  count = 0;
+  for (i=0;i<len;i++)
+    if (routeList[i] == ';')
+      count++;
+  if (routeList[len-1] != ';') {
+    LOG(LOG_ERROR,
+       _("Invalid network notation (does not end with ';': `%s')\n"),
+       routeList);
+    FREE(routeList);
+    return NULL;
+  }
+
+  result = MALLOC(sizeof(CIDR6Network) * (count+1));
+  memset(result,
+        0,
+        sizeof(CIDR6Network) * (count+1));
+  i=0;
+  pos = 0;
+  while (i < count) {
+    start = pos;
+    while (routeList[pos] != ';')
+      pos++;
+    slash = pos;
+    while ( (slash >= start) &&
+           (routeList[slash] != '/') )
+      slash--;
+    if (slash < start) {
+      memset(&result[i].netmask,
+            0xFF,
+            sizeof(IP6addr));  
+      slash = pos;
+    } else {
+      routeList[pos] = '\0';
+      ret = inet_pton(AF_INET6,
+                     &routeList[slash+1],
+                     &result[i].netmask);
+      if (ret <= 0) {
+       LOG(LOG_ERROR,
+           _("Wrong format `%s' for netmask: %s\n"),
+           &routeList[slash+1],
+           STRERROR(errno));
+       FREE(result);
+       FREE(routeList);
+       return NULL;
+      }
+    }
+    routeList[slash] = '\0';
+    ret = inet_pton(AF_INET6,
+                   &routeList[start],
+                   &result[i].network);
+    if (ret <= 0) {
+      LOG(LOG_ERROR,
+         _("Wrong format `%s' for network: %s\n"),
+         &routeList[slash+1],
+         STRERROR(errno));
+      FREE(result);
+      FREE(routeList);
+      return NULL;
+    }
+    pos++;
+  }
+  FREE(routeList);
+  return result;
+}
+
+/**
+ * Check if the given IP address is in the list of IP addresses.
+ *
+ * @param list a list of networks
+ * @param ip the IP to check (in network byte order)
+ * @return NO if the IP is not in the list, YES if it it is
+ */
+int checkIP6Listed(const CIDR6Network * list,
+                  const IP6addr * ip) {
+  unsigned int i;
+  unsigned int j;
+  struct in6_addr zero;
+
+  i=0;
+  if (list == NULL)
+    return NO;
+
+  memset(&zero, 0, sizeof(struct in6_addr));
+  while ( (memcmp(&zero, &list[i].network, sizeof(struct in6_addr)) != 0) ||
+         (memcmp(&zero, &list[i].netmask, sizeof(struct in6_addr)) != 0) ) {
+    for (j=0;j<sizeof(struct in6_addr)/sizeof(int);j++)
+      if ( ((((int*)ip)[j] & ((int*)&list[i].netmask)[j])) !=
+          (((int*)&list[i].network)[j] & ((int*)&list[i].netmask)[j]) ) {
+      i++;
+      continue;
+    }
+    return YES;
+  }
+  return NO;
+}
+
+/* end of ipcheck.c */

Added: GNUnet/src/util/network/port.c
===================================================================
--- GNUnet/src/util/network/port.c      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/network/port.c      2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,102 @@
+/*
+     This file is part of GNUnet
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file util/port.c
+ * @brief functions for GNUnet clients to establish connection with gnunetd
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+/**
+ * Return the port-number (in host byte order)
+ */
+unsigned short getGNUnetPort() {
+  static unsigned short port;
+  const char *setting;
+
+  if (port != 0)
+    return port;
+  if (testConfigurationString("GNUNETD",
+                             "_MAGIC_",
+                             "YES"))
+    setting = "PORT";
+  else
+    setting = "CLIENT-PORT";
+
+  port = (unsigned short) getConfigurationInt("NETWORK",
+                                             setting);
+  if (port == 0) {
+    errexit(_("Cannot determine port of gnunetd server. "
+             "Define in configuration file in section `%s' under `%s'.\n"),
+           "NETWORK",
+           setting);
+  }
+  return port;
+}
+
+/**
+ * Configuration: get the GNUnetd host where the client
+ * should connect to (via TCP)
+ * @return the name of the host
+ */
+static const char * getGNUnetdHost() {
+  static char * res;
+
+  if (res != NULL)
+    return res;
+  res = getConfigurationString("NETWORK",
+                              "HOST");
+  if (res == NULL)
+    res = "localhost";
+  return res;
+}
+
+/**
+ * Get a GNUnet TCP socket that is connected to gnunetd.
+ */
+GNUNET_TCP_SOCKET * getClientSocket() {
+  GNUNET_TCP_SOCKET * sock;
+  const char * host;
+
+  sock = MALLOC(sizeof(GNUNET_TCP_SOCKET));
+  host = getGNUnetdHost();
+  if (SYSERR == initGNUnetClientSocket(getGNUnetPort(),
+                                      host,
+                                      sock)) {
+    LOG(LOG_ERROR,
+       _("Could not connect to gnunetd.\n"));
+    FREE(sock);
+    return NULL;
+  }
+  return sock;
+}
+
+/**
+ * Free a Client socket.
+ */
+void releaseClientSocket(GNUNET_TCP_SOCKET * sock) {
+  if (sock != NULL) {
+    destroySocket(sock);
+    FREE(sock);
+  }
+}
+
+/* end of port.c */

Added: GNUnet/src/util/network/tcp_return.c
===================================================================
--- GNUnet/src/util/network/tcp_return.c        2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/util/network/tcp_return.c        2006-06-22 17:50:56 UTC (rev 
3024)
@@ -0,0 +1,94 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2004 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/tcp_return.c
+ * @brief code to communicate simple (int) return values via reliable
+ *        TCP stream
+ * @author Christian Grothoff
+ *
+ * Helper methods to send and receive return values over a TCP stream
+ * that has tcpio (see util/tcpio.c) semantics.
+ */
+
+#include "gnunet_util.h"
+#include "gnunet_protocols.h"
+#include "platform.h"
+
+/**
+ * Obtain a return value from a remote call from TCP.
+ *
+ * @param sock the TCP socket
+ * @param ret the return value from TCP
+ * @return SYSERR on error, OK if the return value was read
+ * successfully
+ */
+int readTCPResult(GNUNET_TCP_SOCKET * sock,
+                 int * ret) {
+  CS_returnvalue_MESSAGE * rv;
+
+  rv = NULL;
+  if (SYSERR == readFromSocket(sock,
+                              (CS_MESSAGE_HEADER **) &rv)) {
+    LOG(LOG_WARNING,
+       _("`%s' failed, other side closed connection.\n"),
+       __FUNCTION__);
+    return SYSERR;
+  }
+  if ( (ntohs(rv->header.size) != sizeof(CS_returnvalue_MESSAGE)) ||
+       (ntohs(rv->header.type) != CS_PROTO_RETURN_VALUE) ) {
+    LOG(LOG_WARNING,
+       _("`%s' failed, reply invalid!\n"),
+       __FUNCTION__);
+    FREE(rv);
+    return SYSERR;
+  }
+  *ret = ntohl(rv->return_value);
+  FREE(rv);
+  return OK;
+}
+
+/**
+ * Send a return value to the caller of a remote call via
+ * TCP.
+ * @param sock the TCP socket
+ * @param ret the return value to send via TCP
+ * @return SYSERR on error, OK if the return value was
+ *         send successfully
+ */
+int sendTCPResult(GNUNET_TCP_SOCKET * sock,
+                 int ret) {
+  CS_returnvalue_MESSAGE rv;
+
+  rv.header.size
+    = htons(sizeof(CS_returnvalue_MESSAGE));
+  rv.header.type
+    = htons(CS_PROTO_RETURN_VALUE);
+  rv.return_value
+    = htonl(ret);
+  return writeToSocket(sock,
+                      &rv.header);
+}
+
+
+
+
+
+/* end of tcp_return.c */

Added: GNUnet/src/util/network/tcpio.c
===================================================================
--- GNUnet/src/util/network/tcpio.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/network/tcpio.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,463 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/tcpio.c
+ * @brief code for synchronized access to TCP streams
+ * @author Christian Grothoff
+ *
+ * Generic TCP code for reliable, mostly blocking, record-oriented TCP
+ * connections. GNUnet uses the "tcpio" code for trusted client-server
+ * (e.g. gnunet-gtk to gnunetd via loopback) communications.  Note
+ * that an unblocking write is also provided since if both client and
+ * server use blocking IO, both may block on a write and cause a
+ * mutual inter-process deadlock.
+ *
+ * Since we do not want other peers (!) to be able to block a peer by
+ * not reading from the TCP stream, the peer-to-peer TCP transport
+ * uses unreliable, buffered, non-blocking, record-oriented TCP code
+ * with a select call to reduce the number of threads which is
+ * provided in transports/tcp.c.
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+#define DEBUG_TCPIO NO
+
+/**
+ * Initialize a GNUnet client socket.
+ * @param port the portnumber in host byte order
+ * @param ip IP of the host to connect to, in network byte order
+ * @param result the SOCKET (filled in)
+ * @return OK if successful, SYSERR on failure
+ */
+int initGNUnetClientSocketIP(unsigned short port,
+                            IPaddr ip,
+                            GNUNET_TCP_SOCKET * result) {
+  result->ip = ip;
+  result->port = port;
+  result->socket = -1; /* closed */
+  result->outBufLen = 0;
+  result->outBufPending = NULL;
+  MUTEX_CREATE(&result->readlock);
+  MUTEX_CREATE(&result->writelock);
+  return OK;
+}
+
+/**
+ * Initialize a GNUnet client socket.
+ * @param port the portnumber in host byte order
+ * @param hostname the name of the host to connect to
+ * @param result the SOCKET (filled in)
+ * @return OK if successful, SYSERR on failure
+ */
+int initGNUnetClientSocket(unsigned short port,
+                          const char * hostname,
+                          GNUNET_TCP_SOCKET * result) {
+  GNUNET_ASSERT(hostname != NULL);
+#if DEBUG_TCPIO
+  LOG(LOG_DEBUG,
+      "Connecting to host '%s:%d'.\n",
+      hostname,
+      port);
+#endif
+  if (OK != GN_getHostByName(hostname,
+                            &result->ip)) 
+    return SYSERR;
+  result->port = port;
+  result->socket = -1; /* closed */
+  result->outBufLen = 0;
+  result->outBufPending = NULL;
+  MUTEX_CREATE(&result->readlock);
+  MUTEX_CREATE(&result->writelock);
+  return OK;
+}
+
+/**
+ * Initialize a GNUnet server socket.
+ * @param sock the open socket
+ * @param result the SOCKET (filled in)
+ * @return OK (always successful)
+ */
+int initGNUnetServerSocket(int sock,
+                          GNUNET_TCP_SOCKET * result) {
+  result->ip.addr = 0;
+  result->port = 0;
+  result->socket = sock;
+  result->outBufLen = 0;
+  result->outBufPending = NULL;
+  MUTEX_CREATE(&result->readlock);
+  MUTEX_CREATE(&result->writelock);
+  return OK;
+}
+
+/**
+ * Check if a socket is open. Will ALWAYS return 'true'
+ * for a valid client socket (even if the connection is
+ * closed), but will return false for a closed server socket.
+ * @return 1 if open, 0 if closed
+ */
+int isOpenConnection(GNUNET_TCP_SOCKET * sock) {
+  return (sock->socket != -1);
+}
+
+/**
+ * Check a socket, open and connect if it is closed and it is a client-socket.
+ */
+int checkSocket(GNUNET_TCP_SOCKET * sock) {
+  int res;
+  struct sockaddr_in soaddr;
+  fd_set rset;
+  fd_set wset;
+  fd_set eset;
+  struct timeval timeout;
+  int ret;
+  int wasSockBlocking;
+
+  if (sock->socket != -1)
+    return OK;
+  sock->socket = SOCKET(PF_INET, SOCK_STREAM, 6); /* 6: TCP */
+  if (sock->socket == -1) {
+    LOG_STRERROR(LOG_FAILURE, "socket");
+    return SYSERR;
+  }
+
+  wasSockBlocking = isSocketBlocking(sock->socket);
+  setBlocking(sock->socket, NO);
+       
+  soaddr.sin_family = AF_INET;
+  GNUNET_ASSERT(sizeof(struct in_addr) == sizeof(sock->ip.addr));
+  memcpy(&soaddr.sin_addr,
+        &sock->ip.addr,
+        sizeof(struct in_addr));
+  soaddr.sin_port = htons(sock->port);
+  res = CONNECT(sock->socket,
+               (struct sockaddr*)&soaddr,
+               sizeof(soaddr));
+  if ( (res < 0) &&
+       (errno != EINPROGRESS) ) {
+    LOG(LOG_INFO,
+       _("Cannot connect to %u.%u.%u.%u:%u: %s\n"),
+       PRIP(ntohl(*(int*)&sock->ip.addr)),
+       sock->port,
+       STRERROR(errno));
+    closefile(sock->socket);
+    sock->socket = -1;
+    return SYSERR;
+  }
+
+  /* we call select() first with a timeout of 5s to
+     avoid blocking on a later write indefinitely;
+     this is mostly needed for gnunet-testbed to keep
+     working if an advertised testbed-client is behind
+     a firewall and unreachable.  But it is also nice
+     if a local firewall decides to just drop the TCP
+     handshake...*/
+  FD_ZERO(&rset);
+  FD_ZERO(&wset);
+  FD_ZERO(&eset);
+  if (sock->socket < 0)
+    return SYSERR;
+  FD_SET(sock->socket, &wset);
+  timeout.tv_sec = 5;
+  timeout.tv_usec = 0;
+  ret = SELECT(sock->socket+1, &rset, &wset, &eset, &timeout);
+  if ( (ret == -1) ||
+       (sock->socket == -1) ||
+       (! FD_ISSET(sock->socket,
+                  &wset)) ) {
+    LOG(LOG_INFO,
+       _("Cannot connect to %u.%u.%u.%u:%u: %s\n"),
+       PRIP(ntohl(*(int*)&sock->ip.addr)),
+       sock->port,
+       STRERROR(errno));
+    setBlocking(sock->socket, wasSockBlocking);
+    return SYSERR;
+  }
+  setBlocking(sock->socket, wasSockBlocking);
+
+  return OK;
+}
+
+/**
+ * Write to a GNUnet TCP socket.  Will also potentially complete the
+ * sending of a previous non-blocking writeToSocket call.
+ *
+ * @param sock the socket to write to
+ * @param buffer the buffer to write
+ * @return OK if the write was sucessful, otherwise SYSERR.
+ */
+int writeToSocket(GNUNET_TCP_SOCKET * sock,
+                 const CS_MESSAGE_HEADER * buffer) {
+  int res;
+  int size;
+
+  if (SYSERR == checkSocket(sock))
+    return SYSERR;
+  size = ntohs(buffer->size);
+  MUTEX_LOCK(&sock->writelock);
+
+  /* write pending data from prior non-blocking call
+     -- but this time use blocking IO! */
+  if (sock->outBufLen > 0) {
+    res = SEND_BLOCKING_ALL(sock->socket,
+                           sock->outBufPending,
+                           sock->outBufLen);
+    if (res < 0) {
+      if (errno == EAGAIN) {
+       MUTEX_UNLOCK(&sock->writelock);
+       return SYSERR; /* can not send right now;
+                         but do NOT close socket in this case! */
+      }
+      LOG_STRERROR(LOG_INFO, "send");
+      closeSocketTemporarily(sock);
+      MUTEX_UNLOCK(&sock->writelock);
+      return SYSERR;
+    }
+    FREE(sock->outBufPending);
+    sock->outBufPending = NULL;
+    sock->outBufLen = 0;
+  }
+
+  res = SEND_BLOCKING_ALL(sock->socket,
+                         buffer,
+                         size);
+  if (res < 0) {
+    if (errno == EAGAIN) {
+      MUTEX_UNLOCK(&sock->writelock);
+      return SYSERR; /* would block, can not send right now;
+                       but do NOT close socket in this case! */
+    }
+    LOG_STRERROR(LOG_INFO, "send");
+    closeSocketTemporarily(sock);
+    MUTEX_UNLOCK(&sock->writelock);
+    return SYSERR;
+  }
+  MUTEX_UNLOCK(&sock->writelock);
+  return OK;
+}
+
+
+/**
+ * Write to a GNUnet TCP socket non-blocking.  Note that it is
+ * possible that only a part of the message is send and that tcpio
+ * buffers the rest until the next writeToSocket operation.  If that
+ * buffer is full or if send did not transmit any byte of the message,
+ * NO is returned to indicate that the write failed (would have
+ * blocked).
+ *
+ * @param sock the socket to write to
+ * @param buffer the buffer to write
+ * @return OK if the write was sucessful, NO if it would have blocked and was 
not performed,
+ *         otherwise SYSERR.
+ */
+int writeToSocketNonBlocking(GNUNET_TCP_SOCKET * sock,
+                            const CS_MESSAGE_HEADER * buffer) {
+  size_t res;
+  size_t size;
+
+  if (SYSERR == checkSocket(sock))
+    return SYSERR;
+  MUTEX_LOCK(&sock->writelock);
+  if (sock->outBufLen > 0) {
+    SEND_NONBLOCKING(sock->socket,
+                    sock->outBufPending,
+                    sock->outBufLen,
+                    &res);
+    if (res == (size_t)-1) {
+      if ( (errno == EWOULDBLOCK) ||
+          (errno == EAGAIN) ) {
+       MUTEX_UNLOCK(&sock->writelock);
+       return NO;
+      }
+      LOG_STRERROR(LOG_INFO, "write");
+      closeSocketTemporarily(sock);
+      MUTEX_UNLOCK(&sock->writelock);
+      return SYSERR;
+    }
+    if (res < sock->outBufLen) {
+      memcpy(sock->outBufPending,
+            &((char*)sock->outBufPending)[res],
+            sock->outBufLen - res);
+      sock->outBufLen -= res;
+      MUTEX_UNLOCK(&sock->writelock);
+      return SYSERR;
+    }
+    /* completely send out deferred buffer, so
+       we can in fact continue! */
+    FREENONNULL(sock->outBufPending);
+    sock->outBufPending = NULL;
+    sock->outBufLen = 0;
+  }
+
+  size = ntohs(buffer->size);
+
+  SEND_NONBLOCKING(sock->socket,
+                  (const char*)buffer,
+                  size,
+                  &res);
+  if (res == (size_t) -1) {
+    if ( (errno == EWOULDBLOCK) ||
+        (errno == EAGAIN) ) {
+      MUTEX_UNLOCK(&sock->writelock);
+      return NO; /* would block, can not send right now;
+                   but do NOT close socket in this case;
+                   do not use SYSERR as return value
+                   since this is not an error! */
+    }
+    LOG_STRERROR(LOG_INFO, "send");
+    closeSocketTemporarily(sock);
+    MUTEX_UNLOCK(&sock->writelock);
+    return SYSERR;
+  }
+  GNUNET_ASSERT(res <= size);
+  if (res != size) {
+    sock->outBufPending = MALLOC(size - res);
+    memcpy(sock->outBufPending,
+          &((const char*)buffer)[res],
+          size - res);
+    sock->outBufLen = size - res;
+    MUTEX_UNLOCK(&sock->writelock);
+    return OK; /* return OK here means that the message will be transmitted,
+                 though it may be a bit later (on the next call, in fact). */
+  }
+  MUTEX_UNLOCK(&sock->writelock);
+  return OK;
+}
+
+/**
+ * Read from a GNUnet TCP socket.
+ * @param sock the socket
+ * @param buffer the buffer to write data to
+ * @return OK if the read was successful, SYSERR if the socket
+ *         was closed by the other side (if the socket is a
+ *         client socket and is used again, tcpio will attempt
+ *         to re-establish the connection [temporary error]).
+ */
+int readFromSocket(GNUNET_TCP_SOCKET * sock,
+                  CS_MESSAGE_HEADER ** buffer) {
+  int res;
+  unsigned int pos;
+  char * buf;
+  unsigned short size;
+
+  if (SYSERR == checkSocket(sock))
+    return SYSERR;
+
+  MUTEX_LOCK(&sock->readlock);
+  pos = 0;
+  res = 0;
+
+  pos = RECV_BLOCKING_ALL(sock->socket,
+                         &size,
+                         sizeof(unsigned short));
+  if (pos != sizeof(unsigned short)) {
+#if DEBUG_TCPIO
+    LOG_STRERROR(LOG_INFO, "recv");
+#endif
+    closeSocketTemporarily(sock);
+    MUTEX_UNLOCK(&sock->readlock);
+    return SYSERR; /* other side closed socket or invalid header */
+  }
+  size = ntohs(size);
+  if (size < sizeof(CS_MESSAGE_HEADER)) {
+#if DEBUG_TCPIO
+    LOG_STRERROR(LOG_INFO, "recv");
+#endif
+    closeSocketTemporarily(sock);
+    MUTEX_UNLOCK(&sock->readlock);
+    return SYSERR; /* invalid header */
+  }
+
+  buf = (char*) *buffer;
+  if (buf == NULL)
+    buf = MALLOC(size);
+
+  res = RECV_BLOCKING_ALL(sock->socket,
+                         &buf[pos],
+                         size - pos);
+
+  if (res != (int)(size - pos)) {  /* error, abort */
+    if (sock->socket != -1)
+      LOG_STRERROR(LOG_INFO, "recv");
+    closeSocketTemporarily(sock);
+    if (*buffer == NULL)
+      FREE(buf);
+    MUTEX_UNLOCK(&sock->readlock);
+    return SYSERR;
+  }
+#if DEBUG_TCPIO
+  LOG(LOG_DEBUG,
+      "Successfully received %d bytes from TCP socket.\n",
+      size);
+#endif
+  MUTEX_UNLOCK(&sock->readlock);
+  *buffer = (CS_MESSAGE_HEADER*) buf;
+  (*buffer)->size = htons(size);
+  return OK; /* success */
+}
+
+/**
+ * Close a GNUnet TCP socket for now (use to temporarily close
+ * a TCP connection that will probably not be used for a long
+ * time; the socket will still be auto-reopened by the
+ * readFromSocket/writeToSocket methods if it is a client-socket).
+ */
+void closeSocketTemporarily(GNUNET_TCP_SOCKET * sock) {
+  if (sock == NULL)
+    return;
+  if (sock->socket != -1) {
+    int i;
+
+    i = sock->socket;
+#if DEBUG_TCPIO
+    LOG(LOG_DEBUG,
+       "TCP: closing socket %d.\n",
+       sock->socket);
+#endif
+    sock->socket = -1;
+    if (0 != SHUTDOWN(i, SHUT_RDWR))
+      LOG_STRERROR(LOG_DEBUG, "shutdown");
+    closefile(i);
+  }
+  sock->outBufLen = 0;
+  FREENONNULL(sock->outBufPending);
+  sock->outBufPending = NULL;
+}
+
+/**
+ * Destroy a socket for good. If you use this socket afterwards,
+ * you must first invoke initializeSocket, otherwise the operation
+ * will fail.
+ */
+void destroySocket(GNUNET_TCP_SOCKET * sock) {
+  closeSocketTemporarily(sock);
+  sock->ip.addr = 0;
+  sock->port = 0;
+  sock->outBufLen = 0;
+  FREENONNULL(sock->outBufPending);
+  sock->outBufPending = NULL;
+  MUTEX_DESTROY(&sock->readlock);
+  MUTEX_DESTROY(&sock->writelock);
+}
+
+
+/*  end of tcpio.c */

Added: GNUnet/src/util/network/tcpiotest.c
===================================================================
--- GNUnet/src/util/network/tcpiotest.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/network/tcpiotest.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,261 @@
+/**
+ * @file test/tcpiotest.c
+ * @brief testcase for util/tcpiotest.c
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+static int openServerSocket() {
+  int listenerFD;
+  int listenerPort;
+  struct sockaddr_in serverAddr;
+  const int on = 1;
+
+  listenerPort = getGNUnetPort();
+  /* create the socket */
+  while ( (listenerFD = SOCKET(PF_INET, SOCK_STREAM, 0)) < 0) {
+    LOG(LOG_ERROR,
+       "ERROR opening socket (%s).  "
+       "No client service started.  "
+       "Trying again in 30 seconds.\n",
+       STRERROR(errno));
+    sleep(30);
+  }
+
+  /* fill in the inet address structure */
+  memset((char *) &serverAddr,
+        0,
+        sizeof(serverAddr));
+  serverAddr.sin_family = AF_INET;
+  serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);
+  serverAddr.sin_port=htons(listenerPort);
+
+  if ( SETSOCKOPT(listenerFD,
+                 SOL_SOCKET,
+                 SO_REUSEADDR,
+                 &on, sizeof(on)) < 0 )
+    perror("setsockopt");
+
+  /* bind the socket */
+  if (BIND (listenerFD,
+          (struct sockaddr *) &serverAddr,
+           sizeof(serverAddr)) < 0) {
+    LOG(LOG_ERROR,
+       "ERROR (%s) binding the TCP listener to port %d. "
+       "Test failed.  Is gnunetd running?\n",
+       STRERROR(errno),
+       listenerPort);
+    return -1;
+  }
+
+  /* start listening for new connections */
+  if (0 != LISTEN(listenerFD, 5)) {
+    LOG(LOG_ERROR,
+       " listen failed: %s\n",
+       STRERROR(errno));
+    return -1;
+  }
+  return listenerFD;
+}
+
+static int doAccept(int serverSocket) {
+  int incomingFD;
+  int lenOfIncomingAddr;
+  struct sockaddr_in clientAddr;
+
+  incomingFD = -1;
+  while (incomingFD < 0) {
+    lenOfIncomingAddr = sizeof(clientAddr);
+    incomingFD = ACCEPT(serverSocket,
+                       (struct sockaddr *)&clientAddr,
+                       &lenOfIncomingAddr);
+    if (incomingFD < 0) {
+      LOG(LOG_ERROR,
+         "ERROR accepting new connection (%s).\n",
+         STRERROR(errno));
+      continue;
+    }
+  }
+  return incomingFD;
+}
+
+/**
+ * Perform option parsing from the command line.
+ */
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  char c;
+
+  while (1) {
+    int option_index = 0;
+    static struct GNoption long_options[] = {
+      { "config",  1, 0, 'c' },
+      { 0,0,0,0 }
+    };
+
+    c = GNgetopt_long(argc,
+                     argv,
+                     "c:",
+                     long_options,
+                     &option_index);
+
+    if (c == -1)
+      break;  /* No more flags to process */
+
+    switch(c) {
+    case 'c':
+      FREENONNULL(setConfigurationString("FILES",
+                                        "gnunet.conf",
+                                        GNoptarg));
+      break;
+    } /* end of parsing commandline */
+  }
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGFILE",
+                                    NULL));
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGLEVEL",
+                                    "DEBUG"));
+  return OK;
+}
+
+static int testTransmission(GNUNET_TCP_SOCKET * a,
+                           GNUNET_TCP_SOCKET * b) {
+  CS_MESSAGE_HEADER * hdr;
+  CS_MESSAGE_HEADER * buf;
+  int i;
+  int j;
+
+  hdr = MALLOC(1024);
+  for (i=0;i<1024-sizeof(CS_MESSAGE_HEADER);i+=7) {
+    fprintf(stderr, ".");
+    for (j=0;j<i;j++)
+      ((char*)&hdr[1])[j] = (char)i+j;
+    hdr->size = htons(i+sizeof(CS_MESSAGE_HEADER));
+    hdr->type = 0;
+    if (OK != writeToSocket(a, hdr)) {
+      FREE(hdr);
+      return 1;
+    }
+    buf = NULL;
+    if (OK != readFromSocket(b, &buf)) {
+      FREE(hdr);
+      return 2;
+    }
+    if (0 != memcmp(buf, hdr, i+sizeof(CS_MESSAGE_HEADER))) {
+      FREE(buf);
+      FREE(hdr);
+      return 4;
+    }
+    FREE(buf);
+  }
+  FREE(hdr);
+  return 0;
+}
+
+static int testNonblocking(GNUNET_TCP_SOCKET * a,
+                          GNUNET_TCP_SOCKET * b) {
+  CS_MESSAGE_HEADER * hdr;
+  CS_MESSAGE_HEADER * buf;
+  int i;
+  int cnt;
+
+  hdr = MALLOC(1024);
+  for (i=0;i<1024-sizeof(CS_MESSAGE_HEADER);i+=11)
+    ((char*)&hdr[1])[i] = (char)i;
+  hdr->size = htons(64+sizeof(CS_MESSAGE_HEADER));
+  hdr->type = 0;
+  while (OK == writeToSocketNonBlocking(a,
+                                       hdr))
+    hdr->type++;
+  i = 0;
+  cnt = hdr->type;
+  /* printf("Reading %u messages.\n", cnt); */
+  if (cnt < 2)
+    return 8; /* could not write ANY data non-blocking!? */
+  for (i=0;i<cnt;i++) {
+    hdr->type = i;
+    buf = NULL;
+    if (OK != readFromSocket(b, &buf)) {
+      FREE(hdr);
+      return 16;
+    }
+    if (0 != memcmp(buf, hdr, 64+sizeof(CS_MESSAGE_HEADER))) {
+      printf("Failure in message %u.  Headers: %d ? %d\n",
+            i,
+            buf->type,
+            hdr->type);
+      FREE(buf);
+      FREE(hdr);
+      return 32;
+    }
+    FREE(buf);
+    if (i == cnt - 2) {
+      /* printf("Blocking write to flush last non-blocking message.\n"); */
+      hdr->type = cnt;
+      if (OK != writeToSocket(a,
+                             hdr)) {
+       FREE(hdr);
+       return 64;
+      }
+    }
+  }
+  hdr->type = i;
+  buf = NULL;
+  if (OK != readFromSocket(b, &buf)) {
+    FREE(hdr);
+    return 128;
+  }
+  if (0 != memcmp(buf, hdr, 64+sizeof(CS_MESSAGE_HEADER))) {
+    FREE(buf);
+    FREE(hdr);
+    return 256;
+  }
+  FREE(buf);
+  FREE(hdr);
+  return 0;
+}
+
+int main(int argc, char * argv[]){
+  int i;
+  int ret;
+  int serverSocket;
+  GNUNET_TCP_SOCKET * clientSocket;
+  GNUNET_TCP_SOCKET acceptSocket;
+
+  ret = 0;
+  initUtil(argc, argv, &parseCommandLine);
+  serverSocket = openServerSocket();
+  clientSocket = getClientSocket();
+  if (serverSocket == -1) {
+    releaseClientSocket(clientSocket);
+    doneUtil();
+    return 1;
+  }
+  for (i=0;i<2;i++) {
+    if (OK == checkSocket(clientSocket)) {
+      if (OK == initGNUnetServerSocket(doAccept(serverSocket),
+                                      &acceptSocket)) {
+       ret = ret | testTransmission(clientSocket, &acceptSocket);
+       ret = ret | testTransmission(&acceptSocket, clientSocket);
+       ret = ret | testNonblocking(clientSocket, &acceptSocket);
+       ret = ret | testNonblocking(&acceptSocket, clientSocket);
+       closeSocketTemporarily(clientSocket);
+       destroySocket(&acceptSocket);
+       fprintf(stderr, "\n");
+      } else {
+       fprintf(stderr, "initGNUnetServerSocket failed.\n");
+       ret = -1;
+      }
+    } else {
+      fprintf(stderr, "checkSocket faild.\n");
+      ret = -1;
+    }
+  }
+  releaseClientSocket(clientSocket);
+  doneUtil();
+  if (ret > 0)
+    fprintf(stderr, "Error %d\n", ret);
+  return ret;
+}

Added: GNUnet/src/util/os/Makefile.am
===================================================================
--- GNUnet/src/util/os/Makefile.am      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/os/Makefile.am      2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,35 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+SUBDIRS = .
+
+noinst_LTLIBRARIES = \
+  libos.la
+
+libos_la_SOURCES = \
+ daemon.c \
+ dso.c \
+ osconfig.c \
+ semaphore.c \
+ statuscalls.c 
+
+check_PROGRAMS = \
+ daemontest \
+ semaphoretest \
+ statuscallstest
+
+TESTS = $(check_PROGRAMS)
+
+daemontest_SOURCES = \
+ daemontest.c 
+daemontest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  
+
+semaphoretest_SOURCES = \
+ semaphoretest.c
+semaphoretest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  
+
+statuscallstest_SOURCES = \
+ statuscallstest.c
+statuscallstest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  

Added: GNUnet/src/util/os/daemon.c
===================================================================
--- GNUnet/src/util/os/daemon.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/os/daemon.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,336 @@
+/*
+     This file is part of GNUnet.
+     (C) 2005 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file src/util/daemon.c
+ * @brief code for client-gnunetd interaction (start, stop, waitpid, check 
running)
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util.h"
+#include "gnunet_protocols.h"
+
+
+/**
+ * Checks if gnunetd is running
+ *
+ * Uses CS_PROTO_traffic_COUNT query to determine if gnunetd is
+ * running.
+ *
+ * @return OK if gnunetd is running, SYSERR if not
+ */
+int checkGNUnetDaemonRunning(struct GE_Context * ectx) {
+  GNUNET_TCP_SOCKET * sock;
+  CS_MESSAGE_HEADER csHdr;
+  int ret;
+
+  sock = getClientSocket(ectx);
+  if (sock == NULL) 
+    return SYSERR;
+
+  csHdr.size
+    = htons(sizeof(CS_MESSAGE_HEADER));
+  csHdr.type
+    = htons(CS_PROTO_traffic_COUNT);
+  if (SYSERR == writeToSocket(sock,
+                              &csHdr)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  }
+  if (SYSERR == readTCPResult(sock,
+                             &ret)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  }
+  releaseClientSocket(sock);
+  return OK;
+}
+
+
+#if LINUX || OSX || SOLARIS || SOMEBSD
+/**
+ * Fork a gnunetd process
+ *
+ * @param daemonize YES if gnunetd should be daemonized
+ * @return pid_t of gnunetd if NOT daemonized, 0 if
+ *  daemonized sucessfully, -1 on error
+ */
+static pid_t launchWithExec(int daemonize) {
+  pid_t pid;
+
+  pid = fork();
+  if (pid == 0) {
+    char * args[5];
+    char * path;
+    char * cp;
+
+    path = NULL;
+    cp = getConfigurationString("MAIN",
+                               "ARGV[0]");
+    if (cp != NULL) {
+      int i = strlen(cp);
+      while ( (i >= 0) &&
+             (cp[i] != DIR_SEPARATOR) )
+       i--;
+      if ( i != -1 ) {
+       cp[i+1] = '\0';
+       path = MALLOC(i+2+strlen("gnunetd"));
+       strcpy(path, cp);
+       strcat(path, "gnunetd");
+       if (ACCESS(path, X_OK) == 0) {
+         args[0] = path;
+       } else {
+         FREE(path);
+         path = NULL;
+         args[0] = "gnunetd";
+       }
+       FREE(cp);
+      } else {
+       args[0] = "gnunetd";
+      }
+    }
+    cp = getConfigurationString("GNUNET",
+                               "GNUNETD-CONFIG");
+    if (cp != NULL) {
+      args[1] = "-c";
+      args[2] = cp;
+      if (NO == daemonize) {
+       args[3] = "-d";
+       args[4] = NULL;
+      } else
+       args[3] = NULL;
+    } else {
+      if (NO == daemonize) {
+       args[1] = "-d";
+       args[2] = NULL;
+      } else
+       args[1] = NULL;
+    }
+    errno = 0;
+    nice(10); /* return value is not well-defined */
+    if (errno != 0)
+      LOG_STRERROR(LOG_WARNING, "nice");
+    if (path != NULL)
+      execv(path,
+           args);
+    else
+      execvp("gnunetd",
+            args);
+    LOG_STRERROR(LOG_FAILURE, "exec");
+    LOG(LOG_FAILURE,
+       _("Attempted path to `%s' was `%s'.\n"),
+       "gnunetd",
+       (path == NULL) ? "gnunetd" : path);
+    FREENONNULL(path); /* yeah, right, like we're likely to get
+                         here... */
+    _exit(-1);
+  } else if (daemonize) {
+    pid_t ret;
+    int status;
+
+    ret = waitpid(pid, &status, 0);
+    if (ret == -1) {
+      LOG_STRERROR(LOG_ERROR, "waitpid");
+      return SYSERR;
+    }
+    if ( (WIFEXITED(status) &&
+         (0 != WEXITSTATUS(status)) ) ) {
+      return SYSERR;
+    }
+#ifdef WCOREDUMP
+    if (WCOREDUMP(status)) {
+      return SYSERR;
+    }
+#endif
+    if (WIFSIGNALED(status) ||
+       WTERMSIG(status) ) {
+      return SYSERR;
+    }
+    return 0;
+  }
+  return pid;
+}
+#endif
+
+/**
+ * Start gnunetd process
+ *
+ * @param daemonize YES if gnunetd should be daemonized
+ * @return pid_t of gnunetd if NOT daemonized, 0 if
+ *  daemonized sucessfully, -1 on error
+ */
+int startGNUnetDaemon(int daemonize) {
+#if LINUX || OSX || SOLARIS || SOMEBSD
+  return launchWithExec(daemonize);
+#elif MINGW
+  char szCall[_MAX_PATH + 1], szWd[_MAX_PATH + 1], szCWd[_MAX_PATH + 1];
+  char *args[1], *cp = NULL;
+  int pid;
+  int idx = 0;
+
+  plibc_conv_to_win_path("/bin/gnunetd.exe", szCall);
+  plibc_conv_to_win_path("/bin", szWd);
+  _getcwd(szCWd, _MAX_PATH);
+
+  chdir(szWd);
+
+  if (daemonize == NO) {
+       args[0] = "-d";
+               idx = 1;
+
+    cp = getConfigurationString("GNUNET",
+                               "GNUNETD-CONFIG");
+               if (cp) {
+                       args[1] = "-c";
+                       args[2] = cp;
+                       idx=3;
+               }               
+  }
+
+  args[idx] = NULL;
+  pid = spawnvp(_P_NOWAIT, szCall, (const char *const *) args);
+  chdir(szCWd);
+
+  FREENONNULL(cp);
+
+  return (daemonize == NO) ? pid : 0;
+#else
+  /* any system out there that does not support THIS!? */
+  system("gnunetd"); /* we may not have nice,
+                       so let's be minimalistic here. */
+  return 0;
+#endif
+}
+
+
+/**
+ * Stop gnunetd
+ *
+ * Note that returning an error does NOT mean that
+ * gnunetd will continue to run (it may have been
+ * shutdown by something else in the meantime or
+ * crashed).  Call checkDaemonRunning() frequently
+ * to check the status of gnunetd.
+ *
+ * Furthermore, note that this WILL potentially kill
+ * gnunetd processes on remote machines that cannot
+ * be restarted with startGNUnetDaemon!
+ *
+ * This function does NOT need the PID and will also
+ * kill daemonized gnunetd's.
+ *
+ * @return OK successfully stopped, SYSERR: error
+ */
+int stopGNUnetDaemon() {
+  GNUNET_TCP_SOCKET * sock;
+  CS_MESSAGE_HEADER csHdr;
+  int ret;
+
+  sock = getClientSocket();
+  if (sock == NULL)
+    return SYSERR;
+  csHdr.size
+    = htons(sizeof(CS_MESSAGE_HEADER));
+  csHdr.type
+    = htons(CS_PROTO_SHUTDOWN_REQUEST);
+  if (SYSERR == writeToSocket(sock,
+                             &csHdr)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  }
+  if (SYSERR == readTCPResult(sock,
+                             &ret)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  }
+  releaseClientSocket(sock);
+  return ret;
+}
+
+/**
+ * Wait until the gnunet daemon is
+ * running.
+ *
+ * @param timeout how long to wait at most
+ * @return OK if gnunetd is now running
+ */
+int waitForGNUnetDaemonRunning(cron_t timeout) {
+  timeout += cronTime(NULL);
+  while (OK != checkGNUnetDaemonRunning()) {
+    gnunet_util_sleep(100 * cronMILLIS);
+    if (timeout < cronTime(NULL))
+      return checkGNUnetDaemonRunning();
+  }
+  return OK;
+}
+
+/**
+ * Wait until the gnunet daemon (or any other CHILD process for that
+ * matter) with the given PID has terminated.  Assumes that
+ * the daemon was started with startGNUnetDaemon in no-daemonize mode.
+ * On arbitrary PIDs, this function may fail unexpectedly.
+ *
+ * @return YES if gnunetd shutdown with
+ *  return value 0, SYSERR if waitpid
+ *  failed, NO if gnunetd shutdown with
+ *  some error
+ */
+int waitForGNUnetDaemonTermination(int pid) {
+  pid_t p;
+  int status;
+
+  p = pid;
+  if (p != WAITPID(p, &status, 0)) {
+    LOG_STRERROR(LOG_ERROR, "waitpid");
+    return SYSERR;
+  }
+  if (WEXITSTATUS(status) == 0)
+    return YES;
+  else
+    return NO;
+}
+
+int termProcess(int pid) {
+#ifndef MINGW
+  return kill(pid, SIGTERM) == 0;
+#else
+  int ret;
+  DWORD dwExitCode = 0;
+  
+  HANDLE hProc = OpenProcess(1, 0, pid);
+  GenerateConsoleCtrlEvent(CTRL_C_EVENT, pid);
+  
+  WaitForSingleObject(hProc, 3000);
+  
+  GetExitCodeProcess(hProc, &dwExitCode);
+  if(dwExitCode == STILL_ACTIVE) {
+    ret = TerminateProcess(hProc, 0);
+  }
+  else
+    ret = 1;
+  
+  CloseHandle(hProc);
+  
+  return ret;
+#endif
+}
+
+/* end of daemon.c */

Added: GNUnet/src/util/os/daemontest.c
===================================================================
--- GNUnet/src/util/os/daemontest.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/os/daemontest.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,61 @@
+/*
+     This file is part of GNUnet.
+     (C) 2005 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file test/daemontest.c
+ * @brief Testcase for the daemon functions
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "_MAGIC_",
+                                    "NO"));
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGFILE",
+                                    NULL));
+  FREENONNULL(setConfigurationString("GNUNET",
+                                    "LOGLEVEL",
+                                    "NOTHING"));
+  FREENONNULL(setConfigurationString("GNUNET",
+                                    "GNUNETD-CONFIG",
+                                    "check.conf"));
+  return OK;
+}
+
+int main(int argc, char *argv[]) {
+  int daemon;
+
+  if (OK != initUtil(argc,
+                    argv,
+                    &parseCommandLine))
+    return -1;
+  daemon = startGNUnetDaemon(NO);
+  GNUNET_ASSERT(daemon > 0);
+  GNUNET_ASSERT(OK == waitForGNUnetDaemonRunning(30 * cronSECONDS));
+  GNUNET_ASSERT(OK == stopGNUnetDaemon());
+  GNUNET_ASSERT(OK == waitForGNUnetDaemonTermination(daemon));
+  doneUtil();
+  return 0;
+}
+
+/* end of deamontest.c */

Added: GNUnet/src/util/os/dso.c
===================================================================
--- GNUnet/src/util/os/dso.c    2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/os/dso.c    2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,160 @@
+/*
+     This file is part of GNUnet
+     (C) 2002, 2003, 2004, 2005 Christian Grothoff (and other contributing 
authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/dso.c
+ * @brief Methods to access dynamic shared objects (DSOs).
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util.h"
+
+static int using_valgrind;
+
+static char * old_dlsearchpath = NULL;
+
+/* using libtool, needs init! */
+void __attribute__ ((constructor)) gnc_ltdl_init(void) {
+  int err;
+
+  err = lt_dlinit ();
+  if (err > 0)
+    {
+#if DEBUG
+      fprintf(stderr,
+             _("Initialization of plugin mechanism failed: %s!\n"),
+             lt_dlerror());
+#endif
+      return;
+    }
+  if (lt_dlgetsearchpath() != NULL)
+    old_dlsearchpath = strdup(lt_dlgetsearchpath());
+  if (lt_dlgetsearchpath () == NULL)
+    lt_dladdsearchdir ("/usr/lib/GNUnet");
+  else if (strstr (lt_dlgetsearchpath (), "/usr/lib/GNUnet") == NULL)
+    lt_dladdsearchdir ("/usr/lib/GNUnet");
+  if (strstr (lt_dlgetsearchpath (), "/usr/local/lib/GNUnet") == NULL)
+    lt_dladdsearchdir ("/usr/local/lib/GNUnet");
+#ifdef PLUGIN_PATH
+  if (strstr (lt_dlgetsearchpath (), PLUGIN_PATH) == NULL)
+    lt_dladdsearchdir (PLUGIN_PATH);
+#endif
+}
+
+void __attribute__ ((destructor)) gnc_ltdl_fini(void) {
+  lt_dlsetsearchpath(old_dlsearchpath);
+  if (old_dlsearchpath != NULL) {
+    free(old_dlsearchpath);
+    old_dlsearchpath = NULL;
+  }
+  if (0 != using_valgrind)
+    lt_dlexit ();
+}
+
+
+static char * buildLibName(const char * prefix,
+                          const char * dso) {
+  char * libname;
+
+  libname = MALLOC(strlen(dso) +
+                  strlen(prefix) + 1);
+  libname[0] = '\0';
+  strcat(libname, prefix);
+  strcat(libname, dso);
+  return libname;
+}
+
+void * loadDynamicLibrary(const char * libprefix,
+                         const char * dsoname) {
+  void * libhandle;
+  char * libname;
+
+  if (0 != lt_dlinit())
+    DIE_STRERROR("lt_dlinit");
+  /* finally, load the library */
+  libname = buildLibName(libprefix,
+                        dsoname);
+  libhandle = lt_dlopenext(libname);
+  if (libhandle == NULL) {
+    LOG(LOG_ERROR,
+       _("`%s' failed for library `%s' at %s:%d with error: %s\n"),
+       "lt_dlopenext",
+       libname,
+       __FILE__, __LINE__,
+       lt_dlerror());
+  }
+  FREE(libname);
+  return libhandle;
+}
+
+void unloadDynamicLibrary(void * libhandle) {
+  /* when valgrinding, comment out these lines
+     to get decent traces for memory leaks on exit */
+  if (0 != getConfigurationInt("GNUNETD",
+                              "VALGRIND")) {
+    lt_dlclose(libhandle);
+    if (0 != lt_dlexit())
+      LOG_STRERROR(LOG_WARNING, "lt_dlexit");
+  } else
+    using_valgrind = 1;
+}
+
+void * trybindDynamicMethod(void * libhandle,
+                           const char * methodprefix,
+                           const char * dsoname) {
+  char * initName;
+  void * mptr;
+
+  initName = MALLOC(strlen(dsoname) +
+                   strlen(methodprefix) + 2);
+  initName[0] = '\0';
+  strcat(initName, "_");
+  strcat(initName, methodprefix);
+  strcat(initName, dsoname);
+  mptr = lt_dlsym(libhandle, &initName[1]);
+  if (mptr == NULL) {
+    /* try again with "_" prefix; some systems use that
+       variant. */
+    mptr = lt_dlsym(libhandle, initName);
+  }
+  FREE(initName);
+  return mptr;
+}
+
+void * bindDynamicMethod(void * libhandle,
+                        const char * methodprefix,
+                        const char * dsoname) {
+  void * mptr;
+
+  mptr = trybindDynamicMethod(libhandle,
+                             methodprefix,
+                             dsoname);
+  if (mptr == NULL)
+    LOG(LOG_ERROR,
+       _("`%s' failed to resolve method '%s%s' at %s:%d with error: %s\n"),
+       "lt_dlsym",
+       methodprefix, dsoname,
+       __FILE__, __LINE__,
+       lt_dlerror());
+  return mptr;
+}
+
+/* end of dso.c */                     

Added: GNUnet/src/util/os/osconfig.c
===================================================================
--- GNUnet/src/util/os/osconfig.c       2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/os/osconfig.c       2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,403 @@
+/*
+     This file is part of GNUnet.
+     (C) 2004, 2005 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+*/
+
+/**
+ * @file util/osconfig.c
+ * @brief functions to read or change the OS configuration
+ * @author Nils Durner
+ */
+#include "platform.h"
+#include "gnunet_util.h"
+
+/**
+ * @brief Enumerate all network interfaces
+ * @param callback the callback function
+ */
+void enumNetworkIfs(void (*callback) (const char *, int, void *),
+                   void * cls) {
+#ifdef MINGW
+  ListNICs(callback, cls);
+#else
+  char entry[11], *dst;
+  FILE *f;
+
+  if (system("ifconfig > /dev/null 2> /dev/null"))
+    if (system("/sbin/ifconfig > /dev/null 2> /dev/null") == 0)
+      f = popen("/sbin/ifconfig 2> /dev/null", "r");
+    else
+      f = NULL;
+  else
+    f = popen("ifconfig 2> /dev/null", "r");
+
+  if (!f)
+    return;
+
+  while(1)
+    {
+      int i = 0;
+      int c = fgetc(f);
+
+      if (c == EOF)
+       break;
+
+      dst = entry;
+
+      /* Read interface name until the first space (or colon under OS X) */
+      while (c != EOF && c != '\n' &&
+#ifdef OSX
+            c != ':'
+#else
+            c != ' '
+#endif
+            && i < 10)
+       {
+         *dst++ = c;
+         i++;
+         c = fgetc(f);
+       }
+      *dst = 0;
+
+      if (entry[0])
+       callback(entry, strcmp(entry, "eth0") == 0, cls);
+
+      while(c != '\n' && c != EOF)
+       c = fgetc(f);
+    }
+
+  pclose(f);
+#endif
+}
+
+/**
+ * @brief Checks if we can start GNUnet automatically
+ * @return 1 if yes, 0 otherwise
+ */
+int isOSAutostartCapable() {
+#ifdef LINUX
+  if (ACCESS("/usr/sbin/update-rc.d", X_OK) == 0) {
+    /* Debian */
+    if (ACCESS("/etc/init.d/", W_OK) == 0)
+      return 1;
+  }
+  return 0;
+#else
+  #ifdef WINDOWS
+    return 1;
+  #else
+    return 0;
+  #endif
+#endif
+}
+
+/**
+ * @brief Make GNUnet start automatically
+ * @param doAutoStart true to enable autostart, false to disable it
+ * @param username name of the user account to use
+ * @param groupname name of the group to use
+ * @return 0 on success
+ */
+int autostartService(int doAutoStart, 
+                    const char * username, 
+                    const char * groupname) {
+#ifdef WINDOWS
+  if (doAutoStart)
+    {
+      if (IsWinNT())
+       {
+         char *err = NULL;
+         DWORD dwErr = 0;
+       
+         if (username && !strlen(username))
+           username = NULL;
+       
+         /* Install service */
+         switch(InstallAsService(username))
+           {
+           case 0:
+           case 1:
+             break;
+           case 2:
+             if (GetLastError() != ERROR_SERVICE_EXISTS)
+               return 1;
+           case 3:
+             return 2;
+           default:
+             return -1;
+           }
+       
+         /* Grant permissions to the GNUnet directory */
+         if ((!err || dwErr == ERROR_SERVICE_EXISTS) && username)
+           {
+             char szHome[_MAX_PATH + 1];
+       
+             plibc_conv_to_win_path("/", szHome);
+       
+             if (!AddPathAccessRights(szHome, username, GENERIC_ALL))
+               return 3;
+           }
+       }
+      else
+       {
+         char szPath[_MAX_PATH + 1];
+    HKEY hKey;
+
+         plibc_conv_to_win_path("/bin/gnunetd.exe", szPath);
+       
+    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+        "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_EXECUTE,
+        &hKey) == ERROR_SUCCESS)
+    {
+      if (RegSetValueEx(hKey, "GNUnet", 0, REG_SZ, szPath, strlen(szPath)) !=
+        ERROR_SUCCESS)
+        return 4;
+
+      RegCloseKey(hKey);
+    }
+    else
+      return 4;
+       }
+    }
+  else
+    {
+      if (IsWinNT())
+       {
+         switch (UninstallService())
+           {
+           case 0:
+           case 1:
+             break;
+           case 2:
+             return 1;
+           case 3:
+             return 5;
+           case 4:
+             return 6;
+           default:
+             return -1;
+           }
+       }
+      else
+       {
+         HKEY hKey;
+       
+         if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 
0, KEY_SET_VALUE,
+                       &hKey) == ERROR_SUCCESS)
+           {
+             RegDeleteValue(hKey, "GNUnet");
+       
+             RegCloseKey(hKey);
+           }
+       }
+    }
+#else
+  /* Unix */
+  if (ACCESS("/usr/sbin/update-rc.d", X_OK) == 0) {
+    /* Debian */
+    if (doAutoStart) {
+      struct stat buf;
+      if (STAT("/etc/init.d/gnunetd", &buf) == -1) {
+       /* create init file */
+       FILE *f = FOPEN("/etc/init.d/gnunetd", "w");
+       if (! f)
+         return 1;
+       
+       fputs("#! /bin/sh\n"
+             "#\n"
+             "# Automatically created by gnunet-setup\n"
+             "#\n"
+             "\n"
+             "PATH=$PATH:" PREFIX_PATH "/bin"
+             "PIDFILE=/var/run/gnunetd/gnunetd.pid\n"
+             "\n"
+             "case \"$1\" in\n"
+             " start)\n"
+             "         echo -n \"Starting GNUnet: \"\n"
+             "         gnunetd\n"
+             "         echo \"gnunetd\"\n"
+             "         ;;\n"
+             " stop)\n"
+             "         echo -n \"Stopping GNUnet: \"\n"
+             "         kill `cat $PIDFILE`\n"
+             "         echo \"gnunetd\"\n"
+             "         ;;\n"
+             " reload)\n"
+             "         echo -n \"Reloading GNUnet: \"\n"
+             "         kill -HUP `cat $PIDFILE`\n"
+             "         echo \"gnunetd\"\n"
+             "         ;;\n"
+             " restart|force-reload)\n"
+             "         echo \"Restarting GNUnet: gnunetd...\"\n"
+             "         $0 stop\n"
+             "         sleep 1\n"
+             "         $0 start\n"
+             "         ;;\n"
+             " *)\n"
+             "         echo \"Usage: /etc/init.d/gnunetd 
{start|stop|reload|restart|force-reload}\" >&2\n"
+             "         exit 1\n"
+             "         ;;\n"
+             "\n"
+             "esac\n"
+             "exit 0\n", f);
+       fclose(f);
+       CHMOD("/etc/init.d/gnunetd", S_IRWXU | S_IRGRP | S_IXGRP |
+             S_IROTH | S_IXOTH);
+      }
+      errno = system("/usr/sbin/update-rc.d gnunetd defaults");
+      if (errno != 0)
+       return 1;
+    }
+    else {
+      if ( (UNLINK("/etc/init.d/gnunetd") != -1) ||
+          (errno != ENOENT)) {
+       if (ACCESS("/usr/sbin/update-rc.d", X_OK) == 0) {
+         errno = system("/usr/sbin/update-rc.d gnunetd remove");
+         if (errno != 0) {
+           errno = EPERM;
+           return 1;
+         }
+       }
+       else {
+         errno = EPERM;
+         return 1;
+       }
+      }
+      else
+       return 0;
+    }
+  }
+  else
+    return 1;
+#endif
+  return 0;
+}
+
+/**
+ * @brief Checks if we can add an user for the GNUnet service
+ * @return 1 if yes, 0 otherwise
+ * @todo support for useradd(8)
+ */
+int isOSUserAddCapable(){
+#ifdef WINDOWS
+       return IsWinNT();
+#endif
+#ifdef LINUX
+       if (ACCESS("/usr/sbin/adduser", X_OK) == 0)
+         return (geteuid() == 0);
+       else
+               /* TODO: useradd */
+#endif
+               return 0;
+}
+
+/**
+ * @brief Checks if we can add a group for the GNUnet service
+ * @return 1 if yes, 0 otherwise
+ * @todo support for groupadd(8)
+ */
+int isOSGroupAddCapable() {
+#ifdef LINUX
+       if (ACCESS("/usr/sbin/addgroup", X_OK) == 0) {
+         return (geteuid() == 0);
+       }
+       /* TODO: groupadd */
+       else
+#endif
+               return 0;
+}
+
+/**
+ * @brief Add a service account for GNUnet
+ * @param group the group of the new user
+ * @param name the name of the new user
+ * @return 0 on success
+ */
+int createGroupUser(const char *group_name, 
+                   const char *user_name) {
+       int haveGroup;
+
+       if ( (user_name == NULL) ||
+            (0 == strlen(user_name)) ) 
+               return 0;
+       
+#ifdef WINDOWS
+       if (IsWinNT())
+       {
+               return CreateServiceAccount(user_name, "GNUnet service 
account");
+       }
+#else
+
+       if (ACCESS("/usr/sbin/adduser", X_OK) == 0) {
+               /* Debian */
+               /* TODO: FreeBSD? 
http://www.freebsd.org/cgi/man.cgi?query=adduser&sektion=8 */
+               char *cmd;
+
+               haveGroup = group_name && strlen(group_name) > 0;               
+               cmd = MALLOC(haveGroup ? strlen(group_name) : 0 + 
strlen(user_name) + 64);
+               
+               if (haveGroup) {
+                       sprintf(cmd, "/usr/sbin/addgroup --quiet --system %s", 
group_name);             
+                       system(cmd);
+               }
+               
+               sprintf(cmd, "/usr/sbin/adduser --quiet --system %s %s "
+                       "--no-create-home %s", haveGroup ? "--ingroup" : "",
+                       haveGroup ? group_name : "", user_name);
+               system(cmd);
+               
+               FREE(cmd);
+       }
+       /* TODO: useradd */
+       else
+               return 1;
+#endif
+
+       return 0;
+}
+
+char *winErrorStr(const char *prefix, int dwErr)
+{
+#ifdef WINDOWS
+       char *err, *ret;
+       int mem;
+       
+       if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM,
+       NULL, (DWORD) dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
(LPTSTR) &err,
+               0, NULL ))
+       {
+               err = "";
+       }
+
+       mem = strlen(err) + strlen(prefix) + 20;
+       ret = (char *) malloc(mem);
+
+  snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr);
+
+  LocalFree(err);
+
+  return ret;
+#else
+       return NULL;
+#endif
+}
+
+
+/* end of osconfig.c */

Added: GNUnet/src/util/os/statuscalls.c
===================================================================
--- GNUnet/src/util/os/statuscalls.c    2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/os/statuscalls.c    2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,873 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2005, 2006 Christian Grothoff (and other 
contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/statuscalls.c
+ * @brief calls to determine current network and CPU load
+ * @author Tzvetan Horozov
+ * @author Christian Grothoff
+ * @author Igor Wronsky
+ *
+ * Status calls implementation for load management.
+ */
+
+#include "platform.h"
+#include "gnunet_util.h"
+
+#if SOLARIS
+#if HAVE_KSTAT_H
+#include <kstat.h>
+#endif
+#if HAVE_SYS_SYSINFO_H
+#include <sys/sysinfo.h>
+#endif
+#if HAVE_KVM_H
+#include <kvm.h>
+#endif
+#endif
+#if SOMEBSD
+#if HAVE_KVM_H
+#include <kvm.h>
+#endif
+#endif
+
+#define DEBUG_STATUSCALLS NO
+
+/**
+ * where to read network interface information from
+ * under Linux
+ */
+#define PROC_NET_DEV "/proc/net/dev"
+
+typedef struct {
+  char * name;
+  unsigned long long last_in;
+  unsigned long long last_out;
+} NetworkStats;
+
+/**
+ * Traffic counter for only gnunetd traffic.
+ */
+static NetworkStats globalTrafficBetweenProc;
+
+/**
+ * tracking
+ */
+static NetworkStats * ifcs;
+
+/**
+ * how many interfaces do we have?
+ */
+static unsigned int ifcsSize;
+
+/**
+ * Current load of the machine, -1 for error
+ */
+static int currentLoad;
+
+/**
+ * Maximum bandwidth (down) as per config.
+ */
+static int maxNetDownBPS;
+
+/**
+ * Maximum bandwidth (up) as per config.
+ */
+static int maxNetUpBPS;
+
+/**
+ * Maximum load as per config.
+ */
+static int maxCPULoad;
+
+/**
+ * How to measure traffic (YES == only gnunetd,
+ * NO == try to include all apps)
+ */
+static int useBasicMethod = YES;
+
+/**
+ * Lock.
+ */
+static Mutex statusMutex;
+
+static int initialized_ = NO;
+
+#ifdef LINUX
+static FILE * proc_stat;
+static FILE * proc_net_dev;
+#endif
+
+/**
+ * Increment the number of bytes sent.  Transports should use this
+ * so that statuscalls module can measure gnunet traffic usage between
+ * calls to /proc.
+ *
+ * Note: the caller doesn't know what interface it is attached to,
+ * so this type of bandwidth limitation is always global (for all
+ * network interfaces).
+ */
+void incrementBytesSent(unsigned long long delta) {
+  if (initialized_ == NO)
+    return;
+  MUTEX_LOCK(&statusMutex);
+  globalTrafficBetweenProc.last_out += delta;
+  MUTEX_UNLOCK(&statusMutex);
+}
+
+void incrementBytesReceived(unsigned long long delta) {
+  if (initialized_ == NO)
+    return;
+  MUTEX_LOCK(&statusMutex);
+  globalTrafficBetweenProc.last_in += delta;
+  MUTEX_UNLOCK(&statusMutex);
+}
+
+/**
+ * Reset the traffic counters for GNUnet traffic between
+ * systemwide readings.
+ */
+static void resetBetweenProc() {
+  globalTrafficBetweenProc.last_in = 0;
+  globalTrafficBetweenProc.last_out = 0;
+}
+
+#define MAX_PROC_LINE 5000
+
+static void updateInterfaceTraffic() {
+#ifdef LINUX
+  unsigned long long rxnew;
+  unsigned long long txnew;
+  char line[MAX_PROC_LINE];
+  char * data;
+  int i;
+  int found;
+
+  MUTEX_LOCK(&statusMutex);
+  if (proc_net_dev != NULL) {
+    found = 0;
+    rewind(proc_net_dev);
+    fflush(proc_net_dev);
+    /* Parse the line matching the interface ('eth0') */
+    while (! feof(proc_net_dev) ) {
+      if (NULL == fgets(line,
+                       MAX_PROC_LINE,
+                       proc_net_dev))
+       break;
+      for (i=0;i<ifcsSize;i++) {
+       if (NULL != strstr(line, ifcs[i].name) ) {
+         data = strchr(line, ':');
+         if (data == NULL)
+           continue;
+         data++;       
+         if (2 != SSCANF(data,
+                         "%llu %*s %*s %*s %*s %*s %*s %*s %llu",
+                         &rxnew,
+                         &txnew)) {
+           LOG(LOG_ERROR,
+               _("Failed to parse interface data from `%s' at %s:%d.\n"),
+               PROC_NET_DEV,
+               __FILE__,
+               __LINE__);
+           continue;
+         }     
+         ifcs[i].last_in  = rxnew;
+         ifcs[i].last_out = txnew;
+         resetBetweenProc();
+         break;
+       }
+      }
+    }
+  }
+  MUTEX_UNLOCK(&statusMutex);
+
+#elif MINGW
+  unsigned long long rxnew;
+  unsigned long long txnew;
+  int i;
+  PMIB_IFTABLE pTable;
+  DWORD dwIfIdx;
+  unsigned long long l;
+  BYTE bPhysAddr[MAXLEN_PHYSADDR];
+  int iLine = 0;
+  char line[MAX_PROC_LINE];
+  FILE * command;
+
+  MUTEX_LOCK(&statusMutex);
+  /* Win 98 and NT SP 4 */
+  if (GNGetIfEntry) {
+    EnumNICs(&pTable, NULL);
+    for (i=0;i<ifcsSize;i++) {
+      for (dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
+        l = _atoi64(ifcs[i].name);
+
+        memset(bPhysAddr,
+              0,
+              MAXLEN_PHYSADDR);
+        memcpy(bPhysAddr,
+              pTable->table[dwIfIdx].bPhysAddr,
+              pTable->table[dwIfIdx].dwPhysAddrLen);
+
+        if (0 == memcmp(bPhysAddr,
+                       &l,
+                       sizeof(unsigned long long))) {
+         ifcs[i].last_in
+           = pTable->table[dwIfIdx].dwInOctets;
+         ifcs[i].last_out
+           = pTable->table[dwIfIdx].dwOutOctets;
+         resetBetweenProc();
+          break;
+        }
+      }
+    }
+    GlobalFree(pTable);
+  } else { /* Win 95 */
+    if ( ( command = popen("netstat -e", "rt") ) == NULL ) {
+      LOG_FILE_STRERROR(LOG_ERROR,
+                       "popen",
+                       "netstat -e");
+      MUTEX_UNLOCK(&statusMutex);
+      return;
+    }
+    while (!feof(command)) {
+      if (NULL == fgets(line,
+                       MAX_PROC_LINE,
+                       command))
+       break;
+      /* PORT-ME: any way to do this per-ifc? */
+      if (iLine == 1) {
+        sscanf("%*s%i%i",
+              &rxnew,
+              &txnew);
+       ifcs[0].last_in
+         = rxnew;
+       ifcs[0].last_out
+         = txnew;
+       resetBetweenProc();
+       break;
+      }
+      iLine++;
+    }
+    pclose(command);
+  }
+  MUTEX_UNLOCK(&statusMutex);
+#else
+  /* PORT-ME! */
+#endif
+}
+
+/**
+ * The following routine returns a number between 0-100 (can be larger
+ * than 100 if the load is > 1) which indicates the percentage CPU
+ * usage.
+ *
+ * Before its first invocation the method initStatusCalls() must be called.
+ * If there is an error the method returns -1
+ */
+static void updateCpuUsage(){
+  if (initialized_ == NO) {
+    currentLoad = -1;
+    return;
+  }
+  MUTEX_LOCK(&statusMutex);
+
+#ifdef LINUX
+  /* under linux, first try %idle/usage using /proc/stat;
+     if that does not work, disable /proc/stat for the future
+     by closing the file and use the next-best method. */
+  if (proc_stat != NULL) {
+    static unsigned long long last_cpu_results[4] = { 0, 0, 0, 0 };
+    static int have_last_cpu = NO;
+    char line[128];
+    unsigned long long user_read, system_read, nice_read, idle_read;
+    unsigned long long user, system, nice, idle;
+    unsigned long long usage_time=0, total_time=1;
+
+    /* Get the first line with the data */
+    rewind(proc_stat);
+    fflush(proc_stat);
+    if (NULL == fgets(line, 128, proc_stat)) {
+      LOG_FILE_STRERROR(LOG_ERROR,
+                       "fgets",
+                       "/proc/stat");
+      fclose(proc_stat);
+      proc_stat = NULL; /* don't try again */
+    } else {
+      if (sscanf(line, "%*s %llu %llu %llu %llu",
+                &user_read,
+                &system_read,
+                &nice_read,
+                &idle_read) != 4) {
+       LOG_FILE_STRERROR(LOG_ERROR,
+                         "fgets-sscanf",
+                         "/proc/stat");
+       fclose(proc_stat);
+       proc_stat = NULL; /* don't try again */
+       have_last_cpu = NO;
+      } else {
+       /* Store the current usage*/
+       user   = user_read - last_cpu_results[0];
+       system = system_read - last_cpu_results[1];
+       nice   = nice_read - last_cpu_results[2];
+       idle   = idle_read - last_cpu_results[3];       
+       /* Calculate the % usage */
+       if ( (user + system + nice + idle) > 0) {
+         usage_time = user + system + nice;
+         total_time = usage_time + idle;
+       }
+       if ( (total_time > 0) &&
+            (have_last_cpu == YES) ) 
+         currentLoad = (100 * usage_time) / total_time;
+       else
+         currentLoad = -1;
+       /* Store the values for the next calculation*/
+       last_cpu_results[0] = user_read;
+       last_cpu_results[1] = system_read;
+       last_cpu_results[2] = nice_read;
+       last_cpu_results[3] = idle_read;
+       have_last_cpu = YES;
+       MUTEX_UNLOCK(&statusMutex);
+       return;
+      }
+    }
+  }
+#endif
+
+  /* try kstat (Solaris only) */
+#if SOLARIS && HAVE_KSTAT_H && HAVE_SYS_SYSINFO_H
+  {
+    static long long last_idlecount;
+    static long long last_totalcount;
+    static int kstat_once; /* if open fails, don't keep
+                             trying */
+    kstat_ctl_t * kc;
+    kstat_t * khelper;
+    long long idlecount;
+    long long totalcount;
+    long long deltaidle;
+    long long deltatotal;
+
+    if (kstat_once == 1)
+      goto ABORT_KSTAT;
+    kc = kstat_open();
+    if (kc == NULL) {
+      LOG_STRERROR(LOG_ERROR, "kstat_open");
+      goto ABORT_KSTAT;
+    }
+
+    idlecount = 0;
+    totalcount = 0;
+    for (khelper = kc->kc_chain;
+        khelper != NULL;
+        khelper = khelper->ks_next) {
+      cpu_stat_t stats;
+
+      if (0 != strncmp(khelper->ks_name,
+                      "cpu_stat",
+                      strlen("cpu_stat")) )
+       continue;
+      if (khelper->ks_data_size > sizeof(cpu_stat_t))
+       continue; /* better save then sorry! */
+      if (-1 != kstat_read(kc, khelper, &stats)) {
+       idlecount
+         += stats.cpu_sysinfo.cpu[CPU_IDLE];
+       totalcount
+         += stats.cpu_sysinfo.cpu[CPU_IDLE] +
+         stats.cpu_sysinfo.cpu[CPU_USER] +
+         stats.cpu_sysinfo.cpu[CPU_KERNEL] +
+         stats.cpu_sysinfo.cpu[CPU_WAIT];
+      }
+    }
+    if (0 != kstat_close(kc))
+      LOG_STRERROR(LOG_ERROR, "kstat_close");
+    if ( (idlecount == 0) &&
+        (totalcount == 0) )
+      goto ABORT_KSTAT; /* no stats found => abort */
+    deltaidle = idlecount - last_idlecount;
+    deltatotal = totalcount - last_totalcount;
+    if ( (deltatotal > 0) &&
+        (last_totalcount > 0) )
+      currentLoad = (int) (100 * deltaidle / deltatotal);
+    else
+      currentLoad = -1;
+    last_idlecount = idlecount;
+    last_totalcount = totalcount;
+    MUTEX_UNLOCK(&statusMutex);
+    return;
+  ABORT_KSTAT:
+    kstat_once = 1; /* failed, don't try again */
+  }
+#endif
+
+  /* insert methods better than getloadavg for
+     other platforms HERE! */
+
+  /* ok, maybe we have getloadavg on this platform */
+#if HAVE_GETLOADAVG
+  {
+    static int warnOnce = 0;
+    double loadavg;
+    if (1 != getloadavg(&loadavg, 1)) {
+      /* only warn once, if there is a problem with
+        getloadavg, we're going to hit it frequently... */
+      if (warnOnce == 0) {
+       warnOnce = 1;
+       LOG_STRERROR(LOG_ERROR, "getloadavg");
+      }
+      currentLoad = -1;
+    } else {
+      /* success with getloadavg */
+      currentLoad = (int) (100 * loadavg);
+      MUTEX_UNLOCK(&statusMutex);
+      return;
+    }
+  }
+#endif
+
+#if MINGW
+  /* Win NT? */
+  if (GNNtQuerySystemInformation) {
+    static double dLastKernel;
+    static double dLastIdle;
+    static double dLastUser;
+    double dKernel;
+    double dIdle;
+    double dUser;
+    double dDiffKernel;
+    double dDiffIdle;
+    double dDiffUser;
+    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION theInfo;
+
+    if (GNNtQuerySystemInformation(SystemProcessorPerformanceInformation,
+                                  &theInfo,
+                                  sizeof(theInfo),
+                                  NULL) == NO_ERROR) {
+      /* PORT-ME MINGW: Multi-processor? */
+      dKernel = Li2Double(theInfo.KernelTime);
+      dIdle = Li2Double(theInfo.IdleTime);
+      dUser = Li2Double(theInfo.UserTime);
+      dDiffKernel = dKernel - dLastKernel;
+      dDiffIdle = dIdle - dLastIdle;
+      dDiffUser = dUser - dLastUser;
+
+      if ( ( (dDiffKernel + dDiffUser) > 0) &&
+          (dLastIdle + dLastKernel + dLastUser > 0) )
+        currentLoad = 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 100.0;
+      else
+        currentLoad = -1; /* don't know (yet) */
+
+      dLastKernel = dKernel;
+      dLastIdle = dIdle;
+      dLastUser = dUser;
+
+      MUTEX_UNLOCK(&statusMutex);
+      return;
+    } else {
+      /* only warn once, if there is a problem with
+        NtQuery..., we're going to hit it frequently... */
+      static int once;
+      if (once == 0) {
+       once = 1;
+       LOG(LOG_ERROR,
+           _("Cannot query the CPU usage (Windows NT).\n"));
+      }
+    }
+  } else { /* Win 9x */
+    HKEY hKey;
+    DWORD dwDataSize, dwType, dwDummy;
+
+    /* Start query */
+    if (RegOpenKeyEx(HKEY_DYN_DATA,
+                    "PerfStats\\StartSrv",
+                    0,
+                    KEY_ALL_ACCESS,
+                     &hKey) != ERROR_SUCCESS) {
+      /* only warn once */
+      static int once = 0;
+      if (once == 0) {
+       once = 1;
+       LOG(LOG_ERROR,
+           _("Cannot query the CPU usage (Win 9x)\n"));
+      }
+    }
+
+    RegOpenKeyEx(HKEY_DYN_DATA,
+                "PerfStats\\StartStat",
+                0,
+                KEY_ALL_ACCESS,
+                &hKey);
+    dwDataSize = sizeof(dwDummy);
+    RegQueryValueEx(hKey,
+                   "KERNEL\\CPUUsage",
+                   NULL,
+                   &dwType,
+                   (LPBYTE) &dwDummy,
+                    &dwDataSize);
+    RegCloseKey(hKey);
+
+    /* Get CPU usage */
+    RegOpenKeyEx(HKEY_DYN_DATA,
+                "PerfStats\\StatData",
+                0,
+                KEY_ALL_ACCESS,
+                 &hKey);
+    dwDataSize = sizeof(currentLoad);
+    RegQueryValueEx(hKey,
+                   "KERNEL\\CPUUsage",
+                   NULL,
+                   &dwType,
+                    (LPBYTE) &currentLoad,
+                   &dwDataSize);
+    RegCloseKey(hKey);
+
+    /* Stop query */
+    RegOpenKeyEx(HKEY_DYN_DATA,
+                "PerfStats\\StopStat",
+                0,
+                KEY_ALL_ACCESS,
+                 &hKey);
+    RegOpenKeyEx(HKEY_DYN_DATA,
+                "PerfStats\\StopSrv",
+                0,
+                KEY_ALL_ACCESS,
+                 &hKey);
+    dwDataSize = sizeof(dwDummy);
+    RegQueryValueEx(hKey,
+                   "KERNEL\\CPUUsage",
+                   NULL,
+                   &dwType,
+                   (LPBYTE)&dwDummy,
+                    &dwDataSize);
+    RegCloseKey(hKey);
+
+    MUTEX_UNLOCK(&statusMutex);
+    return;
+  }
+#endif
+
+  /* loadaverage not defined and no platform
+     specific alternative defined
+     => default: error
+  */
+  currentLoad = -1;
+  MUTEX_UNLOCK(&statusMutex);
+}
+
+static void cronLoadUpdate(void * unused) {
+  updateCpuUsage();
+  if (! useBasicMethod)
+    updateInterfaceTraffic();
+}
+
+/**
+ * Re-read the configuration for statuscalls.
+ */
+static void resetStatusCalls() {
+  char * interfaces;
+  int i;
+  int numInterfaces;
+
+  MUTEX_LOCK(&statusMutex);
+  for (i=0;i<ifcsSize;i++)
+    FREE(ifcs[i].name);
+  GROW(ifcs,
+       ifcsSize,
+       0);
+  interfaces
+    = getConfigurationString("LOAD",
+                            "INTERFACES");
+  /* fail if config-file is incomplete */
+  if ( (interfaces == NULL) ||
+       (strlen(interfaces) == 0) ) {
+    LOG(LOG_ERROR,
+       _("No network interfaces defined in configuration section `%s' under 
`%s'!\n"),
+       "LOAD",
+       "INTERFACES");
+  } else {
+    /* The string containing the interfaces is formatted in the following way:
+     * each comma is replaced by '\0' and the pointers to the beginning of 
every
+     * interface are stored
+     */
+    numInterfaces = 1;
+    for (i=strlen(interfaces)-1;i>=0;i--)
+      if (interfaces[i] == ',')
+       numInterfaces++;
+    GROW(ifcs,
+        ifcsSize,
+        numInterfaces);
+    for (i=strlen(interfaces)-1;i>=0;i--) {
+      if (interfaces[i] == ',') {
+       ifcs[--numInterfaces].name = STRDUP(&interfaces[i+1]);
+       numInterfaces++;
+       interfaces[i] = '\0';
+      }
+    }
+    ifcs[--numInterfaces].name = STRDUP(interfaces);
+    GNUNET_ASSERT(numInterfaces == 0);
+    for (i=0;i<ifcsSize;i++) {
+      ifcs[i].last_in = 0;
+      ifcs[i].last_out = 0;
+    }
+  }
+  FREENONNULL(interfaces);
+  useBasicMethod
+    = testConfigurationString("LOAD",
+                             "BASICLIMITING",
+                             "YES");
+  maxNetDownBPS
+    = getConfigurationInt("LOAD",
+                         "MAXNETDOWNBPSTOTAL");
+  if (maxNetDownBPS == 0)
+    maxNetDownBPS = 50000;
+  maxNetUpBPS
+    = getConfigurationInt("LOAD",
+                         "MAXNETUPBPSTOTAL");
+  if (maxNetUpBPS == 0)
+    maxNetUpBPS = 50000;
+  maxCPULoad
+    = getConfigurationInt("LOAD",
+                         "MAXCPULOAD");
+  if (maxCPULoad == 0)
+    maxCPULoad = 100;
+  MUTEX_UNLOCK(&statusMutex);
+}
+
+
+
+/**
+ * Get the load of the network relative to what is allowed.
+ * @return the network load as a percentage of allowed
+ *        (100 is equivalent to full load)
+ */
+int getNetworkLoadUp() {
+  static unsigned long long overload;
+  static unsigned long long lastSum;
+  static cron_t lastCall;
+  static int lastValue;
+  cron_t now;
+  unsigned long long maxExpect;
+  unsigned long long currentLoadSum;
+  int i;
+  int ret;
+
+  MUTEX_LOCK(&statusMutex);
+  currentLoadSum = globalTrafficBetweenProc.last_out;
+  for (i=0;i<ifcsSize;i++)
+    currentLoadSum += ifcs[i].last_out;
+  cronTime(&now);
+  if ( (lastSum > currentLoadSum) ||
+       (lastSum == 0) ||
+       (now < lastCall) ) {
+    /* integer overflow or first datapoint; since we cannot tell where
+       / by how much the overflow happened, all we can do is ignore
+       this datapoint.  So we return -1 -- AND reset lastSum / lastCall. */
+    lastSum = currentLoadSum;
+    lastCall = now;
+    MUTEX_UNLOCK(&statusMutex);
+    return -1;
+  }
+  if (maxNetUpBPS == 0) {
+    MUTEX_UNLOCK(&statusMutex);
+    return -1;
+  }
+  if (now - lastCall < cronSECONDS) {
+    /* increase last load proportional to difference in
+       data transmitted and in relation to the limit */
+    ret = lastValue + 100 * (currentLoadSum - lastSum) / maxNetUpBPS;
+    MUTEX_UNLOCK(&statusMutex);
+    return ret;
+  }
+  currentLoadSum -= lastSum;
+  lastSum += currentLoadSum;
+  currentLoadSum += overload;
+  maxExpect = ( (now - lastCall) * maxNetUpBPS ) / cronSECONDS;
+  lastCall = now;
+  if (currentLoadSum < maxExpect)
+    overload = 0;
+  else
+    overload = currentLoadSum - maxExpect;
+  lastValue = currentLoadSum * 100 / maxExpect;
+  ret = lastValue;
+  MUTEX_UNLOCK(&statusMutex);
+  return ret;
+}
+
+/**
+ * Get the load of the network relative to what is allowed.
+ * @return the network load as a percentage of allowed
+ *        (100 is equivalent to full load)
+ */
+int getNetworkLoadDown() {
+  static unsigned long long overload;
+  static unsigned long long lastSum;
+  static cron_t lastCall;
+  static int lastValue;
+  cron_t now;
+  unsigned long long maxExpect;
+  unsigned long long currentLoadSum;
+  int i;
+  int ret;
+
+  MUTEX_LOCK(&statusMutex);
+  currentLoadSum = globalTrafficBetweenProc.last_in;
+  for (i=0;i<ifcsSize;i++)
+    currentLoadSum += ifcs[i].last_in;
+  cronTime(&now);
+  if ( (lastSum > currentLoadSum) ||
+       (lastSum == 0) ||
+       (now < lastCall) ) {
+    /* integer overflow or first datapoint; since we cannot tell where
+       / by how much the overflow happened, all we can do is ignore
+       this datapoint.  So we return -1 -- AND reset lastSum / lastCall. */
+    lastSum = currentLoadSum;
+    lastCall = now;
+    MUTEX_UNLOCK(&statusMutex);
+    return -1;
+  }
+  if (maxNetDownBPS == 0) {
+    MUTEX_UNLOCK(&statusMutex);
+    return -1;
+  }
+  if (now - lastCall < cronSECONDS) {
+    /* increase last load proportional to difference in
+       data transmitted and in relation to the limit */
+    ret = lastValue + 100 * (currentLoadSum - lastSum) / maxNetDownBPS;
+    MUTEX_UNLOCK(&statusMutex);
+    return ret;
+  }
+  currentLoadSum -= lastSum;
+  lastSum += currentLoadSum;
+  currentLoadSum += overload;
+  maxExpect = ( (now - lastCall) * maxNetDownBPS ) / cronSECONDS;
+  lastCall = now;
+  if (currentLoadSum < maxExpect)
+    overload = 0;
+  else
+    overload = currentLoadSum - maxExpect;
+  lastValue = currentLoadSum * 100 / maxExpect;
+  ret = lastValue;
+  MUTEX_UNLOCK(&statusMutex);
+  return ret;
+}
+
+/**
+ * Get the load of the CPU relative to what is allowed.
+ * @return the CPU load as a percentage of allowed
+ *        (100 is equivalent to full load)
+ */
+int getCPULoad() {
+  static int lastRet = -1;
+  static cron_t lastCall;
+  int ret;
+  cron_t now;
+
+  if (initialized_ == NO) {
+    lastRet = -1;
+    return -1;
+  }
+  MUTEX_LOCK(&statusMutex);
+  ret = (100 * currentLoad) / maxCPULoad;
+
+  cronTime(&now);
+  if ( (lastRet != -1) &&
+       (now - lastCall < 250 * cronMILLIS) ) {
+    /* use smoothing, but do NOT update lastRet at frequencies higher
+       than 250ms; this makes the smoothing (mostly) independent from
+       the frequency at which getCPULoad is called. */
+    ret = (ret + 7 * lastRet)/8;
+    MUTEX_UNLOCK(&statusMutex);
+    return ret;
+  }
+
+  /* for CPU, we don't do the 'fast increase' since CPU is much
+     more jitterish to begin with */
+  if (lastRet != -1)
+    ret = (ret + 7 * lastRet)/8;
+  lastRet = ret;
+  lastCall = now;
+  MUTEX_UNLOCK(&statusMutex);
+  return ret;
+}
+
+/**
+ * The following method is called in order to initialize the status calls
+ * routines.  After that it is safe to call each of the status calls separately
+ * @return OK on success and SYSERR on error (or calls errexit).
+ */
+void initStatusCalls() {
+#ifdef LINUX
+  proc_stat = fopen("/proc/stat", "r");
+  if (NULL == proc_stat)
+    LOG_FILE_STRERROR(LOG_ERROR,
+                     "fopen",
+                     "/proc/stat");
+  proc_net_dev = fopen(PROC_NET_DEV, "r");
+  if (NULL == proc_net_dev)
+    LOG_FILE_STRERROR(LOG_ERROR,
+                     "fopen",
+                     PROC_NET_DEV);
+#endif
+  MUTEX_CREATE_RECURSIVE(&statusMutex);
+  initialized_ = YES;
+  resetBetweenProc();
+  registerConfigurationUpdateCallback(&resetStatusCalls);
+  resetStatusCalls();
+  cronLoadUpdate(NULL);
+  addCronJob(&cronLoadUpdate,
+            10 * cronSECONDS,
+            10 * cronSECONDS,
+            NULL);
+  getNetworkLoadUp();
+  getNetworkLoadDown();
+}
+
+/**
+ * Shutdown the status calls module.
+ */
+void doneStatusCalls() {
+  int i;
+
+  if (initialized_ == NO)
+    return;
+  unregisterConfigurationUpdateCallback(&resetStatusCalls);
+  delCronJob(&cronLoadUpdate,
+            10 * cronSECONDS,
+            NULL);
+  initialized_ = NO;
+#ifdef LINUX
+  if (proc_stat != NULL) {
+    fclose(proc_stat);
+    proc_stat = NULL;
+  }
+  if (proc_net_dev != NULL) {
+    fclose(proc_net_dev);
+    proc_net_dev = NULL;
+  }
+#endif
+  for (i=0;i<ifcsSize;i++)
+    FREE(ifcs[i].name);
+  GROW(ifcs,
+       ifcsSize,
+       0);
+  MUTEX_DESTROY(&statusMutex);
+}
+
+
+/* end of statuscalls.c */

Added: GNUnet/src/util/os/statuscallstest.c
===================================================================
--- GNUnet/src/util/os/statuscallstest.c        2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/util/os/statuscallstest.c        2006-06-22 17:50:56 UTC (rev 
3024)
@@ -0,0 +1,76 @@
+/**
+ * @file util/statuscallstest.c
+ * @brief testcase for util/statuscalls.c
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+/**
+ * Perform option parsing from the command line.
+ */
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  char c;
+
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "_MAGIC_",
+                                    "YES"));
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "GNUNETD_HOME",
+                                    "/tmp/gnunet_test/"));
+  FREENONNULL(setConfigurationString("FILES",
+                                    "gnunet.conf",
+                                    "check.conf"));
+  while (1) {
+    int option_index = 0;
+    static struct GNoption long_options[] = {
+      { "config",  1, 0, 'c' },
+      { 0,0,0,0 }
+    };
+
+    c = GNgetopt_long(argc,
+                     argv,
+                     "c:",
+                     long_options,
+                     &option_index);
+
+    if (c == -1)
+      break;  /* No more flags to process*/
+
+    switch(c) {
+    case 'c':
+      FREENONNULL(setConfigurationString("FILES",
+                                        "gnunet.conf",
+                                        GNoptarg));
+      break;
+    } /* end of parsing commandline */
+  }
+  return OK;
+}
+
+int main(int argc, char * argv[]){
+  int ret;
+  cron_t start;
+
+  if (OK != initUtil(argc, argv, &parseCommandLine))
+    errexit("Error during initialization!\n");
+  startCron();
+  /* need to run each phase for more than 10s since
+     statuscalls only refreshes that often... */
+  cronTime(&start);
+  while (start + 12 * cronSECONDS > cronTime(NULL))
+    sleep(1);
+  cronTime(&start);
+  ret = getCPULoad();
+  while (start + 12 * cronSECONDS > cronTime(NULL))
+    sqrt(245.2523); /* do some processing to drive load up */
+  if (ret > getCPULoad())
+    printf("busy loop decreased CPU load: %d < %d.\n",
+          ret,
+          getCPULoad());
+  stopCron();
+  doneUtil();
+
+  return 0;
+}

Deleted: GNUnet/src/util/osconfig.c
===================================================================
--- GNUnet/src/util/osconfig.c  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/osconfig.c  2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,403 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2004, 2005 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-
-*/
-
-/**
- * @file util/osconfig.c
- * @brief functions to read or change the OS configuration
- * @author Nils Durner
- */
-#include "platform.h"
-#include "gnunet_util.h"
-
-/**
- * @brief Enumerate all network interfaces
- * @param callback the callback function
- */
-void enumNetworkIfs(void (*callback) (const char *, int, void *),
-                   void * cls) {
-#ifdef MINGW
-  ListNICs(callback, cls);
-#else
-  char entry[11], *dst;
-  FILE *f;
-
-  if (system("ifconfig > /dev/null 2> /dev/null"))
-    if (system("/sbin/ifconfig > /dev/null 2> /dev/null") == 0)
-      f = popen("/sbin/ifconfig 2> /dev/null", "r");
-    else
-      f = NULL;
-  else
-    f = popen("ifconfig 2> /dev/null", "r");
-
-  if (!f)
-    return;
-
-  while(1)
-    {
-      int i = 0;
-      int c = fgetc(f);
-
-      if (c == EOF)
-       break;
-
-      dst = entry;
-
-      /* Read interface name until the first space (or colon under OS X) */
-      while (c != EOF && c != '\n' &&
-#ifdef OSX
-            c != ':'
-#else
-            c != ' '
-#endif
-            && i < 10)
-       {
-         *dst++ = c;
-         i++;
-         c = fgetc(f);
-       }
-      *dst = 0;
-
-      if (entry[0])
-       callback(entry, strcmp(entry, "eth0") == 0, cls);
-
-      while(c != '\n' && c != EOF)
-       c = fgetc(f);
-    }
-
-  pclose(f);
-#endif
-}
-
-/**
- * @brief Checks if we can start GNUnet automatically
- * @return 1 if yes, 0 otherwise
- */
-int isOSAutostartCapable() {
-#ifdef LINUX
-  if (ACCESS("/usr/sbin/update-rc.d", X_OK) == 0) {
-    /* Debian */
-    if (ACCESS("/etc/init.d/", W_OK) == 0)
-      return 1;
-  }
-  return 0;
-#else
-  #ifdef WINDOWS
-    return 1;
-  #else
-    return 0;
-  #endif
-#endif
-}
-
-/**
- * @brief Make GNUnet start automatically
- * @param doAutoStart true to enable autostart, false to disable it
- * @param username name of the user account to use
- * @param groupname name of the group to use
- * @return 0 on success
- */
-int autostartService(int doAutoStart, 
-                    const char * username, 
-                    const char * groupname) {
-#ifdef WINDOWS
-  if (doAutoStart)
-    {
-      if (IsWinNT())
-       {
-         char *err = NULL;
-         DWORD dwErr = 0;
-       
-         if (username && !strlen(username))
-           username = NULL;
-       
-         /* Install service */
-         switch(InstallAsService(username))
-           {
-           case 0:
-           case 1:
-             break;
-           case 2:
-             if (GetLastError() != ERROR_SERVICE_EXISTS)
-               return 1;
-           case 3:
-             return 2;
-           default:
-             return -1;
-           }
-       
-         /* Grant permissions to the GNUnet directory */
-         if ((!err || dwErr == ERROR_SERVICE_EXISTS) && username)
-           {
-             char szHome[_MAX_PATH + 1];
-       
-             plibc_conv_to_win_path("/", szHome);
-       
-             if (!AddPathAccessRights(szHome, username, GENERIC_ALL))
-               return 3;
-           }
-       }
-      else
-       {
-         char szPath[_MAX_PATH + 1];
-    HKEY hKey;
-
-         plibc_conv_to_win_path("/bin/gnunetd.exe", szPath);
-       
-    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-        "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_EXECUTE,
-        &hKey) == ERROR_SUCCESS)
-    {
-      if (RegSetValueEx(hKey, "GNUnet", 0, REG_SZ, szPath, strlen(szPath)) !=
-        ERROR_SUCCESS)
-        return 4;
-
-      RegCloseKey(hKey);
-    }
-    else
-      return 4;
-       }
-    }
-  else
-    {
-      if (IsWinNT())
-       {
-         switch (UninstallService())
-           {
-           case 0:
-           case 1:
-             break;
-           case 2:
-             return 1;
-           case 3:
-             return 5;
-           case 4:
-             return 6;
-           default:
-             return -1;
-           }
-       }
-      else
-       {
-         HKEY hKey;
-       
-         if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 
0, KEY_SET_VALUE,
-                       &hKey) == ERROR_SUCCESS)
-           {
-             RegDeleteValue(hKey, "GNUnet");
-       
-             RegCloseKey(hKey);
-           }
-       }
-    }
-#else
-  /* Unix */
-  if (ACCESS("/usr/sbin/update-rc.d", X_OK) == 0) {
-    /* Debian */
-    if (doAutoStart) {
-      struct stat buf;
-      if (STAT("/etc/init.d/gnunetd", &buf) == -1) {
-       /* create init file */
-       FILE *f = FOPEN("/etc/init.d/gnunetd", "w");
-       if (! f)
-         return 1;
-       
-       fputs("#! /bin/sh\n"
-             "#\n"
-             "# Automatically created by gnunet-setup\n"
-             "#\n"
-             "\n"
-             "PATH=$PATH:" PREFIX_PATH "/bin"
-             "PIDFILE=/var/run/gnunetd/gnunetd.pid\n"
-             "\n"
-             "case \"$1\" in\n"
-             " start)\n"
-             "         echo -n \"Starting GNUnet: \"\n"
-             "         gnunetd\n"
-             "         echo \"gnunetd\"\n"
-             "         ;;\n"
-             " stop)\n"
-             "         echo -n \"Stopping GNUnet: \"\n"
-             "         kill `cat $PIDFILE`\n"
-             "         echo \"gnunetd\"\n"
-             "         ;;\n"
-             " reload)\n"
-             "         echo -n \"Reloading GNUnet: \"\n"
-             "         kill -HUP `cat $PIDFILE`\n"
-             "         echo \"gnunetd\"\n"
-             "         ;;\n"
-             " restart|force-reload)\n"
-             "         echo \"Restarting GNUnet: gnunetd...\"\n"
-             "         $0 stop\n"
-             "         sleep 1\n"
-             "         $0 start\n"
-             "         ;;\n"
-             " *)\n"
-             "         echo \"Usage: /etc/init.d/gnunetd 
{start|stop|reload|restart|force-reload}\" >&2\n"
-             "         exit 1\n"
-             "         ;;\n"
-             "\n"
-             "esac\n"
-             "exit 0\n", f);
-       fclose(f);
-       CHMOD("/etc/init.d/gnunetd", S_IRWXU | S_IRGRP | S_IXGRP |
-             S_IROTH | S_IXOTH);
-      }
-      errno = system("/usr/sbin/update-rc.d gnunetd defaults");
-      if (errno != 0)
-       return 1;
-    }
-    else {
-      if ( (UNLINK("/etc/init.d/gnunetd") != -1) ||
-          (errno != ENOENT)) {
-       if (ACCESS("/usr/sbin/update-rc.d", X_OK) == 0) {
-         errno = system("/usr/sbin/update-rc.d gnunetd remove");
-         if (errno != 0) {
-           errno = EPERM;
-           return 1;
-         }
-       }
-       else {
-         errno = EPERM;
-         return 1;
-       }
-      }
-      else
-       return 0;
-    }
-  }
-  else
-    return 1;
-#endif
-  return 0;
-}
-
-/**
- * @brief Checks if we can add an user for the GNUnet service
- * @return 1 if yes, 0 otherwise
- * @todo support for useradd(8)
- */
-int isOSUserAddCapable(){
-#ifdef WINDOWS
-       return IsWinNT();
-#endif
-#ifdef LINUX
-       if (ACCESS("/usr/sbin/adduser", X_OK) == 0)
-         return (geteuid() == 0);
-       else
-               /* TODO: useradd */
-#endif
-               return 0;
-}
-
-/**
- * @brief Checks if we can add a group for the GNUnet service
- * @return 1 if yes, 0 otherwise
- * @todo support for groupadd(8)
- */
-int isOSGroupAddCapable() {
-#ifdef LINUX
-       if (ACCESS("/usr/sbin/addgroup", X_OK) == 0) {
-         return (geteuid() == 0);
-       }
-       /* TODO: groupadd */
-       else
-#endif
-               return 0;
-}
-
-/**
- * @brief Add a service account for GNUnet
- * @param group the group of the new user
- * @param name the name of the new user
- * @return 0 on success
- */
-int createGroupUser(const char *group_name, 
-                   const char *user_name) {
-       int haveGroup;
-
-       if ( (user_name == NULL) ||
-            (0 == strlen(user_name)) ) 
-               return 0;
-       
-#ifdef WINDOWS
-       if (IsWinNT())
-       {
-               return CreateServiceAccount(user_name, "GNUnet service 
account");
-       }
-#else
-
-       if (ACCESS("/usr/sbin/adduser", X_OK) == 0) {
-               /* Debian */
-               /* TODO: FreeBSD? 
http://www.freebsd.org/cgi/man.cgi?query=adduser&sektion=8 */
-               char *cmd;
-
-               haveGroup = group_name && strlen(group_name) > 0;               
-               cmd = MALLOC(haveGroup ? strlen(group_name) : 0 + 
strlen(user_name) + 64);
-               
-               if (haveGroup) {
-                       sprintf(cmd, "/usr/sbin/addgroup --quiet --system %s", 
group_name);             
-                       system(cmd);
-               }
-               
-               sprintf(cmd, "/usr/sbin/adduser --quiet --system %s %s "
-                       "--no-create-home %s", haveGroup ? "--ingroup" : "",
-                       haveGroup ? group_name : "", user_name);
-               system(cmd);
-               
-               FREE(cmd);
-       }
-       /* TODO: useradd */
-       else
-               return 1;
-#endif
-
-       return 0;
-}
-
-char *winErrorStr(const char *prefix, int dwErr)
-{
-#ifdef WINDOWS
-       char *err, *ret;
-       int mem;
-       
-       if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM,
-       NULL, (DWORD) dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
(LPTSTR) &err,
-               0, NULL ))
-       {
-               err = "";
-       }
-
-       mem = strlen(err) + strlen(prefix) + 20;
-       ret = (char *) malloc(mem);
-
-  snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr);
-
-  LocalFree(err);
-
-  return ret;
-#else
-       return NULL;
-#endif
-}
-
-
-/* end of osconfig.c */

Deleted: GNUnet/src/util/port.c
===================================================================
--- GNUnet/src/util/port.c      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/port.c      2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,102 +0,0 @@
-/*
-     This file is part of GNUnet
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-/**
- * @file util/port.c
- * @brief functions for GNUnet clients to establish connection with gnunetd
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-/**
- * Return the port-number (in host byte order)
- */
-unsigned short getGNUnetPort() {
-  static unsigned short port;
-  const char *setting;
-
-  if (port != 0)
-    return port;
-  if (testConfigurationString("GNUNETD",
-                             "_MAGIC_",
-                             "YES"))
-    setting = "PORT";
-  else
-    setting = "CLIENT-PORT";
-
-  port = (unsigned short) getConfigurationInt("NETWORK",
-                                             setting);
-  if (port == 0) {
-    errexit(_("Cannot determine port of gnunetd server. "
-             "Define in configuration file in section `%s' under `%s'.\n"),
-           "NETWORK",
-           setting);
-  }
-  return port;
-}
-
-/**
- * Configuration: get the GNUnetd host where the client
- * should connect to (via TCP)
- * @return the name of the host
- */
-static const char * getGNUnetdHost() {
-  static char * res;
-
-  if (res != NULL)
-    return res;
-  res = getConfigurationString("NETWORK",
-                              "HOST");
-  if (res == NULL)
-    res = "localhost";
-  return res;
-}
-
-/**
- * Get a GNUnet TCP socket that is connected to gnunetd.
- */
-GNUNET_TCP_SOCKET * getClientSocket() {
-  GNUNET_TCP_SOCKET * sock;
-  const char * host;
-
-  sock = MALLOC(sizeof(GNUNET_TCP_SOCKET));
-  host = getGNUnetdHost();
-  if (SYSERR == initGNUnetClientSocket(getGNUnetPort(),
-                                      host,
-                                      sock)) {
-    LOG(LOG_ERROR,
-       _("Could not connect to gnunetd.\n"));
-    FREE(sock);
-    return NULL;
-  }
-  return sock;
-}
-
-/**
- * Free a Client socket.
- */
-void releaseClientSocket(GNUNET_TCP_SOCKET * sock) {
-  if (sock != NULL) {
-    destroySocket(sock);
-    FREE(sock);
-  }
-}
-
-/* end of port.c */

Deleted: GNUnet/src/util/printhelp.c
===================================================================
--- GNUnet/src/util/printhelp.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/printhelp.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,169 +0,0 @@
-/*
-     This file is part of GNUnet
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-/**
- * @file printhelp.c
- * @brief Common option processing methods for GNUnet clients.
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#define BORDER 29
-
-
-void formatHelp(const char * general,
-               const char * description,
-               const Help * opt) {
-  int slen;
-  int i;
-  int j;
-  int ml;
-  int p;
-  char * scp;
-  const char * trans;
-       
-  printf(_("Usage: %s\n%s\n\n"),
-        gettext(general),
-        gettext(description));
-  printf(_("Arguments mandatory for long options are also mandatory for short 
options.\n"));
-  slen = 0;
-  i = 0;
-  while (opt[i].description != NULL) {
-    if (opt[i].shortArg == 0)
-      printf("      ");
-    else
-      printf("  -%c, ",
-            opt[i].shortArg);
-    printf("--%s",
-          opt[i].longArg);
-    slen = 8 + strlen(opt[i].longArg);
-    if (opt[i].mandatoryArg != NULL) {
-      printf("=%s",
-            opt[i].mandatoryArg);
-      slen += 1+strlen(opt[i].mandatoryArg);
-    }
-    if (slen > BORDER) {
-      printf("\n%*s", BORDER, "");
-      slen = BORDER;
-    }
-    if (slen < BORDER) {
-      printf("%*s", BORDER-slen, "");
-      slen = BORDER;
-    }
-    trans = gettext(opt[i].description);
-    ml = strlen(trans);
-    p = 0;
-  OUTER:
-    while (ml - p > 78 - slen) {
-      for (j=p+78-slen;j>p;j--) {
-       if (isspace(trans[j])) {
-         scp = malloc(j-p+1);
-         memcpy(scp,
-                &trans[p],
-                j-p);
-         scp[j-p] = '\0';
-         printf("%s\n%*s",
-                scp,
-                BORDER+2,
-                "");
-         free(scp);
-         p = j+1;
-         slen = BORDER+2;
-         goto OUTER;
-       }
-      }
-      /* could not find space to break line */
-      scp = malloc(78 - slen + 1);
-      memcpy(scp,
-            &trans[p],
-            78 - slen);
-      scp[78 - slen] = '\0';
-      printf("%s\n%*s",
-            scp,
-            BORDER+2,
-            "");       
-      free(scp);
-      slen = BORDER+2;
-      p = p + 78 - slen;
-    }
-    /* print rest */
-    if (p < ml)
-      printf("%s\n",
-            &trans[p]);
-    i++;
-  }
-}
-
-/**
- * Parse the default set of options and set
- * options in the configuration accordingly.
- * This does not include --help or --version.
- * @return YES if the option was a default option
- *  that was successfully processed
- */
-int parseDefaultOptions(char c,
-                       char * optarg) {
-  char * host;
-  char * port_string;
-  unsigned short port;
-
-  switch(c) {
-  case 'c':
-    FREENONNULL(setConfigurationString("FILES",
-                                      "gnunet.conf",
-                                      optarg));
-    break;
-  case 'd':
-    FREENONNULL(setConfigurationString("GNUNETD",
-                                      "LOGFILE",
-                                      NULL));
-    break;
-  case 'H': {
-    port_string = strstr(optarg, ":");   
-    if (NULL != port_string) {
-      port = (unsigned short) atoi(port_string+1);
-      setConfigurationInt("NETWORK",
-                         "CLIENT-PORT",
-                         port);
-      host = MALLOC(1 + port_string - optarg);
-      memcpy(host, optarg, port_string - optarg);
-      host[port_string - optarg] = '\0';
-    } else {
-      host = STRDUP(optarg);
-    }
-    FREENONNULL(setConfigurationString("NETWORK",
-                                      "HOST",
-                                      host));
-    FREE(host);
-    break;
-  }
-  case 'L':
-    
-    FREENONNULL(setConfigurationString("GNUNET",
-                                      "LOGLEVEL",
-                                      optarg));
-    break;
-  default:
-    return NO;
-  }
-  return YES;
-}
-
-/* end of printhelp.c */

Deleted: GNUnet/src/util/semaphore.c
===================================================================
--- GNUnet/src/util/semaphore.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/semaphore.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,1042 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004 Christian Grothoff (and other contributing 
authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/semaphore.c
- * @brief functions related to threading and synchronization
- *
- * In particular, functions for mutexes, semaphores
- * and thread creation are provided.
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#if SOLARIS || FREEBSD || OSX
-#include <semaphore.h>
-#endif
-#if SOMEBSD
-# include <pthread_np.h>
-# include <sys/file.h>
-#endif
-#if LINUX
-# include <sys/ipc.h>
-# include <sys/sem.h>
-#endif
-#ifdef _MSC_VER
-#include <pthread.h>
-#include <semaphore.h>
-#endif
-
-/**
- * Shall we use error-checking (slow)
- * mutexes (e.g. for debugging)
- */
-#define USE_CHECKING_MUTEX 1
-
-typedef struct {
-#if SOLARIS || FREEBSD5 || OSX
-  sem_t * internal;
-#elif WINDOWS
-  HANDLE internal;
-#elif LINUX
-  int internal;
-  char * filename;
-#elif SOMEBSD
-  int initialValue;
-  int fd;
-  Mutex internalLock;
-  char * filename;
-#elif _MSC_VER
-  int internal; /* KLB_FIX */
-  char * filename;
-#else
-  /* PORT-ME! */
-#endif
-} IPC_Semaphore_Internal;
-
-#ifndef PTHREAD_MUTEX_NORMAL
-#ifdef PTHREAD_MUTEX_TIMED_NP
-#define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP
-#else
-#define PTHREAD_MUTEX_NORMAL NULL
-#endif
-#endif
-
-/**
- * This prototype is somehow missing in various Linux pthread
- * include files. But we need it and it seems to be available
- * on all pthread-systems so far. Odd.
- */
-#ifndef _MSC_VER
-extern int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
-#endif
-
-/* ********************* public methods ******************* */
-
-void create_mutex_(Mutex * mutex) {
-  pthread_mutexattr_t attr;
-  pthread_mutex_t * mut;
-
-#if WINDOWS
-  attr = NULL;
-#endif
-
-  pthread_mutexattr_init(&attr);
-#if USE_CHECKING_MUTEX
-#if LINUX
-  pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
-#else
-  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
-#endif
-#else
-#if LINUX
-  pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_NORMAL_NP);
-#else
-  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
-#endif
-#endif
-
-  mut = MALLOC(sizeof(pthread_mutex_t));
-  mutex->internal = mut;
-  GNUNET_ASSERT(0 == pthread_mutex_init(mut, &attr));
-}
-
-void create_recursive_mutex_(Mutex * mutex) {
-  pthread_mutexattr_t attr;
-  pthread_mutex_t * mut;
-
-  pthread_mutexattr_init(&attr);
-#if LINUX
-  GNUNET_ASSERT(0 == pthread_mutexattr_setkind_np
-               (&attr,
-                PTHREAD_MUTEX_RECURSIVE_NP));
-#elif SOMEBSD || FREEBSD || FREEBSD5
-  GNUNET_ASSERT(0 == pthread_mutexattr_setkind_np
-               (&attr,
-                PTHREAD_MUTEX_RECURSIVE));
-#elif SOLARIS || OSX || WINDOWS
-  GNUNET_ASSERT(0 == pthread_mutexattr_settype
-               (&attr,
-                PTHREAD_MUTEX_RECURSIVE));
-#endif
-  mut = MALLOC(sizeof(pthread_mutex_t));
-  mutex->internal = mut;
-  GNUNET_ASSERT(pthread_mutex_init(mut, &attr) == 0);
-}
-
-void destroy_mutex_(Mutex * mutex) {
-  pthread_mutex_t * mut;
-  int k;
-  
-  mut = mutex->internal;
-  if (mut == NULL) {
-    BREAK();
-    return;
-  }
-  mutex->internal = NULL;
-  errno = 0;
-  if ((k = pthread_mutex_destroy(mut)) != 0) {
-    LOG(LOG_FATAL, _("`%s' failed with error code %d: %s\n"),
-      "pthread_mutex_destroy",
-      k,
-      STRERROR(k));
-    return;
-  }
-  FREE(mut);
-}
-
-void mutex_lock_(Mutex * mutex,
-                const char * filename,
-                const int line) {
-  pthread_mutex_t * mut;
-  int ret;
-
-  mut = mutex->internal;
-  if (mut == NULL) {
-    BREAK_FL(filename, line);
-    return;
-  }
-  ret = pthread_mutex_lock(mut);
-  if (ret != 0) {
-    if (ret == EINVAL)
-      errexit(_("Invalid argument for `%s' at %s:%d.\n"),
-             "pthread_mutex_lock",
-             filename, line);
-    if (ret == EDEADLK)
-      errexit(_("Deadlock due to `%s' at %s:%d.\n"),
-             "pthread_mutex_lock",
-             filename, line);
-    GNUNET_ASSERT(0);
-  }
-}
-
-void mutex_unlock_(Mutex * mutex,
-                  const char * filename,
-                  const int line) {
-  pthread_mutex_t * mut;
-  int ret;
-
-  mut = mutex->internal;
-  if (mut == NULL) {
-    BREAK_FL(filename, line);
-    return;
-  }
-
-  ret = pthread_mutex_unlock(mut);
-  if (ret != 0) {
-    if (ret == EINVAL)
-      errexit(_("Invalid argument for `%s' at %s:%d.\n"),
-             "pthread_mutex_unlock",
-             filename, line);
-    if (ret == EPERM)
-      errexit(_("Permission denied for `%s' at %s:%d.\n"),
-             "pthread_mutex_unlock",
-             filename, line);
-    GNUNET_ASSERT_FL(0, filename, line);
-  }
-}
-
-/**
- * function must be called prior to semaphore use -- handles
- * setup and initialization.  semaphore destroy (below) should
- * be called when the semaphore is no longer needed.
- */
-Semaphore * semaphore_new_(int value,
-                          const char * filename,
-                          const int linenumber) {
-  pthread_cond_t * cond;
-
-  Semaphore * s = (Semaphore*)xmalloc_(sizeof(Semaphore),
-                                            filename,
-                                            linenumber);
-  s->v = value;
-  MUTEX_CREATE(&(s->mutex));
-  cond = MALLOC(sizeof(pthread_cond_t));
-  s->cond = cond;
-  GNUNET_ASSERT_FL(0 == pthread_cond_init(cond, NULL), filename, linenumber);
-  return s;
-}
-
-void semaphore_free_(Semaphore * s,
-                    const char * filename,
-                    const int linenumber) {
-
-  pthread_cond_t * cond;
-  int k;
-
-  MUTEX_DESTROY(&(s->mutex));
-  cond = s->cond;
-  if ((k = pthread_cond_destroy(cond)) != 0) {
-    LOG(LOG_FATAL, _("`%s' failed with error code %d: %s\n"),
-      "pthread_cond_destroy",
-      k,
-      STRERROR(k));
-    return;    
-  }
-  FREE(cond);
-  xfree_(s,
-        filename,
-        linenumber);
-}
-
-/**
- * function increments the semaphore and signals any threads that
- * are blocked waiting a change in the semaphore.
- */
-int semaphore_up_(Semaphore * s,
-                 const char * filename,
-                 const int linenumber) {
-  int value_after_op;
-  pthread_cond_t * cond;
-
-  GNUNET_ASSERT_FL(s != NULL, filename, linenumber);
-  cond = s->cond;
-  MUTEX_LOCK(&(s->mutex));
-  (s->v)++;
-  value_after_op = s->v;
-  GNUNET_ASSERT(0 == pthread_cond_signal(cond));
-  MUTEX_UNLOCK(&(s->mutex));
-  return value_after_op;
-}
-
-/**
- * function decrements the semaphore and blocks if the semaphore is
- * <= 0 until another thread signals a change.
- */
-int semaphore_down_(Semaphore * s,
-                   const char * filename,
-                   const int linenumber) {
-  int value_after_op;
-  int return_value;
-  pthread_cond_t * cond;
-
-  GNUNET_ASSERT_FL(s != NULL, filename, linenumber);
-  cond = s->cond;
-  MUTEX_LOCK(&(s->mutex));
-  while (s->v <= 0) {
-    if ((return_value = pthread_cond_wait(cond,
-                                         (pthread_mutex_t*)s->mutex.internal)) 
!= 0)
-      DIE_STRERROR_FL("pthread_cond_wait", filename, linenumber);
-  }
-  (s->v)--;
-  value_after_op = s->v;
-  MUTEX_UNLOCK(&(s->mutex));
-  return value_after_op;
-}
-
-/**
- * Function decrements the semaphore. If the semaphore would become
- * negative, the decrement does not happen and the function returns
- * SYSERR. Otherwise OK is returned.
- */
-int semaphore_down_nonblocking_(Semaphore * s,
-                               const char * filename,
-                               const int linenumber) {
-  GNUNET_ASSERT_FL(s != NULL, filename, linenumber);
-  MUTEX_LOCK(&(s->mutex));
-  if (s->v <= 0) {
-    MUTEX_UNLOCK(&(s->mutex));
-    return SYSERR;
-  }
-  (s->v)--;
-  MUTEX_UNLOCK(&(s->mutex));
-  return OK;
-}
-
-#ifdef WINDOWS
-/**
- * @brief Called if a sleeping thread is interrupted
- */
-static void CALLBACK __PTHREAD_SIGNALED(DWORD sig) {
-}
-#endif
-
-/**
- * Returns YES if pt is the handle for THIS thread.
- */
-int PTHREAD_SELF_TEST(PTHREAD_T * pt) {
-  pthread_t * handle;
-
-  GNUNET_ASSERT(pt != NULL);
-  handle = pt->internal;
-  if (handle == NULL)
-    return NO;
-#if HAVE_NEW_PTHREAD_T
-  if (handle->p == pthread_self().p)
-#else
-  if (*handle == pthread_self())
-#endif
-    return YES;
-  else
-    return NO;
-}
-
-/**
- * Get the handle for THIS thread.
- */
-void PTHREAD_GET_SELF(PTHREAD_T * pt) {
-  pt->internal = MALLOC(sizeof(pthread_t));
-  *((pthread_t*)pt->internal) = pthread_self();
-}
-
-/**
- * Release handle for a thread.
- */
-void PTHREAD_REL_SELF(PTHREAD_T * pt) {
-  FREENONNULL(pt->internal);
-  pt->internal = NULL;
-}
-
-/**
- * Create a thread. Use this method instead of pthread_create since
- * BSD may only give a 1k stack otherwise.
- *
- * @param handle handle to the pthread (for detaching, join)
- * @param main the main method of the thread
- * @param arg the argument to main
- * @param stackSize the size of the stack of the thread in bytes.
- *        Note that if the stack overflows, some OSes (seen under BSD)
- *        will just segfault and gdb will give a messed-up stacktrace.
- * @return see pthread_create
- */
-int PTHREAD_CREATE(PTHREAD_T * pt,
-                  PThreadMain main,
-                  void * arg,
-                  size_t stackSize) {
-  pthread_t * handle;
-  pthread_attr_t stack_size_custom_attr;
-  int ret;
-
-  handle = MALLOC(sizeof(pthread_t));
-#ifdef MINGW
-  memset(handle, 0, sizeof(pthread_t));
-#endif
-
-  pthread_attr_init(&stack_size_custom_attr);
-  pthread_attr_setstacksize(&stack_size_custom_attr,
-                           stackSize);
-  ret = pthread_create(handle,
-                      &stack_size_custom_attr,
-                      main,
-                      arg);
-
-  if (ret != 0) {
-    FREE(handle);
-    pt->internal = NULL;
-    return ret;
-  }
-  pt->internal = handle;
-  return ret;
-}
-
-void PTHREAD_JOIN(PTHREAD_T * pt,
-                 void ** ret) {
-  int k;
-  pthread_t * handle;
-
-  GNUNET_ASSERT(pt != NULL);
-  handle = pt->internal;
-  GNUNET_ASSERT(handle != NULL);
-  GNUNET_ASSERT(NO == PTHREAD_SELF_TEST(pt));
-  switch ((k=pthread_join(*handle, ret))) {
-  case 0:
-    FREE(handle);
-    pt->internal = NULL;
-    return;
-  case ESRCH:
-    errexit("`%s' failed with error code %s: %s\n",
-           "pthread_join",
-           "ESRCH",
-           STRERROR(errno));
-  case EINVAL:
-    errexit("`%s' failed with error code %s: %s\n",
-           "pthread_join",
-           "EINVAL",
-           STRERROR(errno));
-  case EDEADLK:
-    errexit("`%s' failed with error code %s: %s\n",
-           "pthread_join",
-           "EDEADLK",
-           STRERROR(errno));
-  default:
-    errexit("`%s' failed with error code %d: %s\n",
-           "pthread_join",
-           k,
-           STRERROR(errno));
-  }
-}
-
-void PTHREAD_DETACH(PTHREAD_T * pt) {
-  pthread_t * handle;
-
-  handle = pt->internal;
-  GNUNET_ASSERT(handle != NULL);
-  if (0 != pthread_detach(*handle))
-    LOG_STRERROR(LOG_ERROR, "pthread_detach");
-  pt->internal = NULL;
-  FREE(handle);
-  return;
-}
-
-void PTHREAD_KILL(PTHREAD_T * pt,
-                 int signal) {
-  pthread_t * handle;
-  int ret;
-
-  handle = pt->internal;
-  if (handle == NULL) {
-    BREAK();
-    return;
-  }
-#ifdef WINDOWS
-  if (signal != 0)
-    ret = QueueUserAPC((PAPCFUNC) __PTHREAD_SIGNALED,
-      pthread_getw32threadhandle_np(*handle), 0) != 0 ? 0 : EINVAL;
-  else
-    ret = pthread_kill(*handle, 0);
-#else
-  ret = pthread_kill(*handle, signal);
-#endif
-  switch (ret) {
-  case 0: 
-    break; /* ok */
-  case EINVAL:
-    LOG(LOG_ERROR, 
-       _("`%s' failed with error code %s: %s\n"),
-       "pthread_kill",
-       "EINVAL",
-       STRERROR(ret));
-    break;
-  case ESRCH:
-    LOG(LOG_ERROR, 
-       _("`%s' failed with error code %s: %s\n"),
-       "pthread_kill",
-       "ESRCH",
-       STRERROR(ret));
-    break;
-  default:
-    LOG(LOG_ERROR, 
-       _("`%s' failed with error code %d: %s\n"),
-       "pthread_kill",
-       ret,
-       STRERROR(ret));
-    break;    
-  }
-}
-
-
-/* ********************** IPC ********************* */
-
-#if LINUX
-  /* IPC semaphore kludging for linux */
-
-  /* Why don't we start at count 0 and increment when opening? */
-  #define PROCCOUNT 10000
-
-  /**
-   * Implementation for a single semaphore actually uses three :
-   *
-   * 0 : actual semaphore value
-   * 1 : process counter
-   * 2 : lock
-   */
-
-  /* Various operations */
-  static struct sembuf op_lock[2] = {
-      {2, 0, 0},        /* wait for [2] (lock) to equal 0 */
-      {2, 1, SEM_UNDO}  /* then increment [2] to 1 - this locks it */
-                        /* UNDO to release the lock if processes exits */      
                         /* before explicitly unlocking */
-  };
-  static struct sembuf op_unlock[1] = {
-      {2, -1, SEM_UNDO} /* decrement [2] (lock) back to 0 */
-  };
-  static struct sembuf    op_endcreate[2] = {
-      {1, -1, SEM_UNDO},/* decrement [1] (proc counter) with undo on exit */
-                       /* UNDO to adjust proc counter if process exits
-                          before explicitly calling sem_close() */
-      {2, -1, SEM_UNDO} /* then decrement [2] (lock) back to 0 */
-  };
-  static struct sembuf    op_close[3] = {
-      {2, 0, 0},        /* wait for [2] (lock) to equal 0 */
-      {2, 1, SEM_UNDO}, /* then increment [2] to 1 - this locks it */
-      {1, 1, SEM_UNDO}  /* then increment [1] (proc counter) */
-  };
-#endif
-
-#if SOMEBSD
-static void FLOCK(int fd,
-                 int operation) {
-  int ret;
-
-  ret = -1;
-  while (ret == -1) {
-    ret = flock(fd, operation);
-    if (ret == -1) {
-      if (errno != EINTR) {
-       LOG_STRERROR(LOG_ERROR, "flock");
-       return;
-      }
-    }
-  }
-  fsync(fd);
-}
-static int LSEEK(int fd, off_t pos, int mode) {
-  int ret;
-  ret = lseek(fd, pos, mode);
-  if (ret == -1)
-    LOG_STRERROR(LOG_ERROR, "lseek");
-  return ret;
-}
-#endif
-
-IPC_Semaphore * ipc_semaphore_new_(const char * basename,
-                                  const unsigned int initialValue,
-                                  const char * filename,
-                                  const int linenumber) {
-  /* Could older FreeBSD use this too since this code can shorten the IPC name 
*/
-#if SOLARIS || OSX || FREEBSD5
-  char * noslashBasename;
-  int i;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
-
-  rret = MALLOC(sizeof(IPC_Semaphore));
-  ret = MALLOC(sizeof(IPC_Semaphore_Internal));
-  rret->platform = ret;
-  noslashBasename = STRDUP(basename);
-  for (i=strlen(noslashBasename);i>0;i--)
-    if (noslashBasename[i] == '/')
-      noslashBasename[i] = '.'; /* first character MUST be /, but Solaris
-                                  forbids it afterwards */
-  noslashBasename[0] = '/';
-  ret->internal = sem_open(noslashBasename,
-                          O_CREAT,
-                          S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, /* 660 */
-                          initialValue);
-  while ( (ret->internal == (void *) SEM_FAILED)
-         && (errno == ENAMETOOLONG) ) {
-    if (strlen(noslashBasename) < 4)
-      break; /* definitely OS error... */
-    noslashBasename[strlen(noslashBasename)/2] = '\0'; /* cut in half */
-    ret->internal = sem_open(noslashBasename,
-                            O_CREAT,
-                            S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, /* 660 */
-                            initialValue);                     
-  }
-  if (ret->internal == (void *) SEM_FAILED)
-    DIE_FILE_STRERROR("sem_open", noslashBasename);
-  FREE(noslashBasename);
-  return rret;
-#elif WINDOWS
-  char * noslashBasename;
-  int i;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
-  SECURITY_ATTRIBUTES sec;
-  DWORD dwErr;
-
-  rret = MALLOC(sizeof(IPC_Semaphore));
-  ret = MALLOC(sizeof(IPC_Semaphore_Internal));
-  rret->platform = ret;
-  noslashBasename = STRDUP(basename);
-  for (i=strlen(noslashBasename);i>0;i--)
-    if (noslashBasename[i] == '\\')
-      noslashBasename[i] = '.'; /* must not contain backslashes */
-
-  sec.nLength = sizeof(SECURITY_ATTRIBUTES);
-  sec.bInheritHandle = TRUE;
-  sec.lpSecurityDescriptor = NULL;
-
-  ret->internal = CreateSemaphore(&sec, initialValue, LONG_MAX, 
noslashBasename);
-  dwErr = GetLastError();
-  if (! ret->internal && dwErr == ERROR_ALREADY_EXISTS) {
-    ret->internal = OpenSemaphore(SEMAPHORE_MODIFY_STATE, TRUE, 
noslashBasename);
-    dwErr = GetLastError();
-  }
-  if (! ret->internal) {
-    LOG(LOG_FAILURE, _("Can't create semaphore: %i"), dwErr);
-    DIE_FILE_STRERROR("sem_open", noslashBasename);
-  }
-  FREE(noslashBasename);
-  return rret;
-#elif LINUX
-  union semun {
-      int             val;
-      struct semid_ds *buf;
-      ushort          *array;
-  } semctl_arg;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
-  key_t key;
-  FILE * fp;
-  int pcount;
-
-  rret = MALLOC(sizeof(IPC_Semaphore));
-  ret = MALLOC(sizeof(IPC_Semaphore_Internal));
-  rret->platform = ret;
-
-  fp = FOPEN(basename, "a+");
-  if (NULL == fp) {
-    LOG_FILE_STRERROR_FL(LOG_FATAL,
-                        "fopen",
-                        basename,
-                        filename,
-                        linenumber);
-    FREE(rret);
-    FREE(ret);
-    return NULL;
-  }
-  fclose(fp);
-
-  key = ftok(basename,'g');
-
-again:
-
-  ret->internal = semget(key, 3, IPC_CREAT|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
-
-  if (ret->internal == -1)
-    DIE_STRERROR_FL("semget", filename, linenumber);
-  if (semop(ret->internal, &op_lock[0], 2) < 0) {
-    if (errno == EINVAL)
-      goto again;
-    else
-      DIE_STRERROR_FL("semop", filename, linenumber);
-  }
-
-  /* get process count */
-  if ( (pcount = semctl(ret->internal, 1, GETVAL, 0)) < 0)
-    DIE_STRERROR_FL("semctl", filename, linenumber);
-  if (pcount==0) {
-     semctl_arg.val = initialValue;
-     if (semctl(ret->internal, 0, SETVAL, semctl_arg) < 0)
-       DIE_STRERROR_FL("semtcl", filename, linenumber);
-     semctl_arg.val = PROCCOUNT;
-     if (semctl(ret->internal, 1, SETVAL, semctl_arg) < 0)
-       DIE_STRERROR_FL("semtcl", filename, linenumber);
-  }
-
-  if (semop(ret->internal, &op_endcreate[0], 2) < 0)
-     DIE_STRERROR_FL("semop", filename, linenumber);
-
-  ret->filename = STRDUP(basename);
-  return rret;
-#elif SOMEBSD
-  int fd;
-  int cnt;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
-
-  rret = MALLOC(sizeof(IPC_Semaphore));
-  ret = MALLOC(sizeof(IPC_Semaphore_Internal));
-  rret->platform = ret;
-
-  MUTEX_CREATE(&ret->internalLock);
-  ret->filename = STRDUP(basename);
-  fd = -1;
-  while (fd == -1) {
-    fd = fileopen(basename,
-             O_CREAT|O_RDWR|O_EXCL,
-             S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP /* 660 */);
-    if ( (fd == -1) &&
-        (errno == EEXIST) ) {
-      /* try without creation */
-      fd = fileopen(basename,
-               O_RDWR,
-               S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP /* 660 */);
-      /* possibly the file was deleted in the meantime,
-        then try again with O_CREAT! */
-      if ( (fd == -1) &&
-          (errno != ENOENT) )
-       break;
-    }
-  }
-  if (fd == -1) {
-    LOG_FILE_STRERROR(LOG_ERROR, "open", ret->filename);
-    MUTEX_DESTROY(&ret->internalLock);
-    FREE(ret->filename);
-    FREE(ret);
-    FREE(rret);
-    return NULL;
-  }
-  FLOCK(fd, LOCK_EX);
-  if (sizeof(int) != READ(fd, &cnt, sizeof(int))) {
-    cnt = htonl(initialValue);
-    LSEEK(fd, 0, SEEK_SET);
-    if (sizeof(int) != WRITE(fd, &cnt, sizeof(int)))
-      LOG_FILE_STRERROR(LOG_WARNING, "write", basename);
-  }
-  LSEEK(fd, sizeof(int), SEEK_SET);
-  if (sizeof(int) != READ(fd, &cnt, sizeof(int)))
-    cnt = htonl(1);
-  else
-    cnt = htonl(ntohl(cnt)+1);
-  LSEEK(fd, sizeof(int), SEEK_SET);
-  if (sizeof(int) != WRITE(fd, &cnt, sizeof(int)))
-     LOG_FILE_STRERROR(LOG_WARNING, "write", basename);
-  FLOCK(fd, LOCK_UN);
-  ret->fd = fd;
-  ret->initialValue = initialValue;
-  return rret;
-#else
- #ifndef _MSC_VER
-   #warning Port IPC.
-   return NULL;
- #else
-   return NULL;
- #endif
-#endif
-}
-
-void ipc_semaphore_up_(IPC_Semaphore * rsem,
-                      const char * filename,
-                      const int linenumber) {
-  IPC_Semaphore_Internal * sem;
-  if (rsem == NULL) /* error on creation, optimistic execution; good luck */
-    return;
-  sem = rsem->platform;
-#if SOLARIS || OSX || FREEBSD5
-  if (0 != sem_post(sem->internal))
-    LOG(LOG_WARNING,
-       "sem_post signaled error: %s at %s:%d\n",
-       STRERROR(errno),
-       filename,
-       linenumber);
-#elif WINDOWS
-  if (!ReleaseSemaphore(sem->internal, 1, NULL))
-    LOG(LOG_WARNING,
-      "ReleaseSemaphore signaled error: %i at %s:%d\n",
-      GetLastError(),
-      filename,
-      linenumber);
-#elif LINUX
-  {
-    struct sembuf sops = {0,1,SEM_UNDO};
-
-    if (0 != semop(sem->internal,&sops,1))
-      LOG(LOG_WARNING,
-         "semop signaled error: %s at %s:%d\n",
-         STRERROR(errno),
-         filename,
-         linenumber);
-  }
-#elif SOMEBSD
-  {
-    int cnt;
-
-
-    MUTEX_LOCK(&sem->internalLock);
-    FLOCK(sem->fd, LOCK_EX);
-    LSEEK(sem->fd, 0, SEEK_SET);
-    if (sizeof(int) != READ(sem->fd, &cnt, sizeof(int))) {
-      LOG(LOG_WARNING,
-         "could not read IPC semaphore count (%s) at %s:%d!\n",
-         STRERROR(errno),
-         __FILE__,
-         __LINE__);
-      MUTEX_UNLOCK(&sem->internalLock);
-      return;
-    }
-    cnt = htonl(ntohl(cnt)+1);
-    LSEEK(sem->fd, 0, SEEK_SET);
-    if (sizeof(int) != WRITE(sem->fd, &cnt, sizeof(int)))
-      LOG(LOG_WARNING,
-         "could not write to IPC file %s (%s) at %s:%d\n",
-         sem->filename,
-         STRERROR(errno),
-         __FILE__,
-         __LINE__);
-    FLOCK(sem->fd, LOCK_UN);
-    MUTEX_UNLOCK(&sem->internalLock);
-  }
-#endif
-}
-
-void ipc_semaphore_down_(IPC_Semaphore * rsem,
-                        const char * filename,
-                        const int linenumber) {
-  IPC_Semaphore_Internal * sem;
-
-  if (rsem == NULL) /* error on creation, optimistic execution; good luck */
-    return;
-  sem = rsem->platform;
-#if OSX || SOLARIS || FREEBSD5
-  while (0 != sem_wait(sem->internal)) {
-    switch(errno) {
-    case EINTR:
-      break;
-    case EINVAL:
-      errexit(" ipc_semaphore_down called on invalid semaphore (in %s:%d)\n",
-             filename,
-             linenumber);
-    case EDEADLK:
-      errexit(" ipc_semaphore_down caused deadlock! (in %s:%d)\n",
-             filename,
-             linenumber);
-    case EAGAIN:
-      LOG(LOG_WARNING,
-         "did not expect EAGAIN from sem_wait (in %s:%d).\n",
-         filename,
-         linenumber);
-      break;
-    default:
-      LOG(LOG_ERROR,
-         "did not expect %s from sem_wait at %s:%d\n",
-         STRERROR(errno),
-         filename,
-         linenumber);
-      break;
-    }
-  }
-#elif WINDOWS
-  if (WaitForSingleObject(sem->internal, INFINITE) == WAIT_FAILED)
-    LOG(LOG_WARNING,
-      "WaitForSingleObject signaled error: %s at %s:%d\n",
-      STRERROR(errno),
-      filename,
-      linenumber);
-#elif LINUX
-  {
-    struct sembuf sops = {0,-1,SEM_UNDO};
-
-    while (0 != semop(sem->internal,&sops,1)) {
-      switch(errno) {
-      case EINTR:
-       break;
-      case EINVAL:
-       errexit(" ipc_semaphore_down called on invalid semaphore (in %s:%d)\n",
-               filename,
-               linenumber);
-      case EAGAIN:
-       LOG(LOG_WARNING,
-           "did not expect EAGAIN from sem_wait (in %s:%d).\n",
-           filename,
-           linenumber);
-       break;
-      default:
-       LOG(LOG_ERROR,
-           "did not expect %s from sem_wait at %s:%d\n",
-           STRERROR(errno),
-           filename,
-           linenumber);
-       break;
-      }
-    }
-  }
-#elif SOMEBSD
-  {
-    int cnt;
-
-    MUTEX_LOCK(&sem->internalLock);
-    FLOCK(sem->fd, LOCK_EX);
-    cnt = ntohl(0);
-    while (htonl(cnt) == 0) {
-      LSEEK(sem->fd, 0, SEEK_SET);
-      if (sizeof(int) != READ(sem->fd, &cnt, sizeof(int))) {
-       LOG(LOG_WARNING,
-           "could not read IPC semaphore count (%s) at %s:%d!\n",
-           STRERROR(errno),
-           __FILE__,
-           __LINE__);
-       FLOCK(sem->fd, LOCK_UN);
-       MUTEX_UNLOCK(&sem->internalLock);
-       return;
-      }
-      if (htonl(cnt) == 0) {
-       /* busy wait! */
-       FLOCK(sem->fd, LOCK_UN);
-       gnunet_util_sleep(50 * cronMILLIS);
-       FLOCK(sem->fd, LOCK_EX);
-      }
-    }
-
-    cnt = htonl(ntohl(cnt)-1);
-    LSEEK(sem->fd, 0, SEEK_SET);
-    if (sizeof(int) != WRITE(sem->fd, &cnt, sizeof(int)))
-      LOG(LOG_WARNING,
-         "could not write update to IPC file %s at %s:%d\n",
-         sem->filename,
-         __FILE__,
-         __LINE__);
-    FLOCK(sem->fd, LOCK_UN);
-    MUTEX_UNLOCK(&sem->internalLock);
-  }
-#else
-#endif
-}
-
-void ipc_semaphore_free_(IPC_Semaphore * rsem,
-                        const char * filename,
-                        const int linenumber) {
-  IPC_Semaphore_Internal * sem;
-  if (rsem == NULL) /* error on creation, optimistic execution; good luck */
-    return;
-  sem = rsem->platform;
-  FREE(rsem);
-#if SOLARIS || OSX || FREEBSD5
-  if (0 != sem_close(sem->internal))
-    LOG(LOG_WARNING,
-       "sem_close signaled error: %s at %s:%d\n",
-       STRERROR(errno),
-       filename,
-       linenumber);
-#elif WINDOWS
-  if (!CloseHandle(sem->internal))
-    LOG(LOG_WARNING,
-    "CloseHandle signaled error: %i at %s:%d\n",
-    GetLastError(),
-    filename,
-    linenumber);
-#elif LINUX
-  {
-    int pcount;
-
-    if (semop(sem->internal, &op_close[0], 3) < 0)
-      LOG(LOG_WARNING,
-         "semop signaled error: %s at %s:%d\n",
-         STRERROR(errno),
-         filename,
-         linenumber);
-
-    if ( (pcount = semctl(sem->internal, 1, GETVAL, 0)) < 0)
-      LOG(LOG_WARNING,
-         "semctl: %s at %s:%d\n",
-         STRERROR(errno),
-         filename,
-         linenumber);
-    if (pcount > PROCCOUNT)
-      LOG(LOG_WARNING,
-         "pcount too large at %s:%d\n",
-         filename,
-         linenumber);
-    else if (pcount == PROCCOUNT) {
-      if (0 != semctl(sem->internal,0,IPC_RMID,0))
-       LOG(LOG_WARNING,
-           "semctl signaled error: %s at %s:%d\n",
-           STRERROR(errno),
-           filename,
-           linenumber);
-      UNLINK(sem->filename);
-    } else {
-      if (semop(sem->internal, &op_unlock[0], 1) < 0)
-       LOG(LOG_WARNING,
-           "semop %s %s:%d\n",
-           STRERROR(errno),
-           filename,
-           linenumber);
-    }
-    FREE(sem->filename);
-  }
-#elif SOMEBSD
-  {
-    int cnt;
-
-    MUTEX_DESTROY(&sem->internalLock);
-    FLOCK(sem->fd, LOCK_EX);
-    LSEEK(sem->fd, sizeof(int), SEEK_SET);
-    if (sizeof(int) == READ(sem->fd, &cnt, sizeof(int))) {
-      cnt = htonl(ntohl(cnt)-1);
-      LSEEK(sem->fd, sizeof(int), SEEK_SET);
-      if (sizeof(int) != WRITE(sem->fd, &cnt, sizeof(int)))
-       LOG(LOG_WARNING,
-           "could not write to IPC file %s at %s:%d\n",
-           sem->filename,
-           __FILE__,
-           __LINE__);
-      if (ntohl(cnt) == 0) {
-       UNLINK(sem->filename);
-      }
-    } else
-      LOG(LOG_WARNING,
-         "could not read process count of IPC %s at %s:%d\n",
-         sem->filename,
-         __FILE__,
-         __LINE__);
-    FREE(sem->filename);
-    FLOCK(sem->fd, LOCK_UN);
-    closefile(sem->fd);
-  }
-#else
-#endif
-  FREE(sem);
-}
-
-
-/* end of semaphore.c */

Deleted: GNUnet/src/util/semaphoretest.c
===================================================================
--- GNUnet/src/util/semaphoretest.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/semaphoretest.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,339 +0,0 @@
-/**
- * @file test/hashtest.c
- * @brief testcase for util/semaphore.c
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#include <sys/types.h>
-#ifndef MINGW             /* PORT-ME MINGW */
-
-
-static Mutex lock;
-
-static Semaphore * sem;
-
-static volatile int sv;
-
-static volatile int tv;
-
-static IPC_Semaphore * ipc;
-
-static void lockIt() {
-  sv = 0;
-  fprintf(stderr, ".");
-  while (sv == 0)
-    gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work */
-  MUTEX_LOCK(&lock);
-  sv = 1;
-  MUTEX_UNLOCK(&lock);
-  sv = 2;
-  tv = 2;
-}
-
-static void bigStack() {
-  int i;
-  char big[1024 * 100];
-
-  fprintf(stderr, ".");
-  for (i=0;i<1024*100;i++)
-    big[i] = (char) i;
-}
-
-static int testPTHREAD_CREATE() {
-  PTHREAD_T pt;
-  void * unused;
-
-  sv = -1; tv = 0;
-  fprintf(stderr, ".");
-  MUTEX_CREATE(&lock);
-  PTHREAD_CREATE(&pt,
-                (PThreadMain)&lockIt,
-                NULL,
-                1024);
-  PTHREAD_DETACH(&pt);
-  while (tv != 2) {
-    sv = 1;
-    gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work */
-  }
-  MUTEX_DESTROY(&lock);
-  PTHREAD_CREATE(&pt,
-                (PThreadMain)&bigStack,
-                NULL,
-                1024*100 + 25000); /* fails by segfault */
-  PTHREAD_JOIN(&pt, &unused);
-  return 0;
-}
-
-static int testMutex() {
-  PTHREAD_T pt;
-  void * unused;
-  MUTEX_CREATE(&lock);
-
-  sv = 1;
-  tv = 0;
-  PTHREAD_CREATE(&pt,
-                (PThreadMain)&lockIt,
-                NULL,
-                1024);
-  while (sv == 1)
-    gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work */
-  MUTEX_LOCK(&lock);
-  sv = 5; /* release lockIt from while sv==0 loop,
-            blocks it on lock */
-  fprintf(stderr, ".");
-
-  if (sv != 5) {
-    MUTEX_UNLOCK(&lock);
-    while (tv != 2)
-      gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work 
*/
-    MUTEX_DESTROY(&lock);
-    printf("MUTEX test failed at %s:%u\n",
-          __FILE__, __LINE__);
-    return 1; /* error */
-  } else {
-    MUTEX_UNLOCK(&lock);
-    while (tv != 2)
-      gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work 
*/
-    PTHREAD_JOIN(&pt, &unused);
-    MUTEX_DESTROY(&lock);
-    return 0; /* ok */
-  }
-}
-
-static int testRecursiveMutex() {
-  int i;
-
-  fprintf(stderr, ".");
-  MUTEX_CREATE_RECURSIVE(&lock);
-  for (i=0;i<50;i++)
-    MUTEX_LOCK(&lock);
-  for (i=0;i<50;i++)
-    MUTEX_UNLOCK(&lock);
-  MUTEX_DESTROY(&lock);
-  return 0; /* ok -- fails by hanging!*/
-}
-
-static void semUpDown() {
-  int i;
-
-  fprintf(stderr, ".");
-  for (i=0;i<42;i++)
-    SEMAPHORE_DOWN(sem); /* fails by blocking */
-  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
-    SEMAPHORE_FREE(sem);
-    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n"
-          "Testcase deadlocked.\n",
-          __FILE__, __LINE__);
-    return; /* will halt testcase! */
-  }
-  for (i=0;i<42;i++)
-    SEMAPHORE_UP(sem);
-}
-
-static int testSemaphore() {
-  int i;
-  PTHREAD_T pt;
-  void * unused;
-
-  sem = SEMAPHORE_NEW(42);
-  fprintf(stderr, ".");
-  for (i=0;i<42;i++)
-    SEMAPHORE_DOWN(sem); /* fails by blocking */
-  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
-    SEMAPHORE_FREE(sem);
-    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
-          __FILE__, __LINE__);
-    return 1;
-  }
-  for (i=0;i<42;i++)
-    SEMAPHORE_UP(sem);
-  for (i=0;i<42;i++)
-    if (OK != SEMAPHORE_DOWN_NONBLOCKING(sem)) {
-      SEMAPHORE_FREE(sem);
-      printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
-            __FILE__, __LINE__);
-      return 1;
-    }
-  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
-    SEMAPHORE_FREE(sem);
-    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
-          __FILE__, __LINE__);
-    return 1;
-  }
-  fprintf(stderr, ".");
-  PTHREAD_CREATE(&pt,
-                (PThreadMain)&semUpDown,
-                NULL,
-                1024);
-  for (i=0;i<42;i++)
-    SEMAPHORE_UP(sem);
-  PTHREAD_JOIN(&pt, &unused);
-  for (i=0;i<42;i++)
-    SEMAPHORE_DOWN(sem);
-  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
-    SEMAPHORE_FREE(sem);
-    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
-          __FILE__, __LINE__);
-    return 1;
-  }
-  return 0;
-}
-
-static int testIPCSemaphore() {
-  pid_t me;
-  int cnt;
-  int i;
-  int j;
-  FILE * fd;
-  int ret;
-  int si;
-  int sw;
-
-  ret = 0;
-  REMOVE("/tmp/gnunet_ipc_xchange");
-  REMOVE("/tmp/gnunet_ipc_semtest");
-  me = fork();
-  sw = me;
-
-  ipc = IPC_SEMAPHORE_NEW("/tmp/gnunet_ipc_semtest",
-                         0);
-  for (cnt=0;cnt<3;cnt++) {
-    if (sw == 0) {
-      for (i=0;i<6;i++) {
-       IPC_SEMAPHORE_DOWN(ipc);
-       fd = FOPEN("/tmp/gnunet_ipc_xchange",
-                      "a+");
-       if (fd == NULL) {
-         printf("Could not open testfile for reading: %s\n",
-                STRERROR(errno));
-         ret = 1;
-         goto END;
-       }
-       fseek(fd, 4*i, SEEK_SET);
-       si = GN_FREAD(&j, 4, 1, fd);
-       while (si == 0)
-         si = GN_FREAD(&j, 4, 1, fd);
-       if (si != 1) {
-         printf("Could not read from testfile: %d - %s at %s:%d\n",
-                si,
-                STRERROR(errno),
-                __FILE__,
-                __LINE__);
-         ret = 1;
-         goto END;
-       }
-       fclose(fd);
-       if (j != i+cnt) {
-         printf("IPC test failed at cnt=%d i=%d j=%d %s:%u\n",
-                cnt, i, j, __FILE__, __LINE__);
-         ret = 1;
-         goto END;
-       } else
-         fprintf(stderr, ".");
-      }
-      REMOVE("/tmp/gnunet_ipc_xchange");
-      sw = 1;
-    } else {
-      for (i=0;i<6;i++) {
-       sleep(1);
-       fd = FOPEN("/tmp/gnunet_ipc_xchange",
-                      "w+");
-       if (fd == NULL) {
-         printf("Could not open testfile for writing: %s\n",
-                STRERROR(errno));
-         ret = 1;
-         goto END;
-       }
-       fseek(fd, 4*i, SEEK_SET);
-       j=cnt+i;
-       if (1 != GN_FWRITE(&j, 4, 1, fd)) {
-         printf("Could not write to testfile: %s\n",
-                STRERROR(errno));
-         ret = 1;
-         goto END;
-       }
-       fclose(fd);
-       IPC_SEMAPHORE_UP(ipc);
-      }
-      fprintf(stderr, ".");
-      sleep(2); /* give reader ample time to finish */
-      sw = 0;
-    }
-  }
- END:
-  IPC_SEMAPHORE_FREE(ipc);
-  REMOVE("/tmp/gnunet_ipc_xchange");
-  if (me == 0) {
-    exit(ret);
-  } else {
-    LOG(LOG_DEBUG,
-       " waiting for other process to exit.\n");
-    if (-1 == waitpid(me, &j, 0))
-      LOG(LOG_ERROR,
-         " waitpid failed: %s\n",
-         STRERROR(errno));
-    if ((! WIFEXITED(j)) || WEXITSTATUS(j) == 1)
-      ret = 1; /* error in child */
-  }
-  return ret;
-}
-
-
-/**
- * Perform option parsing from the command line.
- */
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  char c;
-
-  while (1) {
-    int option_index = 0;
-    static struct GNoption long_options[] = {
-      { "loglevel",1, 0, 'L' },
-      { "config",  1, 0, 'c' },
-      { 0,0,0,0 }
-    };
-
-    c = GNgetopt_long(argc,
-                     argv,
-                     "c:L:",
-                     long_options,
-                     &option_index);
-
-    if (c == -1)
-      break;  /* No more flags to process */
-
-    switch(c) {
-    case 'L':
-      FREENONNULL(setConfigurationString("GNUNET",
-                                        "LOGLEVEL",
-                                        GNoptarg));
-      break;
-    case 'c':
-      FREENONNULL(setConfigurationString("FILES",
-                                        "gnunet.conf",
-                                        GNoptarg));
-      break;
-    } /* end of parsing commandline */
-  }
-  return OK;
-}
-#endif /* PORT-ME MINGW */
-
-int main(int argc, char * argv[]){
-  int ret = 0;
-
-#ifndef MINGW
-  initUtil(argc, argv, &parseCommandLine);
-  ret += testPTHREAD_CREATE();
-  ret += testMutex();
-  ret += testRecursiveMutex();
-  ret += testSemaphore();
-  ret += testIPCSemaphore();
-  fprintf(stderr, "\n");
-  doneUtil();
-#endif
-  return ret;
-}

Deleted: GNUnet/src/util/shutdown.c
===================================================================
--- GNUnet/src/util/shutdown.c  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/shutdown.c  2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,138 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/shutdown.c
- * @brief code to allow clean shutdown of application with signals
- * @author Christian Grothoff
- *
- * Helper code for writing proper termination code when an application
- * receives a SIGTERM/SIGHUP etc.
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-/**
- * Semaphore used to signal "shutdown"
- */
-static Semaphore * shutdown_signal = NULL;
-static int shutdown_active;
-
-/**
- * Stop the application.
- * @param signum is ignored
- */
-void run_shutdown(int signum) {
-  if (shutdown_signal != NULL) {
-    shutdown_active = YES;
-    SEMAPHORE_UP(shutdown_signal);
-  }
-}
-
-/**
- * Stop the application under Windows.
- * @param signum is ignored
- */
-#ifdef MINGW
-BOOL WINAPI run_shutdown_win(DWORD dwCtrlType)
-{
-  switch(dwCtrlType)
-  {
-    case CTRL_C_EVENT:
-    case CTRL_CLOSE_EVENT:
-    case CTRL_SHUTDOWN_EVENT:
-    case CTRL_LOGOFF_EVENT:
-      run_shutdown(1);
-  }
-
-  return TRUE;
-}
-#endif
-
-
-/**
- * Test if the shutdown has been initiated.
- * @return YES if we are shutting down, NO otherwise
- */
-int testShutdown() {
-  return shutdown_active;
-}
-
-/**
- * Initialize the signal handlers, etc.
- */
-void initializeShutdownHandlers() {
-#ifndef MINGW
-  struct sigaction sig;
-  struct sigaction oldsig;
-#endif
-
-  if (shutdown_signal != NULL)
-    errexit(" initializeShutdownHandlers called twice!\n");
-  shutdown_signal = SEMAPHORE_NEW(0);
-  shutdown_active = NO;
-#ifndef MINGW
-  sig.sa_handler = &run_shutdown;
-  sigemptyset(&sig.sa_mask);
-#ifdef SA_INTERRUPT
-  sig.sa_flags = SA_INTERRUPT; /* SunOS */
-#else
-  sig.sa_flags = SA_RESTART;
-#endif
-  sigaction(SIGINT,  &sig, &oldsig);
-  sigaction(SIGTERM, &sig, &oldsig);
-  sigaction(SIGQUIT, &sig, &oldsig);
-#else
-  SetConsoleCtrlHandler(&run_shutdown_win, TRUE);
-#endif
-}
-
-/**
- * Wait until the shutdown has been initiated.
- */
-void wait_for_shutdown() {
-  SEMAPHORE_DOWN(shutdown_signal);
-}
-
-void doneShutdownHandlers() {
-#ifndef MINGW
-  struct sigaction sig;
-  struct sigaction oldsig;
-
-  sig.sa_handler = SIG_DFL;
-  sigemptyset(&sig.sa_mask);
-#ifdef SA_INTERRUPT
-  sig.sa_flags = SA_INTERRUPT; /* SunOS */
-#else
-  sig.sa_flags = SA_RESTART;
-#endif
-  sigaction(SIGINT,  &sig, &oldsig);
-  sigaction(SIGTERM, &sig, &oldsig);
-  sigaction(SIGQUIT, &sig, &oldsig);
-#else
-  SetConsoleCtrlHandler(&run_shutdown_win, FALSE);
-#endif
-
-  SEMAPHORE_FREE(shutdown_signal);
-  shutdown_signal = NULL;
-}
-
-/* end of shutdown.c */

Deleted: GNUnet/src/util/shutdowntest.c
===================================================================
--- GNUnet/src/util/shutdowntest.c      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/shutdowntest.c      2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,95 +0,0 @@
-/**
- * @file test/shutdowntest.c
- * @brief testcase for util/shutdown.c
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-static pid_t myPID;
-
-static int check() {
-  /* first, test / SIGINT (simulated) */
-  initializeShutdownHandlers();
-  if (testShutdown() != NO)
-    return 1;
-#ifndef MINGW
-  kill(myPID, SIGINT);
-#else
-  GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
-#endif
-  if (testShutdown() != YES)
-    return 2;
-  wait_for_shutdown();
-  doneShutdownHandlers();
-
-  /* now, test "run_shutdown" */
-  initializeShutdownHandlers();
-  if (testShutdown() != NO)
-    return 3;
-  run_shutdown(42);
-  if (testShutdown() != YES)
-    return 4;
-  wait_for_shutdown();
-  doneShutdownHandlers();
-
-  return 0;
-}
-
-
-/**
- * Perform option parsing from the command line.
- */
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  char c;
-
-  while (1) {
-    int option_index = 0;
-    static struct GNoption long_options[] = {
-      { "config",  1, 0, 'c' },
-      { 0,0,0,0 }
-    };
-
-    c = GNgetopt_long(argc,
-                     argv,
-                     "c:",
-                     long_options,
-                     &option_index);
-
-    if (c == -1)
-      break;  /* No more flags to process */
-
-    switch(c) {
-    case 'c':
-      FREENONNULL(setConfigurationString("FILES",
-                                        "gnunet.conf",
-                                        GNoptarg));
-      break;
-    } /* end of parsing commandline */
-  }
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGFILE",
-                                    NULL));
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGLEVEL",
-                                    "WARNING"));
-  return OK;
-}
-
-int main(int argc,
-        char * argv[]){
-  int ret;
-
-  myPID = getpid();
-  initUtil(argc, argv, &parseCommandLine);
-
-  ret = check();
-  if (ret != 0)
-    fprintf(stderr,
-           "ERROR %d\n", ret);
-  doneUtil();
-  return ret;
-}
-
-/* end of shutdowntest.c */

Deleted: GNUnet/src/util/state.c
===================================================================
--- GNUnet/src/util/state.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/state.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,272 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2002, 2003, 2004 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/state.c
- * @brief tiny, stateful database too keep track of internal state
- *
- * Directory based implementation of a tiny, stateful database
- * to keep track of GNUnet _internal_ configuration parameters
- * that users are not supposed to see (e.g. *previous* quota,
- * previous database type for AFS, etc.)
- *
- *
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#include <sys/stat.h>
-
-
-#define STATE_DEBUG NO
-
-#define DIR_EXT "state.sdb"
-
-static char * handle = NULL;
-
-/**
- * Initialize the Directory module, expand filename
- * @param dir the directory where content is configured to be stored (e.g. 
~/.gnunet/data/content).
- */
-static char * getDirectory(char * dir) {
-  char * result;
-  char * tmp;
-  size_t n;
-
-#if STATE_DEBUG
-  LOG(LOG_DEBUG,
-      "Database (state): %s\n",
-      dir);
-#endif
-  n = strlen(dir) + strlen(DIR_EXT) + 5;
-  tmp = MALLOC(n);
-  SNPRINTF(tmp, n, "%s/%s/", dir, DIR_EXT);
-  result = expandFileName(tmp);
-  FREE(tmp);
-  return result;
-}
-
-void initState() {
-  char * dbh;
-  char * dir;
-  char * base;
-  char * baseSect;
-
-  if (testConfigurationString("GNUNETD",
-                             "_MAGIC_",
-                             "YES")) {
-    base = "GNUNETD_HOME";
-    baseSect = "GNUNETD";
-       }
-  else {
-    base = "GNUNET_HOME";
-    baseSect = "GNUNET";
-  }
-  dir = getFileName(baseSect,
-                   base,
-                   _("Configuration file must specify a directory"
-                     " for GNUnet to store per-peer data under %s\\%s.\n"));
-  dbh = getDirectory(dir);
-  FREE(dir);
-  GNUNET_ASSERT(dbh != NULL);
-  mkdirp(dbh);
-  handle = dbh;
-}
-
-/**
- * Clean shutdown of the storage module (not used at the moment)
- */
-void doneState() {
-  if (handle == NULL)
-    return; /* bogus call! */
-  FREE(handle);
-  handle = NULL;
-}
-
-/**
- * Read the contents of a bucket to a buffer.
- *
- * @param name the hashcode representing the entry
- * @param result the buffer to write the result to
- *        (*result should be NULL, sufficient space is allocated)
- * @return the number of bytes read on success, -1 on failure
- */
-int stateReadContent(const char * name,
-                    void ** result) {
-  /* open file, must exist, open read only */
-  char * dbh = handle;
-  int fd;
-  int size;
-  char * fil;
-  unsigned long long fsize;
-  size_t n;
-
-  GNUNET_ASSERT(handle != NULL);
-  if (result == NULL)
-    return -1;
-  n = strlen(dbh) + strlen(name) + 2;
-  fil = MALLOC(n);
-  SNPRINTF(fil,
-          n,
-          "%s/%s",
-          dbh,
-          name);
-  if (OK != getFileSize(fil,
-                       &fsize)) {
-    FREE(fil);
-    return -1;
-  }
-  fd = fileopen(fil,
-           O_RDONLY,
-           S_IRUSR);
-  if (fd == -1) {
-    FREE(fil);
-    return -1;
-  }
-  FREE(fil);
-  if (fsize == 0) { /* also invalid! */
-    closefile(fd);
-    return -1;
-  }
-
-  *result = xmalloc_unchecked_(fsize, __FILE__, __LINE__);
-  size = READ(fd,
-             *result,
-             fsize);
-  closefile(fd);
-  if (size == -1) {
-    FREE(*result);
-    *result = NULL;
-  }
-  return size;
-}
-
-
-/**
- * Append content to file.
- *
- * @param name the key for the entry
- * @param len the number of bytes in block
- * @param block the data to store
- * @return SYSERR on error, OK if ok.
- */
-int stateAppendContent(const char * name,
-                      int len,
-                      const void * block) {
-  char * dbh = handle;
-  char * fil;
-  int fd;
-  size_t n;
-
-  GNUNET_ASSERT(handle != NULL);
-  n = strlen(dbh) + strlen(name) + 2;
-  fil = MALLOC(n);
-  SNPRINTF(fil,
-          n,
-          "%s/%s",
-          dbh,
-          name);
-  fd = fileopen(fil,
-               O_RDWR|O_CREAT,
-               S_IRUSR|S_IWUSR);
-  if (fd == -1) {
-    LOG_FILE_STRERROR(LOG_WARNING, "open", fil);
-    FREE(fil);
-    return SYSERR; /* failed! */
-  }
-  FREE(fil);
-  lseek(fd,
-       0,
-       SEEK_END);
-  WRITE(fd,
-       block,
-       len);
-  closefile(fd);
-  return OK;
-}
-
-/**
- * Write content to a file.
- *
- * @param name the key for the entry
- * @param len the number of bytes in block
- * @param block the data to store
- * @return SYSERR on error, OK if ok.
- */
-int stateWriteContent(const char * name,
-                     int len,
-                     const void * block) {
-  char * dbh = handle;
-  char * fil;
-  int fd;
-  size_t n;
-
-  GNUNET_ASSERT(handle != NULL);
-  n = strlen(dbh) + strlen(name) + 2;
-  fil = MALLOC(n);
-  SNPRINTF(fil,
-          n,
-          "%s/%s",
-          dbh,
-          name);
-  fd = fileopen(fil,
-           O_RDWR|O_CREAT,
-           S_IRUSR|S_IWUSR);
-  if (fd == -1) {
-    LOG_FILE_STRERROR(LOG_WARNING, "open", fil);
-    FREE(fil);
-    return SYSERR; /* failed! */
-  }
-  WRITE(fd,
-       block,
-       len);
-  if (0 != ftruncate(fd, len))
-    LOG_FILE_STRERROR(LOG_WARNING, "ftruncate", fil);
-  closefile(fd);
-  FREE(fil);
-  return OK;
-}
-
-/**
- * Free space in the database by removing one file
- * @param name the hashcode representing the name of the file
- *        (without directory)
- */
-int stateUnlinkFromDB(const char * name) {
-  char * dbh = handle;
-  char * fil;
-  size_t n;
-
-  GNUNET_ASSERT(handle != NULL);
-  n = strlen(dbh) + strlen(name) + 2;
-  fil = MALLOC(n);
-  SNPRINTF(fil,
-          n,
-          "%s/%s",
-          dbh,
-          name);
-  UNLINK(fil);
-  FREE(fil);
-  return OK;
-}
-
-/* end of state.c */

Deleted: GNUnet/src/util/statetest.c
===================================================================
--- GNUnet/src/util/statetest.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/statetest.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,81 +0,0 @@
-/**
- * @file test/storagetest.c
- * @brief testcase for the state module
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-/**
- * Perform option parsing from the command line.
- */
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  char c;
-
-  while (1) {
-    int option_index = 0;
-    static struct GNoption long_options[] = {
-      { "config",  1, 0, 'c' },
-      { 0,0,0,0 }
-    };
-
-    c = GNgetopt_long(argc,
-                     argv,
-                     "c:",
-                     long_options,
-                     &option_index);
-
-    if (c == -1)
-      break;  /* No more flags to process */
-
-    switch(c) {
-    case 'c':
-      FREENONNULL(setConfigurationString("FILES",
-                                        "gnunet.conf",
-                                        GNoptarg));
-      break;
-    } /* end of parsing commandline */
-  }
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGLEVEL",
-                                    "NOTHING"));
-  return OK;
-}
-
-#define TH "TestHandle"
-
-int testState() {
-  char * testString = "Hello World";
-  char * ret;
-
-  stateUnlinkFromDB(TH); /* go to defined state */
-  if (SYSERR == stateWriteContent(TH,
-                                 5,
-                                 testString))
-    return 1;
-  if (SYSERR == stateAppendContent(TH,
-                                  6,
-                                  &testString[5]))
-    return 2;
-  ret = NULL;
-  if (SYSERR == stateReadContent(TH,
-                                (void**)&ret))
-    return 3;
-  if (0 != strncmp(ret, testString, 11))
-    return 4;
-  FREE(ret);
-  if (OK != stateUnlinkFromDB(TH))
-    return 5;
-  return 0;
-}
-
-int main(int argc, char * argv[]) {
-  int ret = 0;
-  initUtil(argc, argv, &parseCommandLine);
-  ret = testState();
-
-  doneUtil();
-  return ret;
-} /* end of main */

Deleted: GNUnet/src/util/statuscalls.c
===================================================================
--- GNUnet/src/util/statuscalls.c       2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/statuscalls.c       2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,873 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2005, 2006 Christian Grothoff (and other 
contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/statuscalls.c
- * @brief calls to determine current network and CPU load
- * @author Tzvetan Horozov
- * @author Christian Grothoff
- * @author Igor Wronsky
- *
- * Status calls implementation for load management.
- */
-
-#include "platform.h"
-#include "gnunet_util.h"
-
-#if SOLARIS
-#if HAVE_KSTAT_H
-#include <kstat.h>
-#endif
-#if HAVE_SYS_SYSINFO_H
-#include <sys/sysinfo.h>
-#endif
-#if HAVE_KVM_H
-#include <kvm.h>
-#endif
-#endif
-#if SOMEBSD
-#if HAVE_KVM_H
-#include <kvm.h>
-#endif
-#endif
-
-#define DEBUG_STATUSCALLS NO
-
-/**
- * where to read network interface information from
- * under Linux
- */
-#define PROC_NET_DEV "/proc/net/dev"
-
-typedef struct {
-  char * name;
-  unsigned long long last_in;
-  unsigned long long last_out;
-} NetworkStats;
-
-/**
- * Traffic counter for only gnunetd traffic.
- */
-static NetworkStats globalTrafficBetweenProc;
-
-/**
- * tracking
- */
-static NetworkStats * ifcs;
-
-/**
- * how many interfaces do we have?
- */
-static unsigned int ifcsSize;
-
-/**
- * Current load of the machine, -1 for error
- */
-static int currentLoad;
-
-/**
- * Maximum bandwidth (down) as per config.
- */
-static int maxNetDownBPS;
-
-/**
- * Maximum bandwidth (up) as per config.
- */
-static int maxNetUpBPS;
-
-/**
- * Maximum load as per config.
- */
-static int maxCPULoad;
-
-/**
- * How to measure traffic (YES == only gnunetd,
- * NO == try to include all apps)
- */
-static int useBasicMethod = YES;
-
-/**
- * Lock.
- */
-static Mutex statusMutex;
-
-static int initialized_ = NO;
-
-#ifdef LINUX
-static FILE * proc_stat;
-static FILE * proc_net_dev;
-#endif
-
-/**
- * Increment the number of bytes sent.  Transports should use this
- * so that statuscalls module can measure gnunet traffic usage between
- * calls to /proc.
- *
- * Note: the caller doesn't know what interface it is attached to,
- * so this type of bandwidth limitation is always global (for all
- * network interfaces).
- */
-void incrementBytesSent(unsigned long long delta) {
-  if (initialized_ == NO)
-    return;
-  MUTEX_LOCK(&statusMutex);
-  globalTrafficBetweenProc.last_out += delta;
-  MUTEX_UNLOCK(&statusMutex);
-}
-
-void incrementBytesReceived(unsigned long long delta) {
-  if (initialized_ == NO)
-    return;
-  MUTEX_LOCK(&statusMutex);
-  globalTrafficBetweenProc.last_in += delta;
-  MUTEX_UNLOCK(&statusMutex);
-}
-
-/**
- * Reset the traffic counters for GNUnet traffic between
- * systemwide readings.
- */
-static void resetBetweenProc() {
-  globalTrafficBetweenProc.last_in = 0;
-  globalTrafficBetweenProc.last_out = 0;
-}
-
-#define MAX_PROC_LINE 5000
-
-static void updateInterfaceTraffic() {
-#ifdef LINUX
-  unsigned long long rxnew;
-  unsigned long long txnew;
-  char line[MAX_PROC_LINE];
-  char * data;
-  int i;
-  int found;
-
-  MUTEX_LOCK(&statusMutex);
-  if (proc_net_dev != NULL) {
-    found = 0;
-    rewind(proc_net_dev);
-    fflush(proc_net_dev);
-    /* Parse the line matching the interface ('eth0') */
-    while (! feof(proc_net_dev) ) {
-      if (NULL == fgets(line,
-                       MAX_PROC_LINE,
-                       proc_net_dev))
-       break;
-      for (i=0;i<ifcsSize;i++) {
-       if (NULL != strstr(line, ifcs[i].name) ) {
-         data = strchr(line, ':');
-         if (data == NULL)
-           continue;
-         data++;       
-         if (2 != SSCANF(data,
-                         "%llu %*s %*s %*s %*s %*s %*s %*s %llu",
-                         &rxnew,
-                         &txnew)) {
-           LOG(LOG_ERROR,
-               _("Failed to parse interface data from `%s' at %s:%d.\n"),
-               PROC_NET_DEV,
-               __FILE__,
-               __LINE__);
-           continue;
-         }     
-         ifcs[i].last_in  = rxnew;
-         ifcs[i].last_out = txnew;
-         resetBetweenProc();
-         break;
-       }
-      }
-    }
-  }
-  MUTEX_UNLOCK(&statusMutex);
-
-#elif MINGW
-  unsigned long long rxnew;
-  unsigned long long txnew;
-  int i;
-  PMIB_IFTABLE pTable;
-  DWORD dwIfIdx;
-  unsigned long long l;
-  BYTE bPhysAddr[MAXLEN_PHYSADDR];
-  int iLine = 0;
-  char line[MAX_PROC_LINE];
-  FILE * command;
-
-  MUTEX_LOCK(&statusMutex);
-  /* Win 98 and NT SP 4 */
-  if (GNGetIfEntry) {
-    EnumNICs(&pTable, NULL);
-    for (i=0;i<ifcsSize;i++) {
-      for (dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
-        l = _atoi64(ifcs[i].name);
-
-        memset(bPhysAddr,
-              0,
-              MAXLEN_PHYSADDR);
-        memcpy(bPhysAddr,
-              pTable->table[dwIfIdx].bPhysAddr,
-              pTable->table[dwIfIdx].dwPhysAddrLen);
-
-        if (0 == memcmp(bPhysAddr,
-                       &l,
-                       sizeof(unsigned long long))) {
-         ifcs[i].last_in
-           = pTable->table[dwIfIdx].dwInOctets;
-         ifcs[i].last_out
-           = pTable->table[dwIfIdx].dwOutOctets;
-         resetBetweenProc();
-          break;
-        }
-      }
-    }
-    GlobalFree(pTable);
-  } else { /* Win 95 */
-    if ( ( command = popen("netstat -e", "rt") ) == NULL ) {
-      LOG_FILE_STRERROR(LOG_ERROR,
-                       "popen",
-                       "netstat -e");
-      MUTEX_UNLOCK(&statusMutex);
-      return;
-    }
-    while (!feof(command)) {
-      if (NULL == fgets(line,
-                       MAX_PROC_LINE,
-                       command))
-       break;
-      /* PORT-ME: any way to do this per-ifc? */
-      if (iLine == 1) {
-        sscanf("%*s%i%i",
-              &rxnew,
-              &txnew);
-       ifcs[0].last_in
-         = rxnew;
-       ifcs[0].last_out
-         = txnew;
-       resetBetweenProc();
-       break;
-      }
-      iLine++;
-    }
-    pclose(command);
-  }
-  MUTEX_UNLOCK(&statusMutex);
-#else
-  /* PORT-ME! */
-#endif
-}
-
-/**
- * The following routine returns a number between 0-100 (can be larger
- * than 100 if the load is > 1) which indicates the percentage CPU
- * usage.
- *
- * Before its first invocation the method initStatusCalls() must be called.
- * If there is an error the method returns -1
- */
-static void updateCpuUsage(){
-  if (initialized_ == NO) {
-    currentLoad = -1;
-    return;
-  }
-  MUTEX_LOCK(&statusMutex);
-
-#ifdef LINUX
-  /* under linux, first try %idle/usage using /proc/stat;
-     if that does not work, disable /proc/stat for the future
-     by closing the file and use the next-best method. */
-  if (proc_stat != NULL) {
-    static unsigned long long last_cpu_results[4] = { 0, 0, 0, 0 };
-    static int have_last_cpu = NO;
-    char line[128];
-    unsigned long long user_read, system_read, nice_read, idle_read;
-    unsigned long long user, system, nice, idle;
-    unsigned long long usage_time=0, total_time=1;
-
-    /* Get the first line with the data */
-    rewind(proc_stat);
-    fflush(proc_stat);
-    if (NULL == fgets(line, 128, proc_stat)) {
-      LOG_FILE_STRERROR(LOG_ERROR,
-                       "fgets",
-                       "/proc/stat");
-      fclose(proc_stat);
-      proc_stat = NULL; /* don't try again */
-    } else {
-      if (sscanf(line, "%*s %llu %llu %llu %llu",
-                &user_read,
-                &system_read,
-                &nice_read,
-                &idle_read) != 4) {
-       LOG_FILE_STRERROR(LOG_ERROR,
-                         "fgets-sscanf",
-                         "/proc/stat");
-       fclose(proc_stat);
-       proc_stat = NULL; /* don't try again */
-       have_last_cpu = NO;
-      } else {
-       /* Store the current usage*/
-       user   = user_read - last_cpu_results[0];
-       system = system_read - last_cpu_results[1];
-       nice   = nice_read - last_cpu_results[2];
-       idle   = idle_read - last_cpu_results[3];       
-       /* Calculate the % usage */
-       if ( (user + system + nice + idle) > 0) {
-         usage_time = user + system + nice;
-         total_time = usage_time + idle;
-       }
-       if ( (total_time > 0) &&
-            (have_last_cpu == YES) ) 
-         currentLoad = (100 * usage_time) / total_time;
-       else
-         currentLoad = -1;
-       /* Store the values for the next calculation*/
-       last_cpu_results[0] = user_read;
-       last_cpu_results[1] = system_read;
-       last_cpu_results[2] = nice_read;
-       last_cpu_results[3] = idle_read;
-       have_last_cpu = YES;
-       MUTEX_UNLOCK(&statusMutex);
-       return;
-      }
-    }
-  }
-#endif
-
-  /* try kstat (Solaris only) */
-#if SOLARIS && HAVE_KSTAT_H && HAVE_SYS_SYSINFO_H
-  {
-    static long long last_idlecount;
-    static long long last_totalcount;
-    static int kstat_once; /* if open fails, don't keep
-                             trying */
-    kstat_ctl_t * kc;
-    kstat_t * khelper;
-    long long idlecount;
-    long long totalcount;
-    long long deltaidle;
-    long long deltatotal;
-
-    if (kstat_once == 1)
-      goto ABORT_KSTAT;
-    kc = kstat_open();
-    if (kc == NULL) {
-      LOG_STRERROR(LOG_ERROR, "kstat_open");
-      goto ABORT_KSTAT;
-    }
-
-    idlecount = 0;
-    totalcount = 0;
-    for (khelper = kc->kc_chain;
-        khelper != NULL;
-        khelper = khelper->ks_next) {
-      cpu_stat_t stats;
-
-      if (0 != strncmp(khelper->ks_name,
-                      "cpu_stat",
-                      strlen("cpu_stat")) )
-       continue;
-      if (khelper->ks_data_size > sizeof(cpu_stat_t))
-       continue; /* better save then sorry! */
-      if (-1 != kstat_read(kc, khelper, &stats)) {
-       idlecount
-         += stats.cpu_sysinfo.cpu[CPU_IDLE];
-       totalcount
-         += stats.cpu_sysinfo.cpu[CPU_IDLE] +
-         stats.cpu_sysinfo.cpu[CPU_USER] +
-         stats.cpu_sysinfo.cpu[CPU_KERNEL] +
-         stats.cpu_sysinfo.cpu[CPU_WAIT];
-      }
-    }
-    if (0 != kstat_close(kc))
-      LOG_STRERROR(LOG_ERROR, "kstat_close");
-    if ( (idlecount == 0) &&
-        (totalcount == 0) )
-      goto ABORT_KSTAT; /* no stats found => abort */
-    deltaidle = idlecount - last_idlecount;
-    deltatotal = totalcount - last_totalcount;
-    if ( (deltatotal > 0) &&
-        (last_totalcount > 0) )
-      currentLoad = (int) (100 * deltaidle / deltatotal);
-    else
-      currentLoad = -1;
-    last_idlecount = idlecount;
-    last_totalcount = totalcount;
-    MUTEX_UNLOCK(&statusMutex);
-    return;
-  ABORT_KSTAT:
-    kstat_once = 1; /* failed, don't try again */
-  }
-#endif
-
-  /* insert methods better than getloadavg for
-     other platforms HERE! */
-
-  /* ok, maybe we have getloadavg on this platform */
-#if HAVE_GETLOADAVG
-  {
-    static int warnOnce = 0;
-    double loadavg;
-    if (1 != getloadavg(&loadavg, 1)) {
-      /* only warn once, if there is a problem with
-        getloadavg, we're going to hit it frequently... */
-      if (warnOnce == 0) {
-       warnOnce = 1;
-       LOG_STRERROR(LOG_ERROR, "getloadavg");
-      }
-      currentLoad = -1;
-    } else {
-      /* success with getloadavg */
-      currentLoad = (int) (100 * loadavg);
-      MUTEX_UNLOCK(&statusMutex);
-      return;
-    }
-  }
-#endif
-
-#if MINGW
-  /* Win NT? */
-  if (GNNtQuerySystemInformation) {
-    static double dLastKernel;
-    static double dLastIdle;
-    static double dLastUser;
-    double dKernel;
-    double dIdle;
-    double dUser;
-    double dDiffKernel;
-    double dDiffIdle;
-    double dDiffUser;
-    SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION theInfo;
-
-    if (GNNtQuerySystemInformation(SystemProcessorPerformanceInformation,
-                                  &theInfo,
-                                  sizeof(theInfo),
-                                  NULL) == NO_ERROR) {
-      /* PORT-ME MINGW: Multi-processor? */
-      dKernel = Li2Double(theInfo.KernelTime);
-      dIdle = Li2Double(theInfo.IdleTime);
-      dUser = Li2Double(theInfo.UserTime);
-      dDiffKernel = dKernel - dLastKernel;
-      dDiffIdle = dIdle - dLastIdle;
-      dDiffUser = dUser - dLastUser;
-
-      if ( ( (dDiffKernel + dDiffUser) > 0) &&
-          (dLastIdle + dLastKernel + dLastUser > 0) )
-        currentLoad = 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 100.0;
-      else
-        currentLoad = -1; /* don't know (yet) */
-
-      dLastKernel = dKernel;
-      dLastIdle = dIdle;
-      dLastUser = dUser;
-
-      MUTEX_UNLOCK(&statusMutex);
-      return;
-    } else {
-      /* only warn once, if there is a problem with
-        NtQuery..., we're going to hit it frequently... */
-      static int once;
-      if (once == 0) {
-       once = 1;
-       LOG(LOG_ERROR,
-           _("Cannot query the CPU usage (Windows NT).\n"));
-      }
-    }
-  } else { /* Win 9x */
-    HKEY hKey;
-    DWORD dwDataSize, dwType, dwDummy;
-
-    /* Start query */
-    if (RegOpenKeyEx(HKEY_DYN_DATA,
-                    "PerfStats\\StartSrv",
-                    0,
-                    KEY_ALL_ACCESS,
-                     &hKey) != ERROR_SUCCESS) {
-      /* only warn once */
-      static int once = 0;
-      if (once == 0) {
-       once = 1;
-       LOG(LOG_ERROR,
-           _("Cannot query the CPU usage (Win 9x)\n"));
-      }
-    }
-
-    RegOpenKeyEx(HKEY_DYN_DATA,
-                "PerfStats\\StartStat",
-                0,
-                KEY_ALL_ACCESS,
-                &hKey);
-    dwDataSize = sizeof(dwDummy);
-    RegQueryValueEx(hKey,
-                   "KERNEL\\CPUUsage",
-                   NULL,
-                   &dwType,
-                   (LPBYTE) &dwDummy,
-                    &dwDataSize);
-    RegCloseKey(hKey);
-
-    /* Get CPU usage */
-    RegOpenKeyEx(HKEY_DYN_DATA,
-                "PerfStats\\StatData",
-                0,
-                KEY_ALL_ACCESS,
-                 &hKey);
-    dwDataSize = sizeof(currentLoad);
-    RegQueryValueEx(hKey,
-                   "KERNEL\\CPUUsage",
-                   NULL,
-                   &dwType,
-                    (LPBYTE) &currentLoad,
-                   &dwDataSize);
-    RegCloseKey(hKey);
-
-    /* Stop query */
-    RegOpenKeyEx(HKEY_DYN_DATA,
-                "PerfStats\\StopStat",
-                0,
-                KEY_ALL_ACCESS,
-                 &hKey);
-    RegOpenKeyEx(HKEY_DYN_DATA,
-                "PerfStats\\StopSrv",
-                0,
-                KEY_ALL_ACCESS,
-                 &hKey);
-    dwDataSize = sizeof(dwDummy);
-    RegQueryValueEx(hKey,
-                   "KERNEL\\CPUUsage",
-                   NULL,
-                   &dwType,
-                   (LPBYTE)&dwDummy,
-                    &dwDataSize);
-    RegCloseKey(hKey);
-
-    MUTEX_UNLOCK(&statusMutex);
-    return;
-  }
-#endif
-
-  /* loadaverage not defined and no platform
-     specific alternative defined
-     => default: error
-  */
-  currentLoad = -1;
-  MUTEX_UNLOCK(&statusMutex);
-}
-
-static void cronLoadUpdate(void * unused) {
-  updateCpuUsage();
-  if (! useBasicMethod)
-    updateInterfaceTraffic();
-}
-
-/**
- * Re-read the configuration for statuscalls.
- */
-static void resetStatusCalls() {
-  char * interfaces;
-  int i;
-  int numInterfaces;
-
-  MUTEX_LOCK(&statusMutex);
-  for (i=0;i<ifcsSize;i++)
-    FREE(ifcs[i].name);
-  GROW(ifcs,
-       ifcsSize,
-       0);
-  interfaces
-    = getConfigurationString("LOAD",
-                            "INTERFACES");
-  /* fail if config-file is incomplete */
-  if ( (interfaces == NULL) ||
-       (strlen(interfaces) == 0) ) {
-    LOG(LOG_ERROR,
-       _("No network interfaces defined in configuration section `%s' under 
`%s'!\n"),
-       "LOAD",
-       "INTERFACES");
-  } else {
-    /* The string containing the interfaces is formatted in the following way:
-     * each comma is replaced by '\0' and the pointers to the beginning of 
every
-     * interface are stored
-     */
-    numInterfaces = 1;
-    for (i=strlen(interfaces)-1;i>=0;i--)
-      if (interfaces[i] == ',')
-       numInterfaces++;
-    GROW(ifcs,
-        ifcsSize,
-        numInterfaces);
-    for (i=strlen(interfaces)-1;i>=0;i--) {
-      if (interfaces[i] == ',') {
-       ifcs[--numInterfaces].name = STRDUP(&interfaces[i+1]);
-       numInterfaces++;
-       interfaces[i] = '\0';
-      }
-    }
-    ifcs[--numInterfaces].name = STRDUP(interfaces);
-    GNUNET_ASSERT(numInterfaces == 0);
-    for (i=0;i<ifcsSize;i++) {
-      ifcs[i].last_in = 0;
-      ifcs[i].last_out = 0;
-    }
-  }
-  FREENONNULL(interfaces);
-  useBasicMethod
-    = testConfigurationString("LOAD",
-                             "BASICLIMITING",
-                             "YES");
-  maxNetDownBPS
-    = getConfigurationInt("LOAD",
-                         "MAXNETDOWNBPSTOTAL");
-  if (maxNetDownBPS == 0)
-    maxNetDownBPS = 50000;
-  maxNetUpBPS
-    = getConfigurationInt("LOAD",
-                         "MAXNETUPBPSTOTAL");
-  if (maxNetUpBPS == 0)
-    maxNetUpBPS = 50000;
-  maxCPULoad
-    = getConfigurationInt("LOAD",
-                         "MAXCPULOAD");
-  if (maxCPULoad == 0)
-    maxCPULoad = 100;
-  MUTEX_UNLOCK(&statusMutex);
-}
-
-
-
-/**
- * Get the load of the network relative to what is allowed.
- * @return the network load as a percentage of allowed
- *        (100 is equivalent to full load)
- */
-int getNetworkLoadUp() {
-  static unsigned long long overload;
-  static unsigned long long lastSum;
-  static cron_t lastCall;
-  static int lastValue;
-  cron_t now;
-  unsigned long long maxExpect;
-  unsigned long long currentLoadSum;
-  int i;
-  int ret;
-
-  MUTEX_LOCK(&statusMutex);
-  currentLoadSum = globalTrafficBetweenProc.last_out;
-  for (i=0;i<ifcsSize;i++)
-    currentLoadSum += ifcs[i].last_out;
-  cronTime(&now);
-  if ( (lastSum > currentLoadSum) ||
-       (lastSum == 0) ||
-       (now < lastCall) ) {
-    /* integer overflow or first datapoint; since we cannot tell where
-       / by how much the overflow happened, all we can do is ignore
-       this datapoint.  So we return -1 -- AND reset lastSum / lastCall. */
-    lastSum = currentLoadSum;
-    lastCall = now;
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-  if (maxNetUpBPS == 0) {
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-  if (now - lastCall < cronSECONDS) {
-    /* increase last load proportional to difference in
-       data transmitted and in relation to the limit */
-    ret = lastValue + 100 * (currentLoadSum - lastSum) / maxNetUpBPS;
-    MUTEX_UNLOCK(&statusMutex);
-    return ret;
-  }
-  currentLoadSum -= lastSum;
-  lastSum += currentLoadSum;
-  currentLoadSum += overload;
-  maxExpect = ( (now - lastCall) * maxNetUpBPS ) / cronSECONDS;
-  lastCall = now;
-  if (currentLoadSum < maxExpect)
-    overload = 0;
-  else
-    overload = currentLoadSum - maxExpect;
-  lastValue = currentLoadSum * 100 / maxExpect;
-  ret = lastValue;
-  MUTEX_UNLOCK(&statusMutex);
-  return ret;
-}
-
-/**
- * Get the load of the network relative to what is allowed.
- * @return the network load as a percentage of allowed
- *        (100 is equivalent to full load)
- */
-int getNetworkLoadDown() {
-  static unsigned long long overload;
-  static unsigned long long lastSum;
-  static cron_t lastCall;
-  static int lastValue;
-  cron_t now;
-  unsigned long long maxExpect;
-  unsigned long long currentLoadSum;
-  int i;
-  int ret;
-
-  MUTEX_LOCK(&statusMutex);
-  currentLoadSum = globalTrafficBetweenProc.last_in;
-  for (i=0;i<ifcsSize;i++)
-    currentLoadSum += ifcs[i].last_in;
-  cronTime(&now);
-  if ( (lastSum > currentLoadSum) ||
-       (lastSum == 0) ||
-       (now < lastCall) ) {
-    /* integer overflow or first datapoint; since we cannot tell where
-       / by how much the overflow happened, all we can do is ignore
-       this datapoint.  So we return -1 -- AND reset lastSum / lastCall. */
-    lastSum = currentLoadSum;
-    lastCall = now;
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-  if (maxNetDownBPS == 0) {
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-  if (now - lastCall < cronSECONDS) {
-    /* increase last load proportional to difference in
-       data transmitted and in relation to the limit */
-    ret = lastValue + 100 * (currentLoadSum - lastSum) / maxNetDownBPS;
-    MUTEX_UNLOCK(&statusMutex);
-    return ret;
-  }
-  currentLoadSum -= lastSum;
-  lastSum += currentLoadSum;
-  currentLoadSum += overload;
-  maxExpect = ( (now - lastCall) * maxNetDownBPS ) / cronSECONDS;
-  lastCall = now;
-  if (currentLoadSum < maxExpect)
-    overload = 0;
-  else
-    overload = currentLoadSum - maxExpect;
-  lastValue = currentLoadSum * 100 / maxExpect;
-  ret = lastValue;
-  MUTEX_UNLOCK(&statusMutex);
-  return ret;
-}
-
-/**
- * Get the load of the CPU relative to what is allowed.
- * @return the CPU load as a percentage of allowed
- *        (100 is equivalent to full load)
- */
-int getCPULoad() {
-  static int lastRet = -1;
-  static cron_t lastCall;
-  int ret;
-  cron_t now;
-
-  if (initialized_ == NO) {
-    lastRet = -1;
-    return -1;
-  }
-  MUTEX_LOCK(&statusMutex);
-  ret = (100 * currentLoad) / maxCPULoad;
-
-  cronTime(&now);
-  if ( (lastRet != -1) &&
-       (now - lastCall < 250 * cronMILLIS) ) {
-    /* use smoothing, but do NOT update lastRet at frequencies higher
-       than 250ms; this makes the smoothing (mostly) independent from
-       the frequency at which getCPULoad is called. */
-    ret = (ret + 7 * lastRet)/8;
-    MUTEX_UNLOCK(&statusMutex);
-    return ret;
-  }
-
-  /* for CPU, we don't do the 'fast increase' since CPU is much
-     more jitterish to begin with */
-  if (lastRet != -1)
-    ret = (ret + 7 * lastRet)/8;
-  lastRet = ret;
-  lastCall = now;
-  MUTEX_UNLOCK(&statusMutex);
-  return ret;
-}
-
-/**
- * The following method is called in order to initialize the status calls
- * routines.  After that it is safe to call each of the status calls separately
- * @return OK on success and SYSERR on error (or calls errexit).
- */
-void initStatusCalls() {
-#ifdef LINUX
-  proc_stat = fopen("/proc/stat", "r");
-  if (NULL == proc_stat)
-    LOG_FILE_STRERROR(LOG_ERROR,
-                     "fopen",
-                     "/proc/stat");
-  proc_net_dev = fopen(PROC_NET_DEV, "r");
-  if (NULL == proc_net_dev)
-    LOG_FILE_STRERROR(LOG_ERROR,
-                     "fopen",
-                     PROC_NET_DEV);
-#endif
-  MUTEX_CREATE_RECURSIVE(&statusMutex);
-  initialized_ = YES;
-  resetBetweenProc();
-  registerConfigurationUpdateCallback(&resetStatusCalls);
-  resetStatusCalls();
-  cronLoadUpdate(NULL);
-  addCronJob(&cronLoadUpdate,
-            10 * cronSECONDS,
-            10 * cronSECONDS,
-            NULL);
-  getNetworkLoadUp();
-  getNetworkLoadDown();
-}
-
-/**
- * Shutdown the status calls module.
- */
-void doneStatusCalls() {
-  int i;
-
-  if (initialized_ == NO)
-    return;
-  unregisterConfigurationUpdateCallback(&resetStatusCalls);
-  delCronJob(&cronLoadUpdate,
-            10 * cronSECONDS,
-            NULL);
-  initialized_ = NO;
-#ifdef LINUX
-  if (proc_stat != NULL) {
-    fclose(proc_stat);
-    proc_stat = NULL;
-  }
-  if (proc_net_dev != NULL) {
-    fclose(proc_net_dev);
-    proc_net_dev = NULL;
-  }
-#endif
-  for (i=0;i<ifcsSize;i++)
-    FREE(ifcs[i].name);
-  GROW(ifcs,
-       ifcsSize,
-       0);
-  MUTEX_DESTROY(&statusMutex);
-}
-
-
-/* end of statuscalls.c */

Deleted: GNUnet/src/util/statuscallstest.c
===================================================================
--- GNUnet/src/util/statuscallstest.c   2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/statuscallstest.c   2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,76 +0,0 @@
-/**
- * @file util/statuscallstest.c
- * @brief testcase for util/statuscalls.c
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-/**
- * Perform option parsing from the command line.
- */
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  char c;
-
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "_MAGIC_",
-                                    "YES"));
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "GNUNETD_HOME",
-                                    "/tmp/gnunet_test/"));
-  FREENONNULL(setConfigurationString("FILES",
-                                    "gnunet.conf",
-                                    "check.conf"));
-  while (1) {
-    int option_index = 0;
-    static struct GNoption long_options[] = {
-      { "config",  1, 0, 'c' },
-      { 0,0,0,0 }
-    };
-
-    c = GNgetopt_long(argc,
-                     argv,
-                     "c:",
-                     long_options,
-                     &option_index);
-
-    if (c == -1)
-      break;  /* No more flags to process*/
-
-    switch(c) {
-    case 'c':
-      FREENONNULL(setConfigurationString("FILES",
-                                        "gnunet.conf",
-                                        GNoptarg));
-      break;
-    } /* end of parsing commandline */
-  }
-  return OK;
-}
-
-int main(int argc, char * argv[]){
-  int ret;
-  cron_t start;
-
-  if (OK != initUtil(argc, argv, &parseCommandLine))
-    errexit("Error during initialization!\n");
-  startCron();
-  /* need to run each phase for more than 10s since
-     statuscalls only refreshes that often... */
-  cronTime(&start);
-  while (start + 12 * cronSECONDS > cronTime(NULL))
-    sleep(1);
-  cronTime(&start);
-  ret = getCPULoad();
-  while (start + 12 * cronSECONDS > cronTime(NULL))
-    sqrt(245.2523); /* do some processing to drive load up */
-  if (ret > getCPULoad())
-    printf("busy loop decreased CPU load: %d < %d.\n",
-          ret,
-          getCPULoad());
-  stopCron();
-  doneUtil();
-
-  return 0;
-}

Deleted: GNUnet/src/util/storage.c
===================================================================
--- GNUnet/src/util/storage.c   2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/storage.c   2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,717 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2005 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/storage.c
- * @brief IO convenience methods
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_util.h"
-
-#if LINUX || CYGWIN
-#include <sys/vfs.h>
-#else
-#ifdef SOMEBSD
-#include <sys/param.h>
-#include <sys/mount.h>
-#else
-#ifdef OSX
-#include <sys/param.h>
-#include <sys/mount.h>
-#else
-#ifdef SOLARIS
-#include <sys/types.h>
-#include <sys/statvfs.h>
-#else
-#ifdef MINGW
-#define                _IFMT           0170000 /* type of file */
-#define                _IFLNK          0120000 /* symbolic link */
-#define        S_ISLNK(m)      (((m)&_IFMT) == _IFLNK)
-#else
-#error PORT-ME: need to port statfs (how much space is left on the drive?)
-#endif
-#endif
-#endif
-#endif
-#endif
-
-#ifndef SOMEBSD
- #ifndef WINDOWS
-  #ifndef OSX
-   #include <wordexp.h>
-  #endif
- #endif
-#endif
-
-
-static int getSizeRec(const char * filename,
-                     const char * dirname,
-                     void * ptr) {
-  unsigned long long * size = ptr;
-#ifdef HAVE_STAT64
-  struct stat64 buf;
-#else
-  struct stat buf;
-#endif
-  char * fn;
-
-  if (filename == NULL)
-    return SYSERR;
-  if ( (dirname != NULL) &&
-       (strlen(dirname) > 0) ) {
-    fn = MALLOC(strlen(filename) + strlen(dirname) + 3);
-    if (strlen(dirname) > 0) {
-      strcpy(fn, dirname);
-      if (dirname[strlen(dirname)-1] != DIR_SEPARATOR)
-       strcat(fn, DIR_SEPARATOR_STR); /* add tailing / if needed */
-    }
-    /* Windows paths don't start with / */
-#ifndef MINGW
-    else
-      strcpy(fn, DIR_SEPARATOR_STR);
-#endif
-    if (filename[0] == DIR_SEPARATOR)
-      /* if filename starts with a "/", don't copy it */
-      strcat(fn, &filename[1]);
-    else
-      strcat(fn, filename);
-  } else
-    fn = STRDUP(filename);
-
-#ifdef HAVE_STAT64
-  if (0 != STAT64(fn, &buf)) {
-#else
-  if (0 != STAT(fn, &buf)) {
-#endif
-    LOG_FILE_STRERROR(LOG_EVERYTHING,
-                     "stat",
-                     fn);
-    FREE(fn);
-    return SYSERR;
-  }
-  *size += buf.st_size;
-  if ( (S_ISDIR(buf.st_mode)) &&
-       (!S_ISLNK(buf.st_mode)) ) {
-    if (SYSERR ==
-       scanDirectory(fn,
-                     &getSizeRec,
-                     size)) {
-      FREE(fn);
-      return SYSERR;
-    }
-  }
-  FREE(fn);
-  return OK;
-}
-
-static int getSizeWithoutSymlinksRec(const char * filename,
-                                    const char * dirname,
-                                    void * ptr) {
-  unsigned long long * size = ptr;
-#ifdef HAVE_STAT64
-  struct stat64 buf;
-#else
-  struct stat buf;
-#endif
-  char * fn;
-
-  if (filename == NULL)
-    return SYSERR;
-  if (dirname != NULL) {
-    fn = MALLOC(strlen(filename) + strlen(dirname) + 2);
-    fn[0] = '\0';
-    if (strlen(dirname) > 0) {
-      strcat(fn, dirname);
-      if (dirname[strlen(dirname)-1] != DIR_SEPARATOR)
-       strcat(fn, "/"); /* add tailing / if needed */
-    }
-    /* Windows paths don't start with / */
-#ifndef MINGW
-    else
-      strcat(fn, "/");
-#endif
-    if (filename[0] == DIR_SEPARATOR) /* if filename starts with a "/", don't 
copy it */
-      strcat(fn, &filename[1]);
-    else
-      strcat(fn, filename);
-  } else
-    fn = STRDUP(filename);
-
-#ifdef HAVE_STAT64
-  if (0 != STAT64(fn, &buf)) {
-#else
-  if (0 != STAT(fn, &buf)) {
-#endif
-    LOG_FILE_STRERROR(LOG_EVERYTHING,
-                     "stat",
-                     fn);
-    FREE(fn);
-    return SYSERR;
-  }
-  if (! S_ISLNK(buf.st_mode))
-    *size += buf.st_size;
-  if ( (S_ISDIR(buf.st_mode)) &&
-       (!S_ISLNK(buf.st_mode)) ) {
-    if (SYSERR ==
-       scanDirectory(fn,
-                     &getSizeWithoutSymlinksRec,
-                     size)) {
-      FREE(fn);
-      return SYSERR;
-    }
-  }
-  FREE(fn);
-  return OK;
-}
-
-/**
- * Get the number of blocks that are left on the partition that
- * contains the given file (for normal users).
- *
- * @param part a file on the partition to check
- * @return -1 on errors, otherwise the number of free blocks
- */
-long getBlocksLeftOnDrive(const char * part) {
-#ifdef SOLARIS
-  struct statvfs buf;
-
-  if (0 == statvfs(part, &buf)) {
-    return buf.f_bavail;
-  } else {
-    LOG_STRERROR(LOG_ERROR, "statfs");
-    return -1;
-  }
-#elif MINGW
-  DWORD dwDummy, dwBlocks;
-  char szDrive[4];
-
-  memcpy(szDrive, part, 3);
-  szDrive[3] = 0;
-  if(!GetDiskFreeSpace(szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy))
-  {
-    LOG(LOG_ERROR,
-        _("`%s' failed for drive %s: %u\n"),
-       "GetDiskFreeSpace",
-        szDrive, GetLastError());
-
-    return -1;
-  }
-  else
-  {
-    return dwBlocks;
-  }
-#else
-  struct statfs s;
-  if (0 == statfs(part, &s)) {
-    return s.f_bavail;
-  } else {
-    LOG_STRERROR(LOG_ERROR, "statfs");
-    return -1;
-  }
-#endif
-}
-
-/**
- * Get the size of the file (or directory)
- * of the given file (in bytes).
- *
- * @return SYSERR on error, OK on success
- */
-int getFileSize(const char * filename,
-               unsigned long long * size) {
-  GNUNET_ASSERT(size != NULL);
-  *size = 0;
-  return getSizeRec(filename, "", size);
-}
-
-/**
- * Get the size of the file (or directory) without
- * counting symlinks.
- *
- * @return SYSERR on error, OK on success
- */
-int getFileSizeWithoutSymlinks(const char * filename,
-                              unsigned long long * size) {
-  GNUNET_ASSERT(size != NULL);
-  *size = 0;
-
-  return getSizeWithoutSymlinksRec(filename, "", size);
-}
-
-
-/**
- * Convert string to value ('755' for chmod-call)
- */
-static int atoo(const char *s) {
-  int n = 0;
-
-  while ( ('0' <= *s) && (*s < '8') ) {
-    n <<= 3;
-    n += *s++ - '0';
-  }
-  return n;
-}
-
-/**
- * Test if fil is a directory.
- * @returns YES if yes, NO if not
- */
-int isDirectory(const char * fil) {
-  struct stat filestat;
-  int ret;
-
-  ret = STAT(fil, &filestat);
-  if (ret != 0) {
-    LOG_FILE_STRERROR(LOG_EVERYTHING, "stat", fil);
-    return NO;
-  }
-  if (S_ISDIR(filestat.st_mode))
-    return YES;
-  else
-    return NO;
-}
-
-/**
- * Assert that fil corresponds to a filename
- * (of a file that exists and that is not a directory).
- * @returns 1 if yes, 0 if not (will print an error
- * message in that case, too).
- */
-int assertIsFile(const char * fil) {
-  struct stat filestat;
-  int ret;
-
-  ret = STAT(fil, &filestat);
-  if (ret != 0) {
-    LOG_FILE_STRERROR(LOG_EVERYTHING, "stat", fil);
-    return 0;
-  }
-  if (!S_ISREG(filestat.st_mode)) {
-    LOG(LOG_WARNING,
-       _("`%s' is not a regular file.\n"),
-       fil);
-    return 0;
-  }
-  if (ACCESS(fil, R_OK) < 0 ) {
-    LOG_FILE_STRERROR(LOG_WARNING, "access", fil);
-    return 0;
-  }
-  return 1;
-}
-
-/**
- * Complete filename (a la shell) from abbrevition.
- * @param fil the name of the file, may contain ~/ or
- *        be relative to the current directory
- * @returns the full file name,
- *          NULL is returned on error
- */
-char * expandFileName(const char * fil) {
-  char buffer[512];
-  char * fn;
-#ifndef MINGW
-  size_t n;
-  char * fm;
-  const char *fil_ptr;
-#else
-  long lRet;
-#endif
-
-  if (fil == NULL)
-    return NULL;
-
-#ifndef MINGW
-  if (fil[0] == DIR_SEPARATOR) {
-    /* absolute path, just copy */
-    return(STRDUP(fil));
-  }
-  else if (fil[0] == '~') {
-    fm = getenv("HOME");
-    if (fm == NULL) {
-      /* keep it symbolic to show error to user! */
-      fm = "$HOME";
-    }
-
-    /* do not copy '~' */
-    fil_ptr = fil + 1;
-
-       /* skip over dir seperator to be consistent */
-    if (fil_ptr[0] == DIR_SEPARATOR) {
-       fil_ptr++;
-    }
-  } else {
-    fil_ptr = fil;
-    if (getcwd(buffer, 512) != NULL)
-      fm = buffer;
-    else
-      fm = "$PWD";
-  }
-
-  n = strlen(fm) + 1 + strlen(fil_ptr) + 1;
-  fn = MALLOC(n);
-
-  SNPRINTF(fn, n,
-          "%s/%s", fm, fil_ptr);
-#else
-  fn = MALLOC(MAX_PATH + 1);
-
-  if ((lRet = plibc_conv_to_win_path(fil, buffer)) != ERROR_SUCCESS)
-  {
-       SetErrnoFromWinError(lRet);
-
-    return NULL;
-  }
-  /* is the path relative? */
-  if ((strncmp(buffer + 1, ":\\", 2) != 0) &&
-      (strncmp(buffer, "\\\\", 2) != 0))
-  {
-    char szCurDir[MAX_PATH + 1];
-    lRet = GetCurrentDirectory(MAX_PATH + 1, szCurDir);
-    if (lRet + strlen(fn) + 1 > (MAX_PATH + 1))
-    {
-      SetErrnoFromWinError(ERROR_BUFFER_OVERFLOW);
-
-      return NULL;
-    }
-    SNPRINTF(fn,
-            MAX_PATH+1,
-            "%s\\%s", szCurDir, buffer);
-  }
-  else
-  {
-    strcpy(fn, buffer);
-  }
-#endif
-  return fn;
-}
-
-/**
- * Implementation of "mkdir -p"
- * @param dir the directory to create
- * @returns OK on success, SYSERR on failure
- */
-int mkdirp(const char * dir) {
-  char * rdir;
-  int len;
-  int pos;
-  int ret = OK;
-
-  rdir = expandFileName(dir); /* expand directory */
-  len = strlen(rdir);
-#ifndef MINGW
-  pos = 1; /* skip heading '/' */
-#else
-
-  /* Local or Network path? */
-  if (strncmp(rdir, "\\\\", 2) == 0)
-  {
-    pos = 2;
-    while (rdir[pos])
-    {
-      if (rdir[pos] == '\\')
-      {
-        pos ++;
-
-        break;
-      }
-      pos ++;
-    }
-  }
-  else
-  {
-    pos = 3;  /* strlen("C:\\") */
-  }
-#endif
-  while (pos <= len) {
-    if ( (rdir[pos] == DIR_SEPARATOR) ||
-        (pos == len) ) {
-      rdir[pos] = '\0';
-      if (! isDirectory(rdir))
-#ifndef MINGW
-       if (0 != mkdir(rdir,
-                      S_IRUSR | S_IWUSR |
-                      S_IXUSR | S_IRGRP |
-                      S_IXGRP | S_IROTH |
-                      S_IXOTH)) { /* 755 */
-#else
-       if (0 != mkdir(rdir)) {
-#endif
-         if (errno != EEXIST) {
-           LOG_FILE_STRERROR(LOG_ERROR, "mkdir", rdir);
-           ret = SYSERR;
-         }
-       }
-      rdir[pos] = DIR_SEPARATOR;
-    }
-    pos++;
-  }
-  FREE(rdir);
-  return ret;
-}
-
-/**
- * Read the contents of a binary file into a buffer.
- * @param fileName the name of the file, not freed,
- *        must already be expanded!
- * @param len the maximum number of bytes to read
- * @param result the buffer to write the result to
- * @return the number of bytes read on success, -1 on failure
- */
-int readFile(const char * fileName,
-            int  len,
-            void * result) {
-  /* open file, must exist, open read only */
-  int handle;
-  int size;
-
-  if ((fileName == NULL) || (result == NULL))
-    return -1;
-  handle = fileopen(fileName,O_RDONLY,S_IRUSR);
-  if (handle < 0)
-    return -1;
-  size = READ(handle, result, len);
-  closefile(handle);
-  return size;
-}
-
-/**
- * Write a buffer to a file.
- * @param fileName the name of the file, NOT freed!
- * @param buffer the data to write
- * @param n number of bytes to write
- * @param mode permissions to set on the file
- * @return OK on success, SYSERR on error
- */
-int writeFile(const char * fileName,
-             const void * buffer,
-             unsigned int n,
-             const char *mode) {
-  int handle;
-  /* open file, open with 600, create if not
-     present, otherwise overwrite */
-  if ( (fileName == NULL) ||
-       (buffer == NULL) )
-    return SYSERR;
-  handle = fileopen(fileName,
-                   O_CREAT | O_WRONLY,
-                   S_IRUSR | S_IWUSR);
-  if (handle == -1) {
-    LOG_FILE_STRERROR(LOG_WARNING,
-                     "open",
-                     fileName);
-    return SYSERR;
-  }
-  /* write the buffer take length from the beginning */
-  if (n != WRITE(handle, buffer, n)) {
-    LOG_FILE_STRERROR(LOG_WARNING,
-                     "write",
-                     fileName);
-    closefile(handle);
-    return SYSERR;
-  }
-  CHMOD(fileName,
-       atoo(mode));
-  closefile(handle);
-  return OK;
-}
-
-/**
- * Scan a directory for files. The name of the directory
- * must be expanded first (!).
- * @param dirName the name of the directory
- * @param callback the method to call for each file,
- *        can be NULL, in that case, we only count
- * @param data argument to pass to callback
- * @return the number of files found, SYSERR on error
- */
-int scanDirectory(const char * dirName,
-                 DirectoryEntryCallback callback,
-                 void * data) {
-  DIR * dinfo;
-  struct dirent *finfo;
-  struct stat istat;
-  int count = 0;
-
-  if (dirName == NULL)
-    return SYSERR;
-  if (0 != STAT(dirName, &istat)) {
-    LOG_FILE_STRERROR(LOG_WARNING,
-                     "stat",
-                     dirName);
-    return SYSERR;
-  }
-  if (!S_ISDIR(istat.st_mode)) {
-    LOG(LOG_ERROR,
-       _("`%s' expected `%s' to be a directory!\n"),
-       __FUNCTION__,
-       dirName);
-    return SYSERR;
-  }
-  errno = 0;
-  dinfo = OPENDIR(dirName);
-  if ((errno == EACCES) || (dinfo == NULL)) {
-    LOG_FILE_STRERROR(LOG_WARNING,
-                     "opendir",
-                     dirName);
-    return SYSERR;
-  }
-  while ((finfo = readdir(dinfo)) != NULL) {
-    if (finfo->d_name[0] == '.')
-      continue;
-    if (callback != NULL) {
-      if (OK != callback(finfo->d_name,
-                        dirName,
-                        data)) {
-       closedir(dinfo);
-       return SYSERR;
-      }
-    }  
-    count++;
-  }
-  closedir(dinfo);
-  return count;
-}
-
-/**
- * Callback for rm_minus_rf.
- */
-static int rmHelper(const char * fil,
-                   const char * dir,
-                   void * unused) {
-  char * fn;
-  size_t n;
-
-  n = strlen(dir) + strlen(fil) + 2;
-  fn = MALLOC(n);
-  SNPRINTF(fn,
-          n,
-          "%s/%s",
-          dir,
-          fil);
-  if (SYSERR == rm_minus_rf(fn)) {
-    FREE(fn);
-    return SYSERR;
-  }
-  FREE(fn);
-  return OK;
-}
-
-/**
- * Remove all files in a directory (rm -rf). Call with
- * caution.
- *
- *
- * @param fileName the file to remove
- * @return OK on success, SYSERR on error
- */
-int rm_minus_rf(const char * fileName) {
-  if (UNLINK(fileName) == 0)
-    return OK;
-  if ( (errno == EISDIR) ||
-       /* EISDIR is not sufficient in all cases, e.g.
-         sticky /tmp directory may result in EPERM on BSD.
-         So we also explicitly check "isDirectory" */
-       (YES == isDirectory(fileName)) ) {
-    if (OK == scanDirectory(fileName,
-                           &rmHelper,
-                           NULL)) {
-      if (0 != RMDIR(fileName)) {
-       LOG_FILE_STRERROR(LOG_WARNING,
-                         "rmdir",
-                         fileName);
-       return SYSERR;
-      }
-      return OK;
-    }
-    return SYSERR;
-  } else {
-    LOG_FILE_STRERROR(LOG_WARNING,
-                     "unlink",
-                     fileName);
-    return SYSERR;
-  }
-}
-
-void close_(int fd,
-           const char * filename,
-           int linenumber) {
-  if (0 != CLOSE(fd)) {
-    LOG(LOG_INFO,
-       _("`%s' failed at %s:%d with error: %s\n"),
-       "close",
-       filename,
-       linenumber, STRERROR(errno));
-  }
-}
-
-#define COPY_BLK_SIZE 65536
-
-/**
- * Copy a file.
- * @return OK on success, SYSERR on error
- */
-int copyFile(const char * src,
-            const char * dst) {
-  char * buf;
-  unsigned long long pos;
-  unsigned long long size;
-  unsigned long long len;
-  int in;
-  int out;
-
-  buf = MALLOC(COPY_BLK_SIZE);
-  pos = 0;
-  in = fileopen(src, O_RDONLY | O_LARGEFILE);
-  if (in == -1)
-    return SYSERR;
-  out = fileopen(dst,
-                O_LARGEFILE | O_WRONLY | O_CREAT | O_EXCL,
-                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-  if (out == -1) {
-    closefile(in);
-    return SYSERR;
-  }
-  if (OK != getFileSize(src,
-                       &size)) {
-    closefile(in);
-    return SYSERR;
-  }
-  while (pos < size) {
-    len = COPY_BLK_SIZE;
-    if (len > size - pos)
-      len = size - pos;
-    if (len != READ(in, buf, len))
-      goto FAIL;
-    if (len != WRITE(out, buf, len))
-      goto FAIL;
-    pos += len;
-  }
-  closefile(in);
-  closefile(out);
-  return OK;
- FAIL:
-  closefile(in);
-  closefile(out);
-  return SYSERR;
-}
-
-/* end of storage.c */

Deleted: GNUnet/src/util/storagetest.c
===================================================================
--- GNUnet/src/util/storagetest.c       2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/storagetest.c       2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,54 +0,0 @@
-/**
- * @file test/storagetest.c
- * @brief testcase for the storage module
- * @author Christian Grothoff
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#define TESTSTRING "Hello World\0"
-
-/**
- * Perform option parsing from the command line.
- */
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  return OK;
-}
-
-static int testReadWrite() {
-  HashCode512 ha;
-  EncName filename;
-  char tmp[100];
-
-  hash(TESTSTRING,
-       strlen(TESTSTRING),
-       &ha);
-  hash2enc(&ha, &filename);
-  writeFile((char*)&filename, TESTSTRING, strlen(TESTSTRING), "644");
-  tmp[readFile((char*)&filename, 100, tmp)] = '\0';
-  if (memcmp(tmp,TESTSTRING,strlen(TESTSTRING)+1) == 0)
-    return 0;
-  else {
-    fprintf(stderr,
-           "Error in testReadWrite: *%s* != *%s* for file %s\n",
-           tmp,TESTSTRING,(char*)&filename);
-    return 1;
-  }
-}
-
-int main(int argc, char * argv[]) {
-  int failureCount = 0;
-
-  initUtil(argc, argv, &parseCommandLine);
-  failureCount += testReadWrite();
-  doneUtil();
-  if (failureCount == 0)
-    return 0;
-  else {
-    fprintf(stderr,
-            "\n\n%d TESTS FAILED!\n\n",failureCount);
-    return -1;
-  }
-} /* end of main */

Modified: GNUnet/src/util/string/string.c
===================================================================
--- GNUnet/src/util/string/string.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/string/string.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -97,7 +97,7 @@
  * Give relative time in human-readable fancy format.
  * @param delta time in milli seconds
  */
-char * timeIntervalToFancyString(unsigned long long delta) {
+char * string_get_fancy_time_interval(unsigned long long delta) {
   const char * unit = _(/* time unit */ "ms");
   char * ret;
 
@@ -129,7 +129,7 @@
 /**
  * Convert a given filesize into a fancy human-readable format.
  */
-char * fileSizeToFancyString(unsigned long long size) {
+char * string_get_fancy_byte_size(unsigned long long size) {
 const char * unit = _(/* size unit */ "b");
   char * ret;
 
@@ -169,9 +169,10 @@
  *  if conversion fails, a copy of the orignal
  *  string is returned.
  */
-char * convertToUtf8(const char * input,
-                    size_t len,
-                    const char * charset) {
+char * string_convertToUtf8(struct GE_Context * ectx,
+                           const char * input,
+                           size_t len,
+                           const char * charset) {
   char * ret;
 #if ENABLE_NLS
   size_t tmpSize;
@@ -182,6 +183,9 @@
 
   cd = iconv_open("UTF-8", charset);
   if (cd == (iconv_t) -1) {
+    GE_LOG_STRERROR(ectx,
+                   GE_USER | GE_ADMIN | GE_WARNING | GE_BULK,
+                   "iconv_open");
     ret = MALLOC(len+1);
     memcpy(ret, input, len);
     ret[len] = '\0';
@@ -196,6 +200,9 @@
            &len,
            &itmp,
            &finSize) == (size_t)-1) {
+    GE_LOG_STRERROR(ectx,
+                   GE_USER | GE_WARNING | GE_BULK,
+                   "iconv");    
     iconv_close(cd);
     FREE(tmp);
     ret = MALLOC(len+1);
@@ -209,7 +216,10 @@
         tmpSize - finSize);
   ret[tmpSize - finSize] = '\0';
   FREE(tmp);
-  iconv_close(cd);
+  if (0 != iconv_close(cd))
+    GE_LOG_STRERROR(ectx,
+                   GE_ADMIN | GE_WARNING | GE_REQUEST,
+                   "iconv_close");
   return ret;
 #else
   ret = MALLOC(len+1);
@@ -219,4 +229,110 @@
 #endif
 }
 
+
+
+
+/**
+ * Complete filename (a la shell) from abbrevition.
+ * @param fil the name of the file, may contain ~/ or
+ *        be relative to the current directory
+ * @returns the full file name,
+ *          NULL is returned on error
+ */
+char * string_expandFileName(struct GE_Context * ectx,
+                            const char * fil) {
+  char * buffer;
+  char * fn;
+#ifndef MINGW
+  size_t len;
+  size_t n;
+  char * fm;
+  const char * fil_ptr;
+#else
+  long lRet;
+#endif
+
+  if (fil == NULL)
+    return NULL;
+
+#ifndef MINGW
+  if (fil[0] == DIR_SEPARATOR) 
+    /* absolute path, just copy */
+    return(STRDUP(fil));
+  if (fil[0] == '~') {
+    fm = getenv("HOME");
+    if (fm == NULL) {
+      GE_LOG(ectx,
+            GE_USER | GE_ADMIN | GE_WARNING | GE_IMMEDIATE,
+            _("Failed to expand `$HOME': environment variable `HOME' not 
set"));
+      return NULL;
+    }
+    fm = STRDUP(fm);
+    /* do not copy '~' */
+    fil_ptr = fil + 1;
+
+    /* skip over dir seperator to be consistent */
+    if (fil_ptr[0] == DIR_SEPARATOR) 
+       fil_ptr++;
+  } else { 
+    /* relative path */
+    fil_ptr = fil;
+    len = 512;
+    errno = ERANGE;
+    while (errno == ERANGE) {
+      buffer = MALLOC(len);
+      if (getcwd(buffer, len) != NULL) {
+       fm = buffer;
+       break;
+      } else {
+       GE_LOG_STRERROR(ectx,
+                       GE_USER | GE_WARNING | GE_IMMEDIATE,
+                       "getcwd");
+       FREE(buffer);
+       buffer = getenv("PWD"); /* alternative */
+       if (buffer == NULL) 
+         return NULL; /* fatal */
+       fm = STRDUP(buffer);
+      }
+    }
+  }
+  n = strlen(fm) + 1 + strlen(fil_ptr) + 1;
+  buffer = MALLOC(n);
+  SNPRINTF(fn, n,
+          "%s/%s", fm, fil_ptr);
+  FREE(fm);
+#else
+  fn = MALLOC(MAX_PATH + 1);
+
+  if ((lRet = plibc_conv_to_win_path(fil, buffer)) != ERROR_SUCCESS) {
+    SetErrnoFromWinError(lRet);
+    GE_LOG_STRERROR(ectx,
+                   GE_USER | GE_WARNING | GE_IMMEDIATE,
+                   "plibc_conv_to_win_path");
+    return NULL;
+  }
+  /* is the path relative? */
+  if ( (strncmp(buffer + 1, ":\\", 2) != 0) &&
+       (strncmp(buffer, "\\\\", 2) != 0)) {
+    char szCurDir[MAX_PATH + 1];
+    lRet = GetCurrentDirectory(MAX_PATH + 1, szCurDir);
+    if (lRet + strlen(fn) + 1 > (MAX_PATH + 1)) {
+      SetErrnoFromWinError(ERROR_BUFFER_OVERFLOW);
+      GE_LOG_STRERROR(ectx,
+                     GE_USER | GE_WARNING | GE_IMMEDIATE,
+                     "GetCurrentDirectory");
+      return NULL;
+    }
+    SNPRINTF(fn,
+            MAX_PATH+1,
+            "%s\\%s", szCurDir, buffer);
+  } else {
+    strcpy(fn, buffer);
+  }
+#endif
+  return fn;
+}
+
+
+
 /* end of string.c */

Deleted: GNUnet/src/util/tcp_return.c
===================================================================
--- GNUnet/src/util/tcp_return.c        2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/tcp_return.c        2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,94 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002, 2004 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/tcp_return.c
- * @brief code to communicate simple (int) return values via reliable
- *        TCP stream
- * @author Christian Grothoff
- *
- * Helper methods to send and receive return values over a TCP stream
- * that has tcpio (see util/tcpio.c) semantics.
- */
-
-#include "gnunet_util.h"
-#include "gnunet_protocols.h"
-#include "platform.h"
-
-/**
- * Obtain a return value from a remote call from TCP.
- *
- * @param sock the TCP socket
- * @param ret the return value from TCP
- * @return SYSERR on error, OK if the return value was read
- * successfully
- */
-int readTCPResult(GNUNET_TCP_SOCKET * sock,
-                 int * ret) {
-  CS_returnvalue_MESSAGE * rv;
-
-  rv = NULL;
-  if (SYSERR == readFromSocket(sock,
-                              (CS_MESSAGE_HEADER **) &rv)) {
-    LOG(LOG_WARNING,
-       _("`%s' failed, other side closed connection.\n"),
-       __FUNCTION__);
-    return SYSERR;
-  }
-  if ( (ntohs(rv->header.size) != sizeof(CS_returnvalue_MESSAGE)) ||
-       (ntohs(rv->header.type) != CS_PROTO_RETURN_VALUE) ) {
-    LOG(LOG_WARNING,
-       _("`%s' failed, reply invalid!\n"),
-       __FUNCTION__);
-    FREE(rv);
-    return SYSERR;
-  }
-  *ret = ntohl(rv->return_value);
-  FREE(rv);
-  return OK;
-}
-
-/**
- * Send a return value to the caller of a remote call via
- * TCP.
- * @param sock the TCP socket
- * @param ret the return value to send via TCP
- * @return SYSERR on error, OK if the return value was
- *         send successfully
- */
-int sendTCPResult(GNUNET_TCP_SOCKET * sock,
-                 int ret) {
-  CS_returnvalue_MESSAGE rv;
-
-  rv.header.size
-    = htons(sizeof(CS_returnvalue_MESSAGE));
-  rv.header.type
-    = htons(CS_PROTO_RETURN_VALUE);
-  rv.return_value
-    = htonl(ret);
-  return writeToSocket(sock,
-                      &rv.header);
-}
-
-
-
-
-
-/* end of tcp_return.c */

Deleted: GNUnet/src/util/tcpio.c
===================================================================
--- GNUnet/src/util/tcpio.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/tcpio.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,463 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2001, 2002 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/tcpio.c
- * @brief code for synchronized access to TCP streams
- * @author Christian Grothoff
- *
- * Generic TCP code for reliable, mostly blocking, record-oriented TCP
- * connections. GNUnet uses the "tcpio" code for trusted client-server
- * (e.g. gnunet-gtk to gnunetd via loopback) communications.  Note
- * that an unblocking write is also provided since if both client and
- * server use blocking IO, both may block on a write and cause a
- * mutual inter-process deadlock.
- *
- * Since we do not want other peers (!) to be able to block a peer by
- * not reading from the TCP stream, the peer-to-peer TCP transport
- * uses unreliable, buffered, non-blocking, record-oriented TCP code
- * with a select call to reduce the number of threads which is
- * provided in transports/tcp.c.
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#define DEBUG_TCPIO NO
-
-/**
- * Initialize a GNUnet client socket.
- * @param port the portnumber in host byte order
- * @param ip IP of the host to connect to, in network byte order
- * @param result the SOCKET (filled in)
- * @return OK if successful, SYSERR on failure
- */
-int initGNUnetClientSocketIP(unsigned short port,
-                            IPaddr ip,
-                            GNUNET_TCP_SOCKET * result) {
-  result->ip = ip;
-  result->port = port;
-  result->socket = -1; /* closed */
-  result->outBufLen = 0;
-  result->outBufPending = NULL;
-  MUTEX_CREATE(&result->readlock);
-  MUTEX_CREATE(&result->writelock);
-  return OK;
-}
-
-/**
- * Initialize a GNUnet client socket.
- * @param port the portnumber in host byte order
- * @param hostname the name of the host to connect to
- * @param result the SOCKET (filled in)
- * @return OK if successful, SYSERR on failure
- */
-int initGNUnetClientSocket(unsigned short port,
-                          const char * hostname,
-                          GNUNET_TCP_SOCKET * result) {
-  GNUNET_ASSERT(hostname != NULL);
-#if DEBUG_TCPIO
-  LOG(LOG_DEBUG,
-      "Connecting to host '%s:%d'.\n",
-      hostname,
-      port);
-#endif
-  if (OK != GN_getHostByName(hostname,
-                            &result->ip)) 
-    return SYSERR;
-  result->port = port;
-  result->socket = -1; /* closed */
-  result->outBufLen = 0;
-  result->outBufPending = NULL;
-  MUTEX_CREATE(&result->readlock);
-  MUTEX_CREATE(&result->writelock);
-  return OK;
-}
-
-/**
- * Initialize a GNUnet server socket.
- * @param sock the open socket
- * @param result the SOCKET (filled in)
- * @return OK (always successful)
- */
-int initGNUnetServerSocket(int sock,
-                          GNUNET_TCP_SOCKET * result) {
-  result->ip.addr = 0;
-  result->port = 0;
-  result->socket = sock;
-  result->outBufLen = 0;
-  result->outBufPending = NULL;
-  MUTEX_CREATE(&result->readlock);
-  MUTEX_CREATE(&result->writelock);
-  return OK;
-}
-
-/**
- * Check if a socket is open. Will ALWAYS return 'true'
- * for a valid client socket (even if the connection is
- * closed), but will return false for a closed server socket.
- * @return 1 if open, 0 if closed
- */
-int isOpenConnection(GNUNET_TCP_SOCKET * sock) {
-  return (sock->socket != -1);
-}
-
-/**
- * Check a socket, open and connect if it is closed and it is a client-socket.
- */
-int checkSocket(GNUNET_TCP_SOCKET * sock) {
-  int res;
-  struct sockaddr_in soaddr;
-  fd_set rset;
-  fd_set wset;
-  fd_set eset;
-  struct timeval timeout;
-  int ret;
-  int wasSockBlocking;
-
-  if (sock->socket != -1)
-    return OK;
-  sock->socket = SOCKET(PF_INET, SOCK_STREAM, 6); /* 6: TCP */
-  if (sock->socket == -1) {
-    LOG_STRERROR(LOG_FAILURE, "socket");
-    return SYSERR;
-  }
-
-  wasSockBlocking = isSocketBlocking(sock->socket);
-  setBlocking(sock->socket, NO);
-       
-  soaddr.sin_family = AF_INET;
-  GNUNET_ASSERT(sizeof(struct in_addr) == sizeof(sock->ip.addr));
-  memcpy(&soaddr.sin_addr,
-        &sock->ip.addr,
-        sizeof(struct in_addr));
-  soaddr.sin_port = htons(sock->port);
-  res = CONNECT(sock->socket,
-               (struct sockaddr*)&soaddr,
-               sizeof(soaddr));
-  if ( (res < 0) &&
-       (errno != EINPROGRESS) ) {
-    LOG(LOG_INFO,
-       _("Cannot connect to %u.%u.%u.%u:%u: %s\n"),
-       PRIP(ntohl(*(int*)&sock->ip.addr)),
-       sock->port,
-       STRERROR(errno));
-    closefile(sock->socket);
-    sock->socket = -1;
-    return SYSERR;
-  }
-
-  /* we call select() first with a timeout of 5s to
-     avoid blocking on a later write indefinitely;
-     this is mostly needed for gnunet-testbed to keep
-     working if an advertised testbed-client is behind
-     a firewall and unreachable.  But it is also nice
-     if a local firewall decides to just drop the TCP
-     handshake...*/
-  FD_ZERO(&rset);
-  FD_ZERO(&wset);
-  FD_ZERO(&eset);
-  if (sock->socket < 0)
-    return SYSERR;
-  FD_SET(sock->socket, &wset);
-  timeout.tv_sec = 5;
-  timeout.tv_usec = 0;
-  ret = SELECT(sock->socket+1, &rset, &wset, &eset, &timeout);
-  if ( (ret == -1) ||
-       (sock->socket == -1) ||
-       (! FD_ISSET(sock->socket,
-                  &wset)) ) {
-    LOG(LOG_INFO,
-       _("Cannot connect to %u.%u.%u.%u:%u: %s\n"),
-       PRIP(ntohl(*(int*)&sock->ip.addr)),
-       sock->port,
-       STRERROR(errno));
-    setBlocking(sock->socket, wasSockBlocking);
-    return SYSERR;
-  }
-  setBlocking(sock->socket, wasSockBlocking);
-
-  return OK;
-}
-
-/**
- * Write to a GNUnet TCP socket.  Will also potentially complete the
- * sending of a previous non-blocking writeToSocket call.
- *
- * @param sock the socket to write to
- * @param buffer the buffer to write
- * @return OK if the write was sucessful, otherwise SYSERR.
- */
-int writeToSocket(GNUNET_TCP_SOCKET * sock,
-                 const CS_MESSAGE_HEADER * buffer) {
-  int res;
-  int size;
-
-  if (SYSERR == checkSocket(sock))
-    return SYSERR;
-  size = ntohs(buffer->size);
-  MUTEX_LOCK(&sock->writelock);
-
-  /* write pending data from prior non-blocking call
-     -- but this time use blocking IO! */
-  if (sock->outBufLen > 0) {
-    res = SEND_BLOCKING_ALL(sock->socket,
-                           sock->outBufPending,
-                           sock->outBufLen);
-    if (res < 0) {
-      if (errno == EAGAIN) {
-       MUTEX_UNLOCK(&sock->writelock);
-       return SYSERR; /* can not send right now;
-                         but do NOT close socket in this case! */
-      }
-      LOG_STRERROR(LOG_INFO, "send");
-      closeSocketTemporarily(sock);
-      MUTEX_UNLOCK(&sock->writelock);
-      return SYSERR;
-    }
-    FREE(sock->outBufPending);
-    sock->outBufPending = NULL;
-    sock->outBufLen = 0;
-  }
-
-  res = SEND_BLOCKING_ALL(sock->socket,
-                         buffer,
-                         size);
-  if (res < 0) {
-    if (errno == EAGAIN) {
-      MUTEX_UNLOCK(&sock->writelock);
-      return SYSERR; /* would block, can not send right now;
-                       but do NOT close socket in this case! */
-    }
-    LOG_STRERROR(LOG_INFO, "send");
-    closeSocketTemporarily(sock);
-    MUTEX_UNLOCK(&sock->writelock);
-    return SYSERR;
-  }
-  MUTEX_UNLOCK(&sock->writelock);
-  return OK;
-}
-
-
-/**
- * Write to a GNUnet TCP socket non-blocking.  Note that it is
- * possible that only a part of the message is send and that tcpio
- * buffers the rest until the next writeToSocket operation.  If that
- * buffer is full or if send did not transmit any byte of the message,
- * NO is returned to indicate that the write failed (would have
- * blocked).
- *
- * @param sock the socket to write to
- * @param buffer the buffer to write
- * @return OK if the write was sucessful, NO if it would have blocked and was 
not performed,
- *         otherwise SYSERR.
- */
-int writeToSocketNonBlocking(GNUNET_TCP_SOCKET * sock,
-                            const CS_MESSAGE_HEADER * buffer) {
-  size_t res;
-  size_t size;
-
-  if (SYSERR == checkSocket(sock))
-    return SYSERR;
-  MUTEX_LOCK(&sock->writelock);
-  if (sock->outBufLen > 0) {
-    SEND_NONBLOCKING(sock->socket,
-                    sock->outBufPending,
-                    sock->outBufLen,
-                    &res);
-    if (res == (size_t)-1) {
-      if ( (errno == EWOULDBLOCK) ||
-          (errno == EAGAIN) ) {
-       MUTEX_UNLOCK(&sock->writelock);
-       return NO;
-      }
-      LOG_STRERROR(LOG_INFO, "write");
-      closeSocketTemporarily(sock);
-      MUTEX_UNLOCK(&sock->writelock);
-      return SYSERR;
-    }
-    if (res < sock->outBufLen) {
-      memcpy(sock->outBufPending,
-            &((char*)sock->outBufPending)[res],
-            sock->outBufLen - res);
-      sock->outBufLen -= res;
-      MUTEX_UNLOCK(&sock->writelock);
-      return SYSERR;
-    }
-    /* completely send out deferred buffer, so
-       we can in fact continue! */
-    FREENONNULL(sock->outBufPending);
-    sock->outBufPending = NULL;
-    sock->outBufLen = 0;
-  }
-
-  size = ntohs(buffer->size);
-
-  SEND_NONBLOCKING(sock->socket,
-                  (const char*)buffer,
-                  size,
-                  &res);
-  if (res == (size_t) -1) {
-    if ( (errno == EWOULDBLOCK) ||
-        (errno == EAGAIN) ) {
-      MUTEX_UNLOCK(&sock->writelock);
-      return NO; /* would block, can not send right now;
-                   but do NOT close socket in this case;
-                   do not use SYSERR as return value
-                   since this is not an error! */
-    }
-    LOG_STRERROR(LOG_INFO, "send");
-    closeSocketTemporarily(sock);
-    MUTEX_UNLOCK(&sock->writelock);
-    return SYSERR;
-  }
-  GNUNET_ASSERT(res <= size);
-  if (res != size) {
-    sock->outBufPending = MALLOC(size - res);
-    memcpy(sock->outBufPending,
-          &((const char*)buffer)[res],
-          size - res);
-    sock->outBufLen = size - res;
-    MUTEX_UNLOCK(&sock->writelock);
-    return OK; /* return OK here means that the message will be transmitted,
-                 though it may be a bit later (on the next call, in fact). */
-  }
-  MUTEX_UNLOCK(&sock->writelock);
-  return OK;
-}
-
-/**
- * Read from a GNUnet TCP socket.
- * @param sock the socket
- * @param buffer the buffer to write data to
- * @return OK if the read was successful, SYSERR if the socket
- *         was closed by the other side (if the socket is a
- *         client socket and is used again, tcpio will attempt
- *         to re-establish the connection [temporary error]).
- */
-int readFromSocket(GNUNET_TCP_SOCKET * sock,
-                  CS_MESSAGE_HEADER ** buffer) {
-  int res;
-  unsigned int pos;
-  char * buf;
-  unsigned short size;
-
-  if (SYSERR == checkSocket(sock))
-    return SYSERR;
-
-  MUTEX_LOCK(&sock->readlock);
-  pos = 0;
-  res = 0;
-
-  pos = RECV_BLOCKING_ALL(sock->socket,
-                         &size,
-                         sizeof(unsigned short));
-  if (pos != sizeof(unsigned short)) {
-#if DEBUG_TCPIO
-    LOG_STRERROR(LOG_INFO, "recv");
-#endif
-    closeSocketTemporarily(sock);
-    MUTEX_UNLOCK(&sock->readlock);
-    return SYSERR; /* other side closed socket or invalid header */
-  }
-  size = ntohs(size);
-  if (size < sizeof(CS_MESSAGE_HEADER)) {
-#if DEBUG_TCPIO
-    LOG_STRERROR(LOG_INFO, "recv");
-#endif
-    closeSocketTemporarily(sock);
-    MUTEX_UNLOCK(&sock->readlock);
-    return SYSERR; /* invalid header */
-  }
-
-  buf = (char*) *buffer;
-  if (buf == NULL)
-    buf = MALLOC(size);
-
-  res = RECV_BLOCKING_ALL(sock->socket,
-                         &buf[pos],
-                         size - pos);
-
-  if (res != (int)(size - pos)) {  /* error, abort */
-    if (sock->socket != -1)
-      LOG_STRERROR(LOG_INFO, "recv");
-    closeSocketTemporarily(sock);
-    if (*buffer == NULL)
-      FREE(buf);
-    MUTEX_UNLOCK(&sock->readlock);
-    return SYSERR;
-  }
-#if DEBUG_TCPIO
-  LOG(LOG_DEBUG,
-      "Successfully received %d bytes from TCP socket.\n",
-      size);
-#endif
-  MUTEX_UNLOCK(&sock->readlock);
-  *buffer = (CS_MESSAGE_HEADER*) buf;
-  (*buffer)->size = htons(size);
-  return OK; /* success */
-}
-
-/**
- * Close a GNUnet TCP socket for now (use to temporarily close
- * a TCP connection that will probably not be used for a long
- * time; the socket will still be auto-reopened by the
- * readFromSocket/writeToSocket methods if it is a client-socket).
- */
-void closeSocketTemporarily(GNUNET_TCP_SOCKET * sock) {
-  if (sock == NULL)
-    return;
-  if (sock->socket != -1) {
-    int i;
-
-    i = sock->socket;
-#if DEBUG_TCPIO
-    LOG(LOG_DEBUG,
-       "TCP: closing socket %d.\n",
-       sock->socket);
-#endif
-    sock->socket = -1;
-    if (0 != SHUTDOWN(i, SHUT_RDWR))
-      LOG_STRERROR(LOG_DEBUG, "shutdown");
-    closefile(i);
-  }
-  sock->outBufLen = 0;
-  FREENONNULL(sock->outBufPending);
-  sock->outBufPending = NULL;
-}
-
-/**
- * Destroy a socket for good. If you use this socket afterwards,
- * you must first invoke initializeSocket, otherwise the operation
- * will fail.
- */
-void destroySocket(GNUNET_TCP_SOCKET * sock) {
-  closeSocketTemporarily(sock);
-  sock->ip.addr = 0;
-  sock->port = 0;
-  sock->outBufLen = 0;
-  FREENONNULL(sock->outBufPending);
-  sock->outBufPending = NULL;
-  MUTEX_DESTROY(&sock->readlock);
-  MUTEX_DESTROY(&sock->writelock);
-}
-
-
-/*  end of tcpio.c */

Deleted: GNUnet/src/util/tcpiotest.c
===================================================================
--- GNUnet/src/util/tcpiotest.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/tcpiotest.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,261 +0,0 @@
-/**
- * @file test/tcpiotest.c
- * @brief testcase for util/tcpiotest.c
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-static int openServerSocket() {
-  int listenerFD;
-  int listenerPort;
-  struct sockaddr_in serverAddr;
-  const int on = 1;
-
-  listenerPort = getGNUnetPort();
-  /* create the socket */
-  while ( (listenerFD = SOCKET(PF_INET, SOCK_STREAM, 0)) < 0) {
-    LOG(LOG_ERROR,
-       "ERROR opening socket (%s).  "
-       "No client service started.  "
-       "Trying again in 30 seconds.\n",
-       STRERROR(errno));
-    sleep(30);
-  }
-
-  /* fill in the inet address structure */
-  memset((char *) &serverAddr,
-        0,
-        sizeof(serverAddr));
-  serverAddr.sin_family = AF_INET;
-  serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);
-  serverAddr.sin_port=htons(listenerPort);
-
-  if ( SETSOCKOPT(listenerFD,
-                 SOL_SOCKET,
-                 SO_REUSEADDR,
-                 &on, sizeof(on)) < 0 )
-    perror("setsockopt");
-
-  /* bind the socket */
-  if (BIND (listenerFD,
-          (struct sockaddr *) &serverAddr,
-           sizeof(serverAddr)) < 0) {
-    LOG(LOG_ERROR,
-       "ERROR (%s) binding the TCP listener to port %d. "
-       "Test failed.  Is gnunetd running?\n",
-       STRERROR(errno),
-       listenerPort);
-    return -1;
-  }
-
-  /* start listening for new connections */
-  if (0 != LISTEN(listenerFD, 5)) {
-    LOG(LOG_ERROR,
-       " listen failed: %s\n",
-       STRERROR(errno));
-    return -1;
-  }
-  return listenerFD;
-}
-
-static int doAccept(int serverSocket) {
-  int incomingFD;
-  int lenOfIncomingAddr;
-  struct sockaddr_in clientAddr;
-
-  incomingFD = -1;
-  while (incomingFD < 0) {
-    lenOfIncomingAddr = sizeof(clientAddr);
-    incomingFD = ACCEPT(serverSocket,
-                       (struct sockaddr *)&clientAddr,
-                       &lenOfIncomingAddr);
-    if (incomingFD < 0) {
-      LOG(LOG_ERROR,
-         "ERROR accepting new connection (%s).\n",
-         STRERROR(errno));
-      continue;
-    }
-  }
-  return incomingFD;
-}
-
-/**
- * Perform option parsing from the command line.
- */
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  char c;
-
-  while (1) {
-    int option_index = 0;
-    static struct GNoption long_options[] = {
-      { "config",  1, 0, 'c' },
-      { 0,0,0,0 }
-    };
-
-    c = GNgetopt_long(argc,
-                     argv,
-                     "c:",
-                     long_options,
-                     &option_index);
-
-    if (c == -1)
-      break;  /* No more flags to process */
-
-    switch(c) {
-    case 'c':
-      FREENONNULL(setConfigurationString("FILES",
-                                        "gnunet.conf",
-                                        GNoptarg));
-      break;
-    } /* end of parsing commandline */
-  }
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGFILE",
-                                    NULL));
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGLEVEL",
-                                    "DEBUG"));
-  return OK;
-}
-
-static int testTransmission(GNUNET_TCP_SOCKET * a,
-                           GNUNET_TCP_SOCKET * b) {
-  CS_MESSAGE_HEADER * hdr;
-  CS_MESSAGE_HEADER * buf;
-  int i;
-  int j;
-
-  hdr = MALLOC(1024);
-  for (i=0;i<1024-sizeof(CS_MESSAGE_HEADER);i+=7) {
-    fprintf(stderr, ".");
-    for (j=0;j<i;j++)
-      ((char*)&hdr[1])[j] = (char)i+j;
-    hdr->size = htons(i+sizeof(CS_MESSAGE_HEADER));
-    hdr->type = 0;
-    if (OK != writeToSocket(a, hdr)) {
-      FREE(hdr);
-      return 1;
-    }
-    buf = NULL;
-    if (OK != readFromSocket(b, &buf)) {
-      FREE(hdr);
-      return 2;
-    }
-    if (0 != memcmp(buf, hdr, i+sizeof(CS_MESSAGE_HEADER))) {
-      FREE(buf);
-      FREE(hdr);
-      return 4;
-    }
-    FREE(buf);
-  }
-  FREE(hdr);
-  return 0;
-}
-
-static int testNonblocking(GNUNET_TCP_SOCKET * a,
-                          GNUNET_TCP_SOCKET * b) {
-  CS_MESSAGE_HEADER * hdr;
-  CS_MESSAGE_HEADER * buf;
-  int i;
-  int cnt;
-
-  hdr = MALLOC(1024);
-  for (i=0;i<1024-sizeof(CS_MESSAGE_HEADER);i+=11)
-    ((char*)&hdr[1])[i] = (char)i;
-  hdr->size = htons(64+sizeof(CS_MESSAGE_HEADER));
-  hdr->type = 0;
-  while (OK == writeToSocketNonBlocking(a,
-                                       hdr))
-    hdr->type++;
-  i = 0;
-  cnt = hdr->type;
-  /* printf("Reading %u messages.\n", cnt); */
-  if (cnt < 2)
-    return 8; /* could not write ANY data non-blocking!? */
-  for (i=0;i<cnt;i++) {
-    hdr->type = i;
-    buf = NULL;
-    if (OK != readFromSocket(b, &buf)) {
-      FREE(hdr);
-      return 16;
-    }
-    if (0 != memcmp(buf, hdr, 64+sizeof(CS_MESSAGE_HEADER))) {
-      printf("Failure in message %u.  Headers: %d ? %d\n",
-            i,
-            buf->type,
-            hdr->type);
-      FREE(buf);
-      FREE(hdr);
-      return 32;
-    }
-    FREE(buf);
-    if (i == cnt - 2) {
-      /* printf("Blocking write to flush last non-blocking message.\n"); */
-      hdr->type = cnt;
-      if (OK != writeToSocket(a,
-                             hdr)) {
-       FREE(hdr);
-       return 64;
-      }
-    }
-  }
-  hdr->type = i;
-  buf = NULL;
-  if (OK != readFromSocket(b, &buf)) {
-    FREE(hdr);
-    return 128;
-  }
-  if (0 != memcmp(buf, hdr, 64+sizeof(CS_MESSAGE_HEADER))) {
-    FREE(buf);
-    FREE(hdr);
-    return 256;
-  }
-  FREE(buf);
-  FREE(hdr);
-  return 0;
-}
-
-int main(int argc, char * argv[]){
-  int i;
-  int ret;
-  int serverSocket;
-  GNUNET_TCP_SOCKET * clientSocket;
-  GNUNET_TCP_SOCKET acceptSocket;
-
-  ret = 0;
-  initUtil(argc, argv, &parseCommandLine);
-  serverSocket = openServerSocket();
-  clientSocket = getClientSocket();
-  if (serverSocket == -1) {
-    releaseClientSocket(clientSocket);
-    doneUtil();
-    return 1;
-  }
-  for (i=0;i<2;i++) {
-    if (OK == checkSocket(clientSocket)) {
-      if (OK == initGNUnetServerSocket(doAccept(serverSocket),
-                                      &acceptSocket)) {
-       ret = ret | testTransmission(clientSocket, &acceptSocket);
-       ret = ret | testTransmission(&acceptSocket, clientSocket);
-       ret = ret | testNonblocking(clientSocket, &acceptSocket);
-       ret = ret | testNonblocking(&acceptSocket, clientSocket);
-       closeSocketTemporarily(clientSocket);
-       destroySocket(&acceptSocket);
-       fprintf(stderr, "\n");
-      } else {
-       fprintf(stderr, "initGNUnetServerSocket failed.\n");
-       ret = -1;
-      }
-    } else {
-      fprintf(stderr, "checkSocket faild.\n");
-      ret = -1;
-    }
-  }
-  releaseClientSocket(clientSocket);
-  doneUtil();
-  if (ret > 0)
-    fprintf(stderr, "Error %d\n", ret);
-  return ret;
-}

Added: GNUnet/src/util/threads/Makefile.am
===================================================================
--- GNUnet/src/util/threads/Makefile.am 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/threads/Makefile.am 2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,34 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+SUBDIRS = .
+
+noinst_LTLIBRARIES = \
+  libthreads.la
+
+libthreads_la_SOURCES = \
+ mutex.c \
+ pthread.c \
+ semaphore.c \
+ shutdown.c 
+
+check_PROGRAMS = \
+ semaphoretest \
+ shutdowntest \
+ timertest 
+
+TESTS = $(check_PROGRAMS)
+
+semaphoretest_SOURCES = \
+ semaphoretest.c
+semaphoretest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  
+
+shutdowntest_SOURCES = \
+ shutdowntest.c
+shutdowntest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  
+
+timertest_SOURCES = \
+ timertest.c
+timertest_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la  

Added: GNUnet/src/util/threads/mutex.c
===================================================================
--- GNUnet/src/util/threads/mutex.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/threads/mutex.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,162 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004 Christian Grothoff (and other contributing 
authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/threads/mutex.c
+ * @brief implementation of mutual exclusion
+ */
+
+#include "gnunet_util_threads.h"
+#include "gnunet_util_error.h"
+#include "gnunet_util_string.h"
+#include "platform.h"
+
+#if SOLARIS || FREEBSD || OSX
+#include <semaphore.h>
+#endif
+#if SOMEBSD
+# include <pthread_np.h>
+# include <sys/file.h>
+#endif
+#if LINUX
+# include <sys/sem.h>
+#endif
+#ifdef _MSC_VER
+#include <pthread.h>
+#include <semaphore.h>
+#endif
+
+#ifndef PTHREAD_MUTEX_NORMAL
+#ifdef PTHREAD_MUTEX_TIMED_NP
+#define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP
+#else
+#define PTHREAD_MUTEX_NORMAL NULL
+#endif
+#endif
+
+/**
+ * This prototype is somehow missing in various Linux pthread
+ * include files. But we need it and it seems to be available
+ * on all pthread-systems so far. Odd.
+ */
+#ifndef _MSC_VER
+extern int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, 
+                                       int kind);
+#endif
+
+
+typedef struct MUTEX {
+  pthread_mutex_t pt;
+} Mutex;
+
+Mutex * MUTEX_CREATE(int isRecursive) {
+  pthread_mutexattr_t attr;
+  Mutex * mut;
+#if WINDOWS
+  attr = NULL;
+#endif
+
+  pthread_mutexattr_init(&attr);
+  if (isRecursive) {
+#if LINUX
+    GE_ASSERT(NULL,
+             0 == pthread_mutexattr_setkind_np
+             (&attr,
+              PTHREAD_MUTEX_RECURSIVE_NP));
+#elif SOMEBSD || FREEBSD || FREEBSD5
+    GE_ASSERT(NULL,
+             0 == pthread_mutexattr_setkind_np
+             (&attr,
+              PTHREAD_MUTEX_RECURSIVE));
+#elif SOLARIS || OSX || WINDOWS
+    GE_ASSERT(NULL,
+             0 == pthread_mutexattr_settype
+             (&attr,
+              PTHREAD_MUTEX_RECURSIVE));
+#endif
+  } else {
+#if LINUX
+    GE_ASSERT(NULL,
+             0 == pthread_mutexattr_setkind_np
+             (&attr, 
+              PTHREAD_MUTEX_ERRORCHECK_NP));
+#else
+    GE_ASSERT(NULL,
+             0 == pthread_mutexattr_settype
+             (&attr, 
+              PTHREAD_MUTEX_ERRORCHECK));
+#endif
+  }
+  mut = MALLOC(sizeof(Mutex));
+  GE_ASSERT(NULL, 
+           0 == pthread_mutex_init(&mut->pt, 
+                                   &attr));
+  return mut;
+}
+
+void MUTEX_DESTROY(Mutex * mutex) {
+  GE_ASSERT(NULL, mutex != NULL);
+  errno = 0;
+  GE_ASSERT(NULL,
+           0 == pthread_mutex_destroy(&mutex->pt));
+  FREE(mutex);
+}
+
+void MUTEX_LOCK(Mutex * mutex) {
+  int ret;
+
+  GE_ASSERT(NULL, mutex != NULL);
+  ret = pthread_mutex_lock(&mutex->pt);
+  if (ret != 0) {
+    if (ret == EINVAL)
+      GE_LOG(NULL,
+            GE_FATAL | GE_DEVELOPER | GE_USER | GE_IMMEDIATE,
+            _("Invalid argument for `%s'.\n"),
+            "pthread_mutex_lock");
+    if (ret == EDEADLK)
+      GE_LOG(NULL,
+            GE_FATAL | GE_DEVELOPER | GE_USER | GE_IMMEDIATE,
+            _("Deadlock due to `%s'.\n"),
+             "pthread_mutex_lock");
+    GE_ASSERT(NULL, 0);
+  }
+}
+
+void MUTEX_UNLOCK(Mutex * mutex) {
+  int ret;
+
+  GE_ASSERT(NULL, mutex != NULL);
+  ret = pthread_mutex_unlock(&mutex->pt);
+  if (ret != 0) {
+    if (ret == EINVAL)
+      GE_LOG(NULL,
+            GE_FATAL | GE_DEVELOPER | GE_USER | GE_IMMEDIATE,
+            _("Invalid argument for `%s'.\n"),
+            "pthread_mutex_lock");
+    if (ret == EPERM)
+      GE_LOG(NULL,
+            GE_FATAL | GE_DEVELOPER | GE_USER | GE_IMMEDIATE,
+            _("Permission denied for `%s'.\n"),
+            "pthread_mutex_unlock");
+    GE_ASSERT(NULL, 0);
+  }
+}
+
+/* end of mutex.c */

Added: GNUnet/src/util/threads/pthread.c
===================================================================
--- GNUnet/src/util/threads/pthread.c   2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/threads/pthread.c   2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,292 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004, 2006 Christian Grothoff (and other 
contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/threads/pthread.c
+ * @brief implementation of pthread start/join/sleep
+ */
+
+#include "gnunet_util_threads.h"
+#include "gnunet_util_error.h"
+#include "gnunet_util_string.h"
+#include "platform.h"
+
+#if SOLARIS || FREEBSD || OSX
+#include <semaphore.h>
+#endif
+#if SOMEBSD
+# include <pthread_np.h>
+# include <sys/file.h>
+#endif
+#if LINUX
+# include <sys/sem.h>
+#endif
+#ifdef _MSC_VER
+#include <pthread.h>
+#endif
+
+typedef struct PTHREAD {
+  pthread_t pt;
+} PThread;
+
+/**
+ * Returns YES if pt is the handle for THIS thread.
+ */
+int PTHREAD_TEST_SELF(PThread * handle) {
+  GE_ASSERT(NULL, handle != NULL);
+#if pthread_equal
+  if (pthread_equal(pthread_self(), handle->pt))
+#else
+#if HAVE_NEW_PTHREAD_T
+  if (handle->pt->p == pthread_self().p)
+#else
+  if (handle->pt == pthread_self())
+#endif
+#endif
+    return YES;
+  else
+    return NO;
+}
+
+/**
+ * Get the handle for THIS thread.
+ */
+PThread * PTHREAD_GET_SELF() {
+  PThread * ret;
+  ret = MALLOC(sizeof(PThread));
+  ret->pt = pthread_self();
+  return ret;
+}
+
+/**
+ * Release handle for a thread.
+ */
+void PTHREAD_REL_SELF(PThread * handle) {
+  FREE(handle);
+}
+
+/**
+ * Create a thread. Use this method instead of pthread_create since
+ * BSD may only give a 1k stack otherwise.
+ *
+ * @param handle handle to the pthread (for detaching, join)
+ * @param main the main method of the thread
+ * @param arg the argument to main
+ * @param stackSize the size of the stack of the thread in bytes.
+ *        Note that if the stack overflows, some OSes (seen under BSD)
+ *        will just segfault and gdb will give a messed-up stacktrace.
+ * @return see pthread_create
+ */
+PThread * PTHREAD_CREATE(PThreadMain main,
+                        void * arg,
+                        unsigned int stackSize) {
+  PThread * handle;
+  pthread_attr_t stack_size_custom_attr;
+  int ret;
+
+  handle = MALLOC(sizeof(PThread));
+#ifdef MINGW
+  memset(handle, 0, sizeof(PThread));
+#endif
+  pthread_attr_init(&stack_size_custom_attr);
+  pthread_attr_setstacksize(&stack_size_custom_attr,
+                           stackSize);
+  ret = pthread_create(&handle->pt,
+                      &stack_size_custom_attr,
+                      main,
+                      arg);
+
+  if (ret != 0) {
+    FREE(handle);
+    return NULL;
+  }
+  return handle;
+}
+
+void PTHREAD_JOIN(PThread * handle,
+                 void ** ret) {
+  int k;
+
+  GE_ASSERT(NULL, 
+           handle != NULL);
+  GE_ASSERT(NULL, 
+           NO == PTHREAD_TEST_SELF(handle));
+  k = pthread_join(handle->pt, ret);
+  FREE(handle);
+  switch (k) {
+  case 0:
+    return;
+  case ESRCH:
+    GE_LOG(NULL,
+          GE_FATAL | GE_USER | GE_DEVELOPER | GE_IMMEDIATE,
+          _("`%s' failed with error code %s: %s\n"),
+          "pthread_join",
+          "ESRCH",
+          STRERROR(errno));
+    break;
+  case EINVAL:
+    GE_LOG(NULL,
+          GE_FATAL | GE_USER | GE_DEVELOPER | GE_IMMEDIATE,
+          _("`%s' failed with error code %s: %s\n"),
+          "pthread_join",
+          "EINVAL",
+          STRERROR(errno));
+  case EDEADLK:
+    GE_LOG(NULL,
+          GE_FATAL | GE_USER | GE_DEVELOPER | GE_IMMEDIATE,
+          _("`%s' failed with error code %s: %s\n"),
+          "pthread_join",
+          "EDEADLK",
+          STRERROR(errno));
+  default:
+    GE_LOG(NULL,
+          GE_FATAL | GE_USER | GE_DEVELOPER | GE_IMMEDIATE,
+          _("`%s' failed with error code %d: %s\n"),
+          "pthread_join",
+          k,
+          STRERROR(errno));
+  }
+  GE_ASSERT(NULL, 0);
+}
+
+#ifdef WINDOWS
+/**
+ * @brief Called if a sleeping thread is interrupted
+ */
+static void CALLBACK __PTHREAD_SIGNALED(DWORD sig) {
+}
+#else
+static void sigalrmHandler(int sig) {
+}
+#endif
+
+
+/**
+ * Sleep for the specified time interval.  Use PTHREAD_STOP_SLEEP to
+ * wake the thread up early.  Caller is responsible to check that the
+ * sleep was long enough.
+ */
+void PTHREAD_SLEEP(unsigned long long delay) {
+#ifndef MINGW
+  static struct sigaction sig;
+  static struct sigaction old;
+#endif
+#if LINUX || SOLARIS || SOMEBSD || OSX
+  struct timespec req;
+  struct timespec rem;
+#elif WINDOWS
+#else
+  int ret;
+  struct timeval timeout;
+#endif
+
+  /* make sure SIGALRM does not kill us */
+#ifndef MINGW
+  memset(&sig, 0, sizeof(struct sigaction));
+  memset(&old, 0, sizeof(struct sigaction));
+  sig.sa_flags = SA_NODEFER;
+  sig.sa_handler =  &sigalrmHandler; 
+  if (0 != sigaction(SIGALRM, &sig, &old))
+    GE_LOG_STRERROR(NULL,
+                   GE_WARNING | GE_ADMIN | GE_BULK,
+                   "sigaction");                   
+#endif
+
+  /* actual sleep */
+#if LINUX || SOLARIS || SOMEBSD || OSX
+  req.tv_sec
+    = delay / 1000; /* ms -> seconds */
+  req.tv_nsec
+    = (delay - req.tv_sec * 1000) * 1000 * 1000; /* ms -> ns */
+  rem.tv_sec = 0;
+  rem.tv_nsec = 0;
+  if ( (0 != nanosleep(&req, &rem)) &&
+       (errno != EINTR) )
+      GE_LOG_STRERROR(NULL,
+                     GE_WARNING | GE_USER | GE_BULK,
+                     "nanosleep");
+#elif WINDOWS
+  SleepEx(delay, TRUE);
+#else
+  /* fall back to select */
+  timeout.tv_sec
+    = delay / CRON_UNIT_TO_SECONDS;
+  timeout.tv_usec
+    = (delay - timeout.tv_sec * CRON_UNIT_TO_SECONDS)
+    * MICROSEC_TO_CRON_UNIT;
+  ret = SELECT(0, NULL, NULL, NULL, &timeout);
+  if ( (ret == -1) &&
+       (errno != EINTR) ) 
+    GE_LOG_STRERROR(NULL,
+                   GE_WARNING | GE_USER | GE_BULK,
+                   "select");
+#endif
+
+  /* restore signal handler */
+#ifndef MINGW
+  if (0 != sigaction(SIGALRM, &old, &sig))
+    GE_LOG_STRERROR(NULL,
+                   GE_WARNING | GE_ADMIN | GE_BULK,
+                   "sigaction");                   
+#endif
+}
+
+void PTHREAD_STOP_SLEEP(PThread * handle) {
+  int ret;
+
+  GE_ASSERT(NULL, handle != NULL);
+#ifdef WINDOWS
+  ret = QueueUserAPC((PAPCFUNC) __PTHREAD_SIGNALED,
+                    pthread_getw32threadhandle_np(handle->pt), 
+                    0) != 0 ? 0 : EINVAL;
+#else
+  ret = pthread_kill(handle->pt, SIGALRM);
+#endif
+  switch (ret) {
+  case 0: 
+    break; /* ok */
+  case EINVAL:
+    GE_LOG(NULL,
+          GE_ERROR | GE_USER | GE_DEVELOPER | GE_BULK,
+          _("`%s' failed with error code %s: %s\n"),
+          "pthread_kill",
+          "EINVAL",
+          STRERROR(ret));
+    break;
+  case ESRCH:
+    GE_LOG(NULL,
+          GE_ERROR | GE_USER | GE_DEVELOPER | GE_BULK,
+          _("`%s' failed with error code %s: %s\n"),
+          "pthread_kill",
+          "ESRCH",
+          STRERROR(ret));
+    break;
+  default:
+    GE_LOG(NULL,
+          GE_ERROR | GE_USER | GE_DEVELOPER | GE_BULK,
+          _("`%s' failed with error code %d: %s\n"),
+          "pthread_kill",
+          ret,
+          STRERROR(ret));
+    break;
+  }
+}
+
+/* end of semaphore.c */

Added: GNUnet/src/util/threads/semaphore.c
===================================================================
--- GNUnet/src/util/threads/semaphore.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/threads/semaphore.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,165 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004, 2006 Christian Grothoff (and other 
contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/pthreads/semaphore.c
+ * @brief functions related to threading and synchronization
+ *
+ * In particular, functions for mutexes, semaphores
+ * and thread creation are provided.
+ */
+
+#include "gnunet_util_threads.h"
+#include "gnunet_util_error.h"
+#include "gnunet_util_string.h"
+#include "platform.h"
+
+#if SOLARIS || FREEBSD || OSX
+#include <semaphore.h>
+#include <sys/file.h>
+#endif
+#if SOMEBSD
+#include <pthread_np.h>
+#endif
+#if LINUX
+#include <sys/sem.h>
+#endif
+#ifdef _MSC_VER
+#include <pthread.h>
+#include <semaphore.h>
+#endif
+
+/**
+ * @brief Internal state of a semaphore.
+ */
+typedef struct SEMAPHORE {
+  /**
+   * Counter
+   */
+  int v;
+
+  /**
+   * Mutex
+   */
+  pthread_mutex_t mutex;
+
+  /**
+   * Wrapper for pthread condition variable.
+   */
+  pthread_cond_t cond;
+} Semaphore;
+
+#ifndef PTHREAD_MUTEX_NORMAL
+#ifdef PTHREAD_MUTEX_TIMED_NP
+#define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP
+#else
+#define PTHREAD_MUTEX_NORMAL NULL
+#endif
+#endif
+
+/**
+ * This prototype is somehow missing in various Linux pthread
+ * include files. But we need it and it seems to be available
+ * on all pthread-systems so far. Odd.
+ */
+#ifndef _MSC_VER
+extern int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, 
+                                       int kind);
+#endif
+
+/**
+ * function must be called prior to semaphore use -- handles
+ * setup and initialization.  semaphore destroy (below) should
+ * be called when the semaphore is no longer needed.
+ */
+Semaphore * SEMAPHORE_CREATE(int value) {
+  Semaphore * s;
+  pthread_mutexattr_t attr;
+#if WINDOWS
+  attr = NULL;
+#endif
+
+  pthread_mutexattr_init(&attr);
+#if LINUX
+  GE_ASSERT(NULL,
+           0 == pthread_mutexattr_setkind_np
+           (&attr, 
+            PTHREAD_MUTEX_ERRORCHECK_NP));
+#else
+  GE_ASSERT(NULL,
+           0 == pthread_mutexattr_settype
+           (&attr, 
+            PTHREAD_MUTEX_ERRORCHECK));
+#endif
+  s = MALLOC(sizeof(Semaphore));
+  s->v = value;
+  GE_ASSERT(NULL, 
+           0 == pthread_mutex_init(&s->mutex, 
+                                   &attr));
+  GE_ASSERT(NULL,
+           0 == pthread_cond_init(&s->cond, 
+                                  NULL));
+  return s;
+}
+
+void SEMAPHORE_DESTROY(Semaphore * s) {
+  GE_ASSERT(NULL, s != NULL);
+  GE_ASSERT(NULL,
+           0 == pthread_cond_destroy(&s->cond));
+  GE_ASSERT(NULL,
+           0 == pthread_mutex_destroy(&s->mutex));
+  FREE(s);
+}
+
+int SEMAPHORE_UP(Semaphore * s) {
+  int ret;
+
+  GE_ASSERT(NULL, s != NULL);
+  GE_ASSERT(NULL,
+           0 == pthread_mutex_lock(&s->mutex));
+  ret = ++(s->v);
+  GE_ASSERT(NULL,
+           0 == pthread_cond_signal(&s->cond));
+  GE_ASSERT(NULL,
+           0 == pthread_mutex_unlock(&s->mutex));
+  return ret;
+}
+
+int SEMAPHORE_DOWN(Semaphore * s,
+                  int mayblock) {
+  int ret;
+
+  GE_ASSERT(NULL, s != NULL);
+  GE_ASSERT(NULL,
+           0 == pthread_mutex_lock(&s->mutex));
+  while ( (s->v <= 0) && mayblock) 
+    GE_ASSERT(NULL,
+             0 == pthread_cond_wait(&s->cond,
+                                    &s->mutex));
+  if (s->v > 0) 
+    ret = --(s->v);
+  else 
+    ret = SYSERR;
+  GE_ASSERT(NULL,
+           0 == pthread_mutex_unlock(&s->mutex));
+  return ret;
+}
+
+/* end of semaphore.c */

Added: GNUnet/src/util/threads/semaphoretest.c
===================================================================
--- GNUnet/src/util/threads/semaphoretest.c     2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/util/threads/semaphoretest.c     2006-06-22 17:50:56 UTC (rev 
3024)
@@ -0,0 +1,255 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2003, 2004 Christian Grothoff (and other contributing 
authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file test/semaphore.c
+ * @brief testcase for util/threads/semaphore.c
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+#include <sys/types.h>
+#ifndef MINGW             /* PORT-ME MINGW */
+
+
+static Mutex lock;
+
+static Semaphore * sem;
+
+static volatile int sv;
+
+static volatile int tv;
+
+static void lockIt() {
+  sv = 0;
+  fprintf(stderr, ".");
+  while (sv == 0)
+    gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work */
+  MUTEX_LOCK(&lock);
+  sv = 1;
+  MUTEX_UNLOCK(&lock);
+  sv = 2;
+  tv = 2;
+}
+
+static void bigStack() {
+  int i;
+  char big[1024 * 100];
+
+  fprintf(stderr, ".");
+  for (i=0;i<1024*100;i++)
+    big[i] = (char) i;
+}
+
+static int testPTHREAD_CREATE() {
+  PTHREAD_T pt;
+  void * unused;
+
+  sv = -1; tv = 0;
+  fprintf(stderr, ".");
+  MUTEX_CREATE(&lock);
+  PTHREAD_CREATE(&pt,
+                (PThreadMain)&lockIt,
+                NULL,
+                1024);
+  PTHREAD_DETACH(&pt);
+  while (tv != 2) {
+    sv = 1;
+    gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work */
+  }
+  MUTEX_DESTROY(&lock);
+  PTHREAD_CREATE(&pt,
+                (PThreadMain)&bigStack,
+                NULL,
+                1024*100 + 25000); /* fails by segfault */
+  PTHREAD_JOIN(&pt, &unused);
+  return 0;
+}
+
+static int testMutex() {
+  PTHREAD_T pt;
+  void * unused;
+  MUTEX_CREATE(&lock);
+
+  sv = 1;
+  tv = 0;
+  PTHREAD_CREATE(&pt,
+                (PThreadMain)&lockIt,
+                NULL,
+                1024);
+  while (sv == 1)
+    gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work */
+  MUTEX_LOCK(&lock);
+  sv = 5; /* release lockIt from while sv==0 loop,
+            blocks it on lock */
+  fprintf(stderr, ".");
+
+  if (sv != 5) {
+    MUTEX_UNLOCK(&lock);
+    while (tv != 2)
+      gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work 
*/
+    MUTEX_DESTROY(&lock);
+    printf("MUTEX test failed at %s:%u\n",
+          __FILE__, __LINE__);
+    return 1; /* error */
+  } else {
+    MUTEX_UNLOCK(&lock);
+    while (tv != 2)
+      gnunet_util_sleep(50 * cronMILLIS); /* busy waiting may not always work 
*/
+    PTHREAD_JOIN(&pt, &unused);
+    MUTEX_DESTROY(&lock);
+    return 0; /* ok */
+  }
+}
+
+static int testRecursiveMutex() {
+  int i;
+
+  fprintf(stderr, ".");
+  MUTEX_CREATE_RECURSIVE(&lock);
+  for (i=0;i<50;i++)
+    MUTEX_LOCK(&lock);
+  for (i=0;i<50;i++)
+    MUTEX_UNLOCK(&lock);
+  MUTEX_DESTROY(&lock);
+  return 0; /* ok -- fails by hanging!*/
+}
+
+static void semUpDown() {
+  int i;
+
+  fprintf(stderr, ".");
+  for (i=0;i<42;i++)
+    SEMAPHORE_DOWN(sem); /* fails by blocking */
+  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
+    SEMAPHORE_FREE(sem);
+    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n"
+          "Testcase deadlocked.\n",
+          __FILE__, __LINE__);
+    return; /* will halt testcase! */
+  }
+  for (i=0;i<42;i++)
+    SEMAPHORE_UP(sem);
+}
+
+static int testSemaphore() {
+  int i;
+  PTHREAD_T pt;
+  void * unused;
+
+  sem = SEMAPHORE_NEW(42);
+  fprintf(stderr, ".");
+  for (i=0;i<42;i++)
+    SEMAPHORE_DOWN(sem); /* fails by blocking */
+  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
+    SEMAPHORE_FREE(sem);
+    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
+          __FILE__, __LINE__);
+    return 1;
+  }
+  for (i=0;i<42;i++)
+    SEMAPHORE_UP(sem);
+  for (i=0;i<42;i++)
+    if (OK != SEMAPHORE_DOWN_NONBLOCKING(sem)) {
+      SEMAPHORE_FREE(sem);
+      printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
+            __FILE__, __LINE__);
+      return 1;
+    }
+  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
+    SEMAPHORE_FREE(sem);
+    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
+          __FILE__, __LINE__);
+    return 1;
+  }
+  fprintf(stderr, ".");
+  PTHREAD_CREATE(&pt,
+                (PThreadMain)&semUpDown,
+                NULL,
+                1024);
+  for (i=0;i<42;i++)
+    SEMAPHORE_UP(sem);
+  PTHREAD_JOIN(&pt, &unused);
+  for (i=0;i<42;i++)
+    SEMAPHORE_DOWN(sem);
+  if (SEMAPHORE_DOWN_NONBLOCKING(sem) != SYSERR) {
+    SEMAPHORE_FREE(sem);
+    printf("SEMAPHORE_DOWN_NONBLOCKING failed at %s:%u\n",
+          __FILE__, __LINE__);
+    return 1;
+  }
+  return 0;
+}
+
+/**
+ * Perform option parsing from the command line.
+ */
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  char c;
+
+  while (1) {
+    int option_index = 0;
+    static struct GNoption long_options[] = {
+      { "loglevel",1, 0, 'L' },
+      { "config",  1, 0, 'c' },
+      { 0,0,0,0 }
+    };
+
+    c = GNgetopt_long(argc,
+                     argv,
+                     "c:L:",
+                     long_options,
+                     &option_index);
+
+    if (c == -1)
+      break;  /* No more flags to process */
+
+    switch(c) {
+    case 'L':
+      FREENONNULL(setConfigurationString("GNUNET",
+                                        "LOGLEVEL",
+                                        GNoptarg));
+      break;
+    case 'c':
+      FREENONNULL(setConfigurationString("FILES",
+                                        "gnunet.conf",
+                                        GNoptarg));
+      break;
+    } /* end of parsing commandline */
+  }
+  return OK;
+}
+#endif /* PORT-ME MINGW */
+
+int main(int argc, char * argv[]){
+  int ret = 0;
+
+#ifndef MINGW
+  initUtil(argc, argv, &parseCommandLine);
+  ret += testPTHREAD_CREATE();
+  ret += testMutex();
+  ret += testRecursiveMutex();
+  ret += testSemaphore();
+  fprintf(stderr, "\n");
+  doneUtil();
+#endif
+  return ret;
+}

Added: GNUnet/src/util/threads/shutdown.c
===================================================================
--- GNUnet/src/util/threads/shutdown.c  2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/threads/shutdown.c  2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,123 @@
+/*
+     This file is part of GNUnet.
+     (C) 2001, 2002, 2006 Christian Grothoff (and other contributing authors)
+
+     GNUnet 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, or (at your
+     option) any later version.
+
+     GNUnet 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.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/threads/shutdown.c
+ * @brief code to allow clean shutdown of application with signals
+ * @author Christian Grothoff
+ *
+ * Helper code for writing proper termination code when an application
+ * receives a SIGTERM/SIGHUP etc.
+ */
+
+#include "gnunet_util_threads.h"
+#include "gnunet_util_error.h"
+#include "gnunet_util_string.h"
+#include "platform.h"
+
+/**
+ * Semaphore used to signal "shutdown"
+ */
+static struct SEMAPHORE * shutdown_signal;
+
+static int shutdown_active;
+
+void GNUNET_SHUTDOWN_INITIATE() {
+  GE_ASSERT(NULL, shutdown_signal != NULL);
+  shutdown_active = YES;
+  SEMAPHORE_UP(shutdown_signal);
+}
+
+int GNUNET_SHUTDOWN_TEST() {
+  return shutdown_active;
+}
+
+void GNUNET_SHUTDOWN_WAITFOR() {
+  SEMAPHORE_DOWN(shutdown_signal, YES);
+}
+
+#ifdef MINGW
+BOOL WINAPI run_shutdown_win(DWORD dwCtrlType) {
+  switch(dwCtrlType) {
+  case CTRL_C_EVENT:
+  case CTRL_CLOSE_EVENT:
+  case CTRL_SHUTDOWN_EVENT:
+  case CTRL_LOGOFF_EVENT:
+    GNUNET_SHUTDOWN_INITIATE();
+  }
+  return TRUE;
+}
+#else
+static void run_shutdown(int signum) {
+  GNUNET_SHUTDOWN_INITIATE();
+}
+#endif
+
+/**
+ * Initialize the signal handlers, etc.
+ */
+void __attribute__ ((constructor)) shutdown_handlers_ltdl_init() {
+#ifndef MINGW
+  struct sigaction sig;
+  struct sigaction oldsig;
+#endif
+
+  GE_ASSERT(NULL, shutdown_signal == NULL);
+  GE_ASSERT(NULL, shutdown_active == NO);
+  shutdown_signal = SEMAPHORE_CREATE(0);
+#ifndef MINGW
+  sig.sa_handler = &run_shutdown;
+  sigemptyset(&sig.sa_mask);
+#ifdef SA_INTERRUPT
+  sig.sa_flags = SA_INTERRUPT; /* SunOS */
+#else
+  sig.sa_flags = SA_RESTART;
+#endif
+  sigaction(SIGINT,  &sig, &oldsig);
+  sigaction(SIGTERM, &sig, &oldsig);
+  sigaction(SIGQUIT, &sig, &oldsig);
+#else
+  SetConsoleCtrlHandler(&run_shutdown_win, TRUE);
+#endif
+}
+
+void __attribute__ ((destructor)) shutdown_handlers_ltdl_fini() {
+#ifndef MINGW
+  struct sigaction sig;
+  struct sigaction oldsig;
+
+  sig.sa_handler = SIG_DFL;
+  sigemptyset(&sig.sa_mask);
+#ifdef SA_INTERRUPT
+  sig.sa_flags = SA_INTERRUPT; /* SunOS */
+#else
+  sig.sa_flags = SA_RESTART;
+#endif
+  sigaction(SIGINT,  &sig, &oldsig);
+  sigaction(SIGTERM, &sig, &oldsig);
+  sigaction(SIGQUIT, &sig, &oldsig);
+#else
+  SetConsoleCtrlHandler(&run_shutdown_win, FALSE);
+#endif
+  SEMAPHORE_DESTROY(shutdown_signal);
+  shutdown_signal = NULL;
+}
+
+/* end of shutdown.c */

Added: GNUnet/src/util/threads/shutdowntest.c
===================================================================
--- GNUnet/src/util/threads/shutdowntest.c      2006-06-22 17:39:19 UTC (rev 
3023)
+++ GNUnet/src/util/threads/shutdowntest.c      2006-06-22 17:50:56 UTC (rev 
3024)
@@ -0,0 +1,95 @@
+/**
+ * @file test/shutdowntest.c
+ * @brief testcase for util/shutdown.c
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+static pid_t myPID;
+
+static int check() {
+  /* first, test / SIGINT (simulated) */
+  initializeShutdownHandlers();
+  if (testShutdown() != NO)
+    return 1;
+#ifndef MINGW
+  kill(myPID, SIGINT);
+#else
+  GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
+#endif
+  if (testShutdown() != YES)
+    return 2;
+  wait_for_shutdown();
+  doneShutdownHandlers();
+
+  /* now, test "run_shutdown" */
+  initializeShutdownHandlers();
+  if (testShutdown() != NO)
+    return 3;
+  run_shutdown(42);
+  if (testShutdown() != YES)
+    return 4;
+  wait_for_shutdown();
+  doneShutdownHandlers();
+
+  return 0;
+}
+
+
+/**
+ * Perform option parsing from the command line.
+ */
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  char c;
+
+  while (1) {
+    int option_index = 0;
+    static struct GNoption long_options[] = {
+      { "config",  1, 0, 'c' },
+      { 0,0,0,0 }
+    };
+
+    c = GNgetopt_long(argc,
+                     argv,
+                     "c:",
+                     long_options,
+                     &option_index);
+
+    if (c == -1)
+      break;  /* No more flags to process */
+
+    switch(c) {
+    case 'c':
+      FREENONNULL(setConfigurationString("FILES",
+                                        "gnunet.conf",
+                                        GNoptarg));
+      break;
+    } /* end of parsing commandline */
+  }
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGFILE",
+                                    NULL));
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGLEVEL",
+                                    "WARNING"));
+  return OK;
+}
+
+int main(int argc,
+        char * argv[]){
+  int ret;
+
+  myPID = getpid();
+  initUtil(argc, argv, &parseCommandLine);
+
+  ret = check();
+  if (ret != 0)
+    fprintf(stderr,
+           "ERROR %d\n", ret);
+  doneUtil();
+  return ret;
+}
+
+/* end of shutdowntest.c */

Added: GNUnet/src/util/threads/timertest.c
===================================================================
--- GNUnet/src/util/threads/timertest.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/threads/timertest.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,182 @@
+/**
+ * @file test/timertest.c
+ * @brief testcase for util/timer.c; also measures how
+ *  precise the timers are.  Expect values between 10 and 20 ms on
+ *  modern machines.
+ */
+
+#include "gnunet_util.h"
+#include "platform.h"
+
+#define VERBOSE NO
+
+static void semaphore_up(Semaphore * sem) {
+  SEMAPHORE_UP(sem);
+}
+
+static int check() {
+  cron_t now;
+  cron_t last;
+  TIME_T tnow;
+  TIME_T tlast;
+  int i;
+  unsigned long long cumDelta;
+  Semaphore * sem;
+
+  /* test that time/cronTime are monotonically
+     increasing;
+     measure precision of sleep and report;
+     test that sleep is interrupted by signals; */
+  last = cronTime(&now);
+  if (last != now)
+    return 1;
+  tlast = TIME(&tnow);
+  if (tlast != tnow)
+    return 2;
+  while (now == last)
+    now = cronTime(NULL);
+  while (tnow == tlast)
+    tnow = TIME(NULL);
+  if (now < last)
+    return 3;
+  if (tnow < tlast)
+    return 4;
+  cumDelta = 0;
+#define INCR 47
+#define MAXV 1500
+  for (i=0;i<MAXV;i+=INCR) {
+    cronTime(&last);
+    if (0 != gnunet_util_sleep(cronMILLIS * i))
+      return 5;
+    cronTime(&now);
+#if VERBOSE
+    fprintf(stderr,
+           "%4u ms requested, got: %4lld ms\n",
+           i / cronMILLIS,
+           (now - last) / cronMILLIS);
+#endif
+    if (last + cronMILLIS * i < now)
+      cumDelta += (now - (last+cronMILLIS*i));
+    else
+      cumDelta += ((last+cronMILLIS*i) - now);
+  }
+  FPRINTF(stdout,
+         "Sleep precision: %llu ms.  ",
+         cumDelta / cronMILLIS / (MAXV/INCR));
+  if (cumDelta <= 10 * cronMILLIS * MAXV / INCR)
+    fprintf(stdout,
+           "Timer precision is excellent.\n");
+  else if (cumDelta <= 50 * cronMILLIS * MAXV / INCR) /* 50 ms average 
deviation */
+    fprintf(stdout,
+           "Timer precision is good.\n");
+  else if (cumDelta > 250 * cronMILLIS * MAXV / INCR)
+    fprintf(stdout,
+           "Timer precision is awful.\n");
+  else
+    fprintf(stdout,
+           "Timer precision is acceptable.\n");
+
+  sem = SEMAPHORE_NEW(0);
+
+  startCron();
+  cumDelta = 0;
+
+#define MAXV2 1500
+#define INCR2 113
+  for (i=50;i<MAXV2+50;i+=INCR2) {
+    cronTime(&last);
+    addCronJob((CronJob) &semaphore_up,
+              i * cronMILLIS,
+              0,
+              sem);
+    SEMAPHORE_DOWN(sem);
+    cronTime(&now);
+    if (now < last + i)
+      now = last + i - now;
+    else
+      now = now - (last + i);
+    cumDelta += now;
+#if VERBOSE
+    FPRINTF(stderr,
+           "Sleep interrupted by signal within %llu ms of deadline (intended 
delay: %d ms).\n",
+           now,
+           i);
+#endif
+  }
+  FPRINTF(stdout,
+         "Sleep interrupt precision is %llums. ",
+         cumDelta / (MAXV2/INCR2) );
+  if (cumDelta <= 10 * cronMILLIS * MAXV2 / INCR2)
+    fprintf(stdout,
+           "Timer precision is excellent.\n");
+  else if (cumDelta <= 50 * cronMILLIS * MAXV2 / INCR2) /* 50ms average 
deviation */
+    fprintf(stdout,
+           "Timer precision is good.\n");
+  else if (cumDelta > 250 * cronMILLIS * MAXV2 / INCR2)
+    fprintf(stdout,
+           "Timer precision is awful.\n");
+  else
+    fprintf(stdout,
+           "Timer precision is acceptable.\n");
+
+  stopCron();
+  SEMAPHORE_FREE(sem);
+
+  return 0;
+}
+
+
+/**
+ * Perform option parsing from the command line.
+ */
+static int parseCommandLine(int argc,
+                           char * argv[]) {
+  char c;
+
+  while (1) {
+    int option_index = 0;
+    static struct GNoption long_options[] = {
+      { "config",  1, 0, 'c' },
+      { 0,0,0,0 }
+    };
+
+    c = GNgetopt_long(argc,
+                     argv,
+                     "c:",
+                     long_options,
+                     &option_index);
+
+    if (c == -1)
+      break;  /* No more flags to process */
+
+    switch(c) {
+    case 'c':
+      FREENONNULL(setConfigurationString("FILES",
+                                        "gnunet.conf",
+                                        GNoptarg));
+      break;
+    } /* end of parsing commandline */
+  }
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGFILE",
+                                    NULL));
+  FREENONNULL(setConfigurationString("GNUNETD",
+                                    "LOGLEVEL",
+                                    "WARNING"));
+  return OK;
+}
+
+int main(int argc,
+        char * argv[]){
+  int ret;
+  initUtil(argc, argv, &parseCommandLine);
+
+  ret = check();
+  if (ret != 0)
+    fprintf(stderr,
+           "ERROR %d\n", ret);
+  doneUtil();
+  return ret;
+}
+
+/* end of timertest.c */

Added: GNUnet/src/util/time.c
===================================================================
--- GNUnet/src/util/time.c      2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/time.c      2006-06-22 17:50:56 UTC (rev 3024)
@@ -0,0 +1,30 @@
+/**
+ * TIME prototype. "man time".
+ */
+TIME_T TIME(TIME_T * t) {
+  TIME_T now;
+
+  now = (TIME_T) time(NULL); /* potential 64-bit to 32-bit conversion!*/
+  if (t != NULL)
+    *t = now;
+  return now;
+}
+
+/**
+ * "man ctime_r".  Automagically expands the 32-bit
+ * GNUnet time value to a 64-bit value of the current
+ * epoc if needed.
+ */
+char * GN_CTIME(const TIME_T * t) {
+  TIME_T now;
+  time_t tnow;
+
+  tnow = time(NULL);
+  now = (TIME_T) tnow;
+  tnow = tnow - now + *t;
+#ifdef ctime_r
+  return ctime_r(&tnow, MALLOC(32));
+#else
+  return STRDUP(ctime(&tnow));
+#endif
+}

Deleted: GNUnet/src/util/timer.c
===================================================================
--- GNUnet/src/util/timer.c     2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/timer.c     2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,187 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2003, 2004 Christian Grothoff (and other contributing authors)
-
-     GNUnet 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, or (at your
-     option) any later version.
-
-     GNUnet 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.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/timer.c
- * @brief abstraction of the time and sleep functions
- * @author Christian Grothoff
- *
- * GNUnet uses both 32-bit and 64-bit timer values.
- *
- * 32-bit timers are measured in seconds and are used
- * for some of the messages exchanged over
- * the network.  We don't really care if they overrun
- * in 2037, as long as the relative times are correct.<p>
- * The type used for these values is TIME_T since
- * some architectures use 64-bit time_t values.
- * We wrap all time() calls into "TIME()" calls and
- * replace time_t with a GNUnet internal, 32-bit
- * TIME_T type.
- *
- * <p>
- * GNUnet also uses 64-bit cron_t timer values.
- * This is a milli-second precision timer that is
- * mostly used for internal timers.  Some
- * network messages also use milli-second precision,
- * but these are so far always relative times which
- * are again represented as 32-bit (int) values.
- * <p>
- *
- * Consequently, whenever handling times in GNUnet,
- * watch out for the types and units involved.
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-/* change this value to artificially speed up all
-   GNUnet cron timers by this factor. E.g. with 10,
-   a cron-job scheduled after 1 minute in the code
-   will occur after 6 seconds. This is useful for
-   testing bugs that would otherwise occur only after
-   a long time.
-
-   For releases, this value should always be 1 */
-#define SPEED_UP 1
-
-/** number of cron units (ms) in a second */
-#define CRON_UNIT_TO_SECONDS (1000 / SPEED_UP)
-
-/** number of ns [usec] in a cron-unit (1000000) */
-#define NANOSEC_TO_CRON_UNIT (1000 * 1000 * SPEED_UP)
-
-/** number of us [usec] in a cron-unit (1000) */
-#define MICROSEC_TO_CRON_UNIT (1000 * SPEED_UP)
-
-
-/**
- * Sleep for the specified time interval.  A signal interrupts the
- * sleep.  Caller is responsible to check that the sleep was long
- * enough.
- *
- * @return 0 if there was no interrupt, 1 if there was, -1 on error.
- */
-int gnunet_util_sleep(cron_t delay) {
-#if LINUX || SOLARIS || SOMEBSD || OSX
-  struct timespec req;
-  struct timespec rem;
-  req.tv_sec
-    = delay / CRON_UNIT_TO_SECONDS;
-  req.tv_nsec
-    = (delay - req.tv_sec * CRON_UNIT_TO_SECONDS)
-    * NANOSEC_TO_CRON_UNIT;
-  rem.tv_sec = 0;
-  rem.tv_nsec = 0;
-  if (0 != nanosleep(&req, &rem)) {
-    if (errno == EINTR) {
-      return 1;
-    } else {
-      LOG_STRERROR(LOG_WARNING, "nanosleep");
-      return -1;
-    }
-  } else
-    return 0;
-#elif WINDOWS
-  SleepEx(delay, TRUE);
-  return 0; /* interrupt information is just an information, but
-              not strict; error handling is, well, lacking,
-              but this is Win32... */
-#else
-  /* fall back to select */
-  int ret;
-  struct timeval timeout;
-
-  timeout.tv_sec
-    = delay / CRON_UNIT_TO_SECONDS;
-  timeout.tv_usec
-    = (delay - timeout.tv_sec * CRON_UNIT_TO_SECONDS)
-    * MICROSEC_TO_CRON_UNIT;
-  ret = SELECT(0, NULL, NULL, NULL, &timeout);
-  if (ret == -1) {
-    if (errno == EINTR) {
-      return 1;
-    } else {
-      LOG_STRERROR(LOG_WARNING, "select");
-      return -1;
-    }
-  }
-  return 0;
-#endif
-}
-
-/**
- * Get the current time (works just as "time", just that we use the
- * unit of time that the cron-jobs use (and is 64 bit)).
- *
- * @param setme will set the current time if non-null
- * @return the current time
- */
-cron_t cronTime(cron_t * setme) {
-  cron_t res;
-  struct timeval tv;
-#ifndef WINDOWS
-  struct timezone tz; /* man page says it's obsolete, but
-                        I'd rather not pass a NULL pointer */
-
-  gettimeofday(&tv, &tz);
-#else
-  gettimeofday(&tv, NULL);
-#endif
-  res =
-    (((cron_t)tv.tv_sec) * CRON_UNIT_TO_SECONDS) +
-    (tv.tv_usec / MICROSEC_TO_CRON_UNIT);
-  if (setme != NULL)
-    *setme = res;
-  return res;
-}
-
-/**
- * TIME prototype. "man time".
- */
-TIME_T TIME(TIME_T * t) {
-  TIME_T now;
-
-  now = (TIME_T) time(NULL); /* potential 64-bit to 32-bit conversion!*/
-  if (t != NULL)
-    *t = now;
-  return now;
-}
-
-/**
- * "man ctime_r".  Automagically expands the 32-bit
- * GNUnet time value to a 64-bit value of the current
- * epoc if needed.
- */
-char * GN_CTIME(const TIME_T * t) {
-  TIME_T now;
-  time_t tnow;
-
-  tnow = time(NULL);
-  now = (TIME_T) tnow;
-  tnow = tnow - now + *t;
-#ifdef ctime_r
-  return ctime_r(&tnow, MALLOC(32));
-#else
-  return STRDUP(ctime(&tnow));
-#endif
-}
-
-
-/* end of timer.c */

Deleted: GNUnet/src/util/timertest.c
===================================================================
--- GNUnet/src/util/timertest.c 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/src/util/timertest.c 2006-06-22 17:50:56 UTC (rev 3024)
@@ -1,182 +0,0 @@
-/**
- * @file test/timertest.c
- * @brief testcase for util/timer.c; also measures how
- *  precise the timers are.  Expect values between 10 and 20 ms on
- *  modern machines.
- */
-
-#include "gnunet_util.h"
-#include "platform.h"
-
-#define VERBOSE NO
-
-static void semaphore_up(Semaphore * sem) {
-  SEMAPHORE_UP(sem);
-}
-
-static int check() {
-  cron_t now;
-  cron_t last;
-  TIME_T tnow;
-  TIME_T tlast;
-  int i;
-  unsigned long long cumDelta;
-  Semaphore * sem;
-
-  /* test that time/cronTime are monotonically
-     increasing;
-     measure precision of sleep and report;
-     test that sleep is interrupted by signals; */
-  last = cronTime(&now);
-  if (last != now)
-    return 1;
-  tlast = TIME(&tnow);
-  if (tlast != tnow)
-    return 2;
-  while (now == last)
-    now = cronTime(NULL);
-  while (tnow == tlast)
-    tnow = TIME(NULL);
-  if (now < last)
-    return 3;
-  if (tnow < tlast)
-    return 4;
-  cumDelta = 0;
-#define INCR 47
-#define MAXV 1500
-  for (i=0;i<MAXV;i+=INCR) {
-    cronTime(&last);
-    if (0 != gnunet_util_sleep(cronMILLIS * i))
-      return 5;
-    cronTime(&now);
-#if VERBOSE
-    fprintf(stderr,
-           "%4u ms requested, got: %4lld ms\n",
-           i / cronMILLIS,
-           (now - last) / cronMILLIS);
-#endif
-    if (last + cronMILLIS * i < now)
-      cumDelta += (now - (last+cronMILLIS*i));
-    else
-      cumDelta += ((last+cronMILLIS*i) - now);
-  }
-  FPRINTF(stdout,
-         "Sleep precision: %llu ms.  ",
-         cumDelta / cronMILLIS / (MAXV/INCR));
-  if (cumDelta <= 10 * cronMILLIS * MAXV / INCR)
-    fprintf(stdout,
-           "Timer precision is excellent.\n");
-  else if (cumDelta <= 50 * cronMILLIS * MAXV / INCR) /* 50 ms average 
deviation */
-    fprintf(stdout,
-           "Timer precision is good.\n");
-  else if (cumDelta > 250 * cronMILLIS * MAXV / INCR)
-    fprintf(stdout,
-           "Timer precision is awful.\n");
-  else
-    fprintf(stdout,
-           "Timer precision is acceptable.\n");
-
-  sem = SEMAPHORE_NEW(0);
-
-  startCron();
-  cumDelta = 0;
-
-#define MAXV2 1500
-#define INCR2 113
-  for (i=50;i<MAXV2+50;i+=INCR2) {
-    cronTime(&last);
-    addCronJob((CronJob) &semaphore_up,
-              i * cronMILLIS,
-              0,
-              sem);
-    SEMAPHORE_DOWN(sem);
-    cronTime(&now);
-    if (now < last + i)
-      now = last + i - now;
-    else
-      now = now - (last + i);
-    cumDelta += now;
-#if VERBOSE
-    FPRINTF(stderr,
-           "Sleep interrupted by signal within %llu ms of deadline (intended 
delay: %d ms).\n",
-           now,
-           i);
-#endif
-  }
-  FPRINTF(stdout,
-         "Sleep interrupt precision is %llums. ",
-         cumDelta / (MAXV2/INCR2) );
-  if (cumDelta <= 10 * cronMILLIS * MAXV2 / INCR2)
-    fprintf(stdout,
-           "Timer precision is excellent.\n");
-  else if (cumDelta <= 50 * cronMILLIS * MAXV2 / INCR2) /* 50ms average 
deviation */
-    fprintf(stdout,
-           "Timer precision is good.\n");
-  else if (cumDelta > 250 * cronMILLIS * MAXV2 / INCR2)
-    fprintf(stdout,
-           "Timer precision is awful.\n");
-  else
-    fprintf(stdout,
-           "Timer precision is acceptable.\n");
-
-  stopCron();
-  SEMAPHORE_FREE(sem);
-
-  return 0;
-}
-
-
-/**
- * Perform option parsing from the command line.
- */
-static int parseCommandLine(int argc,
-                           char * argv[]) {
-  char c;
-
-  while (1) {
-    int option_index = 0;
-    static struct GNoption long_options[] = {
-      { "config",  1, 0, 'c' },
-      { 0,0,0,0 }
-    };
-
-    c = GNgetopt_long(argc,
-                     argv,
-                     "c:",
-                     long_options,
-                     &option_index);
-
-    if (c == -1)
-      break;  /* No more flags to process */
-
-    switch(c) {
-    case 'c':
-      FREENONNULL(setConfigurationString("FILES",
-                                        "gnunet.conf",
-                                        GNoptarg));
-      break;
-    } /* end of parsing commandline */
-  }
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGFILE",
-                                    NULL));
-  FREENONNULL(setConfigurationString("GNUNETD",
-                                    "LOGLEVEL",
-                                    "WARNING"));
-  return OK;
-}
-
-int main(int argc,
-        char * argv[]){
-  int ret;
-  initUtil(argc, argv, &parseCommandLine);
-
-  ret = check();
-  if (ret != 0)
-    fprintf(stderr,
-           "ERROR %d\n", ret);
-  doneUtil();
-  return ret;
-}
-
-/* end of timertest.c */

Modified: GNUnet/todo
===================================================================
--- GNUnet/todo 2006-06-22 17:39:19 UTC (rev 3023)
+++ GNUnet/todo 2006-06-22 17:50:56 UTC (rev 3024)
@@ -12,7 +12,11 @@
 
 
 0.7.1 ['06] (aka "stabilization")
-- known bugs (see Mantis for updates):
+- finish util refactoring
+- adapt util testcases and main GNUnet codebase
+- use new util to improve error handling capabilities
+- use new util to clean up gnunet-setup
+- fix known bugs (see Mantis for updates):
   * gnunet-setup memory leaks (#878)
   * gnunet-setup category switch update bug (#892)  [ RC ]
   * file/socket leak (#955)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]