gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r3037 - in GNUnet/src: include util util/network util/os ut


From: grothoff
Subject: [GNUnet-SVN] r3037 - in GNUnet/src: include util util/network util/os util/threads
Date: Sat, 24 Jun 2006 13:38:05 -0700 (PDT)

Author: grothoff
Date: 2006-06-24 13:37:52 -0700 (Sat, 24 Jun 2006)
New Revision: 3037

Added:
   GNUnet/src/util/os/cpustatus.c
   GNUnet/src/util/threads/time.c
Removed:
   GNUnet/src/util/network/port.c
   GNUnet/src/util/network/tcp_return.c
Modified:
   GNUnet/src/include/gnunet_util.h
   GNUnet/src/include/gnunet_util_config.h
   GNUnet/src/include/gnunet_util_cron.h
   GNUnet/src/include/gnunet_util_network.h
   GNUnet/src/include/gnunet_util_os.h
   GNUnet/src/include/gnunet_util_threads.h
   GNUnet/src/util/README
   GNUnet/src/util/initialize.c
   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/tcpio.c
   GNUnet/src/util/os/Makefile.am
   GNUnet/src/util/os/daemon.c
   GNUnet/src/util/os/dso.c
   GNUnet/src/util/os/osconfig.c
   GNUnet/src/util/os/semaphore.c
   GNUnet/src/util/os/statuscalls.c
   GNUnet/src/util/threads/Makefile.am
Log:
denver

Modified: GNUnet/src/include/gnunet_util.h
===================================================================
--- GNUnet/src/include/gnunet_util.h    2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/include/gnunet_util.h    2006-06-24 20:37:52 UTC (rev 3037)
@@ -146,13 +146,6 @@
 
 
 /**
- * The configuration was re-loaded. All
- * util modules should check if it has
- * changed for them.
- */
-void resetUtil(void);
-
-/**
  * Shutdown the util services in proper order.
  */
 void doneUtil(void);

Modified: GNUnet/src/include/gnunet_util_config.h
===================================================================
--- GNUnet/src/include/gnunet_util_config.h     2006-06-24 16:34:56 UTC (rev 
3036)
+++ GNUnet/src/include/gnunet_util_config.h     2006-06-24 20:37:52 UTC (rev 
3037)
@@ -19,14 +19,14 @@
 */
 
 /**
- * @file include/gnunet_config.h
+ * @file include/gnunet_util_config.h
  * @brief configuration API
  *
  * @author Christian Grothoff
  */
 
-#ifndef GNUNET_CONFIG_H
-#define GNUNET_CONFIG_H
+#ifndef GNUNET_UTIL_CONFIG_H
+#define GNUNET_UTIL_CONFIG_H
 
 #include "gnunet_util_error.h"
 
@@ -52,8 +52,8 @@
  * used (since failing to change an option may have to be reported
  * in a fundamentally different way to the user).
  * 
- * @parm ectx maybe NULL, in that case errors will no longer
- *       be reported
+ * @param ectx may be NULL, in that case errors will no longer
+ *        be reported
  */
 void GC_set_error_context(struct GC_Configuration * cfg,
                          struct GE_Context * ectx);

Modified: GNUnet/src/include/gnunet_util_cron.h
===================================================================
--- GNUnet/src/include/gnunet_util_cron.h       2006-06-24 16:34:56 UTC (rev 
3036)
+++ GNUnet/src/include/gnunet_util_cron.h       2006-06-24 20:37:52 UTC (rev 
3037)
@@ -38,28 +38,11 @@
 #endif
 
 /**
- * @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))
-
-/**
  * 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;
-
-/**
  * Start the cron jobs.
  */
 void cron_start_jobs(void);
@@ -95,13 +78,6 @@
 int cron_test_running(void);
 
 /**
- * Get the current time (in cron-units).
- *
- * @return the current time
- */
-cron_t cron_get_time(void);
-
-/**
  * 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

Modified: GNUnet/src/include/gnunet_util_network.h
===================================================================
--- GNUnet/src/include/gnunet_util_network.h    2006-06-24 16:34:56 UTC (rev 
3036)
+++ GNUnet/src/include/gnunet_util_network.h    2006-06-24 20:37:52 UTC (rev 
3037)
@@ -27,30 +27,15 @@
  * @author Gerd Knorr <address@hidden>
  * @author Ioana Patrascu
  * @author Tzvetan Horozov
- *
- *
- * TODO:
- * - add configuration argument to 
- *   methods that need it
- * - abstract sockets that are
- *   represented as "int" 
- *   (typedef int GNUNET_SOCKET or so) 
- * - 
  */
 
 #ifndef GNUNET_UTIL_NETWORK_H
 #define GNUNET_UTIL_NETWORK_H
 
-/* we need size_t, and since it can be both unsigned int
-   or unsigned long long, this IS platform dependent;
-   but "stdlib.h" should be portable 'enough' to be
-   unconditionally available... */
-#include <stdlib.h>
-
-/* add error and config prototypes */
 #include "gnunet_util_config.h"
 #include "gnunet_util_string.h"
 #include "gnunet_util_os.h"
+#include "gnunet_util_threads.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -68,19 +53,23 @@
  * @brief Specify low-level network IO behavior
  */
 typedef enum {
+
   /**
    * Do not block.
    */
   NC_Nonblocking = 0x000,
+
   /**
    * Call may block.
    */
   NC_Blocking    = 0x001,
+
   /**
    * Ignore interrupts (re-try if operation
    * was aborted due to interrupt)
    */
   NC_IgnoreInt   = 0x010,
+
   /**
    * Always try to read/write the maximum
    * amount of data (using possibly multiple
@@ -88,6 +77,7 @@
    * error or if completely done.
    */
   NC_Complete    = 0x111,
+
 } NC_KIND;
 
 /**
@@ -126,7 +116,10 @@
  * @brief an IPv4 address
  */
 typedef struct {
-  unsigned int addr; /* struct in_addr */
+  /**
+   * struct in_addr 
+   */
+  unsigned int addr; 
 } IPaddr;
 
 /**
@@ -138,7 +131,10 @@
  * @brief an IPV6 address.
  */
 typedef struct {
-  unsigned int addr[4]; /* struct in6_addr addr; */
+  /**
+   * struct in6_addr addr; 
+   */
+  unsigned int addr[4]; 
 } IP6addr;
 
 /**
@@ -247,7 +243,7 @@
 struct ClientServerConnection * 
 client_connection_create(struct GE_Context * ectx,
                         struct GC_Configuration * cfg,
-                        SocketHandle sock);
+                        struct SocketHandle * sock);
 
 /**
  * Close a GNUnet TCP socket for now (use to temporarily close
@@ -303,16 +299,13 @@
  *
  * @param sock the socket to write to
  * @param buffer the buffer to write
- * @param isBlocking is this call allowed to block
  * @return OK if the write was sucessful, 
  *         NO if it would block and isBlocking was NO,
  *         SYSERR if the write failed (error will be logged)
  */
 int connection_write(struct ClientServerConnection * sock,
-                    const CS_MESSAGE_HEADER * buffer,
-                    int isBlocking);
+                    const MESSAGE_HEADER * buffer);
 
-
 /**
  * Obtain a simple return value from the connection.
  * Note that the protocol will automatically communicate
@@ -340,6 +333,22 @@
                            int ret);
 
 /**
+ * Send a return value that indicates
+ * a serious error to the other side.
+ *
+ * @param sock the TCP socket
+ * @param mask GE_MASK 
+ * @param date date string
+ * @param msg message string
+ * @return SYSERR on error, OK if the error code was send
+ *         successfully
+ */
+int connection_write_error(struct ClientServerConnection * sock,
+                          GE_KIND mask,
+                          const char * date,
+                          const char * msg);
+
+/**
  * Stop gnunetd
  *
  * Note that returning an error does NOT mean that
@@ -367,7 +376,8 @@
  *
  * @return OK if gnunetd is running, SYSERR if not
  */
-int connection_test_running(struct GE_Context * ectx);
+int connection_test_running(struct GE_Context * ectx,
+                           struct GC_Configuration * cfg);
 
 /**
  * Wait until the gnunet daemon is
@@ -377,24 +387,9 @@
  * @return OK if gnunetd is now running
  */
 int connection_wait_for_running(struct GE_Context * ectx,
-                               unsigned long long_t timeout);
+                               struct GC_Configuration * cfg,
+                               cron_t timeout);
 
-/**
- * Send a return value that indicates
- * a serious error to the other side.
- *
- * @param sock the TCP socket
- * @param mask GE_MASK 
- * @param date date string
- * @param msg message string
- * @return SYSERR on error, OK if the error code was send
- *         successfully
- */
-int connection_write_error(struct ClientServerConnection * sock,
-                          GE_KIND mask,
-                          const char * date,
-                          const char * msg);
-
 /* ********************* low-level socket operations **************** */
 
 /**

Modified: GNUnet/src/include/gnunet_util_os.h
===================================================================
--- GNUnet/src/include/gnunet_util_os.h 2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/include/gnunet_util_os.h 2006-06-24 20:37:52 UTC (rev 3037)
@@ -72,12 +72,15 @@
                     const char * basename,
                     unsigned int initialValue);
 
-void IPC_SEMAPHORE_DESTROY(struct IPC_Semaphore * sem);
+void IPC_SEMAPHORE_DESTROY(struct IPC_SEMAPHORE * sem);
 
 void IPC_SEMAPHORE_UP(struct IPC_SEMAPHORE * sem);
 
-void IPC_SEMAPHORE_DOWN(struct IPC_SEMAPHORE * sem,
-                       int mayBlock);
+/**
+ * @return OK on success, SYSERR if would block
+ */
+int IPC_SEMAPHORE_DOWN(struct IPC_SEMAPHORE * sem,
+                      int mayBlock);
 
 /**
  * Load plugin
@@ -105,7 +108,7 @@
 
 struct LoadMonitor * 
 os_network_monitor_create(struct GE_Context * ectx,
-                      struct GC_Configuration * cfg);
+                         struct GC_Configuration * cfg);
 
 void os_network_monitor_destroy(struct LoadMonitor * mon);
 
@@ -116,12 +119,13 @@
  *        (100 is equivalent to full load)
  */
 int os_network_monitor_get_load(struct LoadMonitor * monitor,
-                            NetworkDirection dir);
+                               NetworkDirection dir);
 
 /**
  * Tell monitor to increment the number of bytes sent/received
  */
-void os_network_monitor_notify_transmission(NetworkDirection dir,
+void os_network_monitor_notify_transmission(struct LoadMonitor * monitor,
+                                           NetworkDirection dir,
                                            unsigned long long delta);
 
 /**
@@ -156,7 +160,7 @@
 int os_modify_autostart(struct GE_Context * ectx,
                        int testCapability,
                        int doAutoStart,
-                       const char * application
+                       const char * application,
                        const char * username, 
                        const char * groupname);
 
@@ -179,6 +183,7 @@
  * @return OK on success, SYSERR on error
  */
 int os_modify_user(struct GE_Context * ectx,
+                  int testCapability,
                   int doAdd,
                   const char * name,
                   const char * group);
@@ -201,6 +206,7 @@
  *  daemonized sucessfully, -1 on error
  */
 int os_daemon_start(struct GE_Context * ectx,
+                   struct GC_Configuration * cfg,
                    const char * cfgFile,
                    int daemonize);
 

Modified: GNUnet/src/include/gnunet_util_threads.h
===================================================================
--- GNUnet/src/include/gnunet_util_threads.h    2006-06-24 16:34:56 UTC (rev 
3036)
+++ GNUnet/src/include/gnunet_util_threads.h    2006-06-24 20:37:52 UTC (rev 
3037)
@@ -27,11 +27,6 @@
  * @author Gerd Knorr <address@hidden>
  * @author Ioana Patrascu
  * @author Tzvetan Horozov
- *
- * TODO:
- * - consider moving SHUTDOWN into
- *   seperate shared library (not part of
- *   libgnunetutil binary at all!)
  */
 
 #ifndef GNUNET_UTIL_THREADS_H
@@ -45,6 +40,24 @@
 #endif
 
 /**
+ * Time for absolute times used by cron (64 bit)
+ */
+typedef unsigned long long cron_t;
+
+
+/**
+ * @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))
+
+/**
  * Main method of a thread.
  */
 typedef void * (*PThreadMain)(void*);
@@ -111,9 +124,16 @@
  *
  * @param time how long to sleep (in milli seconds)
  */
-void PTHREAD_SLEEP(unsigned long long time);
+void PTHREAD_SLEEP(cron_t time);
 
 /**
+ * Get the current time (in cron-units).
+ *
+ * @return the current time
+ */
+cron_t get_time(void);
+
+/**
  * Stop the sleep of anothe thread.
  */
 void PTHREAD_STOP_SLEEP(struct PTHREAD * handle);

Modified: GNUnet/src/util/README
===================================================================
--- GNUnet/src/util/README      2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/README      2006-06-24 20:37:52 UTC (rev 3037)
@@ -7,9 +7,9 @@
  util/config: configuration handling (depends on error)
   util/getopt: command line parsing (depends on config)
  util/threads: pthread abstractions (depends on error)
+  util/os: process and system abstractions (depends on threads, config)
 
 -------- TODO ----------
-  util/os: process and system abstractions (depends on threads, config)
    util/network: network IO abstractions (depends on threads, config, os)
 
 util: main utility library (depends on all of the above)

Modified: GNUnet/src/util/initialize.c
===================================================================
--- GNUnet/src/util/initialize.c        2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/initialize.c        2006-06-24 20:37:52 UTC (rev 3037)
@@ -195,4 +195,41 @@
   gnunet_util_doneIO();
 }
 
+
+
+
+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 initialize.c */

Modified: GNUnet/src/util/network/Makefile.am
===================================================================
--- GNUnet/src/util/network/Makefile.am 2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/network/Makefile.am 2006-06-24 20:37:52 UTC (rev 3037)
@@ -6,11 +6,10 @@
   libnetwork.la
 
 libnetwork_la_SOURCES = \
+ daemon.c \
  endian.c \
  io.c \
  ipcheck.c \
- port.c \
- tcp_return.c \
  tcpio.c 
 
 check_PROGRAMS = \

Modified: GNUnet/src/util/network/endian.c
===================================================================
--- GNUnet/src/util/network/endian.c    2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/network/endian.c    2006-06-24 20:37:52 UTC (rev 3037)
@@ -19,13 +19,13 @@
 */
 
 /**
- * @file util/endian.c
+ * @file util/network/endian.c
  * @brief endian conversion helpers
  * @author Christian Grothoff
  */
 
 #include "platform.h"
-#include "gnunet_util.h"
+#include "gnunet_util_network.h"
 
 unsigned long long ntohll(unsigned long long n) {
 #if __BYTE_ORDER == __BIG_ENDIAN

Modified: GNUnet/src/util/network/io.c
===================================================================
--- GNUnet/src/util/network/io.c        2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/network/io.c        2006-06-24 20:37:52 UTC (rev 3037)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2003 Christian Grothoff (and other contributing authors)
+     (C) 2003, 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
@@ -19,297 +19,244 @@
 */
 
 /**
- * @file util/io.c
+ * @file util/network/io.c
  * @brief (network) input/output operations
  * @author Christian Grothoff
  */
 
-#include "gnunet_util.h"
+#include "gnunet_util_network.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);
-}
+typedef struct SocketHandle {
 
+  struct LoadMonitor * mon;
+  
+  struct GE_Context * ectx;
 
-#endif
+  int handle;
+  
+} SocketHandle;
 
-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
+struct SocketHandle * 
+socket_create(struct GE_Context * ectx,
+             struct LoadMonitor * mon,
+             int osSocket) {
+  SocketHandle * ret;
+
+  ret = MALLOC(sizeof(SocketHandle));
+  ret->ectx = ectx;
+  ret->mon = mon;
+  ret->handle = osSocket;
+  return ret;
 }
 
-void gnunet_util_doneIO() {
+void socket_destroy(struct SocketHandle * s) {
+  if (0 != CLOSE(s->handle))
+    GE_LOG_STRERROR(s->ectx,
+                   GE_WARNING | GE_USER | GE_DEVELOPER | GE_BULK,
+                   "close");
+  FREE(s);
 }
 
-/**
- * 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) {
+/* TODO: log errors! */
+int socket_set_blocking(struct SocketHandle * s, 
+                       int doBlock) {
 #if MINGW
   u_long l = !doBlock;
-  if (ioctlsocket(s, FIONBIO, &l) == SOCKET_ERROR) {
+  if (ioctlsocket(s->handle, 
+                 FIONBIO, &l) == SOCKET_ERROR) {
     SetErrnoFromWinsockError(WSAGetLastError());
-
+    
     return -1;
   } else {
     /* store the blocking mode */
-    __win_SetHandleBlockingMode(s, doBlock);
+    __win_SetHandleBlockingMode(s->handle, doBlock);
     return 0;
   }
 #else
-  int flags = fcntl(s, F_GETFL);
+  int flags = fcntl(s->handle, F_GETFL);
   if (doBlock)
     flags &= ~O_NONBLOCK;
   else
     flags |= O_NONBLOCK;
-
-  return fcntl(s,
+  return fcntl(s->handle,
               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)
+int socket_test_blocking(struct SocketHandle * s)
 {
 #ifndef MINGW
- return (fcntl(s, F_GETFL) & O_NONBLOCK) ? NO : YES;
+ return (fcntl(s->handle, 
+              F_GETFL) & O_NONBLOCK) ? NO : YES;
 #else
-  return __win_IsHandleMarkedAsBlocking(s);
+  return __win_IsHandleMarkedAsBlocking(s->handle);
 #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 socket_recv(struct SocketHandle * s,
+               NC_KIND nc,
+               void * buf,
+               size_t max,
+               size_t * read) {
   int flags;
+  size_t pos;
+  size_t ret;
 
-  setBlocking(s, NO);
-
+  socket_set_blocking(s, 
+                     0 == (nc & NC_Blocking));
+  flags = 0;
 #ifdef CYGWIN
-    flags = MSG_NOSIGNAL;
+  if (0 == (nc & NC_IgnoreInt))
+    flags |= MSG_NOSIGNAL;
 #elif OSX
-    flags = 0;
+  /* anything? */
 #elif SOMEBSD || SOLARIS
-    flags = MSG_DONTWAIT;
+  if (0 == (nc & NC_Blocking))
+    flags |= MSG_DONTWAIT;
 #elif LINUX
-    flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+  if (0 == (nc & NC_Blocking))
+    flags |= MSG_DONTWAIT;
+  if (0 == (nc & NC_IgnoreInt))
+    flags |= MSG_NOSIGNAL;
 #else
-    /* good luck */
-    flags = 0;
+  /* good luck */
 #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) )
+  do {
+    ret = (size_t) RECV(s->handle,
+                       &((char*)buf)[pos],
+                       max - pos,
+                       flags);
+    if ( (ret == (size_t) -1) &&
+        (errno == EINTR) &&
+        (0 != (nc & NC_IgnoreInt)) )
       continue;
-    if (i <= 0)
-    {
-      setBlocking(s, NO);
+    if (ret == (size_t) -1) {
+      if (errno == EINTR) {
+       *read = pos;
+       return YES;
+      }
+      if ( (errno == EAGAIN) ||
+          (errno == EWOULDBLOCK) ) {
+       if (0 != (nc & NC_Blocking))
+         continue;
+       *read = pos;
+       return (pos == 0) ? NO : YES;
+      }
+      GE_LOG_STRERROR(s->ectx,
+                     GE_DEBUG | GE_USER | GE_REQUEST,
+                     "recv");
+      *read = pos;
       return SYSERR;
     }
-    pos += i;
-  }
-  GNUNET_ASSERT(pos == len);
-
-  setBlocking(s, NO);
-
-  return pos;
+    pos += ret;
+  } while ( (pos < max) &&
+           (0 != (nc & NC_Blocking)) );
+  *read = pos;
+  return YES;
 }
 
-/**
- * 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 socket_send(struct SocketHandle * s,
+               NC_KIND nc,
+               const void * buf,
+               size_t max,
+               size_t * sent) {
   int flags;
+  size_t pos;
+  size_t ret;
 
-  setBlocking(s, NO);
-
-#ifdef SOMEBSD
-    flags = MSG_DONTWAIT;
-#elif SOLARIS
-    flags = MSG_DONTWAIT;
+  socket_set_blocking(s, 
+                     0 == (nc & NC_Blocking));
+  flags = 0;
+#if SOMEBSD || SOLARIS
+  if (0 == (nc & NC_Blocking))
+    flags |= MSG_DONTWAIT;
 #elif OSX
-    /* As braindead as Win32? */
-    flags = 0;
+  /* As braindead as Win32? */
 #elif CYGWIN
-       flags = MSG_NOSIGNAL;
+  if (0 == (nc & NC_IgnoreInt))
+    flags |= MSG_NOSIGNAL;
 #elif LINUX
-       flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+  if (0 == (nc & NC_Blocking))
+    flags |= MSG_DONTWAIT;
+  if (0 == (nc & NC_IgnoreInt))
+    flags |= MSG_NOSIGNAL;
 #else
-    /* pray */
-       flags = 0;
+  /* pray */
 #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");
+  do {
+    ret = (size_t) SEND(s->handle,
+                       &((char*)buf)[pos],
+                       max - pos,
+                       flags);
+    if ( (ret == (size_t) -1) &&
+        (errno == EINTR) &&
+        (0 != (nc & NC_IgnoreInt)) )
+      continue;
+    if (ret == (size_t) -1) {
+      if (errno == EINTR) {
+       *sent = pos;
+       return YES;
+      }
+      if ( (errno == EAGAIN) ||
+          (errno == EWOULDBLOCK) ) {
+       if (0 != (nc & NC_Blocking))
+         continue;
+       *sent = pos;
+       return (pos == 0) ? NO : YES;
+      }
+      GE_LOG_STRERROR(s->ectx,
+                     GE_DEBUG | GE_USER | GE_REQUEST,
+                     "send");
+      *sent = pos;
       return SYSERR;
     }
-    pos += i;
-  }
-  setBlocking(s, NO);
-  GNUNET_ASSERT(pos == len);
-  return pos;
+    pos += ret;
+  } while ( (pos < max) &&
+           (0 != (nc & NC_Blocking)) );
+  *sent = pos;
+  return YES;
 }
 
 /**
  * Check if socket is valid
  * @return 1 if valid, 0 otherwise
  */
-int isSocketValid(int s)
-{
+int socket_test_valid(struct SocketHandle * s) {
 #ifndef MINGW
   struct stat buf;
-  return -1 != fstat(s, &buf);
+  return -1 != fstat(s->handle, 
+                    &buf);
 #else
   long l;
-  return ioctlsocket(s, FIONREAD, &l) != SOCKET_ERROR;
+  return ioctlsocket(s->handle, 
+                    FIONREAD, 
+                    &l) != SOCKET_ERROR;
 #endif
 }
 
+
+/* some systems send us signals, so we'd better
+   catch them (& ignore) */
+#ifndef LINUX
+static void catcher(int sig) {
+  /* re-install signal handler! */
+  signal(sig, &catcher);
+}
+#endif
+
+/* TODO: add destructor to restore signal handler */
+void __attribute__ ((constructor)) gnunet_io_ltdl_init() {
+#if ! (defined(LINUX) || defined(MINGW))
+  if ( SIG_ERR == signal(SIGPIPE, SIG_IGN))
+    if ( SIG_ERR == signal(SIGPIPE, &catcher))
+      LOG_STRERROR(LOG_WARNING, "signal");
+#endif
+}
+
+
 /* end of io.c */

Modified: GNUnet/src/util/network/ipcheck.c
===================================================================
--- GNUnet/src/util/network/ipcheck.c   2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/network/ipcheck.c   2006-06-24 20:37:52 UTC (rev 3037)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004 Christian Grothoff (and other contributing 
authors)
+     (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
@@ -19,12 +19,14 @@
 */
 
 /**
- * @file util/ipcheck.c
+ * @file util/network/ipcheck.c
  * @brief test if an IP matches a given subnet
  * @author Christian Grothoff
  */
 
-#include "gnunet_util.h"
+#include "gnunet_util_network.h"
+#include "gnunet_util_string.h"
+#include "gnunet_util_error.h"
 #include "platform.h"
 
 /**
@@ -55,7 +57,8 @@
  * @param routeList a string specifying the forbidden networks
  * @return the converted list, NULL if the synatx is flawed
  */
-CIDRNetwork * parseRoutes(const char * routeList) {
+CIDRNetwork * parse_ipv4_network_specification(struct GE_Context * ectx,
+                                              const char * routeList) {
   unsigned int count;
   unsigned int i;
   unsigned int j;
@@ -96,9 +99,10 @@
     if (cnt == 8) {
       for (j=0;j<8;j++)
        if (temps[j] > 0xFF) {
-         LOG(LOG_ERROR,
-             _("Invalid format for IP: `%s'\n"),
-             &routeList[pos]);
+         GE_LOG(ectx,
+                GE_ERROR | GE_USER | GE_IMMEDIATE,
+                _("Invalid format for IP: `%s'\n"),
+                &routeList[pos]);
          FREE(result);
          return NULL;
        }
@@ -123,9 +127,10 @@
     if (cnt == 5) {
       for (j=0;j<4;j++)
        if (temps[j] > 0xFF) {
-         LOG(LOG_ERROR,
-             "wrong format for IP: %s\n",
-             &routeList[pos]);
+         GE_LOG(ectx,
+                GE_ERROR | GE_USER | GE_IMMEDIATE,
+                _("Invalid format for IP: `%s'\n"),
+                &routeList[pos]);
          FREE(result);
          return NULL;
        }
@@ -146,23 +151,26 @@
        i++;
        continue;
       } else {
-       LOG(LOG_ERROR,
-           _("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
-           slash);
+       GE_LOG(ectx,
+              GE_ERROR | GE_USER | GE_IMMEDIATE,
+              _("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]);
+    GE_LOG(ectx,
+          GE_ERROR | GE_USER | GE_IMMEDIATE,
+          _("Invalid format for IP: `%s'\n"),
+          &routeList[pos]);
     FREE(result);
     return NULL; /* error */
   }
   if (pos < strlen(routeList)) {
-    LOG(LOG_ERROR,
-       _("Invalid network notation (additional characters: `%s')."),
-       &routeList[pos]);
+    GE_LOG(ectx,
+          GE_ERROR | GE_USER | GE_IMMEDIATE,
+          _("Invalid format for IP: `%s'\n"),
+          &routeList[pos]);
     FREE(result);
     return NULL; /* oops */
   }
@@ -170,35 +178,7 @@
 }
 
 
-
 /**
- * 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
@@ -209,7 +189,8 @@
  * @param routeList a string specifying the forbidden networks
  * @return the converted list, NULL if the synatx is flawed
  */
-CIDR6Network * parseRoutes6(const char * routeListX) {
+CIDR6Network * parse_ipv6_network_specification(struct GE_Context * ectx,
+                                               const char * routeListX) {
   unsigned int count;
   unsigned int i;
   unsigned int len;
@@ -231,9 +212,10 @@
     if (routeList[i] == ';')
       count++;
   if (routeList[len-1] != ';') {
-    LOG(LOG_ERROR,
-       _("Invalid network notation (does not end with ';': `%s')\n"),
-       routeList);
+    GE_LOG(ectx,
+          GE_ERROR | GE_USER | GE_IMMEDIATE,
+          _("Invalid network notation (does not end with ';': `%s')\n"),
+          routeList);
     FREE(routeList);
     return NULL;
   }
@@ -263,10 +245,11 @@
                      &routeList[slash+1],
                      &result[i].netmask);
       if (ret <= 0) {
-       LOG(LOG_ERROR,
-           _("Wrong format `%s' for netmask: %s\n"),
-           &routeList[slash+1],
-           STRERROR(errno));
+       GE_LOG(ectx,
+              GE_ERROR | GE_USER | GE_IMMEDIATE,
+              _("Wrong format `%s' for netmask: %s\n"),
+              &routeList[slash+1],
+              STRERROR(errno));
        FREE(result);
        FREE(routeList);
        return NULL;
@@ -277,10 +260,11 @@
                    &routeList[start],
                    &result[i].network);
     if (ret <= 0) {
-      LOG(LOG_ERROR,
-         _("Wrong format `%s' for network: %s\n"),
-         &routeList[slash+1],
-         STRERROR(errno));
+      GE_LOG(ectx,
+            GE_ERROR | GE_USER | GE_IMMEDIATE,
+            _("Wrong format `%s' for network: %s\n"),
+            &routeList[slash+1],
+              STRERROR(errno));
       FREE(result);
       FREE(routeList);
       return NULL;
@@ -291,6 +275,7 @@
   return result;
 }
 
+
 /**
  * Check if the given IP address is in the list of IP addresses.
  *
@@ -298,8 +283,35 @@
  * @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) {
+int check_ipv4_listed(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;
+}
+
+/**
+ * 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 check_ipv6_listed(const CIDR6Network * list,
+                     IP6addr ip) {
   unsigned int i;
   unsigned int j;
   struct in6_addr zero;
@@ -312,7 +324,7 @@
   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])) !=
+      if ( ((((int*)&ip)[j] & ((int*)&list[i].netmask)[j])) !=
           (((int*)&list[i].network)[j] & ((int*)&list[i].netmask)[j]) ) {
       i++;
       continue;

Deleted: GNUnet/src/util/network/port.c
===================================================================
--- GNUnet/src/util/network/port.c      2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/network/port.c      2006-06-24 20:37:52 UTC (rev 3037)
@@ -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/network/tcp_return.c
===================================================================
--- GNUnet/src/util/network/tcp_return.c        2006-06-24 16:34:56 UTC (rev 
3036)
+++ GNUnet/src/util/network/tcp_return.c        2006-06-24 20:37:52 UTC (rev 
3037)
@@ -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 */

Modified: GNUnet/src/util/network/tcpio.c
===================================================================
--- GNUnet/src/util/network/tcpio.c     2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/network/tcpio.c     2006-06-24 20:37:52 UTC (rev 3037)
@@ -19,7 +19,7 @@
 */
 
 /**
- * @file util/tcpio.c
+ * @file util/network/tcpio.c
  * @brief code for synchronized access to TCP streams
  * @author Christian Grothoff
  *
@@ -53,7 +53,7 @@
   /**
    * the socket handle, -1 if invalid / not life
    */
-  int socket;
+  struct SocketHandle * socket;
 
   /**
    * the following is the IP for the remote host for client-sockets,
@@ -81,108 +81,156 @@
 
   struct Mutex * writelock;
 
+  struct CE_Context * ectx;
+
 } GNUNET_TCP_SOCKET;
 
 
 /**
- * CS communication: simple return value
+ * Return the port-number (in host byte order)
  */
-typedef struct {
+static unsigned short getGNUnetPort() {
+  // TODO!
+  static unsigned short port;
+  const char *setting;
 
-  /**
-   * The CS header (values: sizeof(CS_returnvalue_MESSAGE) + error-size, 
CS_PROTO_RETURN_VALUE)
-   */
-  MESSAGE_HEADER header;
+  if (port != 0)
+    return port;
+  if (testConfigurationString("GNUNETD",
+                             "_MAGIC_",
+                             "YES"))
+    setting = "PORT";
+  else
+    setting = "CLIENT-PORT";
 
-  /**
-   * The return value (network byte order)
-   */
-  int return_value;
-} RETURN_VALUE_MESSAGE;
+  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() {
+  // TODO!
+  static char * res;
 
+  if (res != NULL)
+    return res;
+  res = getConfigurationString("NETWORK",
+                              "HOST");
+  if (res == NULL)
+    res = "localhost";
+  return res;
+}
 
 /**
- * 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
+ * Initialize a GNUnet server socket.
+ * @param sock the open socket
  * @param result the SOCKET (filled in)
- * @return OK if successful, SYSERR on failure
+ * @return OK (always successful)
  */
-int initGNUnetClientSocketIP(unsigned short port,
-                            IPaddr ip,
-                            GNUNET_TCP_SOCKET * result) {
-  result->ip = ip;
-  result->port = port;
-  result->socket = -1; /* closed */
+struct ClientServerConnection * 
+client_connection_create(struct GE_Context * ectx,
+                        struct GC_Configuration * cfg,
+                        struct SocketHandle * sock) {
+  // TODO!
+  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;
+  return result;
 }
 
+
 /**
- * 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
+ * Get a GNUnet TCP socket that is connected to gnunetd.
  */
-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;
+struct ClientServerConnection * 
+daemon_connection_create(struct GE_Context * ectx,
+                        struct GC_Configuration * cfg) {
+  // TODO!
+  struct ClientServerConnection * sock;
+  const char * host;
+
+  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;
+
+  if (OK != GN_getHostByName(hostname,
+                            &result->ip)) 
+    return SYSERR;
+
+  sock = MALLOC(sizeof(struct ClientServerConnection));
+  host = getGNUnetdHost();
+  if (SYSERR == initGNUnetClientSocket(getGNUnetPort(),
+                                      host,
+                                      sock)) {
+    LOG(LOG_ERROR,
+       _("Could not connect to gnunetd.\n"));
+    FREE(sock);
+    return NULL;
+  }
+  return sock;
 }
 
-/**
- * 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;
+void connection_close_temporarily(struct ClientServerConnection * sock) {
+  // TODO!
+  int i;
+  GE_ASSERT(NULL, sock != NULL);
+  if (sock->socket != -1) {
+    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");
+    CLOSE(i);
+  }
+  sock->outBufLen = 0;
+  FREENONNULL(sock->outBufPending);
+  sock->outBufPending = NULL;
 }
 
-/**
- * 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) {
+void connection_destroy(struct ClientServerConnection * sock) {
+  connection_close_temporarily(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);
+  FREE(sock);
+}
+
+int connection_test_open(struct ClientServerConnection * 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 connection_ensure_connected(struct ClientServerConnection * sock) {
+  // TODO!
   int res;
   struct sockaddr_in soaddr;
   fd_set rset;
@@ -265,8 +313,9 @@
  * @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 connection_write(struct ClientServerConnection * sock,
+                    const MESSAGE_HEADER * buffer) {
+  // TODO!
   int res;
   int size;
 
@@ -315,152 +364,45 @@
   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 connection_read(struct ClientServerConnection * sock,
+                   MESSAGE_HEADER ** buffer) {
   int res;
   unsigned int pos;
   char * buf;
   unsigned short size;
 
-  if (SYSERR == checkSocket(sock))
+  if (OK != connection_ensure_connected(sock))
     return SYSERR;
-
-  MUTEX_LOCK(&sock->readlock);
+  
+  MUTEX_LOCK(sock->readlock);
   pos = 0;
   res = 0;
-
-  pos = RECV_BLOCKING_ALL(sock->socket,
+  if ( (OK != socket_recv(sock->handle,
+                         NC_Complete,
                          &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 */
+                         sizeof(unsigned short),
+                         &pos)) ||
+       (pos != sizeof(unsigned short)) ) {
+    connection_close_temporarily(sock);
+    MUTEX_UNLOCK(sock->readlock);
+    return SYSERR;
   }
   size = ntohs(size);
-  if (size < sizeof(CS_MESSAGE_HEADER)) {
-#if DEBUG_TCPIO
-    LOG_STRERROR(LOG_INFO, "recv");
-#endif
-    closeSocketTemporarily(sock);
-    MUTEX_UNLOCK(&sock->readlock);
+  if (size < sizeof(MESSAGE_HEADER)) {
+    connection_close_temporarily(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 = MALLOC(size);
+  if ( (OK != socket_recv(sock->handle,
+                         NC_Complete,
                          &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);
+                         size - pos,
+                         &pos)) ||
+       (pos != sizeof(unsigned short) + size) ) {
+    connection_close_temporarily(sock);
+    FREE(buf);
     MUTEX_UNLOCK(&sock->readlock);
     return SYSERR;
   }
@@ -470,54 +412,102 @@
       size);
 #endif
   MUTEX_UNLOCK(&sock->readlock);
-  *buffer = (CS_MESSAGE_HEADER*) buf;
+  *buffer = (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).
+ * CS communication: simple return value
  */
-void closeSocketTemporarily(GNUNET_TCP_SOCKET * sock) {
-  if (sock == NULL)
-    return;
-  if (sock->socket != -1) {
-    int i;
+typedef struct {
 
-    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);
+  /**
+   * The CS header (values: sizeof(CS_returnvalue_MESSAGE) + error-size, 
CS_PROTO_RETURN_VALUE)
+   */
+  MESSAGE_HEADER header;
+
+  /**
+   * The return value (network byte order)
+   */
+  int return_value;
+
+} RETURN_VALUE_MESSAGE;
+
+/**
+ * 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 connection_read_result(struct ClientServerConnection * sock,
+                          int * ret) {
+  RETURN_VALUE_MESSAGE * rv;
+
+  rv = NULL;
+  if (SYSERR == connection_read(sock,
+                               (MESSAGE_HEADER **) &rv)) 
+    return SYSERR;
+  if ( (ntohs(rv->header.size) != sizeof(RETURN_VALUE_MESSAGE)) ||
+       (ntohs(rv->header.type) != CS_PROTO_RETURN_VALUE) ) {
+    GE_LOG(sock->ectx,
+          GE_WARNING | GE_DEVELOPER | GE_BULK,
+          _("`%s' failed, reply invalid!\n"),
+          __FUNCTION__);
+    FREE(rv);
+    return SYSERR;
   }
-  sock->outBufLen = 0;
-  FREENONNULL(sock->outBufPending);
-  sock->outBufPending = NULL;
+  *ret = ntohl(rv->return_value);
+  FREE(rv);
+  return OK;
 }
 
 /**
- * Destroy a socket for good. If you use this socket afterwards,
- * you must first invoke initializeSocket, otherwise the operation
- * will fail.
+ * 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
  */
-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);
+int connection_write_result(struct ClientServerConnection * sock,
+                           int ret) {
+  RETURN_VALUE_MESSAGE rv;
+
+  rv.header.size
+    = htons(sizeof(CS_returnvalue_MESSAGE));
+  rv.header.type
+    = htons(CS_PROTO_RETURN_VALUE);
+  rv.return_value
+    = htonl(ret);
+  return connection_write(sock,
+                         &rv.header,
+                         YES);
 }
 
+/**
+ * Send a return value that indicates
+ * a serious error to the other side.
+ *
+ * @param sock the TCP socket
+ * @param mask GE_MASK 
+ * @param date date string
+ * @param msg message string
+ * @return SYSERR on error, OK if the error code was send
+ *         successfully
+ */
+int connection_write_error(struct ClientServerConnection * sock,
+                          GE_KIND mask,
+                          const char * date,
+                          const char * msg) {
+  return SYSERR; /* not implemented! */
+}
 
+
+
+
 /*  end of tcpio.c */

Modified: GNUnet/src/util/os/Makefile.am
===================================================================
--- GNUnet/src/util/os/Makefile.am      2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/os/Makefile.am      2006-06-24 20:37:52 UTC (rev 3037)
@@ -6,6 +6,7 @@
   libos.la
 
 libos_la_SOURCES = \
+ cpustatus.c \
  daemon.c \
  dso.c \
  osconfig.c \

Added: GNUnet/src/util/os/cpustatus.c
===================================================================
--- GNUnet/src/util/os/cpustatus.c      2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/os/cpustatus.c      2006-06-24 20:37:52 UTC (rev 3037)
@@ -0,0 +1,435 @@
+/*
+     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/os/cpustatus.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_os.h"
+#include "gnunet_util_error.h"
+#include "gnunet_util_threads.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
+
+#ifdef LINUX
+static FILE * proc_stat;
+#endif
+
+static struct MUTEX * statusMutex;
+
+/**
+ * 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 int updateCpuUsage(){
+  int currentLoad;
+#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)) {
+      GE_LOG_STRERROR_FILE(NULL,
+                          GE_ERROR | GE_USER | GE_ADMIN | GE_BULK,
+                          "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) {
+       GE_LOG_STRERROR_FILE(NULL,
+                            GE_ERROR | GE_USER | GE_ADMIN | GE_BULK,
+                            "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;
+       return currentLoad;
+      }
+    }
+  }
+#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) {
+      GE_LOG_STRERROR(NULL,
+                     GE_ERROR | GE_USER | GE_ADMIN | GE_BULK, 
+                     "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))
+      GE_LOG_STRERROR(NULL,
+                     GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
+                     "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;
+    return currentLoad;
+  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;
+       GE_LOG_STRERROR(NULL,
+                       GE_ERROR | GE_USER | GE_ADMIN | GE_BULK,
+                       "getloadavg");
+      }
+      currentLoad = -1;
+    } else {
+      /* success with getloadavg */
+      currentLoad = (int) (100 * loadavg);
+      return currentLoad;
+    }
+  }
+#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;
+
+      return currentLoad;
+    } 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;
+       GE_LOG(NULL,
+              GE_ERROR | GE_USER | GE_ADMIN | GE_BULK,
+              _("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;
+       GE_LOG(NULL,
+              GE_USER | GE_ADMIN | GE_ERROR | GE_BULK,
+              _("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);
+
+    return currentLoad;
+  }
+#endif
+
+  /* loadaverage not defined and no platform
+     specific alternative defined
+     => default: error
+  */
+  return -1;
+}
+
+
+/**
+ * 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 os_cpu_get_load(struct GE_Context * ectx,
+                   struct GC_Configuration * cfg) {
+  static int currentLoad;
+  static int lastRet = -1;
+  static cron_t lastCall;
+  unsigned long long maxCPULoad;
+  int ret;
+  cron_t now;
+
+  if (-1 == GC_get_configuration_value_number(cfg,
+                                             "LOAD",
+                                             "MAXCPULOAD",
+                                             0,
+                                             100,
+                                             100,
+                                             &maxCPULoad))
+    return -1;
+  MUTEX_LOCK(statusMutex);
+  ret = (100 * currentLoad) / maxCPULoad;
+  now = get_time();
+  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;
+  }
+  currentLoad = updateCpuUsage();
+  ret = (100 * currentLoad) / maxCPULoad;
+  /* 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 __attribute__ ((constructor)) gnunet_cpustats_ltdl_init() {
+  statusMutex = MUTEX_CREATE(NO);
+#ifdef LINUX
+  proc_stat = fopen("/proc/stat", "r");
+  if (NULL == proc_stat)
+    GE_LOG_STRERROR_FILE(NULL,
+                        GE_ERROR | GE_USER | GE_ADMIN | GE_BULK,
+                        "fopen",
+                        "/proc/stat");
+#endif
+}
+
+/**
+ * Shutdown the status calls module.
+ */
+void __attribute__ ((destructor)) gnunet_cpustats_ltdl_fini() {
+#ifdef LINUX
+  if (proc_stat != NULL) {
+    fclose(proc_stat);
+    proc_stat = NULL;
+  }
+#endif
+  MUTEX_DESTROY(statusMutex);
+}
+
+
+/* end of cpustatus.c */

Modified: GNUnet/src/util/os/daemon.c
===================================================================
--- GNUnet/src/util/os/daemon.c 2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/os/daemon.c 2006-06-24 20:37:52 UTC (rev 3037)
@@ -19,52 +19,15 @@
 */
 
 /**
- * @file src/util/daemon.c
- * @brief code for client-gnunetd interaction (start, stop, waitpid, check 
running)
+ * @file src/util/os/daemon.c
+ * @brief code for client-gnunetd interaction (start, stop, waitpid)
  * @author Christian Grothoff
  */
 
 #include "platform.h"
-#include "gnunet_util.h"
-#include "gnunet_protocols.h"
+#include "gnunet_util_os.h"
+#include "gnunet_util_string.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
@@ -73,45 +36,44 @@
  * @return pid_t of gnunetd if NOT daemonized, 0 if
  *  daemonized sucessfully, -1 on error
  */
-static pid_t launchWithExec(int daemonize) {
+static pid_t launchWithExec(struct GE_Context * ectx,
+                           const char * binary_home,
+                           const char * cfgFile,
+                           int daemonize) {
   pid_t pid;
 
   pid = fork();
   if (pid == 0) {
-    char * args[5];
+    const char * args[5];
     char * path;
     char * cp;
+    int i;
 
     path = NULL;
-    cp = getConfigurationString("MAIN",
-                               "ARGV[0]");
-    if (cp != NULL) {
-      int i = strlen(cp);
-      while ( (i >= 0) &&
-             (cp[i] != DIR_SEPARATOR) )
+    cp = STRDUP(binary_home);
+    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);
+    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) {
+    if (cfgFile != NULL) {
       args[1] = "-c";
-      args[2] = cp;
+      args[2] = cfgFile;
       if (NO == daemonize) {
        args[3] = "-d";
        args[4] = NULL;
@@ -127,20 +89,20 @@
     errno = 0;
     nice(10); /* return value is not well-defined */
     if (errno != 0)
-      LOG_STRERROR(LOG_WARNING, "nice");
+      GE_LOG_STRERROR(ectx,
+                     GE_WARNING | GE_USER | GE_BULK, 
+                     "nice");
     if (path != NULL)
       execv(path,
-           args);
+           (char**) 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... */
+            (char**) args);
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_ERROR | GE_USER | GE_BULK, 
+                        "exec",
+                        path == NULL ? "gnunetd" : path);
+    FREENONNULL(path);
     _exit(-1);
   } else if (daemonize) {
     pid_t ret;
@@ -148,7 +110,9 @@
 
     ret = waitpid(pid, &status, 0);
     if (ret == -1) {
-      LOG_STRERROR(LOG_ERROR, "waitpid");
+      GE_LOG_STRERROR(ectx,
+                     GE_ERROR | GE_USER | GE_BULK, 
+                     "waitpid");
       return SYSERR;
     }
     if ( (WIFEXITED(status) &&
@@ -177,9 +141,26 @@
  * @return pid_t of gnunetd if NOT daemonized, 0 if
  *  daemonized sucessfully, -1 on error
  */
-int startGNUnetDaemon(int daemonize) {
+int os_daemon_start(struct GE_Context * ectx,
+                   struct GC_Configuration * cfg,
+                   const char * cfgFile,
+                   int daemonize) {
 #if LINUX || OSX || SOLARIS || SOMEBSD
-  return launchWithExec(daemonize);
+  int ret;
+  char * binName;
+
+  if (0 != GC_get_configuration_value_string(cfg,
+                                            "ARGV",
+                                            "0",
+                                            NULL,
+                                            &binName))
+    return -1;
+  ret = launchWithExec(ectx,
+                      cfgFile,
+                      binName,
+                      daemonize);
+  FREE(binName);
+  return ret;
 #elif MINGW
   char szCall[_MAX_PATH + 1], szWd[_MAX_PATH + 1], szCWd[_MAX_PATH + 1];
   char *args[1], *cp = NULL;
@@ -193,20 +174,22 @@
   chdir(szWd);
 
   if (daemonize == NO) {
-       args[0] = "-d";
-               idx = 1;
-
+    args[0] = "-d";
+    idx = 1;
+    
     cp = getConfigurationString("GNUNET",
                                "GNUNETD-CONFIG");
-               if (cp) {
-                       args[1] = "-c";
-                       args[2] = cp;
-                       idx=3;
-               }               
+    if (cp) {
+      args[1] = "-c";
+      args[2] = cp;
+      idx=3;
+    }          
   }
 
   args[idx] = NULL;
-  pid = spawnvp(_P_NOWAIT, szCall, (const char *const *) args);
+  pid = spawnvp(_P_NOWAIT, 
+               szCall,
+               (const char *const *) args);
   chdir(szCWd);
 
   FREENONNULL(cp);
@@ -220,68 +203,33 @@
 #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;
+static int termProcess(int pid) {
+#ifndef MINGW
+  return kill(pid, SIGTERM) == 0;
+#else
   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;
+  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);
   }
-  if (SYSERR == readTCPResult(sock,
-                             &ret)) {
-    releaseClientSocket(sock);
-    return SYSERR;
-  }
-  releaseClientSocket(sock);
+  else
+    ret = 1;
+  
+  CloseHandle(hProc);
+  
   return ret;
+#endif
 }
 
-/**
- * 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
@@ -293,13 +241,17 @@
  *  failed, NO if gnunetd shutdown with
  *  some error
  */
-int waitForGNUnetDaemonTermination(int pid) {
+int os_daemon_stop(struct GE_Context * ectx,
+                  int pid) {
   pid_t p;
   int status;
 
+  termProcess(pid);
   p = pid;
   if (p != WAITPID(p, &status, 0)) {
-    LOG_STRERROR(LOG_ERROR, "waitpid");
+    GE_LOG_STRERROR(ectx,
+                   GE_ERROR | GE_USER | GE_BULK,
+                   "waitpid");
     return SYSERR;
   }
   if (WEXITSTATUS(status) == 0)
@@ -308,29 +260,4 @@
     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 */

Modified: GNUnet/src/util/os/dso.c
===================================================================
--- GNUnet/src/util/os/dso.c    2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/os/dso.c    2006-06-24 20:37:52 UTC (rev 3037)
@@ -26,6 +26,7 @@
 
 #include "platform.h"
 #include "gnunet_util_os.h"
+#include "gnunet_util_string.h"
 
 typedef struct PluginHandle {
   struct GE_Context * ectx;
@@ -146,7 +147,7 @@
   return plug;
 }
 
-void os_plugin_unload(struct PluginHandle * libhandle) {
+void os_plugin_unload(struct PluginHandle * plugin) {
   lt_dlclose(plugin->handle);
   FREE(plugin->libprefix);
   FREE(plugin->dsoname);
@@ -154,7 +155,7 @@
 }
 
 void * 
-os_plugin_resolve_function(struct PluginHandle * plugin,
+os_plugin_resolve_function(struct PluginHandle * plug,
                           const char * methodprefix,
                           int logError) {
   char * initName;
@@ -164,10 +165,10 @@
                    strlen(methodprefix) + 2);
   strcpy(initName, "_");
   strcat(initName, methodprefix);
-  strcat(initName, dsoname);
-  mptr = lt_dlsym(libhandle, &initName[1]);
+  strcat(initName, plug->dsoname);
+  mptr = lt_dlsym(plug->handle, &initName[1]);
   if (mptr == NULL) 
-    mptr = lt_dlsym(libhandle, initName);
+    mptr = lt_dlsym(plug->handle, initName);
   if ( (mptr == NULL) &&
        (logError) )
     GE_LOG(plug->ectx,

Modified: GNUnet/src/util/os/osconfig.c
===================================================================
--- GNUnet/src/util/os/osconfig.c       2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/os/osconfig.c       2006-06-24 20:37:52 UTC (rev 3037)
@@ -20,21 +20,23 @@
 */
 
 /**
- * @file util/osconfig.c
+ * @file util/os/osconfig.c
  * @brief functions to read or change the OS configuration
  * @author Nils Durner
  */
 #include "platform.h"
-#include "gnunet_util.h"
+#include "gnunet_util_os.h"
+#include "gnunet_util_string.h"
 
 /**
  * @brief Enumerate all network interfaces
  * @param callback the callback function
  */
-void enumNetworkIfs(void (*callback) (const char *, int, void *),
-                   void * cls) {
+void os_list_network_interfaces(struct GE_Context * ectx,
+                               NetworkIfcProcessor proc,
+                               void * cls) {
 #ifdef MINGW
-  ListNICs(callback, cls);
+  ListNICs(proc, cls);
 #else
   char entry[11], *dst;
   FILE *f;
@@ -46,42 +48,46 @@
       f = NULL;
   else
     f = popen("ifconfig 2> /dev/null", "r");
-
-  if (!f)
+  if (!f) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_USER | GE_ADMIN | GE_BULK | GE_WARNING,
+                        "popen",
+                        "ifconfig");
     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' &&
+  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 != ':'
+          c != ':'
 #else
-            c != ' '
+          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);
+          && i < 10) {
+      *dst++ = c;
+      i++;
+      c = fgetc(f);
     }
-
+    *dst = 0;
+    
+    if ( (entry[0] != '\0') &&
+        (OK != proc(entry, 
+                    strcmp(entry, "eth0") == 0,
+                    cls)) )
+      break;
+    
+    while ((c != '\n') && (c != EOF))
+      c = fgetc(f);
+  }
   pclose(f);
 #endif
 }
@@ -90,159 +96,171 @@
  * @brief Checks if we can start GNUnet automatically
  * @return 1 if yes, 0 otherwise
  */
-int isOSAutostartCapable() {
+static int isOSAutostartCapable() {
 #ifdef LINUX
-  if (ACCESS("/usr/sbin/update-rc.d", X_OK) == 0) {
+  if (ACCESS("/usr/sbin/update-rc.d", 
+            X_OK) == 0) {
     /* Debian */
-    if (ACCESS("/etc/init.d/", W_OK) == 0)
+    if (ACCESS("/etc/init.d/", 
+              W_OK) == 0)
       return 1;
   }
   return 0;
 #else
-  #ifdef WINDOWS
-    return 1;
-  #else
-    return 0;
-  #endif
+#ifdef WINDOWS
+  return IsWinNT();
+#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) {
+int os_modify_autostart(struct GE_Context * ectx,
+                       int testCapability,
+                       int doAutoStart,
+                       const char * application,
+                       const char * username, 
+                       const char * groupname) {
+  if (testCapability) {
+    /* TODO: check that user/group/application
+       exist! */
+    return isOSAutostartCapable();
+  }
 #ifdef WINDOWS
-  if (doAutoStart)
-    {
-      if (IsWinNT())
-       {
-         char *err = NULL;
-         DWORD dwErr = 0;
+  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];
        
-         if (username && !strlen(username))
-           username = NULL;
+       plibc_conv_to_win_path("/", szHome);
        
-         /* 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;
-           }
+       if (!AddPathAccessRights(szHome, username, GENERIC_ALL))
+         return 3;
+      }
+    } else {
+      char szPath[_MAX_PATH + 1];
+      HKEY hKey;
+      
+      plibc_conv_to_win_path(application, 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;
        
-         /* 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);
+       RegCloseKey(hKey);
+      } else
+       return 4;
     }
-    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
-    {
-      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
+  struct stat buf;
+      
   /* 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"
+  if ( (ACCESS("/usr/sbin/update-rc.d",
+              X_OK) != 0) ) {
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                        "access",
+                        "/usr/sbin/update-rc.d");
+    return SYSERR;
+  }
+  
+  /* Debian */
+  if (doAutoStart) {
+    if (ACCESS(application,
+              X_OK) != 0) {
+      GE_LOG_STRERROR_FILE(ectx,
+                          GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                          "access",
+                          application);
+    }
+    if (STAT("/etc/init.d/gnunetd", 
+            &buf) == -1) {
+      /* create init file */
+      FILE * f = FOPEN("/etc/init.d/gnunetd", "w");
+      if (! f) {
+       GE_LOG_STRERROR_FILE(ectx,
+                            GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                            "fopen",
+                            "/etc/init.d/gnunetd");
+       return 1;
+      }
+      
+      fprintf(f,
+             "#!/bin/sh\n"
              "#\n"
-             "# Automatically created by gnunet-setup\n"
+             "# Automatically created by %s\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"
+             "         %s\n && echo ok || echo failed\n"
              "         ;;\n"
              " stop)\n"
              "         echo -n \"Stopping GNUnet: \"\n"
-             "         kill `cat $PIDFILE`\n"
-             "         echo \"gnunetd\"\n"
+             "         kill `cat $PIDFILE`\n && echo ok || echo failed\n"
              "         ;;\n"
              " reload)\n"
              "         echo -n \"Reloading GNUnet: \"\n"
-             "         kill -HUP `cat $PIDFILE`\n"
-             "         echo \"gnunetd\"\n"
+             "         kill -HUP `cat $PIDFILE`\n && echo ok || echo failed\n"
              "         ;;\n"
              " restart|force-reload)\n"
              "         echo \"Restarting GNUnet: gnunetd...\"\n"
@@ -256,148 +274,132 @@
              "         ;;\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);
+             "exit 0\n", 
+             "gnunet-setup",
+             application);
+      fclose(f);
+      if (0 != CHMOD("/etc/init.d/gnunetd", 
+                    S_IRWXU | S_IRGRP | S_IXGRP |
+                    S_IROTH | S_IXOTH)) {
+       GE_LOG_STRERROR_FILE(ectx,
+                            GE_WARNING | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                            "chmod",
+                            "/etc/init.d/gnunetd");    
+       return SYSERR;
       }
-      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;
+    errno = 0;
+    if (-1 == system("/usr/sbin/update-rc.d gnunetd defaults")) {
+      GE_LOG_STRERROR_FILE(ectx,
+                          GE_WARNING | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                          "system",
+                          "/usr/sbin/update-rc.d");    
+      return SYSERR;
     }
+    return OK;
+  } else { /* REMOVE autostart */
+    if ( (UNLINK("/etc/init.d/gnunetd") == -1) &&
+        (errno != ENOENT)) {
+      GE_LOG_STRERROR_FILE(ectx,
+                          GE_WARNING | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                          "unlink",
+                          "/etc/init.d/gnunetd");      
+      return SYSERR;
+    }
+    errno = 0;
+    if (-1 != system("/usr/sbin/update-rc.d gnunetd remove")) {
+      GE_LOG_STRERROR_FILE(ectx,
+                          GE_WARNING | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                          "system",
+                          "/usr/sbin/update-rc.d");    
+      return SYSERR;
+    } 
+    return OK;
   }
-  else
-    return 1;
 #endif
-  return 0;
+  return SYSERR;
 }
 
-/**
- * @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(){
+int os_modify_user(struct GE_Context * ectx,
+                  int testCapability,
+                  int doAdd,              
+                  const char *group_name, 
+                  const char *user_name) {
+  int haveGroup;
+
+  if (testCapability) {
+    /* TODO: actually check that group/user
+       exists/does not yet exist */
 #ifdef WINDOWS
-       return IsWinNT();
+    return IsWinNT() ? OK : SYSERR;
 #endif
 #ifdef LINUX
-       if (ACCESS("/usr/sbin/adduser", X_OK) == 0)
-         return (geteuid() == 0);
-       else
-               /* TODO: useradd */
+    if (geteuid() != 0)
+      return SYSERR;
+    if (doAdd == YES) {
+      if ( ( (ACCESS("/usr/sbin/adduser", X_OK) == 0) ||
+            (ACCESS("/usr/sbin/useradd", X_OK) == 0) ) &&
+          ( (ACCESS("/usr/sbin/addgroup", X_OK) == 0) ||
+            (ACCESS("/usr/sbin/groupadd", X_OK) == 0) ) )
+       return OK;
+      return SYSERR;
+    } else if (doAdd == NO) {
+      if ( (ACCESS("/usr/sbin/deluser", X_OK) == 0) ||
+          (ACCESS("/usr/sbin/userdel", X_OK) == 0) )
+       return OK;
+      return SYSERR;
+    } else if (doAdd == SYSERR) {
+      if ( ( (ACCESS("/usr/sbin/dleuser", X_OK) == 0) ||
+            (ACCESS("/usr/sbin/userdel", X_OK) == 0) ) &&
+          ( (ACCESS("/usr/sbin/delgroup", X_OK) == 0) ||
+            (ACCESS("/usr/sbin/groupdel", X_OK) == 0) ) )
+       return OK;
+      return SYSERR;
+    }
 #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;
-       
+    return SYSERR;
+  }
+  if ( (user_name == NULL) ||
+       (0 == strlen(user_name)) ) 
+    return 0;
+  
 #ifdef WINDOWS
-       if (IsWinNT())
-       {
-               return CreateServiceAccount(user_name, "GNUnet service 
account");
-       }
+  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;
 
-       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;
+    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);
+    return OK;
+  }
+  /* TODO: useradd */
+  else
+    return SYSERR;
 #endif
-
-       return 0;
+  return SYSERR;
 }
 
-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 */

Modified: GNUnet/src/util/os/semaphore.c
===================================================================
--- GNUnet/src/util/os/semaphore.c      2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/os/semaphore.c      2006-06-24 20:37:52 UTC (rev 3037)
@@ -21,9 +21,13 @@
 /**
  * @file util/os/semaphore.c
  * @brief functions related to IPC synchronization
+ *
+ * TODO: implement non-blocking semaphore down!
  */
 
 #include "gnunet_util_os.h"
+#include "gnunet_util_string.h"
+#include "gnunet_util_error.h"
 #include "platform.h"
 
 #if SOLARIS || FREEBSD || OSX
@@ -148,8 +152,7 @@
 #if SOLARIS || OSX || FREEBSD5
   char * noslashBasename;
   int i;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
+  IPC_Semaphore * ret;
 
   ret = MALLOC(sizeof(IPC_Semaphore));
   ret->ectx = ectx;
@@ -180,19 +183,15 @@
                         noslashBasename);
   FREE(noslashBasename);
   return ret;
-
-  /* *********************** fix from here *********** */
 #elif WINDOWS
   char * noslashBasename;
   int i;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
+  IPC_Semaphore * ret;
   SECURITY_ATTRIBUTES sec;
   DWORD dwErr;
 
-  rret = MALLOC(sizeof(IPC_Semaphore));
-  ret = MALLOC(sizeof(IPC_Semaphore_Internal));
-  rret->platform = ret;
+  ret = MALLOC(sizeof(IPC_Semaphore));
+  ret->ectx = ectx;
   noslashBasename = STRDUP(basename);
   for (i=strlen(noslashBasename);i>0;i--)
     if (noslashBasename[i] == '\\')
@@ -209,35 +208,35 @@
     dwErr = GetLastError();
   }
   if (! ret->internal) {
-    LOG(LOG_FAILURE, _("Can't create semaphore: %i"), dwErr);
-    DIE_FILE_STRERROR("sem_open", noslashBasename);
+    GE_LOG(ectx,
+          GE_FAILURE | GE_USER | GE_DEVELOPER | GE_BULK,
+          _("Can't create semaphore: %i"), 
+          dwErr);
+    DIE_STRERROR_FILE(ectx,
+                     GE_FAILURE | GE_USER | GE_DEVELOPER | GE_BULK,
+                     "OpenSemaphore", noslashBasename);
   }
   FREE(noslashBasename);
-  return rret;
+  return ret;
 #elif LINUX
   union semun {
       int             val;
       struct semid_ds *buf;
       ushort          *array;
   } semctl_arg;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
+  IPC_Semaphore * ret;
   key_t key;
   FILE * fp;
   int pcount;
 
-  rret = MALLOC(sizeof(IPC_Semaphore));
-  ret = MALLOC(sizeof(IPC_Semaphore_Internal));
-  rret->platform = ret;
-
+  ret = MALLOC(sizeof(IPC_Semaphore));
+  ret->ectx = ectx;
   fp = FOPEN(basename, "a+");
   if (NULL == fp) {
-    LOG_FILE_STRERROR_FL(LOG_FATAL,
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_ERROR | GE_USER | GE_BULK,
                         "fopen",
-                        basename,
-                        filename,
-                        linenumber);
-    FREE(rret);
+                        basename);
     FREE(ret);
     return NULL;
   }
@@ -246,58 +245,81 @@
   key = ftok(basename,'g');
 
 again:
+  ret->internal = semget(key,
+                        3, 
+                        IPC_CREAT|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
 
-  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);
+    GE_DIE_STRERROR(ectx,
+                   GE_FATAL | GE_USER | GE_IMMEDIATE, 
+                   "semget");
   if (semop(ret->internal, &op_lock[0], 2) < 0) {
     if (errno == EINVAL)
       goto again;
     else
-      DIE_STRERROR_FL("semop", filename, linenumber);
+      GE_DIE_STRERROR(ectx, 
+                     GE_FATAL | GE_USER | GE_IMMEDIATE, 
+                     "semop");
   }
 
   /* get process count */
-  if ( (pcount = semctl(ret->internal, 1, GETVAL, 0)) < 0)
-    DIE_STRERROR_FL("semctl", filename, linenumber);
+  if ( (pcount = semctl(ret->internal,
+                       1,
+                       GETVAL,
+                       0)) < 0)
+    GE_DIE_STRERROR(ectx, 
+                   GE_FATAL | GE_USER | GE_IMMEDIATE, 
+                   "semctl");
   if (pcount==0) {
      semctl_arg.val = initialValue;
-     if (semctl(ret->internal, 0, SETVAL, semctl_arg) < 0)
-       DIE_STRERROR_FL("semtcl", filename, linenumber);
+     if (semctl(ret->internal, 
+               0, 
+               SETVAL, 
+               semctl_arg) < 0)
+       GE_DIE_STRERROR(ectx, 
+                      GE_FATAL | GE_USER | GE_IMMEDIATE, 
+                      "semtcl");
      semctl_arg.val = PROCCOUNT;
-     if (semctl(ret->internal, 1, SETVAL, semctl_arg) < 0)
-       DIE_STRERROR_FL("semtcl", filename, linenumber);
+     if (semctl(ret->internal, 
+               1,
+               SETVAL,
+               semctl_arg) < 0)
+       GE_DIE_STRERROR(ectx, 
+                      GE_FATAL | GE_USER | GE_IMMEDIATE, 
+                      "semtcl");
   }
 
-  if (semop(ret->internal, &op_endcreate[0], 2) < 0)
-     DIE_STRERROR_FL("semop", filename, linenumber);
-
+  if (semop(ret->internal, 
+           &op_endcreate[0],
+           2) < 0)
+    GE_DIE_STRERROR(ectx, 
+                   GE_FATAL | GE_USER | GE_IMMEDIATE, 
+                   "semop");
   ret->filename = STRDUP(basename);
-  return rret;
+  return ret;
 #elif SOMEBSD
   int fd;
   int cnt;
-  IPC_Semaphore * rret;
-  IPC_Semaphore_Internal * ret;
+  IPC_Semaphore * ret;
 
-  rret = MALLOC(sizeof(IPC_Semaphore));
-  ret = MALLOC(sizeof(IPC_Semaphore_Internal));
-  rret->platform = ret;
+  ret = MALLOC(sizeof(IPC_Semaphore));
+  ret->ectx = ectx;
 
   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 */);
+    fd = disk_file_open(ectx,
+                       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 */);
+      fd = disk_file_open(ectx,
+                         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) &&
@@ -306,28 +328,48 @@
     }
   }
   if (fd == -1) {
-    LOG_FILE_STRERROR(LOG_ERROR, "open", ret->filename);
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_ERROR | GE_USER | GE_BULK, 
+                        "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))) {
+  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, 
+         0, 
+         SEEK_SET);
+    if (sizeof(int) != WRITE(fd, 
+                            &cnt, 
+                            sizeof(int)))
+      GE_LOG_STRERROR_FILE(ectx,
+                          GE_ERROR | GE_USER | GE_BULK,
+                          "write", 
+                          basename);
   }
-  LSEEK(fd, sizeof(int), SEEK_SET);
-  if (sizeof(int) != READ(fd, &cnt, sizeof(int)))
+  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);
+  if (sizeof(int) != WRITE(fd,
+                          &cnt,
+                          sizeof(int)))
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_WARNING | GE_USER | GE_BULK, 
+                        "write",
+                        basename);
   FLOCK(fd, LOCK_UN);
   ret->fd = fd;
   ret->initialValue = initialValue;
@@ -342,244 +384,205 @@
 #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 */
+void IPC_SEMAPHORE_UP(IPC_Semaphore * sem) {
+  if (sem == 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);
+    GE_LOG_STRERROR(sem->ectx,
+                   GE_WARNING | GE_USER | GE_BULK,
+                   "sem_post");
 #elif WINDOWS
   if (!ReleaseSemaphore(sem->internal, 1, NULL))
-    LOG(LOG_WARNING,
-      "ReleaseSemaphore signaled error: %i at %s:%d\n",
-      GetLastError(),
-      filename,
-      linenumber);
+    GE_LOG(GE_WARNING | GE_USER | GE_BULK,
+          "ReleaseSemaphore signaled error: %i\n",
+          GetLastError());
 #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);
+      GE_LOG_STRERROR(sem->ectx,
+                     GE_WARNING | GE_USER | GE_BULK,
+                     "semop");
   }
 #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__);
+    FLOCK(sem->fd,
+         LOCK_EX);
+    LSEEK(sem->fd, 
+         0, 
+         SEEK_SET);
+    if (sizeof(int) != READ(sem->fd, 
+                           &cnt, 
+                           sizeof(int))) {
+      GE_LOG_STRERROR_FILE(sem->ectx,
+                          GE_WARNING | GE_USER | GE_BULK,
+                          "read",
+                          sem->filename);
+      FLOCK(sem->fd,
+           LOCK_UN);
       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);
+    LSEEK(sem->fd,
+         0, 
+         SEEK_SET);
+    if (sizeof(int) != WRITE(sem->fd,
+                            &cnt, 
+                            sizeof(int)))
+      GE_LOG_STRERROR_FILE(sem->ectx,
+                          GE_WARNING | GE_USER | GE_BULK,
+                          "write",
+                          sem->filename);
+    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;
+/* FIXME: add support for mayBlock! */
+int IPC_SEMAPHORE_DOWN(IPC_Semaphore * sem,
+                       int mayBlock) {
+  if (sem == NULL) /* error on creation, optimistic execution; good luck */
+    return OK;
 #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;
-    }
+    if ( (errno == EINTR) ||
+        (errno == EAGAIN) )
+      continue;
+    GE_DIE_STRERROR(sem->ectx,
+                   GE_FATAL | GE_USER | GE_IMMEDIATE,
+                   "sem_wait");
   }
+  return OK;
 #elif WINDOWS
-  if (WaitForSingleObject(sem->internal, INFINITE) == WAIT_FAILED)
-    LOG(LOG_WARNING,
-      "WaitForSingleObject signaled error: %s at %s:%d\n",
-      STRERROR(errno),
-      filename,
-      linenumber);
+  if (WaitForSingleObject(sem->internal, 
+                         INFINITE) == WAIT_FAILED)
+    GE_LOG_STRERROR(sem->ectx,
+                   GE_WARNING | GE_USER | GE_BULK,
+                   "WaitForSingleObject");
+  return OK;
 #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;
-      }
+    while (0 != semop(sem->internal,
+                     &sops,
+                     1)) {
+      if ( (errno == EINTR) ||
+          (errno == EAGAIN) )
+       continue;
+      GE_DIE_STRERROR(sem->ectx,
+                     GE_FATAL | GE_USER | GE_IMMEDIATE,
+                     "semop");
     }
+    return OK;
   }
 #elif SOMEBSD
   {
     int cnt;
 
     MUTEX_LOCK(&sem->internalLock);
-    FLOCK(sem->fd, LOCK_EX);
+    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);
+      LSEEK(sem->fd, 
+           0, 
+           SEEK_SET);
+      if (sizeof(int) != READ(sem->fd, 
+                             &cnt, 
+                             sizeof(int))) {
+       GE_LOG_STRERROR_FILE(sem->ectx,
+                            GE_WARNING | GE_USER | GE_BULK,
+                            "read",
+                            sem->filename);
+       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);
+       FLOCK(sem->fd,
+             LOCK_UN);
+       PTHREAD_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);
+    if (sizeof(int) != WRITE(sem->fd, 
+                            &cnt, 
+                            sizeof(int)))
+      GE_LOG_STRERROR_FILE(sem->ectx,
+                          GE_WARNING | GE_USER | GE_BULK,
+                          "write",
+                          sem->filename);
+    FLOCK(sem->fd, 
+         LOCK_UN);
     MUTEX_UNLOCK(&sem->internalLock);
   }
+  return OK;
 #else
+  return OK;
 #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 */
+void IPC_SEMAPHORE_DESTROY(IPC_Semaphore * sem) {
+  if (sem == 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);
+    GE_LOG_STRERROR(sem->ectx,
+                   GE_USER | GE_WARNING | GE_BULK,
+                   "sem_close");
 #elif WINDOWS
   if (!CloseHandle(sem->internal))
-    LOG(LOG_WARNING,
-    "CloseHandle signaled error: %i at %s:%d\n",
-    GetLastError(),
-    filename,
-    linenumber);
+    GE_LOG(sem->ectx,
+          GE_USER | GE_WARNING | GE_BULK,
+          "CloseHandle signaled error: %i\n",
+          GetLastError());
 #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);
+      GE_LOG_STRERROR(sem->ectx,
+                     GE_USER | GE_WARNING | GE_BULK,
+                     "semop");
+    if ( (pcount = semctl(sem->internal, 1, GETVAL, 0)) < 0) 
+      GE_LOG_STRERROR(sem->ectx,
+                     GE_USER | GE_WARNING | GE_BULK,
+                     "semctl");
+    if (pcount > PROCCOUNT) {
+      GE_BREAK(sem->ectx, 0);
+    } else if (pcount == PROCCOUNT) {
+      if (0 != semctl(sem->internal,
+                     0,
+                     IPC_RMID,
+                     0))
+       GE_LOG_STRERROR(sem->ectx,
+                       GE_USER | GE_WARNING | GE_BULK,
+                       "semctl");
       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);
+      if (semop(sem->internal, 
+               &op_unlock[0],
+               1) < 0)
+       GE_LOG_STRERROR(sem->ectx,
+                       GE_USER | GE_WARNING | GE_BULK,
+                       "semop");
     }
-    FREE(sem->filename);
+    FREE(sem->filename);   
   }
 #elif SOMEBSD
   {
@@ -592,23 +595,20 @@
       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);
-      }
+       GE_LOG_STRERROR(sem->ectx,
+                       GE_WARNING | GE_USER | GE_BULK,
+                       "write");
+      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__);
+      GE_LOG_STRERROR(sem->ectx,
+                     GE_WARNING | GE_USER | GE_BULK,
+                     "read");
+    FLOCK(sem->fd, LOCK_UN);
+    disk_file_close(sem->ectx,
+                   sem->filename,
+                   sem->fd);
     FREE(sem->filename);
-    FLOCK(sem->fd, LOCK_UN);
-    closefile(sem->fd);
   }
 #else
 #endif

Modified: GNUnet/src/util/os/statuscalls.c
===================================================================
--- GNUnet/src/util/os/statuscalls.c    2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/os/statuscalls.c    2006-06-24 20:37:52 UTC (rev 3037)
@@ -19,8 +19,8 @@
 */
 
 /**
- * @file util/statuscalls.c
- * @brief calls to determine current network and CPU load
+ * @file util/os/statuscalls.c
+ * @brief calls to determine current network load
  * @author Tzvetan Horozov
  * @author Christian Grothoff
  * @author Igor Wronsky
@@ -29,7 +29,10 @@
  */
 
 #include "platform.h"
-#include "gnunet_util.h"
+#include "gnunet_util_os.h"
+#include "gnunet_util_error.h"
+#include "gnunet_util_string.h"
+#include "gnunet_util_threads.h"
 
 #if SOLARIS
 #if HAVE_KSTAT_H
@@ -62,117 +65,87 @@
   unsigned long long last_out;
 } NetworkStats;
 
-/**
- * Traffic counter for only gnunetd traffic.
- */
-static NetworkStats globalTrafficBetweenProc;
+typedef struct LoadMonitor {
+  
+  /**
+   * Traffic counter for only gnunetd traffic.
+   */
+  NetworkStats globalTrafficBetweenProc;
 
-/**
- * tracking
- */
-static NetworkStats * ifcs;
+  /**
+   * tracking
+   */
+  NetworkStats * ifcs;
 
-/**
- * how many interfaces do we have?
- */
-static unsigned int ifcsSize;
+  /**
+   * how many interfaces do we have?
+   */
+  unsigned int ifcsSize;
 
-/**
- * Current load of the machine, -1 for error
- */
-static int currentLoad;
+  /**
+   * Maximum bandwidth (down) as per config.
+   */
+  unsigned long long maxNetDownBPS;
 
-/**
- * Maximum bandwidth (down) as per config.
- */
-static int maxNetDownBPS;
+  /**
+   * Maximum bandwidth (up) as per config.
+   */
+  unsigned long long maxNetUpBPS;
 
-/**
- * Maximum bandwidth (up) as per config.
- */
-static int maxNetUpBPS;
+  /**
+   * How to measure traffic (YES == only gnunetd,
+   * NO == try to include all apps)
+   */
+  int useBasicMethod;
 
-/**
- * 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;
+  FILE * proc_net_dev;
 #endif
+  
+  /**
+   * Lock.
+   */
+  struct MUTEX * statusMutex;
 
-/**
- * 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);
-}
+  struct GE_Context * ectx;
 
-void incrementBytesReceived(unsigned long long delta) {
-  if (initialized_ == NO)
-    return;
-  MUTEX_LOCK(&statusMutex);
-  globalTrafficBetweenProc.last_in += delta;
-  MUTEX_UNLOCK(&statusMutex);
-}
+  struct GC_Configuration * cfg;
 
-/**
- * Reset the traffic counters for GNUnet traffic between
- * systemwide readings.
- */
-static void resetBetweenProc() {
-  globalTrafficBetweenProc.last_in = 0;
-  globalTrafficBetweenProc.last_out = 0;
+} LoadMonitor;
+
+void os_network_monitor_notify_transmission(struct LoadMonitor * monitor,
+                                           NetworkDirection dir,
+                                           unsigned long long delta) {
+  MUTEX_LOCK(monitor->statusMutex);
+  monitor->globalTrafficBetweenProc.last_in += delta;
+  MUTEX_UNLOCK(monitor->statusMutex);
 }
 
 #define MAX_PROC_LINE 5000
 
-static void updateInterfaceTraffic() {
-#ifdef LINUX
+static void updateInterfaceTraffic(struct LoadMonitor * monitor) {
   unsigned long long rxnew;
   unsigned long long txnew;
+  int i;
   char line[MAX_PROC_LINE];
+  NetworkStats * ifc;
+#ifdef LINUX
   char * data;
-  int i;
   int found;
 
-  MUTEX_LOCK(&statusMutex);
-  if (proc_net_dev != NULL) {
+  if (monitor->proc_net_dev != NULL) {
     found = 0;
-    rewind(proc_net_dev);
-    fflush(proc_net_dev);
+    rewind(monitor->proc_net_dev);
+    fflush(monitor->proc_net_dev);
     /* Parse the line matching the interface ('eth0') */
-    while (! feof(proc_net_dev) ) {
+    while (! feof(monitor->proc_net_dev) ) {
       if (NULL == fgets(line,
                        MAX_PROC_LINE,
-                       proc_net_dev))
+                       monitor->proc_net_dev))
        break;
-      for (i=0;i<ifcsSize;i++) {
-       if (NULL != strstr(line, ifcs[i].name) ) {
+      for (i=0;i<monitor->ifcsSize;i++) {
+       ifc = &monitor->ifcs[i];
+       if (NULL != strstr(line, ifc->name) ) {
          data = strchr(line, ':');
          if (data == NULL)
            continue;
@@ -181,58 +154,52 @@
                          "%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__);
+           GE_LOG(monitor->ectx,
+                  GE_ERROR | GE_ADMIN | GE_BULK,
+                  _("Failed to parse interface data from `%s'.\n"),
+                  PROC_NET_DEV);
            continue;
-         }     
-         ifcs[i].last_in  = rxnew;
-         ifcs[i].last_out = txnew;
-         resetBetweenProc();
+         }
+         ifc->last_in  = rxnew;
+         ifc->last_out = txnew;
+         monitor->globalTrafficBetweenProc.last_in = 0;
+         monitor->globalTrafficBetweenProc.last_out = 0;
          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 (i=0;i<monitor->ifcsSize;i++) {
+      ifc = &monitor->ifcs[i];
       for (dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
-        l = _atoi64(ifcs[i].name);
-
+        l = _atoi64(ifc->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
+         ifc->last_in
            = pTable->table[dwIfIdx].dwInOctets;
-         ifcs[i].last_out
+         ifc->last_out
            = pTable->table[dwIfIdx].dwOutOctets;
-         resetBetweenProc();
+         monitor->globalTrafficBetweenProc.last_in = 0;
+         monitor->globalTrafficBetweenProc.last_out = 0;
           break;
         }
       }
@@ -243,9 +210,9 @@
       LOG_FILE_STRERROR(LOG_ERROR,
                        "popen",
                        "netstat -e");
-      MUTEX_UNLOCK(&statusMutex);
       return;
     }
+    ifc = &monitor->ifcs[0];
     while (!feof(command)) {
       if (NULL == fgets(line,
                        MAX_PROC_LINE,
@@ -253,460 +220,120 @@
        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;
+        if (2 == sscanf("%*s%i%i",
+                       &rxnew,
+                       &txnew)) {
+         ifc->last_in
+           = rxnew;
+         ifc->last_out
+           = txnew;
+         monitor->globalTrafficBetweenProc.last_in = 0;
+         monitor->globalTrafficBetweenProc.last_out = 0;
+         break;
+       } else {
+         GE_LOG(monitor->ectx,
+                GE_ERROR | GE_ADMIN | GE_BULK,
+                _("Failed to parse interface data from `%s'.\n"),
+                PROC_NET_DEV);
+       }
       }
       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() {
+static int resetStatusCalls(void * cls,
+                           struct GC_Configuration * cfg,
+                           struct GE_Context * ectx,
+                           const char * sect,
+                           const char * op) {
+  static const char * yesno[] = { "YES", "NO", NULL };
+  struct LoadMonitor * monitor = cls;
+  const char * y;
   char * interfaces;
   int i;
   int numInterfaces;
+  int basic;
 
-  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;
-    }
+  if (-1 == GC_get_configuration_value_choice(cfg,
+                                             "LOAD",
+                                             "BASICLIMITING",
+                                             yesno,
+                                             "NO",
+                                             &y))
+    return SYSERR;
+  basic = (y == "YES") ? YES : NO;
+  if (-1 == GC_get_configuration_value_string(cfg,
+                                             "LOAD",
+                                             "INTERFACES",
+                                             NULL,
+                                             &interfaces))
+    return SYSERR;
+  if (interfaces == NULL) {
+    GE_LOG(ectx,
+          GE_ERROR | GE_USER | GE_BULK,
+          _("No network interfaces defined in configuration section `%s' under 
`%s'!\n"),
+          "LOAD",
+          "INTERFACES");
+    return SYSERR;
   }
-  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 (strlen(interfaces) == 0) {
+    FREE(interfaces);
+    GE_LOG(ectx,
+          GE_ERROR | GE_USER | GE_BULK,
+          _("No network interfaces defined in configuration section `%s' under 
`%s'!\n"),
+          "LOAD",
+          "INTERFACES");
+    return SYSERR;
   }
-  if (maxNetUpBPS == 0) {
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
+  MUTEX_LOCK(monitor->statusMutex);
+  for (i=0;i<monitor->ifcsSize;i++)
+    FREE(monitor->ifcs[i].name);
+  numInterfaces = 1;
+  for (i=strlen(interfaces)-1;i>=0;i--)
+    if (interfaces[i] == ',')
+      numInterfaces++;
+  GROW(monitor->ifcs,
+       monitor->ifcsSize,
+       numInterfaces);
+  for (i=strlen(interfaces)-1;i>=0;i--) {
+    if (interfaces[i] == ',') {
+      monitor->ifcs[--numInterfaces].name = STRDUP(&interfaces[i+1]);
+      numInterfaces++;
+      interfaces[i] = '\0';
+    }
   }
-  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;
+  monitor->ifcs[--numInterfaces].name = STRDUP(interfaces);
+  GE_ASSERT(ectx, numInterfaces == 0);
+  for (i=0;i<monitor->ifcsSize;i++) {
+    monitor->ifcs[i].last_in = 0;
+    monitor->ifcs[i].last_out = 0;
   }
-  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;
+  FREE(interfaces);
+  monitor->useBasicMethod = basic;
+  GC_get_configuration_value_number(cfg,
+                                   "LOAD",
+                                   "MAXNETDOWNBPSTOTAL",
+                                   0,
+                                   (unsigned long long)-1,
+                                   50000,
+                                   &monitor->maxNetDownBPS);
+  GC_get_configuration_value_number(cfg,
+                                   "LOAD",
+                                   "MAXNETUPBPSTOTAL",
+                                   0,
+                                   (unsigned long long)-1,
+                                   50000,
+                                   &monitor->maxNetUpBPS);
+  MUTEX_UNLOCK(monitor->statusMutex);
+  return OK;
 }
 
 /**
@@ -714,7 +341,8 @@
  * @return the network load as a percentage of allowed
  *        (100 is equivalent to full load)
  */
-int getNetworkLoadDown() {
+int os_network_monitor_get_load(struct LoadMonitor * monitor,
+                               NetworkDirection dir) {
   static unsigned long long overload;
   static unsigned long long lastSum;
   static cron_t lastCall;
@@ -724,12 +352,16 @@
   unsigned long long currentLoadSum;
   int i;
   int ret;
+  int weight;
 
-  MUTEX_LOCK(&statusMutex);
-  currentLoadSum = globalTrafficBetweenProc.last_in;
-  for (i=0;i<ifcsSize;i++)
-    currentLoadSum += ifcs[i].last_in;
-  cronTime(&now);
+  MUTEX_LOCK(monitor->statusMutex);
+  now = get_time();
+  if ( (monitor->useBasicMethod == NO) &&
+       (now - lastCall > 10 * cronSECONDS) ) 
+    updateInterfaceTraffic(monitor);
+  currentLoadSum = monitor->globalTrafficBetweenProc.last_in;
+  for (i=0;i<monitor->ifcsSize;i++)
+    currentLoadSum += monitor->ifcs[i].last_in;
   if ( (lastSum > currentLoadSum) ||
        (lastSum == 0) ||
        (now < lastCall) ) {
@@ -738,24 +370,26 @@
        this datapoint.  So we return -1 -- AND reset lastSum / lastCall. */
     lastSum = currentLoadSum;
     lastCall = now;
-    MUTEX_UNLOCK(&statusMutex);
+    MUTEX_UNLOCK(monitor->statusMutex);
     return -1;
   }
-  if (maxNetDownBPS == 0) {
-    MUTEX_UNLOCK(&statusMutex);
+  if (monitor->maxNetDownBPS == 0) {
+    MUTEX_UNLOCK(monitor->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);
+
+  maxExpect = (now - lastCall) * monitor->maxNetDownBPS / cronSECONDS;
+  if (now - lastCall < 5 * cronSECONDS) {
+    /* return weighted average between last return value and
+       load in the last interval */
+    weight = (now - lastCall) * 100 / (5 * cronSECONDS); /* how close are we 
to lastCall? */
+    ret = (lastValue * (100-weight) + weight * (currentLoadSum - lastSum) / 
maxExpect) / 2;
+    MUTEX_UNLOCK(monitor->statusMutex);
     return ret;
   }
   currentLoadSum -= lastSum;
   lastSum += currentLoadSum;
   currentLoadSum += overload;
-  maxExpect = ( (now - lastCall) * maxNetDownBPS ) / cronSECONDS;
   lastCall = now;
   if (currentLoadSum < maxExpect)
     overload = 0;
@@ -763,111 +397,60 @@
     overload = currentLoadSum - maxExpect;
   lastValue = currentLoadSum * 100 / maxExpect;
   ret = lastValue;
-  MUTEX_UNLOCK(&statusMutex);
+  MUTEX_UNLOCK(monitor->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;
+struct LoadMonitor * 
+os_network_monitor_create(struct GE_Context * ectx,
+                         struct GC_Configuration * cfg) {
+  struct LoadMonitor * monitor;
 
-  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() {
+  monitor = MALLOC(sizeof(struct LoadMonitor));
+  memset(monitor,
+        0,
+        sizeof(struct LoadMonitor));
+  monitor->ectx = ectx;
+  monitor->cfg = cfg;
 #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);
+  monitor->proc_net_dev = fopen(PROC_NET_DEV, "r");
+  if (NULL == monitor->proc_net_dev)
+    GE_LOG_STRERROR_FILE(ectx,
+                        GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
+                        "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();
+  monitor->statusMutex = MUTEX_CREATE(NO);
+  if (OK != resetStatusCalls(monitor,
+                            cfg,
+                            ectx,
+                            NULL,
+                            NULL)) {
+    os_network_monitor_destroy(monitor);
+    return NULL;
+  }
+  GC_attach_change_listener(cfg,
+                           &resetStatusCalls,
+                           monitor);
+  return monitor;
 }
 
-/**
- * Shutdown the status calls module.
- */
-void doneStatusCalls() {
+void os_network_monitor_destroy(struct LoadMonitor * monitor) {
   int i;
 
-  if (initialized_ == NO)
-    return;
-  unregisterConfigurationUpdateCallback(&resetStatusCalls);
-  delCronJob(&cronLoadUpdate,
-            10 * cronSECONDS,
-            NULL);
-  initialized_ = NO;
+  GC_detach_change_listener(monitor->cfg,
+                           &resetStatusCalls,
+                           monitor);
 #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;
-  }
+  if (monitor->proc_net_dev != NULL) 
+    fclose(monitor->proc_net_dev);
 #endif
-  for (i=0;i<ifcsSize;i++)
-    FREE(ifcs[i].name);
-  GROW(ifcs,
-       ifcsSize,
+  for (i=0;i<monitor->ifcsSize;i++)
+    FREE(monitor->ifcs[i].name);
+  GROW(monitor->ifcs,
+       monitor->ifcsSize,
        0);
-  MUTEX_DESTROY(&statusMutex);
+  MUTEX_DESTROY(monitor->statusMutex);
 }
 
-
 /* end of statuscalls.c */

Modified: GNUnet/src/util/threads/Makefile.am
===================================================================
--- GNUnet/src/util/threads/Makefile.am 2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/threads/Makefile.am 2006-06-24 20:37:52 UTC (rev 3037)
@@ -9,7 +9,8 @@
  mutex.c \
  pthread.c \
  semaphore.c \
- shutdown.c 
+ shutdown.c \
+ time.c
 
 check_PROGRAMS = \
  semaphoretest \

Added: GNUnet/src/util/threads/time.c
===================================================================
--- GNUnet/src/util/threads/time.c      2006-06-24 16:34:56 UTC (rev 3036)
+++ GNUnet/src/util/threads/time.c      2006-06-24 20:37:52 UTC (rev 3037)
@@ -0,0 +1,46 @@
+/*
+     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/time.c
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util_threads.h"
+
+/**
+ * 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)).
+ *
+ * @return the current time
+ */
+cron_t get_time() {
+  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
+  return (((cron_t)tv.tv_sec) * 1000) + (tv.tv_usec / 1000 / 1000);
+}





reply via email to

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