gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r6162 - in GNUnet: . libltdl src/applications src/applicati


From: gnunet
Subject: [GNUnet-SVN] r6162 - in GNUnet: . libltdl src/applications src/applications/fs src/applications/fs/ecrs src/applications/fs/gap src/applications/fs/lib src/applications/stats src/include src/server
Date: Wed, 6 Feb 2008 00:11:29 -0700 (MST)

Author: grothoff
Date: 2008-02-06 00:11:29 -0700 (Wed, 06 Feb 2008)
New Revision: 6162

Removed:
   GNUnet/src/applications/gap/
   GNUnet/src/include/gnunet_gap_service.h
Modified:
   GNUnet/ChangeLog
   GNUnet/configure.ac
   GNUnet/libltdl/ltdl.c
   GNUnet/libltdl/ltmain.sh
   GNUnet/src/applications/Makefile.am
   GNUnet/src/applications/fs/Makefile.am
   GNUnet/src/applications/fs/ecrs/download.c
   GNUnet/src/applications/fs/ecrs/search.c
   GNUnet/src/applications/fs/gap/plan.c
   GNUnet/src/applications/fs/lib/fslib.c
   GNUnet/src/applications/stats/clientapi.c
   GNUnet/src/include/Makefile.am
   GNUnet/src/include/ecrs_core.h
   GNUnet/src/include/fs.h
   GNUnet/src/include/gnunet_core.h
   GNUnet/src/include/gnunet_dht_service.h
   GNUnet/src/include/gnunet_fs_lib.h
   GNUnet/src/include/gnunet_protocols.h
   GNUnet/src/server/core.c
   GNUnet/todo
Log:
uploading draft of new gap/fs code

Modified: GNUnet/ChangeLog
===================================================================
--- GNUnet/ChangeLog    2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/ChangeLog    2008-02-06 07:11:29 UTC (rev 6162)
@@ -1,3 +1,14 @@
+Sun Feb  3 13:17:09 MST 2008
+       Dramatic changes to the GAP implementation (breaking
+       protocol compatibility).  Essentially, we can save
+       a few bytes in each reply.  More importantly, the new
+       code allows the searching client to specify a set of
+       replies that are not desired (hopefully helping to
+       dramatically increase the diversity of search replies
+       obtained over time).  Note that the actual encoding
+       and databases are not affected (just P2P protocol).
+       The update is not complete yet, but should compile.
+
 Tue Jan  8 20:07:20 MST 2008
        Added option for testing ("make check") to use weak(er)
        PRNG for key generation (thanks to Werner Koch for 

Modified: GNUnet/configure.ac
===================================================================
--- GNUnet/configure.ac 2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/configure.ac 2008-02-06 07:11:29 UTC (rev 6162)
@@ -863,11 +863,10 @@
 src/applications/fs/ecrs/Makefile
 src/applications/fs/fsui/Makefile
 src/applications/fs/lib/Makefile
-src/applications/fs/module/Makefile
+src/applications/fs/gap/Makefile
 src/applications/fs/namespace/Makefile
 src/applications/fs/uritrack/Makefile
 src/applications/fs/tools/Makefile
-src/applications/gap/Makefile
 src/applications/getoption/Makefile
 src/applications/identity/Makefile
 src/applications/kvstore_sqlite/Makefile

Modified: GNUnet/libltdl/ltdl.c
===================================================================
--- GNUnet/libltdl/ltdl.c       2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/libltdl/ltdl.c       2008-02-06 07:11:29 UTC (rev 6162)
@@ -1,4560 +0,0 @@
-/* ltdl.c -- system independent dlopen wrapper
-   Copyright (C) 1998, 1999, 2000, 2004, 2005  Free Software Foundation, Inc.
-   Originally by Thomas Tanner <address@hidden>
-   This file is part of GNU Libtool.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-As a special exception to the GNU Lesser General Public License,
-if you distribute this file as part of a program or library that
-is built using GNU libtool, you may include it under the same
-distribution terms that you use for the rest of that program.
-
-This library 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301  USA
-
-*/
-
-#if HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#if HAVE_UNISTD_H
-#  include <unistd.h>
-#endif
-
-#if HAVE_STDIO_H
-#  include <stdio.h>
-#endif
-
-/* Include the header defining malloc.  On K&R C compilers,
-   that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>.  */
-#if HAVE_STDLIB_H
-#  include <stdlib.h>
-#else
-#  if HAVE_GNUNET_malloc_H
-#    include <malloc.h>
-#  endif
-#endif
-
-#if HAVE_STRING_H
-#  include <string.h>
-#else
-#  if HAVE_STRINGS_H
-#    include <strings.h>
-#  endif
-#endif
-
-#if HAVE_CTYPE_H
-#  include <ctype.h>
-#endif
-
-#if HAVE_MEMORY_H
-#  include <memory.h>
-#endif
-
-#if HAVE_ERRNO_H
-#  include <errno.h>
-#endif
-
-
-#ifndef __WINDOWS__
-#  ifdef __WIN32__
-#    define __WINDOWS__
-#  endif
-#endif
-
-
-#undef LT_USE_POSIX_DIRENT
-#ifdef HAVE_CLOSEDIR
-#  ifdef HAVE_OPENDIR
-#    ifdef HAVE_READDIR
-#      ifdef HAVE_DIRENT_H
-#        define LT_USE_POSIX_DIRENT
-#      endif /* HAVE_DIRENT_H */
-#    endif /* HAVE_READDIR */
-#  endif /* HAVE_OPENDIR */
-#endif /* HAVE_CLOSEDIR */
-
-
-#undef LT_USE_WINDOWS_DIRENT_EMULATION
-#ifndef LT_USE_POSIX_DIRENT
-#  ifdef __WINDOWS__
-#    define LT_USE_WINDOWS_DIRENT_EMULATION
-#  endif /* __WINDOWS__ */
-#endif /* LT_USE_POSIX_DIRENT */
-
-
-#ifdef LT_USE_POSIX_DIRENT
-#  include <dirent.h>
-#  define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
-#else
-#  ifdef LT_USE_WINDOWS_DIRENT_EMULATION
-#    define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
-#  else
-#    define dirent direct
-#    define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
-#    if HAVE_SYS_NDIR_H
-#      include <sys/ndir.h>
-#    endif
-#    if HAVE_SYS_DIR_H
-#      include <sys/dir.h>
-#    endif
-#    if HAVE_NDIR_H
-#      include <ndir.h>
-#    endif
-#  endif
-#endif
-
-#if HAVE_ARGZ_H
-#  include <argz.h>
-#endif
-
-#if HAVE_ASSERT_H
-#  include <assert.h>
-#else
-#  define assert(arg)  ((void) 0)
-#endif
-
-#include "ltdl.h"
-
-#if WITH_DGNUNET_malloc
-#  include <dmalloc.h>
-#endif
-
-
-
-
-/* --- WINDOWS SUPPORT --- */
-
-
-#ifdef DLL_EXPORT
-#  define LT_GLOBAL_DATA       __declspec(dllexport)
-#else
-#  define LT_GLOBAL_DATA
-#endif
-
-/* fopen() mode flags for reading a text file */
-#undef LT_READTEXT_MODE
-#ifdef __WINDOWS__
-#  define LT_READTEXT_MODE "rt"
-#else
-#  define LT_READTEXT_MODE "r"
-#endif
-
-#ifdef LT_USE_WINDOWS_DIRENT_EMULATION
-
-#include <windows.h>
-
-#define dirent lt_dirent
-#define DIR lt_DIR
-
-struct dirent
-{
-  char d_name[2048];
-  int d_namlen;
-};
-
-typedef struct _DIR
-{
-  HANDLE hSearch;
-  WIN32_FIND_DATA Win32FindData;
-  BOOL firsttime;
-  struct dirent file_info;
-} DIR;
-
-#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
-
-
-/* --- MANIFEST CONSTANTS --- */
-
-
-/* Standard libltdl search path environment variable name  */
-#undef  LTDL_SEARCHPATH_VAR
-#define LTDL_SEARCHPATH_VAR    "LTDL_LIBRARY_PATH"
-
-/* Standard libtool archive file extension.  */
-#undef  LTDL_ARCHIVE_EXT
-#define LTDL_ARCHIVE_EXT       ".la"
-
-/* max. filename length */
-#ifndef LT_FILENAME_MAX
-#  define LT_FILENAME_MAX      1024
-#endif
-
-/* This is the maximum symbol size that won't require malloc/free */
-#undef LT_SYMBOL_LENGTH
-#define LT_SYMBOL_LENGTH       128
-
-/* This accounts for the _LTX_ separator */
-#undef LT_SYMBOL_OVERHEAD
-#define LT_SYMBOL_OVERHEAD     5
-
-
-
-
-/* --- MEMORY HANDLING --- */
-
-
-/* These are the functions used internally.  In addition to making
-   use of the associated function pointers above, they also perform
-   error handling.  */
-static char *lt_estrdup LT_PARAMS ((const char *str));
-static lt_ptr lt_emalloc LT_PARAMS ((size_t size));
-static lt_ptr lt_erealloc LT_PARAMS ((lt_ptr addr, size_t size));
-
-/* static lt_ptr rpl_realloc   LT_PARAMS((lt_ptr ptr, size_t size)); */
-#define rpl_realloc realloc
-
-/* These are the pointers that can be changed by the caller:  */
-LT_GLOBAL_DATA
-lt_ptr (*lt_dlmalloc)
-LT_PARAMS ((size_t size)) = (lt_ptr (*)LT_PARAMS ((size_t))) malloc;
-     LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc)
-  LT_PARAMS ((lt_ptr ptr, size_t size)) =
-  (lt_ptr (*)LT_PARAMS ((lt_ptr, size_t))) rpl_realloc;
-     LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS ((lt_ptr ptr)) =
-  (void (*)LT_PARAMS ((lt_ptr))) free;
-
-/* The following macros reduce the amount of typing needed to cast
-   assigned memory.  */
-#if WITH_DGNUNET_malloc
-
-#define LT_DLGNUNET_malloc(tp, n)      ((tp *) xmalloc ((n) * sizeof(tp)))
-#define LT_DLGNUNET_realloc(tp, p, n)  ((tp *) xrealloc ((p), (n) * 
sizeof(tp)))
-#define LT_DLGNUNET_free(p)                                            \
-       LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
-
-#define LT_EGNUNET_malloc(tp, n)       ((tp *) xmalloc ((n) * sizeof(tp)))
-#define LT_EGNUNET_realloc(tp, p, n)   ((tp *) xrealloc ((p), (n) * 
sizeof(tp)))
-
-#else
-
-#define LT_DLGNUNET_malloc(tp, n)      ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
-#define LT_DLGNUNET_realloc(tp, p, n)  ((tp *) lt_dlrealloc ((p), (n) * 
sizeof(tp)))
-#define LT_DLGNUNET_free(p)                                            \
-       LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
-
-#define LT_EGNUNET_malloc(tp, n)       ((tp *) lt_emalloc ((n) * sizeof(tp)))
-#define LT_EGNUNET_realloc(tp, p, n)   ((tp *) lt_erealloc ((p), (n) * 
sizeof(tp)))
-
-#endif
-
-#define LT_DLMEM_REASSIGN(p, q)                        LT_STMT_START { \
-       if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; }   \
-                                               } LT_STMT_END
-
-
-/* --- REPLACEMENT FUNCTIONS --- */
-
-
-#undef strdup
-#define strdup rpl_strdup
-
-     static char *strdup LT_PARAMS ((const char *str));
-
-     static char *strdup (str)
-     const char *str;
-{
-  char *tmp = 0;
-
-  if (str)
-    {
-      tmp = LT_DLGNUNET_malloc (char, 1 + strlen (str));
-      if (tmp)
-        {
-          strcpy (tmp, str);
-        }
-    }
-
-  return tmp;
-}
-
-
-#if ! HAVE_STRCMP
-
-#undef strcmp
-#define strcmp rpl_strcmp
-
-static int strcmp LT_PARAMS ((const char *str1, const char *str2));
-
-static int
-strcmp (str1, str2)
-     const char *str1;
-     const char *str2;
-{
-  if (str1 == str2)
-    return 0;
-  if (str1 == 0)
-    return -1;
-  if (str2 == 0)
-    return 1;
-
-  for (; *str1 && *str2; ++str1, ++str2)
-    {
-      if (*str1 != *str2)
-        break;
-    }
-
-  return (int) (*str1 - *str2);
-}
-#endif
-
-
-#if ! HAVE_STRCHR
-
-#  if HAVE_INDEX
-#    define strchr index
-#  else
-#    define strchr rpl_strchr
-
-static const char *strchr LT_PARAMS ((const char *str, int ch));
-
-static const char *
-strchr (str, ch)
-     const char *str;
-     int ch;
-{
-  const char *p;
-
-  for (p = str; *p != (char) ch && *p != LT_EOS_CHAR; ++p)
-     /*NOWORK*/;
-
-  return (*p == (char) ch) ? p : 0;
-}
-
-#  endif
-#endif /* !HAVE_STRCHR */
-
-
-#if ! HAVE_STRRCHR
-
-#  if HAVE_RINDEX
-#    define strrchr rindex
-#  else
-#    define strrchr rpl_strrchr
-
-static const char *strrchr LT_PARAMS ((const char *str, int ch));
-
-static const char *
-strrchr (str, ch)
-     const char *str;
-     int ch;
-{
-  const char *p, *q = 0;
-
-  for (p = str; *p != LT_EOS_CHAR; ++p)
-    {
-      if (*p == (char) ch)
-        {
-          q = p;
-        }
-    }
-
-  return q;
-}
-
-# endif
-#endif
-
-/* NOTE:  Neither bcopy nor the memcpy implementation below can
-          reliably handle copying in overlapping areas of memory.  Use
-          memmove (for which there is a fallback implmentation below)
-         if you need that behaviour.  */
-#if ! HAVE_MEMCPY
-
-#  if HAVE_BCOPY
-#    define memcpy(dest, src, size)    bcopy (src, dest, size)
-#  else
-#    define memcpy rpl_memcpy
-
-static lt_ptr memcpy LT_PARAMS ((lt_ptr dest, const lt_ptr src, size_t size));
-
-static lt_ptr
-memcpy (dest, src, size)
-     lt_ptr dest;
-     const lt_ptr src;
-     size_t size;
-{
-  const char *s = src;
-  char *d = dest;
-  size_t i = 0;
-
-  for (i = 0; i < size; ++i)
-    {
-      d[i] = s[i];
-    }
-
-  return dest;
-}
-
-#  endif /* !HAVE_BCOPY */
-#endif /* !HAVE_MEMCPY */
-
-#if ! HAVE_MEMMOVE
-#  define memmove rpl_memmove
-
-static lt_ptr memmove
-LT_PARAMS ((lt_ptr dest, const lt_ptr src, size_t size));
-
-static lt_ptr
-memmove (dest, src, size)
-     lt_ptr dest;
-     const lt_ptr src;
-     size_t size;
-{
-  const char *s = src;
-  char *d = dest;
-  size_t i;
-
-  if (d < s)
-    for (i = 0; i < size; ++i)
-      {
-        d[i] = s[i];
-      }
-  else if (d > s && size > 0)
-    for (i = size - 1;; --i)
-      {
-        d[i] = s[i];
-        if (i == 0)
-          break;
-      }
-
-  return dest;
-}
-
-#endif /* !HAVE_MEMMOVE */
-
-#ifdef LT_USE_WINDOWS_DIRENT_EMULATION
-
-static void closedir LT_PARAMS ((DIR * entry));
-
-static void
-closedir (entry)
-     DIR *entry;
-{
-  assert (entry != (DIR *) NULL);
-  FindClose (entry->hSearch);
-  lt_dlfree ((lt_ptr) entry);
-}
-
-
-static DIR *opendir LT_PARAMS ((const char *path));
-
-static DIR *
-opendir (path)
-     const char *path;
-{
-  char file_specification[LT_FILENAME_MAX];
-  DIR *entry;
-
-  assert (path != (char *) NULL);
-  /* allow space for: path + '\\' '\\' '*' '.' '*' + '\0' */
-  (void) strncpy (file_specification, path, LT_FILENAME_MAX - 6);
-  file_specification[LT_FILENAME_MAX - 6] = LT_EOS_CHAR;
-  (void) strcat (file_specification, "\\");
-  entry = LT_DLGNUNET_malloc (DIR, sizeof (DIR));
-  if (entry != (DIR *) 0)
-    {
-      entry->firsttime = TRUE;
-      entry->hSearch =
-        FindFirstFile (file_specification, &entry->Win32FindData);
-    }
-  if (entry->hSearch == INVALID_HANDLE_VALUE)
-    {
-      (void) strcat (file_specification, "\\*.*");
-      entry->hSearch =
-        FindFirstFile (file_specification, &entry->Win32FindData);
-      if (entry->hSearch == INVALID_HANDLE_VALUE)
-        {
-          LT_DLGNUNET_free (entry);
-          return (DIR *) 0;
-        }
-    }
-  return (entry);
-}
-
-
-static struct dirent *readdir LT_PARAMS ((DIR * entry));
-
-static struct dirent *
-readdir (entry)
-     DIR *entry;
-{
-  int status;
-
-  if (entry == (DIR *) 0)
-    return ((struct dirent *) 0);
-  if (!entry->firsttime)
-    {
-      status = FindNextFile (entry->hSearch, &entry->Win32FindData);
-      if (status == 0)
-        return ((struct dirent *) 0);
-    }
-  entry->firsttime = FALSE;
-  (void) strncpy (entry->file_info.d_name, entry->Win32FindData.cFileName,
-                  LT_FILENAME_MAX - 1);
-  entry->file_info.d_name[LT_FILENAME_MAX - 1] = LT_EOS_CHAR;
-  entry->file_info.d_namlen = strlen (entry->file_info.d_name);
-  return (&entry->file_info);
-}
-
-#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
-
-/* According to Alexandre Oliva <address@hidden>,
-    ``realloc is not entirely portable''
-   In any case we want to use the allocator supplied by the user without
-   burdening them with an lt_dlrealloc function pointer to maintain.
-   Instead implement our own version (with known boundary conditions)
-   using lt_dlmalloc and lt_dlfree. */
-
-/* #undef realloc
-   #define realloc rpl_realloc
-*/
-#if 0
-  /* You can't (re)define realloc unless you also (re)define malloc.
-     Right now, this code uses the size of the *destination* to decide
-     how much to copy.  That's not right, but you can't know the size
-     of the source unless you know enough about, or wrote malloc.  So
-     this code is disabled... */
-
-static lt_ptr
-realloc (ptr, size)
-     lt_ptr ptr;
-     size_t size;
-{
-  if (size == 0)
-    {
-      /* For zero or less bytes, free the original memory */
-      if (ptr != 0)
-        {
-          lt_dlfree (ptr);
-        }
-
-      return (lt_ptr) 0;
-    }
-  else if (ptr == 0)
-    {
-      /* Allow reallocation of a NULL pointer.  */
-      return lt_dlmalloc (size);
-    }
-  else
-    {
-      /* Allocate a new block, copy and free the old block.  */
-      lt_ptr mem = lt_dlmalloc (size);
-
-      if (mem)
-        {
-          memcpy (mem, ptr, size);
-          lt_dlfree (ptr);
-        }
-
-      /* Note that the contents of PTR are not damaged if there is
-         insufficient memory to realloc.  */
-      return mem;
-    }
-}
-#endif
-
-
-#if ! HAVE_ARGZ_GNUNET_array_append
-#  define argz_append rpl_argz_append
-
-static error_t argz_append LT_PARAMS ((char **pargz, size_t * pargz_len,
-                                       const char *buf, size_t buf_len));
-
-static error_t
-argz_append (pargz, pargz_len, buf, buf_len)
-     char **pargz;
-     size_t *pargz_len;
-     const char *buf;
-     size_t buf_len;
-{
-  size_t argz_len;
-  char *argz;
-
-  assert (pargz);
-  assert (pargz_len);
-  assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
-
-  /* If nothing needs to be appended, no more work is required.  */
-  if (buf_len == 0)
-    return 0;
-
-  /* Ensure there is enough room to append BUF_LEN.  */
-  argz_len = *pargz_len + buf_len;
-  argz = LT_DLGNUNET_realloc (char, *pargz, argz_len);
-  if (!argz)
-    return ENOMEM;
-
-  /* Copy characters from BUF after terminating '\0' in ARGZ.  */
-  memcpy (argz + *pargz_len, buf, buf_len);
-
-  /* Assign new values.  */
-  *pargz = argz;
-  *pargz_len = argz_len;
-
-  return 0;
-}
-#endif /* !HAVE_ARGZ_GNUNET_array_append */
-
-
-#if ! HAVE_ARGZ_CREATE_SEP
-#  define argz_create_sep rpl_argz_create_sep
-
-static error_t argz_create_sep LT_PARAMS ((const char *str, int delim,
-                                           char **pargz, size_t * pargz_len));
-
-static error_t
-argz_create_sep (str, delim, pargz, pargz_len)
-     const char *str;
-     int delim;
-     char **pargz;
-     size_t *pargz_len;
-{
-  size_t argz_len;
-  char *argz = 0;
-
-  assert (str);
-  assert (pargz);
-  assert (pargz_len);
-
-  /* Make a copy of STR, but replacing each occurrence of
-     DELIM with '\0'.  */
-  argz_len = 1 + LT_STRLEN (str);
-  if (argz_len)
-    {
-      const char *p;
-      char *q;
-
-      argz = LT_DLGNUNET_malloc (char, argz_len);
-      if (!argz)
-        return ENOMEM;
-
-      for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
-        {
-          if (*p == delim)
-            {
-              /* Ignore leading delimiters, and fold consecutive
-                 delimiters in STR into a single '\0' in ARGZ.  */
-              if ((q > argz) && (q[-1] != LT_EOS_CHAR))
-                *q++ = LT_EOS_CHAR;
-              else
-                --argz_len;
-            }
-          else
-            *q++ = *p;
-        }
-      /* Copy terminating LT_EOS_CHAR.  */
-      *q = *p;
-    }
-
-  /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory.  */
-  if (!argz_len)
-    LT_DLGNUNET_free (argz);
-
-  /* Assign new values.  */
-  *pargz = argz;
-  *pargz_len = argz_len;
-
-  return 0;
-}
-#endif /* !HAVE_ARGZ_CREATE_SEP */
-
-
-#if ! HAVE_ARGZ_INSERT
-#  define argz_insert rpl_argz_insert
-
-static error_t argz_insert LT_PARAMS ((char **pargz, size_t * pargz_len,
-                                       char *before, const char *entry));
-
-static error_t
-argz_insert (pargz, pargz_len, before, entry)
-     char **pargz;
-     size_t *pargz_len;
-     char *before;
-     const char *entry;
-{
-  assert (pargz);
-  assert (pargz_len);
-  assert (entry && *entry);
-
-  /* No BEFORE address indicates ENTRY should be inserted after the
-     current last element.  */
-  if (!before)
-    return argz_append (pargz, pargz_len, entry, 1 + LT_STRLEN (entry));
-
-  /* This probably indicates a programmer error, but to preserve
-     semantics, scan back to the start of an entry if BEFORE points
-     into the middle of it.  */
-  while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
-    --before;
-
-  {
-    size_t entry_len = 1 + LT_STRLEN (entry);
-    size_t argz_len = *pargz_len + entry_len;
-    size_t offset = before - *pargz;
-    char *argz = LT_DLGNUNET_realloc (char, *pargz, argz_len);
-
-    if (!argz)
-      return ENOMEM;
-
-    /* Make BEFORE point to the equivalent offset in ARGZ that it
-       used to have in *PARGZ incase realloc() moved the block.  */
-    before = argz + offset;
-
-    /* Move the ARGZ entries starting at BEFORE up into the new
-       space at the end -- making room to copy ENTRY into the
-       resulting gap.  */
-    memmove (before + entry_len, before, *pargz_len - offset);
-    memcpy (before, entry, entry_len);
-
-    /* Assign new values.  */
-    *pargz = argz;
-    *pargz_len = argz_len;
-  }
-
-  return 0;
-}
-#endif /* !HAVE_ARGZ_INSERT */
-
-
-#if ! HAVE_ARGZ_NEXT
-#  define argz_next rpl_argz_next
-
-static char *argz_next LT_PARAMS ((char *argz, size_t argz_len,
-                                   const char *entry));
-
-static char *
-argz_next (argz, argz_len, entry)
-     char *argz;
-     size_t argz_len;
-     const char *entry;
-{
-  assert ((argz && argz_len) || (!argz && !argz_len));
-
-  if (entry)
-    {
-      /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
-         within the ARGZ vector.  */
-      assert ((!argz && !argz_len)
-              || ((argz <= entry) && (entry < (argz + argz_len))));
-
-      /* Move to the char immediately after the terminating
-         '\0' of ENTRY.  */
-      entry = 1 + strchr (entry, LT_EOS_CHAR);
-
-      /* Return either the new ENTRY, or else NULL if ARGZ is
-         exhausted.  */
-      return (entry >= argz + argz_len) ? 0 : (char *) entry;
-    }
-  else
-    {
-      /* This should probably be flagged as a programmer error,
-         since starting an argz_next loop with the iterator set
-         to ARGZ is safer.  To preserve semantics, handle the NULL
-         case by returning the start of ARGZ (if any).  */
-      if (argz_len > 0)
-        return argz;
-      else
-        return 0;
-    }
-}
-#endif /* !HAVE_ARGZ_NEXT */
-
-
-
-#if ! HAVE_ARGZ_STRINGIFY
-#  define argz_stringify rpl_argz_stringify
-
-static void argz_stringify LT_PARAMS ((char *argz, size_t argz_len, int sep));
-
-static void
-argz_stringify (argz, argz_len, sep)
-     char *argz;
-     size_t argz_len;
-     int sep;
-{
-  assert ((argz && argz_len) || (!argz && !argz_len));
-
-  if (sep)
-    {
-      --argz_len;               /* don't stringify the terminating EOS */
-      while (--argz_len > 0)
-        {
-          if (argz[argz_len] == LT_EOS_CHAR)
-            argz[argz_len] = sep;
-        }
-    }
-}
-#endif /* !HAVE_ARGZ_STRINGIFY */
-
-
-
-
-/* --- TYPE DEFINITIONS -- */
-
-
-/* This type is used for the array of caller data sets in each handler. */
-typedef struct
-{
-  lt_dlcaller_id key;
-  lt_ptr data;
-} lt_caller_data;
-
-
-
-
-/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
-
-
-/* Extract the diagnostic strings from the error table macro in the same
-   order as the enumerated indices in ltdl.h. */
-
-static const char *lt_dlerror_strings[] = {
-#define LT_ERROR(name, diagnostic)     (diagnostic),
-  lt_dlerror_table
-#undef LT_ERROR
-  0
-};
-
-/* This structure is used for the list of registered loaders. */
-struct lt_dlloader
-{
-  struct lt_dlloader *next;
-  const char *loader_name;      /* identifying name for each loader */
-  const char *sym_prefix;       /* prefix for symbols */
-  lt_module_open *module_open;
-  lt_module_close *module_close;
-  lt_find_sym *find_sym;
-  lt_dlloader_exit *dlloader_exit;
-  lt_user_data dlloader_data;
-};
-
-struct lt_dlhandle_struct
-{
-  struct lt_dlhandle_struct *next;
-  lt_dlloader *loader;          /* dlopening interface */
-  lt_dlinfo info;
-  int depcount;                 /* number of dependencies */
-  lt_dlhandle *deplibs;         /* dependencies */
-  lt_module module;             /* system module handle */
-  lt_ptr system;                /* system specific data */
-  lt_caller_data *caller_data;  /* per caller associated data */
-  int flags;                    /* various boolean stats */
-};
-
-/* Various boolean flags can be stored in the flags field of an
-   lt_dlhandle_struct... */
-#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
-#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
-
-#define LT_DLRESIDENT_FLAG         (0x01 << 0)
-/* ...add more flags here... */
-
-#define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
-
-
-#define LT_DLSTRERROR(name)    lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
-
-static const char objdir[] = LTDL_OBJDIR;
-static const char archive_ext[] = LTDL_ARCHIVE_EXT;
-#ifdef LTDL_SHLIB_EXT
-static const char shlib_ext[] = LTDL_SHLIB_EXT;
-#endif
-#ifdef LTDL_SYSSEARCHPATH
-static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
-#endif
-
-
-
-
-/* --- GNUNET_Mutex LOCKING --- */
-
-
-/* Macros to make it easier to run the lock functions only if they have
-   been registered.  The reason for the complicated lock macro is to
-   ensure that the stored error message from the last error is not
-   accidentally erased if the current function doesn't generate an
-   error of its own.  */
-#define LT_DLGNUNET_mutex_lock()                       LT_STMT_START { \
-       if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)();    \
-                                               } LT_STMT_END
-#define LT_DLGNUNET_mutex_unlock()                     LT_STMT_START { \
-       if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
-                                               } LT_STMT_END
-#define LT_DLMUTEX_SETERROR(errormsg)          LT_STMT_START { \
-       if (lt_dlmutex_seterror_func)                           \
-               (*lt_dlmutex_seterror_func) (errormsg);         \
-       else    lt_dllast_error = (errormsg);   } LT_STMT_END
-#define LT_DLMUTEX_GETERROR(errormsg)          LT_STMT_START { \
-       if (lt_dlmutex_seterror_func)                           \
-               (errormsg) = (*lt_dlmutex_geterror_func) ();    \
-       else    (errormsg) = lt_dllast_error;   } LT_STMT_END
-
-/* The mutex functions stored here are global, and are necessarily the
-   same for all threads that wish to share access to libltdl.  */
-static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
-static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
-static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
-static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
-static const char *lt_dllast_error = 0;
-
-
-/* Either set or reset the mutex functions.  Either all the arguments must
-   be valid functions, or else all can be NULL to turn off locking entirely.
-   The registered functions should be manipulating a static global lock
-   from the lock() and unlock() callbacks, which needs to be reentrant.  */
-int
-lt_dlmutex_register (lock, unlock, seterror, geterror)
-     lt_dlmutex_lock *lock;
-     lt_dlmutex_unlock *unlock;
-     lt_dlmutex_seterror *seterror;
-     lt_dlmutex_geterror *geterror;
-{
-  lt_dlmutex_unlock *old_unlock = unlock;
-  int errors = 0;
-
-  /* Lock using the old lock() callback, if any.  */
-  LT_DLGNUNET_mutex_lock ();
-
-  if ((lock && unlock && seterror && geterror)
-      || !(lock || unlock || seterror || geterror))
-    {
-      lt_dlmutex_lock_func = lock;
-      lt_dlmutex_unlock_func = unlock;
-      lt_dlmutex_geterror_func = geterror;
-    }
-  else
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
-      ++errors;
-    }
-
-  /* Use the old unlock() callback we saved earlier, if any.  Otherwise
-     record any errors using internal storage.  */
-  if (old_unlock)
-    (*old_unlock) ();
-
-  /* Return the number of errors encountered during the execution of
-     this function.  */
-  return errors;
-}
-
-
-
-
-/* --- ERROR HANDLING --- */
-
-
-static const char **user_error_strings = 0;
-static int errorcount = LT_ERROR_MAX;
-
-int
-lt_dladderror (diagnostic)
-     const char *diagnostic;
-{
-  int errindex = 0;
-  int result = -1;
-  const char **temp = (const char **) 0;
-
-  assert (diagnostic);
-
-  LT_DLGNUNET_mutex_lock ();
-
-  errindex = errorcount - LT_ERROR_MAX;
-  temp = LT_EGNUNET_realloc (const char *, user_error_strings, 1 + errindex);
-  if (temp)
-    {
-      user_error_strings = temp;
-      user_error_strings[errindex] = diagnostic;
-      result = errorcount++;
-    }
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return result;
-}
-
-int
-lt_dlseterror (errindex)
-     int errindex;
-{
-  int errors = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  if (errindex >= errorcount || errindex < 0)
-    {
-      /* Ack!  Error setting the error message! */
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
-      ++errors;
-    }
-  else if (errindex < LT_ERROR_MAX)
-    {
-      /* No error setting the error message! */
-      LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
-    }
-  else
-    {
-      /* No error setting the error message! */
-      LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
-    }
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-static lt_ptr
-lt_emalloc (size)
-     size_t size;
-{
-  lt_ptr mem = lt_dlmalloc (size);
-  if (size && !mem)
-    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-  return mem;
-}
-
-static lt_ptr
-lt_erealloc (addr, size)
-     lt_ptr addr;
-     size_t size;
-{
-  lt_ptr mem = lt_dlrealloc (addr, size);
-  if (size && !mem)
-    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-  return mem;
-}
-
-static char *
-lt_estrdup (str)
-     const char *str;
-{
-  char *copy = strdup (str);
-  if (LT_STRLEN (str) && !copy)
-    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-  return copy;
-}
-
-
-
-
-/* --- DLOPEN() INTERFACE LOADER --- */
-
-
-#if HAVE_LIBDL
-
-/* dynamic linking with dlopen/dlsym */
-
-#if HAVE_DLFCN_H
-#  include <dlfcn.h>
-#endif
-
-#if HAVE_SYS_DL_H
-#  include <sys/dl.h>
-#endif
-
-/* We may have to define LT_LAZY_OR_NOW in the command line if we
-   find out it does not work in some platform. */
-#ifndef LT_LAZY_OR_NOW
-#  ifdef RTLD_LAZY
-#    define LT_LAZY_OR_NOW     RTLD_LAZY
-#  else
-#    ifdef DL_LAZY
-#      define LT_LAZY_OR_NOW   DL_LAZY
-#    endif
-#  endif /* !RTLD_LAZY */
-#endif
-#ifndef LT_LAZY_OR_NOW
-#  ifdef RTLD_NOW
-#    define LT_LAZY_OR_NOW     RTLD_NOW
-#  else
-#    ifdef DL_NOW
-#      define LT_LAZY_OR_NOW   DL_NOW
-#    endif
-#  endif /* !RTLD_NOW */
-#endif
-#ifndef LT_LAZY_OR_NOW
-#  define LT_LAZY_OR_NOW       0
-#endif /* !LT_LAZY_OR_NOW */
-
-#if HAVE_DLERROR
-#  define DLERROR(arg) dlerror ()
-#else
-#  define DLERROR(arg) LT_DLSTRERROR (arg)
-#endif
-
-static lt_module
-sys_dl_open (loader_data, filename)
-     lt_user_data loader_data;
-     const char *filename;
-{
-  lt_module module = dlopen (filename, LT_LAZY_OR_NOW);
-
-  if (!module)
-    {
-      LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
-    }
-
-  return module;
-}
-
-static int
-sys_dl_close (loader_data, module)
-     lt_user_data loader_data;
-     lt_module module;
-{
-  int errors = 0;
-
-  if (dlclose (module) != 0)
-    {
-      LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
-      ++errors;
-    }
-
-  return errors;
-}
-
-static lt_ptr
-sys_dl_sym (loader_data, module, symbol)
-     lt_user_data loader_data;
-     lt_module module;
-     const char *symbol;
-{
-  lt_ptr address = dlsym (module, symbol);
-
-  if (!address)
-    {
-      LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
-    }
-
-  return address;
-}
-
-static struct lt_user_dlloader sys_dl = {
-#  ifdef NEED_USCORE
-  "_",
-#  else
-  0,
-#  endif
-  sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0
-};
-
-
-#endif /* HAVE_LIBDL */
-
-
-
-/* --- SHL_LOAD() INTERFACE LOADER --- */
-
-#if HAVE_SHL_LOAD
-
-/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
-
-#ifdef HAVE_DL_H
-#  include <dl.h>
-#endif
-
-/* some flags are missing on some systems, so we provide
- * harmless defaults.
- *
- * Mandatory:
- * BIND_IMMEDIATE  - Resolve symbol references when the library is loaded.
- * BIND_DEFERRED   - Delay code symbol resolution until actual reference.
- *
- * Optionally:
- * BIND_FIRST     - Place the library at the head of the symbol search
- *                  order.
- * BIND_NONFATAL   - The default BIND_IMMEDIATE behavior is to treat all
- *                  unsatisfied symbols as fatal.  This flag allows
- *                  binding of unsatisfied code symbols to be deferred
- *                  until use.
- *                  [Perl: For certain libraries, like DCE, deferred
- *                  binding often causes run time problems. Adding
- *                  BIND_NONFATAL to BIND_IMMEDIATE still allows
- *                  unresolved references in situations like this.]
- * BIND_NOSTART           - Do not call the initializer for the shared library
- *                  when the library is loaded, nor on a future call to
- *                  shl_unload().
- * BIND_VERBOSE           - Print verbose messages concerning possible
- *                  unsatisfied symbols.
- *
- * hp9000s700/hp9000s800:
- * BIND_RESTRICTED - Restrict symbols visible by the library to those
- *                  present at library load time.
- * DYNAMIC_PATH           - Allow the loader to dynamically search for the
- *                  library specified by the path argument.
- */
-
-#ifndef        DYNAMIC_PATH
-#  define DYNAMIC_PATH         0
-#endif
-#ifndef        BIND_RESTRICTED
-#  define BIND_RESTRICTED      0
-#endif
-
-#define        LT_BIND_FLAGS   (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
-
-static lt_module
-sys_shl_open (loader_data, filename)
-     lt_user_data loader_data;
-     const char *filename;
-{
-  static shl_t self = (shl_t) 0;
-  lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
-
-  /* Since searching for a symbol against a NULL module handle will also
-     look in everything else that was already loaded and exported with
-     the -E compiler flag, we always cache a handle saved before any
-     modules are loaded.  */
-  if (!self)
-    {
-      lt_ptr address;
-      shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
-    }
-
-  if (!filename)
-    {
-      module = self;
-    }
-  else
-    {
-      module = shl_load (filename, LT_BIND_FLAGS, 0L);
-
-      if (!module)
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
-        }
-    }
-
-  return module;
-}
-
-static int
-sys_shl_close (loader_data, module)
-     lt_user_data loader_data;
-     lt_module module;
-{
-  int errors = 0;
-
-  if (module && (shl_unload ((shl_t) (module)) != 0))
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
-      ++errors;
-    }
-
-  return errors;
-}
-
-static lt_ptr
-sys_shl_sym (loader_data, module, symbol)
-     lt_user_data loader_data;
-     lt_module module;
-     const char *symbol;
-{
-  lt_ptr address = 0;
-
-  /* sys_shl_open should never return a NULL module handle */
-  if (module == (lt_module) 0)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
-    }
-  else
-    if (!shl_findsym ((shl_t *) & module, symbol, TYPE_UNDEFINED, &address))
-    {
-      if (!address)
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
-        }
-    }
-
-  return address;
-}
-
-static struct lt_user_dlloader sys_shl = {
-  0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
-};
-
-#endif /* HAVE_SHL_LOAD */
-
-
-
-
-/* --- LOADLIBRARY() INTERFACE LOADER --- */
-
-#ifdef __WINDOWS__
-
-/* dynamic linking for Win32 */
-
-#include <windows.h>
-
-/* Forward declaration; required to implement handle search below. */
-static lt_dlhandle handles;
-
-static lt_module
-sys_wll_open (loader_data, filename)
-     lt_user_data loader_data;
-     const char *filename;
-{
-  lt_dlhandle cur;
-  lt_module module = 0;
-  const char *errormsg = 0;
-  char *searchname = 0;
-  char *ext;
-  char self_name_buf[MAX_PATH];
-
-  if (!filename)
-    {
-      /* Get the name of main module */
-      *self_name_buf = 0;
-      GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
-      filename = ext = self_name_buf;
-    }
-  else
-    {
-      ext = strrchr (filename, '.');
-    }
-
-  if (ext)
-    {
-      /* FILENAME already has an extension. */
-      searchname = lt_estrdup (filename);
-    }
-  else
-    {
-      /* Append a `.' to stop Windows from adding an
-         implicit `.dll' extension. */
-      searchname = LT_EGNUNET_malloc (char, 2 + LT_STRLEN (filename));
-      if (searchname)
-        sprintf (searchname, "%s.", filename);
-    }
-  if (!searchname)
-    return 0;
-
-  {
-    /* Silence dialog from LoadLibrary on some failures.
-       No way to get the error mode, but to set it,
-       so set it twice to preserve any previous flags. */
-    UINT errormode = SetErrorMode (SEM_FAILCRITICALERRORS);
-    SetErrorMode (errormode | SEM_FAILCRITICALERRORS);
-
-#if defined(__CYGWIN__)
-    {
-      char wpath[MAX_PATH];
-      cygwin_conv_to_full_win32_path (searchname, wpath);
-      module = LoadLibrary (wpath);
-    }
-#else
-    module = LoadLibrary (searchname);
-#endif
-
-    /* Restore the error mode. */
-    SetErrorMode (errormode);
-  }
-
-  LT_DLGNUNET_free (searchname);
-
-  /* libltdl expects this function to fail if it is unable
-     to physically load the library.  Sadly, LoadLibrary
-     will search the loaded libraries for a match and return
-     one of them if the path search load fails.
-
-     We check whether LoadLibrary is returning a handle to
-     an already loaded module, and simulate failure if we
-     find one. */
-  LT_DLGNUNET_mutex_lock ();
-  cur = handles;
-  while (cur)
-    {
-      if (!cur->module)
-        {
-          cur = 0;
-          break;
-        }
-
-      if (cur->module == module)
-        {
-          break;
-        }
-
-      cur = cur->next;
-    }
-  LT_DLGNUNET_mutex_unlock ();
-
-  if (cur || !module)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
-      module = 0;
-    }
-
-  return module;
-}
-
-static int
-sys_wll_close (loader_data, module)
-     lt_user_data loader_data;
-     lt_module module;
-{
-  int errors = 0;
-
-  if (FreeLibrary (module) == 0)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
-      ++errors;
-    }
-
-  return errors;
-}
-
-static lt_ptr
-sys_wll_sym (loader_data, module, symbol)
-     lt_user_data loader_data;
-     lt_module module;
-     const char *symbol;
-{
-  lt_ptr address = GetProcAddress (module, symbol);
-
-  if (!address)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
-    }
-
-  return address;
-}
-
-static struct lt_user_dlloader sys_wll = {
-  0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
-};
-
-#endif /* __WINDOWS__ */
-
-
-
-
-/* --- LOAD_ADD_ON() INTERFACE LOADER --- */
-
-
-#ifdef __BEOS__
-
-/* dynamic linking for BeOS */
-
-#include <kernel/image.h>
-
-static lt_module
-sys_bedl_open (loader_data, filename)
-     lt_user_data loader_data;
-     const char *filename;
-{
-  image_id image = 0;
-
-  if (filename)
-    {
-      image = load_add_on (filename);
-    }
-  else
-    {
-      image_info info;
-      int32 cookie = 0;
-      if (get_next_image_info (0, &cookie, &info) == B_OK)
-        image = load_add_on (info.name);
-    }
-
-  if (image <= 0)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
-      image = 0;
-    }
-
-  return (lt_module) image;
-}
-
-static int
-sys_bedl_close (loader_data, module)
-     lt_user_data loader_data;
-     lt_module module;
-{
-  int errors = 0;
-
-  if (unload_add_on ((image_id) module) != B_OK)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
-      ++errors;
-    }
-
-  return errors;
-}
-
-static lt_ptr
-sys_bedl_sym (loader_data, module, symbol)
-     lt_user_data loader_data;
-     lt_module module;
-     const char *symbol;
-{
-  lt_ptr address = 0;
-  image_id image = (image_id) module;
-
-  if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
-      address = 0;
-    }
-
-  return address;
-}
-
-static struct lt_user_dlloader sys_bedl = {
-  0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
-};
-
-#endif /* __BEOS__ */
-
-
-
-
-/* --- DLD_LINK() INTERFACE LOADER --- */
-
-
-#if HAVE_DLD
-
-/* dynamic linking with dld */
-
-#if HAVE_DLD_H
-#include <dld.h>
-#endif
-
-static lt_module
-sys_dld_open (loader_data, filename)
-     lt_user_data loader_data;
-     const char *filename;
-{
-  lt_module module = strdup (filename);
-
-  if (dld_link (filename) != 0)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
-      LT_DLGNUNET_free (module);
-      module = 0;
-    }
-
-  return module;
-}
-
-static int
-sys_dld_close (loader_data, module)
-     lt_user_data loader_data;
-     lt_module module;
-{
-  int errors = 0;
-
-  if (dld_unlink_by_file ((char *) (module), 1) != 0)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
-      ++errors;
-    }
-  else
-    {
-      LT_DLGNUNET_free (module);
-    }
-
-  return errors;
-}
-
-static lt_ptr
-sys_dld_sym (loader_data, module, symbol)
-     lt_user_data loader_data;
-     lt_module module;
-     const char *symbol;
-{
-  lt_ptr address = dld_get_func (symbol);
-
-  if (!address)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
-    }
-
-  return address;
-}
-
-static struct lt_user_dlloader sys_dld = {
-  0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
-};
-
-#endif /* HAVE_DLD */
-
-/* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
-#if HAVE_DYLD
-
-
-#if HAVE_MACH_O_DYLD_H
-#if !defined(__APPLE_CC__) && !defined(__MWERKS__) && 
!defined(__private_extern__)
-/* Is this correct? Does it still function properly? */
-#define __private_extern__ extern
-#endif
-# include <mach-o/dyld.h>
-#endif
-#include <mach-o/getsect.h>
-
-/* We have to put some stuff here that isn't in older dyld.h files */
-#ifndef ENUM_DYLD_BOOL
-# define ENUM_DYLD_BOOL
-# undef FALSE
-# undef TRUE
-enum DYLD_BOOL
-{
-  FALSE,
-  TRUE
-};
-#endif
-#ifndef LC_REQ_DYLD
-# define LC_REQ_DYLD 0x80000000
-#endif
-#ifndef LC_LOAD_WEAK_DYLIB
-# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
-#endif
-static const struct mach_header *(*ltdl_NSAddImage) (const char *image_name,
-                                                     unsigned long options) =
-  0;
-static NSSymbol (*ltdl_NSLookupSymbolInImage) (const struct mach_header *
-                                               image, const char *symbolName,
-                                               unsigned long options) = 0;
-static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage) (const struct
-                                                            mach_header *
-                                                            image,
-                                                            const char
-                                                            *symbolName) = 0;
-static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic) (NSModule module) = 0;
-
-#ifndef NSADDIMAGE_OPTION_NONE
-#define NSADDIMAGE_OPTION_NONE                          0x0
-#endif
-#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
-#define NSADDIMAGE_OPTION_RETURN_ON_ERROR               0x1
-#endif
-#ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
-#define NSADDIMAGE_OPTION_WITH_SEARCHING                0x2
-#endif
-#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
-#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED         0x4
-#endif
-#ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
-#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
-#endif
-#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
-#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND            0x0
-#endif
-#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
-#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW        0x1
-#endif
-#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
-#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY      0x2
-#endif
-#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
-#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
-#endif
-
-
-static const char *
-lt_int_dyld_error (othererror)
-     char *othererror;
-{
-/* return the dyld error string, or the passed in error string if none */
-  NSLinkEditErrors ler;
-  int lerno;
-  const char *errstr;
-  const char *file;
-  NSLinkEditError (&ler, &lerno, &file, &errstr);
-  if (!errstr || !strlen (errstr))
-    errstr = othererror;
-  return errstr;
-}
-
-static const struct mach_header *
-lt_int_dyld_get_mach_header_from_nsmodule (module)
-     NSModule module;
-{
-/* There should probably be an apple dyld api for this */
-  int i = _dyld_image_count ();
-  int j;
-  const char *modname = NSNameOfModule (module);
-  const struct mach_header *mh = NULL;
-  if (!modname)
-    return NULL;
-  for (j = 0; j < i; j++)
-    {
-      if (!strcmp (_dyld_get_image_name (j), modname))
-        {
-          mh = _dyld_get_image_header (j);
-          break;
-        }
-    }
-  return mh;
-}
-
-static const char *
-lt_int_dyld_lib_install_name (mh)
-     const struct mach_header *mh;
-{
-/* NSAddImage is also used to get the loaded image, but it only works if the 
lib
-   is installed, for uninstalled libs we need to check the install_names 
against
-   each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
-   different lib was loaded as a result
-*/
-  int j;
-  struct load_command *lc;
-  unsigned long offset = sizeof (struct mach_header);
-  const char *retStr = NULL;
-  for (j = 0; j < mh->ncmds; j++)
-    {
-      lc = (struct load_command *) (((unsigned long) mh) + offset);
-      if (LC_ID_DYLIB == lc->cmd)
-        {
-          retStr =
-            (char *) (((struct dylib_command *) lc)->dylib.name.offset +
-                      (unsigned long) lc);
-        }
-      offset += lc->cmdsize;
-    }
-  return retStr;
-}
-
-static const struct mach_header *
-lt_int_dyld_match_loaded_lib_by_install_name (const char *name)
-{
-  int i = _dyld_image_count ();
-  int j;
-  const struct mach_header *mh = NULL;
-  const char *id = NULL;
-  for (j = 0; j < i; j++)
-    {
-      id = lt_int_dyld_lib_install_name (_dyld_get_image_header (j));
-      if ((id) && (!strcmp (id, name)))
-        {
-          mh = _dyld_get_image_header (j);
-          break;
-        }
-    }
-  return mh;
-}
-
-static NSSymbol
-lt_int_dyld_NSlookupSymbolInLinkedLibs (symbol, mh)
-     const char *symbol;
-     const struct mach_header *mh;
-{
-  /* Safe to assume our mh is good */
-  int j;
-  struct load_command *lc;
-  unsigned long offset = sizeof (struct mach_header);
-  NSSymbol retSym = 0;
-  const struct mach_header *mh1;
-  if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined (symbol))
-    {
-      for (j = 0; j < mh->ncmds; j++)
-        {
-          lc = (struct load_command *) (((unsigned long) mh) + offset);
-          if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
-            {
-              mh1 =
-                lt_int_dyld_match_loaded_lib_by_install_name ((char
-                                                               *) (((struct
-                                                                     
dylib_command
-                                                                     *) lc)->
-                                                                   dylib.name.
-                                                                   offset +
-                                                                   (unsigned
-                                                                    long)
-                                                                   lc));
-              if (!mh1)
-                {
-                  /* Maybe NSAddImage can find it */
-                  mh1 =
-                    ltdl_NSAddImage ((char *) (((struct dylib_command *) lc)->
-                                               dylib.name.offset +
-                                               (unsigned long) lc),
-                                     NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
-                                     NSADDIMAGE_OPTION_WITH_SEARCHING +
-                                     NSADDIMAGE_OPTION_RETURN_ON_ERROR);
-                }
-              if (mh1)
-                {
-                  retSym = ltdl_NSLookupSymbolInImage (mh1,
-                                                       symbol,
-                                                       
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
-                                                       |
-                                                       
NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
-                  if (retSym)
-                    break;
-                }
-            }
-          offset += lc->cmdsize;
-        }
-    }
-  return retSym;
-}
-
-static int
-sys_dyld_init ()
-{
-  int retCode = 0;
-  int err = 0;
-  if (!_dyld_present ())
-    {
-      retCode = 1;
-    }
-  else
-    {
-      err =
-        _dyld_func_lookup ("__dyld_NSAddImage",
-                           (unsigned long *) &ltdl_NSAddImage);
-      err =
-        _dyld_func_lookup ("__dyld_NSLookupSymbolInImage",
-                           (unsigned long *) &ltdl_NSLookupSymbolInImage);
-      err =
-        _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage",
-                           (unsigned long *)
-                           &ltdl_NSIsSymbolNameDefinedInImage);
-      err =
-        _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic",
-                           (unsigned long *) &ltdl_NSMakePrivateModulePublic);
-    }
-  return retCode;
-}
-
-static lt_module
-sys_dyld_open (loader_data, filename)
-     lt_user_data loader_data;
-     const char *filename;
-{
-  lt_module module = 0;
-  NSObjectFileImage ofi = 0;
-  NSObjectFileImageReturnCode ofirc;
-
-  if (!filename)
-    return (lt_module) - 1;
-  ofirc = NSCreateObjectFileImageFromFile (filename, &ofi);
-  switch (ofirc)
-    {
-    case NSObjectFileImageSuccess:
-      module = NSLinkModule (ofi, filename,
-                             NSLINKMODULE_OPTION_RETURN_ON_ERROR
-                             | NSLINKMODULE_OPTION_PRIVATE
-                             | NSLINKMODULE_OPTION_BINDNOW);
-      NSDestroyObjectFileImage (ofi);
-      if (module)
-        ltdl_NSMakePrivateModulePublic (module);
-      break;
-    case NSObjectFileImageInappropriateFile:
-      if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
-        {
-          module =
-            (lt_module) ltdl_NSAddImage (filename,
-                                         NSADDIMAGE_OPTION_RETURN_ON_ERROR);
-          break;
-        }
-    default:
-      LT_DLMUTEX_SETERROR (lt_int_dyld_error (LT_DLSTRERROR (CANNOT_OPEN)));
-      return 0;
-    }
-  if (!module)
-    LT_DLMUTEX_SETERROR (lt_int_dyld_error (LT_DLSTRERROR (CANNOT_OPEN)));
-  return module;
-}
-
-static int
-sys_dyld_close (loader_data, module)
-     lt_user_data loader_data;
-     lt_module module;
-{
-  int retCode = 0;
-  int flags = 0;
-  if (module == (lt_module) - 1)
-    return 0;
-#ifdef __BIG_ENDIAN__
-  if (((struct mach_header *) module)->magic == MH_MAGIC)
-#else
-  if (((struct mach_header *) module)->magic == MH_CIGAM)
-#endif
-    {
-      LT_DLMUTEX_SETERROR ("Can not close a dylib");
-      retCode = 1;
-    }
-  else
-    {
-#if 1
-/* Currently, if a module contains c++ static destructors and it is unloaded, 
we
-   get a segfault in atexit(), due to compiler and dynamic loader differences 
of
-   opinion, this works around that.
-*/
-      if ((const struct section *) NULL !=
-          getsectbynamefromheader (lt_int_dyld_get_mach_header_from_nsmodule
-                                   (module), "__DATA", "__mod_term_func"))
-        {
-          flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
-        }
-#endif
-#ifdef __ppc__
-      flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
-#endif
-      if (!NSUnLinkModule (module, flags))
-        {
-          retCode = 1;
-          LT_DLMUTEX_SETERROR (lt_int_dyld_error
-                               (LT_DLSTRERROR (CANNOT_CLOSE)));
-        }
-    }
-
-  return retCode;
-}
-
-static lt_ptr
-sys_dyld_sym (loader_data, module, symbol)
-     lt_user_data loader_data;
-     lt_module module;
-     const char *symbol;
-{
-  lt_ptr address = 0;
-  NSSymbol *nssym = 0;
-  void *unused;
-  const struct mach_header *mh = NULL;
-  char saveError[256] = "Symbol not found";
-  if (module == (lt_module) - 1)
-    {
-      _dyld_lookup_and_bind (symbol, (unsigned long *) &address, &unused);
-      return address;
-    }
-#ifdef __BIG_ENDIAN__
-  if (((struct mach_header *) module)->magic == MH_MAGIC)
-#else
-  if (((struct mach_header *) module)->magic == MH_CIGAM)
-#endif
-    {
-      if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
-        {
-          mh = module;
-          if (ltdl_NSIsSymbolNameDefinedInImage
-              ((struct mach_header *) module, symbol))
-            {
-              nssym =
-                ltdl_NSLookupSymbolInImage ((struct mach_header *) module,
-                                            symbol,
-                                            
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
-                                            |
-                                            
NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
-            }
-        }
-
-    }
-  else
-    {
-      nssym = NSLookupSymbolInModule (module, symbol);
-    }
-  if (!nssym)
-    {
-      strncpy (saveError,
-               lt_int_dyld_error (LT_DLSTRERROR (SYMBOL_NOT_FOUND)), 255);
-      saveError[255] = 0;
-      if (!mh)
-        mh = lt_int_dyld_get_mach_header_from_nsmodule (module);
-      nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs (symbol, mh);
-    }
-  if (!nssym)
-    {
-      LT_DLMUTEX_SETERROR (saveError);
-      return NULL;
-    }
-  return NSAddressOfSymbol (nssym);
-}
-
-static struct lt_user_dlloader sys_dyld =
-  { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
-
-
-#endif /* HAVE_DYLD */
-
-
-/* --- DLPREOPEN() INTERFACE LOADER --- */
-
-
-/* emulate dynamic linking using preloaded_symbols */
-
-typedef struct lt_dlsymlists_t
-{
-  struct lt_dlsymlists_t *next;
-  const lt_dlsymlist *syms;
-} lt_dlsymlists_t;
-
-static const lt_dlsymlist *default_preloaded_symbols = 0;
-static lt_dlsymlists_t *preloaded_symbols = 0;
-
-static int
-presym_init (loader_data)
-     lt_user_data loader_data;
-{
-  int errors = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  preloaded_symbols = 0;
-  if (default_preloaded_symbols)
-    {
-      errors = lt_dlpreload (default_preloaded_symbols);
-    }
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-static int
-presym_free_symlists ()
-{
-  lt_dlsymlists_t *lists;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  lists = preloaded_symbols;
-  while (lists)
-    {
-      lt_dlsymlists_t *tmp = lists;
-
-      lists = lists->next;
-      LT_DLGNUNET_free (tmp);
-    }
-  preloaded_symbols = 0;
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return 0;
-}
-
-static int
-presym_exit (loader_data)
-     lt_user_data loader_data;
-{
-  presym_free_symlists ();
-  return 0;
-}
-
-static int
-presym_add_symlist (preloaded)
-     const lt_dlsymlist *preloaded;
-{
-  lt_dlsymlists_t *tmp;
-  lt_dlsymlists_t *lists;
-  int errors = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  lists = preloaded_symbols;
-  while (lists)
-    {
-      if (lists->syms == preloaded)
-        {
-          goto done;
-        }
-      lists = lists->next;
-    }
-
-  tmp = LT_EGNUNET_malloc (lt_dlsymlists_t, 1);
-  if (tmp)
-    {
-      memset (tmp, 0, sizeof (lt_dlsymlists_t));
-      tmp->syms = preloaded;
-      tmp->next = preloaded_symbols;
-      preloaded_symbols = tmp;
-    }
-  else
-    {
-      ++errors;
-    }
-
-done:
-  LT_DLGNUNET_mutex_unlock ();
-  return errors;
-}
-
-static lt_module
-presym_open (loader_data, filename)
-     lt_user_data loader_data;
-     const char *filename;
-{
-  lt_dlsymlists_t *lists;
-  lt_module module = (lt_module) 0;
-
-  LT_DLGNUNET_mutex_lock ();
-  lists = preloaded_symbols;
-
-  if (!lists)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
-      goto done;
-    }
-
-  /* Can't use NULL as the reflective symbol header, as NULL is
-     used to mark the end of the entire symbol list.  Self-dlpreopened
-     symbols follow this magic number, chosen to be an unlikely
-     clash with a real module name.  */
-  if (!filename)
-    {
-      filename = "@PROGRAM@";
-    }
-
-  while (lists)
-    {
-      const lt_dlsymlist *syms = lists->syms;
-
-      while (syms->name)
-        {
-          if (!syms->address && strcmp (syms->name, filename) == 0)
-            {
-              module = (lt_module) syms;
-              goto done;
-            }
-          ++syms;
-        }
-
-      lists = lists->next;
-    }
-
-  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
-
-done:
-  LT_DLGNUNET_mutex_unlock ();
-  return module;
-}
-
-static int
-presym_close (loader_data, module)
-     lt_user_data loader_data;
-     lt_module module;
-{
-  /* Just to silence gcc -Wall */
-  module = 0;
-  return 0;
-}
-
-static lt_ptr
-presym_sym (loader_data, module, symbol)
-     lt_user_data loader_data;
-     lt_module module;
-     const char *symbol;
-{
-  lt_dlsymlist *syms = (lt_dlsymlist *) module;
-
-  ++syms;
-  while (syms->address)
-    {
-      if (strcmp (syms->name, symbol) == 0)
-        {
-          return syms->address;
-        }
-
-      ++syms;
-    }
-
-  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
-
-  return 0;
-}
-
-static struct lt_user_dlloader presym = {
-  0, presym_open, presym_close, presym_sym, presym_exit, 0
-};
-
-
-
-
-
-/* --- DYNAMIC MODULE LOADING --- */
-
-
-/* The type of a function used at each iteration of  foreach_dirinpath().  */
-typedef int foreach_callback_func LT_PARAMS ((char *filename, lt_ptr data1,
-                                              lt_ptr data2));
-
-static int foreach_dirinpath LT_PARAMS ((const char *search_path,
-                                         const char *base_name,
-                                         foreach_callback_func * func,
-                                         lt_ptr data1, lt_ptr data2));
-
-static int find_file_callback LT_PARAMS ((char *filename, lt_ptr data,
-                                          lt_ptr ignored));
-static int find_handle_callback LT_PARAMS ((char *filename, lt_ptr data,
-                                            lt_ptr ignored));
-static int foreachfile_callback LT_PARAMS ((char *filename, lt_ptr data1,
-                                            lt_ptr data2));
-
-
-static int canonicalize_path LT_PARAMS ((const char *path,
-                                         char **pcanonical));
-static int argzize_path LT_PARAMS ((const char *path,
-                                    char **pargz, size_t * pargz_len));
-static FILE *find_file LT_PARAMS ((const char *search_path,
-                                   const char *base_name, char **pdir));
-static lt_dlhandle *find_handle LT_PARAMS ((const char *search_path,
-                                            const char *base_name,
-                                            lt_dlhandle * handle));
-static int find_module LT_PARAMS ((lt_dlhandle * handle,
-                                   const char *dir,
-                                   const char *libdir,
-                                   const char *dlname,
-                                   const char *old_name, int installed));
-static int free_vars LT_PARAMS ((char *dlname, char *oldname,
-                                 char *libdir, char *deplibs));
-static int load_deplibs LT_PARAMS ((lt_dlhandle handle, char *deplibs));
-static int trim LT_PARAMS ((char **dest, const char *str));
-static int try_dlopen LT_PARAMS ((lt_dlhandle * handle,
-                                  const char *filename));
-static int tryall_dlopen LT_PARAMS ((lt_dlhandle * handle,
-                                     const char *filename));
-static int unload_deplibs LT_PARAMS ((lt_dlhandle handle));
-static int lt_argz_insert LT_PARAMS ((char **pargz,
-                                      size_t * pargz_len,
-                                      char *before, const char *entry));
-static int lt_argz_insertinorder LT_PARAMS ((char **pargz,
-                                             size_t * pargz_len,
-                                             const char *entry));
-static int lt_argz_insertdir LT_PARAMS ((char **pargz,
-                                         size_t * pargz_len,
-                                         const char *dirnam,
-                                         struct dirent * dp));
-static int lt_dlpath_insertdir LT_PARAMS ((char **ppath,
-                                           char *before, const char *dir));
-static int list_files_by_dir LT_PARAMS ((const char *dirnam,
-                                         char **pargz, size_t * pargz_len));
-static int file_not_found LT_PARAMS ((void));
-
-static char *user_search_path = 0;
-static lt_dlloader *loaders = 0;
-static lt_dlhandle handles = 0;
-static int initialized = 0;
-
-/* Initialize libltdl. */
-int
-lt_dlinit ()
-{
-  int errors = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  /* Initialize only at first call. */
-  if (++initialized == 1)
-    {
-      handles = 0;
-      user_search_path = 0;     /* empty search path */
-
-#if HAVE_LIBDL
-      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
-#endif
-#if HAVE_SHL_LOAD
-      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
-#endif
-#ifdef __WINDOWS__
-      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
-#endif
-#ifdef __BEOS__
-      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
-#endif
-#if HAVE_DLD
-      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
-#endif
-#if HAVE_DYLD
-      errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
-      errors += sys_dyld_init ();
-#endif
-      errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
-
-      if (presym_init (presym.dlloader_data))
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
-          ++errors;
-        }
-      else if (errors != 0)
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
-          ++errors;
-        }
-    }
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-int
-lt_dlpreload (preloaded)
-     const lt_dlsymlist *preloaded;
-{
-  int errors = 0;
-
-  if (preloaded)
-    {
-      errors = presym_add_symlist (preloaded);
-    }
-  else
-    {
-      presym_free_symlists ();
-
-      LT_DLGNUNET_mutex_lock ();
-      if (default_preloaded_symbols)
-        {
-          errors = lt_dlpreload (default_preloaded_symbols);
-        }
-      LT_DLGNUNET_mutex_unlock ();
-    }
-
-  return errors;
-}
-
-int
-lt_dlpreload_default (preloaded)
-     const lt_dlsymlist *preloaded;
-{
-  LT_DLGNUNET_mutex_lock ();
-  default_preloaded_symbols = preloaded;
-  LT_DLGNUNET_mutex_unlock ();
-  return 0;
-}
-
-int
-lt_dlexit ()
-{
-  /* shut down libltdl */
-  lt_dlloader *loader;
-  int errors = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-  loader = loaders;
-
-  if (!initialized)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
-      ++errors;
-      goto done;
-    }
-
-  /* shut down only at last call. */
-  if (--initialized == 0)
-    {
-      int level;
-
-      while (handles && LT_DLIS_RESIDENT (handles))
-        {
-          handles = handles->next;
-        }
-
-      /* close all modules */
-      for (level = 1; handles; ++level)
-        {
-          lt_dlhandle cur = handles;
-          int saw_nonresident = 0;
-
-          while (cur)
-            {
-              lt_dlhandle tmp = cur;
-              cur = cur->next;
-              if (!LT_DLIS_RESIDENT (tmp))
-                saw_nonresident = 1;
-              if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
-                {
-                  if (lt_dlclose (tmp))
-                    {
-                      ++errors;
-                    }
-                }
-            }
-          /* done if only resident modules are left */
-          if (!saw_nonresident)
-            break;
-        }
-
-      /* close all loaders */
-      while (loader)
-        {
-          lt_dlloader *next = loader->next;
-          lt_user_data data = loader->dlloader_data;
-          if (loader->dlloader_exit && loader->dlloader_exit (data))
-            {
-              ++errors;
-            }
-
-          LT_DLMEM_REASSIGN (loader, next);
-        }
-      loaders = 0;
-    }
-
-done:
-  LT_DLGNUNET_mutex_unlock ();
-  return errors;
-}
-
-static int
-tryall_dlopen (handle, filename)
-     lt_dlhandle *handle;
-     const char *filename;
-{
-  lt_dlhandle cur;
-  lt_dlloader *loader;
-  const char *saved_error;
-  int errors = 0;
-
-  LT_DLMUTEX_GETERROR (saved_error);
-  LT_DLGNUNET_mutex_lock ();
-
-  cur = handles;
-  loader = loaders;
-
-  /* check whether the module was already opened */
-  while (cur)
-    {
-      /* try to dlopen the program itself? */
-      if (!cur->info.filename && !filename)
-        {
-          break;
-        }
-
-      if (cur->info.filename && filename
-          && strcmp (cur->info.filename, filename) == 0)
-        {
-          break;
-        }
-
-      cur = cur->next;
-    }
-
-  if (cur)
-    {
-      ++cur->info.ref_count;
-      *handle = cur;
-      goto done;
-    }
-
-  cur = *handle;
-  if (filename)
-    {
-      /* Comment out the check of file permissions using access.
-         This call seems to always return -1 with error EACCES.
-       */
-      /* We need to catch missing file errors early so that
-         file_not_found() can detect what happened.
-         if (access (filename, R_OK) != 0)
-         {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
-         ++errors;
-         goto done;
-         } */
-
-      cur->info.filename = lt_estrdup (filename);
-      if (!cur->info.filename)
-        {
-          ++errors;
-          goto done;
-        }
-    }
-  else
-    {
-      cur->info.filename = 0;
-    }
-
-  while (loader)
-    {
-      lt_user_data data = loader->dlloader_data;
-
-      cur->module = loader->module_open (data, filename);
-
-      if (cur->module != 0)
-        {
-          break;
-        }
-      loader = loader->next;
-    }
-
-  if (!loader)
-    {
-      LT_DLGNUNET_free (cur->info.filename);
-      ++errors;
-      goto done;
-    }
-
-  cur->loader = loader;
-  LT_DLMUTEX_SETERROR (saved_error);
-
-done:
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-static int
-tryall_dlopen_module (handle, prefix, dirname, dlname)
-     lt_dlhandle *handle;
-     const char *prefix;
-     const char *dirname;
-     const char *dlname;
-{
-  int error = 0;
-  char *filename = 0;
-  size_t filename_len = 0;
-  size_t dirname_len = LT_STRLEN (dirname);
-
-  assert (handle);
-  assert (dirname);
-  assert (dlname);
-#ifdef LT_DIRSEP_CHAR
-  /* Only canonicalized names (i.e. with DIRSEP chars already converted)
-     should make it into this function:  */
-  assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
-#endif
-
-  if (dirname_len > 0)
-    if (dirname[dirname_len - 1] == '/')
-      --dirname_len;
-  filename_len = dirname_len + 1 + LT_STRLEN (dlname);
-
-  /* Allocate memory, and combine DIRNAME and MODULENAME into it.
-     The PREFIX (if any) is handled below.  */
-  filename = LT_EGNUNET_malloc (char, dirname_len + 1 + filename_len + 1);
-  if (!filename)
-    return 1;
-
-  sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
-
-  /* Now that we have combined DIRNAME and MODULENAME, if there is
-     also a PREFIX to contend with, simply recurse with the arguments
-     shuffled.  Otherwise, attempt to open FILENAME as a module.  */
-  if (prefix)
-    {
-      error += tryall_dlopen_module (handle,
-                                     (const char *) 0, prefix, filename);
-    }
-  else if (tryall_dlopen (handle, filename) != 0)
-    {
-      ++error;
-    }
-
-  LT_DLGNUNET_free (filename);
-  return error;
-}
-
-static int
-find_module (handle, dir, libdir, dlname, old_name, installed)
-     lt_dlhandle *handle;
-     const char *dir;
-     const char *libdir;
-     const char *dlname;
-     const char *old_name;
-     int installed;
-{
-  /* Try to open the old library first; if it was dlpreopened,
-     we want the preopened version of it, even if a dlopenable
-     module is available.  */
-  if (old_name && tryall_dlopen (handle, old_name) == 0)
-    {
-      return 0;
-    }
-
-  /* Try to open the dynamic library.  */
-  if (dlname)
-    {
-      /* try to open the installed module */
-      if (installed && libdir)
-        {
-          if (tryall_dlopen_module (handle,
-                                    (const char *) 0, libdir, dlname) == 0)
-            return 0;
-        }
-
-      /* try to open the not-installed module */
-      if (!installed)
-        {
-          if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
-            return 0;
-        }
-
-      /* maybe it was moved to another directory */
-      {
-        if (dir && (tryall_dlopen_module (handle,
-                                          (const char *) 0, dir,
-                                          dlname) == 0))
-          return 0;
-      }
-    }
-
-  return 1;
-}
-
-
-static int
-canonicalize_path (path, pcanonical)
-     const char *path;
-     char **pcanonical;
-{
-  char *canonical = 0;
-
-  assert (path && *path);
-  assert (pcanonical);
-
-  canonical = LT_EGNUNET_malloc (char, 1 + LT_STRLEN (path));
-  if (!canonical)
-    return 1;
-
-  {
-    size_t dest = 0;
-    size_t src;
-    for (src = 0; path[src] != LT_EOS_CHAR; ++src)
-      {
-        /* Path separators are not copied to the beginning or end of
-           the destination, or if another separator would follow
-           immediately.  */
-        if (path[src] == LT_PATHSEP_CHAR)
-          {
-            if ((dest == 0)
-                || (path[1 + src] == LT_PATHSEP_CHAR)
-                || (path[1 + src] == LT_EOS_CHAR))
-              continue;
-          }
-
-        /* Anything other than a directory separator is copied verbatim.  */
-        if ((path[src] != '/')
-#ifdef LT_DIRSEP_CHAR
-            && (path[src] != LT_DIRSEP_CHAR)
-#endif
-          )
-          {
-            canonical[dest++] = path[src];
-          }
-        /* Directory separators are converted and copied only if they are
-           not at the end of a path -- i.e. before a path separator or
-           NULL terminator.  */
-        else if ((path[1 + src] != LT_PATHSEP_CHAR)
-                 && (path[1 + src] != LT_EOS_CHAR)
-#ifdef LT_DIRSEP_CHAR
-                 && (path[1 + src] != LT_DIRSEP_CHAR)
-#endif
-                 && (path[1 + src] != '/'))
-          {
-            canonical[dest++] = '/';
-          }
-      }
-
-    /* Add an end-of-string marker at the end.  */
-    canonical[dest] = LT_EOS_CHAR;
-  }
-
-  /* Assign new value.  */
-  *pcanonical = canonical;
-
-  return 0;
-}
-
-static int
-argzize_path (path, pargz, pargz_len)
-     const char *path;
-     char **pargz;
-     size_t *pargz_len;
-{
-  error_t error;
-
-  assert (path);
-  assert (pargz);
-  assert (pargz_len);
-
-  if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
-    {
-      switch (error)
-        {
-        case ENOMEM:
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-          break;
-        default:
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
-          break;
-        }
-
-      return 1;
-    }
-
-  return 0;
-}
-
-/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
-   of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
-   non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,
-   it is appended to each SEARCH_PATH element before FUNC is called.  */
-static int
-foreach_dirinpath (search_path, base_name, func, data1, data2)
-     const char *search_path;
-     const char *base_name;
-     foreach_callback_func *func;
-     lt_ptr data1;
-     lt_ptr data2;
-{
-  int result = 0;
-  int filenamesize = 0;
-  size_t lenbase = LT_STRLEN (base_name);
-  size_t argz_len = 0;
-  char *argz = 0;
-  char *filename = 0;
-  char *canonical = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  if (!search_path || !*search_path)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
-      goto cleanup;
-    }
-
-  if (canonicalize_path (search_path, &canonical) != 0)
-    goto cleanup;
-
-  if (argzize_path (canonical, &argz, &argz_len) != 0)
-    goto cleanup;
-
-  {
-    char *dir_name = 0;
-    while ((dir_name = argz_next (argz, argz_len, dir_name)))
-      {
-        size_t lendir = LT_STRLEN (dir_name);
-
-        if (lendir + 1 + lenbase >= filenamesize)
-          {
-            LT_DLGNUNET_free (filename);
-            filenamesize = lendir + 1 + lenbase + 1;    /* "/d" + '/' + "f" + 
'\0' */
-            filename = LT_EGNUNET_malloc (char, filenamesize);
-            if (!filename)
-              goto cleanup;
-          }
-
-        assert (filenamesize > lendir);
-        strcpy (filename, dir_name);
-
-        if (base_name && *base_name)
-          {
-            if (filename[lendir - 1] != '/')
-              filename[lendir++] = '/';
-            strcpy (filename + lendir, base_name);
-          }
-
-        if ((result = (*func) (filename, data1, data2)))
-          {
-            break;
-          }
-      }
-  }
-
-cleanup:
-  LT_DLGNUNET_free (argz);
-  LT_DLGNUNET_free (canonical);
-  LT_DLGNUNET_free (filename);
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return result;
-}
-
-/* If FILEPATH can be opened, store the name of the directory component
-   in DATA1, and the opened FILE* structure address in DATA2.  Otherwise
-   DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */
-static int
-find_file_callback (filename, data1, data2)
-     char *filename;
-     lt_ptr data1;
-     lt_ptr data2;
-{
-  char **pdir = (char **) data1;
-  FILE **pfile = (FILE **) data2;
-  int is_done = 0;
-
-  assert (filename && *filename);
-  assert (pdir);
-  assert (pfile);
-
-  if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
-    {
-      char *dirend = strrchr (filename, '/');
-
-      if (dirend > filename)
-        *dirend = LT_EOS_CHAR;
-
-      LT_DLGNUNET_free (*pdir);
-      *pdir = lt_estrdup (filename);
-      is_done = (*pdir == 0) ? -1 : 1;
-    }
-
-  return is_done;
-}
-
-static FILE *
-find_file (search_path, base_name, pdir)
-     const char *search_path;
-     const char *base_name;
-     char **pdir;
-{
-  FILE *file = 0;
-
-  foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
-
-  return file;
-}
-
-static int
-find_handle_callback (filename, data, ignored)
-     char *filename;
-     lt_ptr data;
-     lt_ptr ignored;
-{
-  lt_dlhandle *handle = (lt_dlhandle *) data;
-  int notfound = access (filename, R_OK);
-
-  /* Bail out if file cannot be read...  */
-  if (notfound)
-    return 0;
-
-  /* Try to dlopen the file, but do not continue searching in any
-     case.  */
-  if (tryall_dlopen (handle, filename) != 0)
-    *handle = 0;
-
-  return 1;
-}
-
-/* If HANDLE was found return it, otherwise return 0.  If HANDLE was
-   found but could not be opened, *HANDLE will be set to 0.  */
-static lt_dlhandle *
-find_handle (search_path, base_name, handle)
-     const char *search_path;
-     const char *base_name;
-     lt_dlhandle *handle;
-{
-  if (!search_path)
-    return 0;
-
-  if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
-                          handle, 0))
-    return 0;
-
-  return handle;
-}
-
-static int
-load_deplibs (handle, deplibs)
-     lt_dlhandle handle;
-     char *deplibs;
-{
-#if LTDL_DLOPEN_DEPLIBS
-  char *p, *save_search_path = 0;
-  int depcount = 0;
-  int i;
-  char **names = 0;
-#endif
-  int errors = 0;
-
-  handle->depcount = 0;
-
-#if LTDL_DLOPEN_DEPLIBS
-  if (!deplibs)
-    {
-      return errors;
-    }
-  ++errors;
-
-  LT_DLGNUNET_mutex_lock ();
-  if (user_search_path)
-    {
-      save_search_path = lt_estrdup (user_search_path);
-      if (!save_search_path)
-        goto cleanup;
-    }
-
-  /* extract search paths and count deplibs */
-  p = deplibs;
-  while (*p)
-    {
-      if (!isspace ((int) *p))
-        {
-          char *end = p + 1;
-          while (*end && !isspace ((int) *end))
-            {
-              ++end;
-            }
-
-          if (strncmp (p, "-L", 2) == 0 || strncmp (p, "-R", 2) == 0)
-            {
-              char save = *end;
-              *end = 0;         /* set a temporary string terminator */
-              if (lt_dladdsearchdir (p + 2))
-                {
-                  goto cleanup;
-                }
-              *end = save;
-            }
-          else
-            {
-              ++depcount;
-            }
-
-          p = end;
-        }
-      else
-        {
-          ++p;
-        }
-    }
-
-  if (!depcount)
-    {
-      errors = 0;
-      goto cleanup;
-    }
-
-  names = LT_EGNUNET_malloc (char *, depcount * sizeof (char *));
-  if (!names)
-    goto cleanup;
-
-  /* now only extract the actual deplibs */
-  depcount = 0;
-  p = deplibs;
-  while (*p)
-    {
-      if (isspace ((int) *p))
-        {
-          ++p;
-        }
-      else
-        {
-          char *end = p + 1;
-          while (*end && !isspace ((int) *end))
-            {
-              ++end;
-            }
-
-          if (strncmp (p, "-L", 2) != 0 && strncmp (p, "-R", 2) != 0)
-            {
-              char *name;
-              char save = *end;
-              *end = 0;         /* set a temporary string terminator */
-              if (strncmp (p, "-l", 2) == 0)
-                {
-                  size_t name_len = 3 + /* "lib" */ LT_STRLEN (p + 2);
-                  name = LT_EGNUNET_malloc (char, 1 + name_len);
-                  if (name)
-                    sprintf (name, "lib%s", p + 2);
-                }
-              else
-                name = lt_estrdup (p);
-
-              if (!name)
-                goto cleanup_names;
-
-              names[depcount++] = name;
-              *end = save;
-            }
-          p = end;
-        }
-    }
-
-  /* load the deplibs (in reverse order)
-     At this stage, don't worry if the deplibs do not load correctly,
-     they may already be statically linked into the loading application
-     for instance.  There will be a more enlightening error message
-     later on if the loaded module cannot resolve all of its symbols.  */
-  if (depcount)
-    {
-      int j = 0;
-
-      handle->deplibs =
-        (lt_dlhandle *) LT_EGNUNET_malloc (lt_dlhandle *, depcount);
-      if (!handle->deplibs)
-        goto cleanup;
-
-      for (i = 0; i < depcount; ++i)
-        {
-          handle->deplibs[j] = lt_dlopenext (names[depcount - 1 - i]);
-          if (handle->deplibs[j])
-            {
-              ++j;
-            }
-        }
-
-      handle->depcount = j;     /* Number of successfully loaded deplibs */
-      errors = 0;
-    }
-
-cleanup_names:
-  for (i = 0; i < depcount; ++i)
-    {
-      LT_DLGNUNET_free (names[i]);
-    }
-
-cleanup:
-  LT_DLGNUNET_free (names);
-  /* restore the old search path */
-  if (user_search_path)
-    {
-      LT_DLGNUNET_free (user_search_path);
-      user_search_path = save_search_path;
-    }
-  LT_DLGNUNET_mutex_unlock ();
-
-#endif
-
-  return errors;
-}
-
-static int
-unload_deplibs (handle)
-     lt_dlhandle handle;
-{
-  int i;
-  int errors = 0;
-
-  if (handle->depcount)
-    {
-      for (i = 0; i < handle->depcount; ++i)
-        {
-          if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
-            {
-              errors += lt_dlclose (handle->deplibs[i]);
-            }
-        }
-    }
-
-  return errors;
-}
-
-static int
-trim (dest, str)
-     char **dest;
-     const char *str;
-{
-  /* remove the leading and trailing "'" from str
-     and store the result in dest */
-  const char *end = strrchr (str, '\'');
-  size_t len = LT_STRLEN (str);
-  char *tmp;
-
-  LT_DLGNUNET_free (*dest);
-
-  if (!end)
-    return 1;
-
-  if (len > 3 && str[0] == '\'')
-    {
-      tmp = LT_EGNUNET_malloc (char, end - str);
-      if (!tmp)
-        return 1;
-
-      strncpy (tmp, &str[1], (end - str) - 1);
-      tmp[len - 3] = LT_EOS_CHAR;
-      *dest = tmp;
-    }
-  else
-    {
-      *dest = 0;
-    }
-
-  return 0;
-}
-
-static int
-free_vars (dlname, oldname, libdir, deplibs)
-     char *dlname;
-     char *oldname;
-     char *libdir;
-     char *deplibs;
-{
-  LT_DLGNUNET_free (dlname);
-  LT_DLGNUNET_free (oldname);
-  LT_DLGNUNET_free (libdir);
-  LT_DLGNUNET_free (deplibs);
-
-  return 0;
-}
-
-static int
-try_dlopen (phandle, filename)
-     lt_dlhandle *phandle;
-     const char *filename;
-{
-  const char *ext = 0;
-  const char *saved_error = 0;
-  char *canonical = 0;
-  char *base_name = 0;
-  char *dir = 0;
-  char *name = 0;
-  int errors = 0;
-  lt_dlhandle newhandle;
-
-  assert (phandle);
-  assert (*phandle == 0);
-
-  LT_DLMUTEX_GETERROR (saved_error);
-
-  /* dlopen self? */
-  if (!filename)
-    {
-      *phandle =
-        (lt_dlhandle) LT_EGNUNET_malloc (struct lt_dlhandle_struct, 1);
-      if (*phandle == 0)
-        return 1;
-
-      memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
-      newhandle = *phandle;
-
-      /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
-      LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
-
-      if (tryall_dlopen (&newhandle, 0) != 0)
-        {
-          LT_DLGNUNET_free (*phandle);
-          return 1;
-        }
-
-      goto register_handle;
-    }
-
-  assert (filename && *filename);
-
-  /* Doing this immediately allows internal functions to safely
-     assume only canonicalized paths are passed.  */
-  if (canonicalize_path (filename, &canonical) != 0)
-    {
-      ++errors;
-      goto cleanup;
-    }
-
-  /* If the canonical module name is a path (relative or absolute)
-     then split it into a directory part and a name part.  */
-  base_name = strrchr (canonical, '/');
-  if (base_name)
-    {
-      size_t dirlen = (1 + base_name) - canonical;
-
-      dir = LT_EGNUNET_malloc (char, 1 + dirlen);
-      if (!dir)
-        {
-          ++errors;
-          goto cleanup;
-        }
-
-      strncpy (dir, canonical, dirlen);
-      dir[dirlen] = LT_EOS_CHAR;
-
-      ++base_name;
-    }
-  else
-    base_name = canonical;
-
-  assert (base_name && *base_name);
-
-  /* Check whether we are opening a libtool module (.la extension).  */
-  ext = strrchr (base_name, '.');
-  if (ext && strcmp (ext, archive_ext) == 0)
-    {
-      /* this seems to be a libtool module */
-      FILE *file = 0;
-      char *dlname = 0;
-      char *old_name = 0;
-      char *libdir = 0;
-      char *deplibs = 0;
-      char *line = 0;
-      size_t line_len;
-
-      /* if we can't find the installed flag, it is probably an
-         installed libtool archive, produced with an old version
-         of libtool */
-      int installed = 1;
-
-      /* extract the module name from the file name */
-      name = LT_EGNUNET_malloc (char, ext - base_name + 1);
-      if (!name)
-        {
-          ++errors;
-          goto cleanup;
-        }
-
-      /* canonicalize the module name */
-      {
-        size_t i;
-        for (i = 0; i < ext - base_name; ++i)
-          {
-            if (isalnum ((int) (base_name[i])))
-              {
-                name[i] = base_name[i];
-              }
-            else
-              {
-                name[i] = '_';
-              }
-          }
-        name[ext - base_name] = LT_EOS_CHAR;
-      }
-
-      /* Now try to open the .la file.  If there is no directory name
-         component, try to find it first in user_search_path and then other
-         prescribed paths.  Otherwise (or in any case if the module was not
-         yet found) try opening just the module name as passed.  */
-      if (!dir)
-        {
-          const char *search_path;
-
-          LT_DLGNUNET_mutex_lock ();
-          search_path = user_search_path;
-          if (search_path)
-            file = find_file (user_search_path, base_name, &dir);
-          LT_DLGNUNET_mutex_unlock ();
-
-          if (!file)
-            {
-              search_path = getenv (LTDL_SEARCHPATH_VAR);
-              if (search_path)
-                file = find_file (search_path, base_name, &dir);
-            }
-
-#ifdef LTDL_SHLIBPATH_VAR
-          if (!file)
-            {
-              search_path = getenv (LTDL_SHLIBPATH_VAR);
-              if (search_path)
-                file = find_file (search_path, base_name, &dir);
-            }
-#endif
-#ifdef LTDL_SYSSEARCHPATH
-          if (!file && sys_search_path)
-            {
-              file = find_file (sys_search_path, base_name, &dir);
-            }
-#endif
-        }
-      if (!file)
-        {
-          file = fopen (filename, LT_READTEXT_MODE);
-        }
-
-      /* If we didn't find the file by now, it really isn't there.  Set
-         the status flag, and bail out.  */
-      if (!file)
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
-          ++errors;
-          goto cleanup;
-        }
-
-      line_len = LT_FILENAME_MAX;
-      line = LT_EGNUNET_malloc (char, line_len);
-      if (!line)
-        {
-          fclose (file);
-          ++errors;
-          goto cleanup;
-        }
-
-      /* read the .la file */
-      while (!feof (file))
-        {
-          if (!fgets (line, (int) line_len, file))
-            {
-              break;
-            }
-
-          /* Handle the case where we occasionally need to read a line
-             that is longer than the initial buffer size.  */
-          while ((line[LT_STRLEN (line) - 1] != '\n') && (!feof (file)))
-            {
-              line = LT_DLGNUNET_realloc (char, line, line_len * 2);
-              if (!fgets (&line[line_len - 1], (int) line_len + 1, file))
-                {
-                  break;
-                }
-              line_len *= 2;
-            }
-
-          if (line[0] == '\n' || line[0] == '#')
-            {
-              continue;
-            }
-
-#undef  STR_DLNAME
-#define STR_DLNAME     "dlname="
-          if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
-            {
-              errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
-            }
-
-#undef  STR_OLD_LIBRARY
-#define STR_OLD_LIBRARY        "old_library="
-          else if (strncmp (line, STR_OLD_LIBRARY,
-                            sizeof (STR_OLD_LIBRARY) - 1) == 0)
-            {
-              errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
-            }
-#undef  STR_LIBDIR
-#define STR_LIBDIR     "libdir="
-          else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
-            {
-              errors += trim (&libdir, &line[sizeof (STR_LIBDIR) - 1]);
-            }
-
-#undef  STR_DL_DEPLIBS
-#define STR_DL_DEPLIBS "dependency_libs="
-          else if (strncmp (line, STR_DL_DEPLIBS,
-                            sizeof (STR_DL_DEPLIBS) - 1) == 0)
-            {
-              errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
-            }
-          else if (strcmp (line, "installed=yes\n") == 0)
-            {
-              installed = 1;
-            }
-          else if (strcmp (line, "installed=no\n") == 0)
-            {
-              installed = 0;
-            }
-
-#undef  STR_LIBRARY_NAMES
-#define STR_LIBRARY_NAMES "library_names="
-          else if (!dlname && strncmp (line, STR_LIBRARY_NAMES,
-                                       sizeof (STR_LIBRARY_NAMES) - 1) == 0)
-            {
-              char *last_libname;
-              errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
-              if (!errors
-                  && dlname && (last_libname = strrchr (dlname, ' ')) != 0)
-                {
-                  last_libname = lt_estrdup (last_libname + 1);
-                  if (!last_libname)
-                    {
-                      ++errors;
-                      goto cleanup;
-                    }
-                  LT_DLMEM_REASSIGN (dlname, last_libname);
-                }
-            }
-
-          if (errors)
-            break;
-        }
-
-      fclose (file);
-      LT_DLGNUNET_free (line);
-
-      /* allocate the handle */
-      *phandle =
-        (lt_dlhandle) LT_EGNUNET_malloc (struct lt_dlhandle_struct, 1);
-      if (*phandle == 0)
-        ++errors;
-
-      if (errors)
-        {
-          free_vars (dlname, old_name, libdir, deplibs);
-          LT_DLGNUNET_free (*phandle);
-          goto cleanup;
-        }
-
-      assert (*phandle);
-
-      memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
-      if (load_deplibs (*phandle, deplibs) == 0)
-        {
-          newhandle = *phandle;
-          /* find_module may replace newhandle */
-          if (find_module
-              (&newhandle, dir, libdir, dlname, old_name, installed))
-            {
-              unload_deplibs (*phandle);
-              ++errors;
-            }
-        }
-      else
-        {
-          ++errors;
-        }
-
-      free_vars (dlname, old_name, libdir, deplibs);
-      if (errors)
-        {
-          LT_DLGNUNET_free (*phandle);
-          goto cleanup;
-        }
-
-      if (*phandle != newhandle)
-        {
-          unload_deplibs (*phandle);
-        }
-    }
-  else
-    {
-      /* not a libtool module */
-      *phandle =
-        (lt_dlhandle) LT_EGNUNET_malloc (struct lt_dlhandle_struct, 1);
-      if (*phandle == 0)
-        {
-          ++errors;
-          goto cleanup;
-        }
-
-      memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
-      newhandle = *phandle;
-
-      /* If the module has no directory name component, try to find it
-         first in user_search_path and then other prescribed paths.
-         Otherwise (or in any case if the module was not yet found) try
-         opening just the module name as passed.  */
-      if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
-                   && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
-                                    &newhandle)
-#ifdef LTDL_SHLIBPATH_VAR
-                   && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
-                                    &newhandle)
-#endif
-#ifdef LTDL_SYSSEARCHPATH
-                   && !find_handle (sys_search_path, base_name, &newhandle)
-#endif
-           )))
-        {
-          if (tryall_dlopen (&newhandle, filename) != 0)
-            {
-              newhandle = NULL;
-            }
-        }
-
-      if (!newhandle)
-        {
-          LT_DLGNUNET_free (*phandle);
-          ++errors;
-          goto cleanup;
-        }
-    }
-
-register_handle:
-  LT_DLMEM_REASSIGN (*phandle, newhandle);
-
-  if ((*phandle)->info.ref_count == 0)
-    {
-      (*phandle)->info.ref_count = 1;
-      LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
-
-      LT_DLGNUNET_mutex_lock ();
-      (*phandle)->next = handles;
-      handles = *phandle;
-      LT_DLGNUNET_mutex_unlock ();
-    }
-
-  LT_DLMUTEX_SETERROR (saved_error);
-
-cleanup:
-  LT_DLGNUNET_free (dir);
-  LT_DLGNUNET_free (name);
-  LT_DLGNUNET_free (canonical);
-
-  return errors;
-}
-
-lt_dlhandle
-lt_dlopen (filename)
-     const char *filename;
-{
-  lt_dlhandle handle = 0;
-
-  /* Just incase we missed a code path in try_dlopen() that reports
-     an error, but forgets to reset handle... */
-  if (try_dlopen (&handle, filename) != 0)
-    return 0;
-
-  return handle;
-}
-
-/* If the last error messge store was `FILE_NOT_FOUND', then return
-   non-zero.  */
-static int
-file_not_found ()
-{
-  const char *error = 0;
-
-  LT_DLMUTEX_GETERROR (error);
-  if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
-    return 1;
-
-  return 0;
-}
-
-/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
-   open the FILENAME as passed.  Otherwise try appending ARCHIVE_EXT,
-   and if a file is still not found try again with SHLIB_EXT appended
-   instead.  */
-lt_dlhandle
-lt_dlopenext (filename)
-     const char *filename;
-{
-  lt_dlhandle handle = 0;
-  char *tmp = 0;
-  char *ext = 0;
-  size_t len;
-  int errors = 0;
-
-  if (!filename)
-    {
-      return lt_dlopen (filename);
-    }
-
-  assert (filename);
-
-  len = LT_STRLEN (filename);
-  ext = strrchr (filename, '.');
-
-  /* If FILENAME already bears a suitable extension, there is no need
-     to try appending additional extensions.  */
-  if (ext && ((strcmp (ext, archive_ext) == 0)
-#ifdef LTDL_SHLIB_EXT
-              || (strcmp (ext, shlib_ext) == 0)
-#endif
-      ))
-    {
-      return lt_dlopen (filename);
-    }
-
-  /* First try appending ARCHIVE_EXT.  */
-  tmp = LT_EGNUNET_malloc (char, len + LT_STRLEN (archive_ext) + 1);
-  if (!tmp)
-    return 0;
-
-  strcpy (tmp, filename);
-  strcat (tmp, archive_ext);
-  errors = try_dlopen (&handle, tmp);
-
-  /* If we found FILENAME, stop searching -- whether we were able to
-     load the file as a module or not.  If the file exists but loading
-     failed, it is better to return an error message here than to
-     report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
-     in the module search path.  */
-  if (handle || ((errors > 0) && !file_not_found ()))
-    {
-      LT_DLGNUNET_free (tmp);
-      return handle;
-    }
-
-#ifdef LTDL_SHLIB_EXT
-  /* Try appending SHLIB_EXT.   */
-  if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
-    {
-      LT_DLGNUNET_free (tmp);
-      tmp = LT_EGNUNET_malloc (char, len + LT_STRLEN (shlib_ext) + 1);
-      if (!tmp)
-        return 0;
-
-      strcpy (tmp, filename);
-    }
-  else
-    {
-      tmp[len] = LT_EOS_CHAR;
-    }
-
-  strcat (tmp, shlib_ext);
-  errors = try_dlopen (&handle, tmp);
-
-  /* As before, if the file was found but loading failed, return now
-     with the current error message.  */
-  if (handle || ((errors > 0) && !file_not_found ()))
-    {
-      LT_DLGNUNET_free (tmp);
-      return handle;
-    }
-#endif
-
-  /* Still here?  Then we really did fail to locate any of the file
-     names we tried.  */
-  LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
-  LT_DLGNUNET_free (tmp);
-  return 0;
-}
-
-
-static int
-lt_argz_insert (pargz, pargz_len, before, entry)
-     char **pargz;
-     size_t *pargz_len;
-     char *before;
-     const char *entry;
-{
-  error_t error;
-
-  /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
-     pargz_len, NULL, entry) failed with EINVAL.  */
-  if (before)
-    error = argz_insert (pargz, pargz_len, before, entry);
-  else
-    error = argz_append (pargz, pargz_len, entry, 1 + LT_STRLEN (entry));
-
-  if (error)
-    {
-      switch (error)
-        {
-        case ENOMEM:
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-          break;
-        default:
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
-          break;
-        }
-      return 1;
-    }
-
-  return 0;
-}
-
-static int
-lt_argz_insertinorder (pargz, pargz_len, entry)
-     char **pargz;
-     size_t *pargz_len;
-     const char *entry;
-{
-  char *before = 0;
-
-  assert (pargz);
-  assert (pargz_len);
-  assert (entry && *entry);
-
-  if (*pargz)
-    while ((before = argz_next (*pargz, *pargz_len, before)))
-      {
-        int cmp = strcmp (entry, before);
-
-        if (cmp < 0)
-          break;
-        if (cmp == 0)
-          return 0;             /* No duplicates! */
-      }
-
-  return lt_argz_insert (pargz, pargz_len, before, entry);
-}
-
-static int
-lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
-     char **pargz;
-     size_t *pargz_len;
-     const char *dirnam;
-     struct dirent *dp;
-{
-  char *buf = 0;
-  size_t buf_len = 0;
-  char *end = 0;
-  size_t end_offset = 0;
-  size_t dir_len = 0;
-  int errors = 0;
-
-  assert (pargz);
-  assert (pargz_len);
-  assert (dp);
-
-  dir_len = LT_STRLEN (dirnam);
-  end = dp->d_name + LT_D_NAMLEN (dp);
-
-  /* Ignore version numbers.  */
-  {
-    char *p;
-    for (p = end; p - 1 > dp->d_name; --p)
-      if (strchr (".0123456789", p[-1]) == 0)
-        break;
-
-    if (*p == '.')
-      end = p;
-  }
-
-  /* Ignore filename extension.  */
-  {
-    char *p;
-    for (p = end - 1; p > dp->d_name; --p)
-      if (*p == '.')
-        {
-          end = p;
-          break;
-        }
-  }
-
-  /* Prepend the directory name.  */
-  end_offset = end - dp->d_name;
-  buf_len = dir_len + 1 + end_offset;
-  buf = LT_EGNUNET_malloc (char, 1 + buf_len);
-  if (!buf)
-    return ++errors;
-
-  assert (buf);
-
-  strcpy (buf, dirnam);
-  strcat (buf, "/");
-  strncat (buf, dp->d_name, end_offset);
-  buf[buf_len] = LT_EOS_CHAR;
-
-  /* Try to insert (in order) into ARGZ/ARGZ_LEN.  */
-  if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
-    ++errors;
-
-  LT_DLGNUNET_free (buf);
-
-  return errors;
-}
-
-static int
-list_files_by_dir (dirnam, pargz, pargz_len)
-     const char *dirnam;
-     char **pargz;
-     size_t *pargz_len;
-{
-  DIR *dirp = 0;
-  int errors = 0;
-
-  assert (dirnam && *dirnam);
-  assert (pargz);
-  assert (pargz_len);
-  assert (dirnam[LT_STRLEN (dirnam) - 1] != '/');
-
-  dirp = opendir (dirnam);
-  if (dirp)
-    {
-      struct dirent *dp = 0;
-
-      while ((dp = readdir (dirp)))
-        if (dp->d_name[0] != '.')
-          if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
-            {
-              ++errors;
-              break;
-            }
-
-      closedir (dirp);
-    }
-  else
-    ++errors;
-
-  return errors;
-}
-
-
-/* If there are any files in DIRNAME, call the function passed in
-   DATA1 (with the name of each file and DATA2 as arguments).  */
-static int
-foreachfile_callback (dirname, data1, data2)
-     char *dirname;
-     lt_ptr data1;
-     lt_ptr data2;
-{
-  int (*func) LT_PARAMS ((const char *filename, lt_ptr data))
-    = (int (*)LT_PARAMS ((const char *filename, lt_ptr data))) data1;
-
-  int is_done = 0;
-  char *argz = 0;
-  size_t argz_len = 0;
-
-  if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
-    goto cleanup;
-  if (!argz)
-    goto cleanup;
-
-  {
-    char *filename = 0;
-    while ((filename = argz_next (argz, argz_len, filename)))
-      if ((is_done = (*func) (filename, data2)))
-        break;
-  }
-
-cleanup:
-  LT_DLGNUNET_free (argz);
-
-  return is_done;
-}
-
-
-/* Call FUNC for each unique extensionless file in SEARCH_PATH, along
-   with DATA.  The filenames passed to FUNC would be suitable for
-   passing to lt_dlopenext.  The extensions are stripped so that
-   individual modules do not generate several entries (e.g. libfoo.la,
-   libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
-   then the same directories that lt_dlopen would search are examined.  */
-int
-lt_dlforeachfile (search_path, func, data)
-     const char *search_path;
-     int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
-     lt_ptr data;
-{
-  int is_done = 0;
-
-  if (search_path)
-    {
-      /* If a specific path was passed, search only the directories
-         listed in it.  */
-      is_done = foreach_dirinpath (search_path, 0,
-                                   foreachfile_callback, func, data);
-    }
-  else
-    {
-      /* Otherwise search the default paths.  */
-      is_done = foreach_dirinpath (user_search_path, 0,
-                                   foreachfile_callback, func, data);
-      if (!is_done)
-        {
-          is_done = foreach_dirinpath (getenv ("LTDL_LIBRARY_PATH"), 0,
-                                       foreachfile_callback, func, data);
-        }
-
-#ifdef LTDL_SHLIBPATH_VAR
-      if (!is_done)
-        {
-          is_done = foreach_dirinpath (getenv (LTDL_SHLIBPATH_VAR), 0,
-                                       foreachfile_callback, func, data);
-        }
-#endif
-#ifdef LTDL_SYSSEARCHPATH
-      if (!is_done)
-        {
-          is_done = foreach_dirinpath (getenv (LTDL_SYSSEARCHPATH), 0,
-                                       foreachfile_callback, func, data);
-        }
-#endif
-    }
-
-  return is_done;
-}
-
-int
-lt_dlclose (handle)
-     lt_dlhandle handle;
-{
-  lt_dlhandle cur, last;
-  int errors = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  /* check whether the handle is valid */
-  last = cur = handles;
-  while (cur && handle != cur)
-    {
-      last = cur;
-      cur = cur->next;
-    }
-
-  if (!cur)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
-      ++errors;
-      goto done;
-    }
-
-  handle->info.ref_count--;
-
-  /* Note that even with resident modules, we must track the ref_count
-     correctly incase the user decides to reset the residency flag
-     later (even though the API makes no provision for that at the
-     moment).  */
-  if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
-    {
-      lt_user_data data = handle->loader->dlloader_data;
-
-      if (handle != handles)
-        {
-          last->next = handle->next;
-        }
-      else
-        {
-          handles = handle->next;
-        }
-
-      errors += handle->loader->module_close (data, handle->module);
-      errors += unload_deplibs (handle);
-
-      /* It is up to the callers to free the data itself.  */
-      LT_DLGNUNET_free (handle->caller_data);
-
-      LT_DLGNUNET_free (handle->info.filename);
-      LT_DLGNUNET_free (handle->info.name);
-      LT_DLGNUNET_free (handle);
-
-      goto done;
-    }
-
-  if (LT_DLIS_RESIDENT (handle))
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
-      ++errors;
-    }
-
-done:
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-lt_ptr
-lt_dlsym (handle, symbol)
-     lt_dlhandle handle;
-     const char *symbol;
-{
-  size_t lensym;
-  char lsym[LT_SYMBOL_LENGTH];
-  char *sym;
-  lt_ptr address;
-  lt_user_data data;
-
-  if (!handle)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
-      return 0;
-    }
-
-  if (!symbol)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
-      return 0;
-    }
-
-  lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
-    + LT_STRLEN (handle->info.name);
-
-  if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
-    {
-      sym = lsym;
-    }
-  else
-    {
-      sym = LT_EGNUNET_malloc (char, lensym + LT_SYMBOL_OVERHEAD + 1);
-      if (!sym)
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
-          return 0;
-        }
-    }
-
-  data = handle->loader->dlloader_data;
-  if (handle->info.name)
-    {
-      const char *saved_error;
-
-      LT_DLMUTEX_GETERROR (saved_error);
-
-      /* this is a libtool module */
-      if (handle->loader->sym_prefix)
-        {
-          strcpy (sym, handle->loader->sym_prefix);
-          strcat (sym, handle->info.name);
-        }
-      else
-        {
-          strcpy (sym, handle->info.name);
-        }
-
-      strcat (sym, "_LTX_");
-      strcat (sym, symbol);
-
-      /* try "modulename_LTX_symbol" */
-      address = handle->loader->find_sym (data, handle->module, sym);
-      if (address)
-        {
-          if (sym != lsym)
-            {
-              LT_DLGNUNET_free (sym);
-            }
-          return address;
-        }
-      LT_DLMUTEX_SETERROR (saved_error);
-    }
-
-  /* otherwise try "symbol" */
-  if (handle->loader->sym_prefix)
-    {
-      strcpy (sym, handle->loader->sym_prefix);
-      strcat (sym, symbol);
-    }
-  else
-    {
-      strcpy (sym, symbol);
-    }
-
-  address = handle->loader->find_sym (data, handle->module, sym);
-  if (sym != lsym)
-    {
-      LT_DLGNUNET_free (sym);
-    }
-
-  return address;
-}
-
-const char *
-lt_dlerror ()
-{
-  const char *error;
-
-  LT_DLMUTEX_GETERROR (error);
-  LT_DLMUTEX_SETERROR (0);
-
-  return error ? error : NULL;
-}
-
-static int
-lt_dlpath_insertdir (ppath, before, dir)
-     char **ppath;
-     char *before;
-     const char *dir;
-{
-  int errors = 0;
-  char *canonical = 0;
-  char *argz = 0;
-  size_t argz_len = 0;
-
-  assert (ppath);
-  assert (dir && *dir);
-
-  if (canonicalize_path (dir, &canonical) != 0)
-    {
-      ++errors;
-      goto cleanup;
-    }
-
-  assert (canonical && *canonical);
-
-  /* If *PPATH is empty, set it to DIR.  */
-  if (*ppath == 0)
-    {
-      assert (!before);         /* BEFORE cannot be set without PPATH.  */
-      assert (dir);             /* Without DIR, don't call this function!  */
-
-      *ppath = lt_estrdup (dir);
-      if (*ppath == 0)
-        ++errors;
-
-      return errors;
-    }
-
-  assert (ppath && *ppath);
-
-  if (argzize_path (*ppath, &argz, &argz_len) != 0)
-    {
-      ++errors;
-      goto cleanup;
-    }
-
-  /* Convert BEFORE into an equivalent offset into ARGZ.  This only works
-     if *PPATH is already canonicalized, and hence does not change length
-     with respect to ARGZ.  We canonicalize each entry as it is added to
-     the search path, and don't call this function with (uncanonicalized)
-     user paths, so this is a fair assumption.  */
-  if (before)
-    {
-      assert (*ppath <= before);
-      assert (before - *ppath <= strlen (*ppath));
-
-      before = before - *ppath + argz;
-    }
-
-  if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
-    {
-      ++errors;
-      goto cleanup;
-    }
-
-  argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
-  LT_DLMEM_REASSIGN (*ppath, argz);
-
-cleanup:
-  LT_DLGNUNET_free (canonical);
-  LT_DLGNUNET_free (argz);
-
-  return errors;
-}
-
-int
-lt_dladdsearchdir (search_dir)
-     const char *search_dir;
-{
-  int errors = 0;
-
-  if (search_dir && *search_dir)
-    {
-      LT_DLGNUNET_mutex_lock ();
-      if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
-        ++errors;
-      LT_DLGNUNET_mutex_unlock ();
-    }
-
-  return errors;
-}
-
-int
-lt_dlinsertsearchdir (before, search_dir)
-     const char *before;
-     const char *search_dir;
-{
-  int errors = 0;
-
-  if (before)
-    {
-      LT_DLGNUNET_mutex_lock ();
-      if ((before < user_search_path)
-          || (before >= user_search_path + LT_STRLEN (user_search_path)))
-        {
-          LT_DLGNUNET_mutex_unlock ();
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
-          return 1;
-        }
-      LT_DLGNUNET_mutex_unlock ();
-    }
-
-  if (search_dir && *search_dir)
-    {
-      LT_DLGNUNET_mutex_lock ();
-      if (lt_dlpath_insertdir (&user_search_path,
-                               (char *) before, search_dir) != 0)
-        {
-          ++errors;
-        }
-      LT_DLGNUNET_mutex_unlock ();
-    }
-
-  return errors;
-}
-
-int
-lt_dlsetsearchpath (search_path)
-     const char *search_path;
-{
-  int errors = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-  LT_DLGNUNET_free (user_search_path);
-  LT_DLGNUNET_mutex_unlock ();
-
-  if (!search_path || !LT_STRLEN (search_path))
-    {
-      return errors;
-    }
-
-  LT_DLGNUNET_mutex_lock ();
-  if (canonicalize_path (search_path, &user_search_path) != 0)
-    ++errors;
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-const char *
-lt_dlgetsearchpath ()
-{
-  const char *saved_path;
-
-  LT_DLGNUNET_mutex_lock ();
-  saved_path = user_search_path;
-  LT_DLGNUNET_mutex_unlock ();
-
-  return saved_path;
-}
-
-int
-lt_dlmakeresident (handle)
-     lt_dlhandle handle;
-{
-  int errors = 0;
-
-  if (!handle)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
-      ++errors;
-    }
-  else
-    {
-      LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
-    }
-
-  return errors;
-}
-
-int
-lt_dlisresident (handle)
-     lt_dlhandle handle;
-{
-  if (!handle)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
-      return -1;
-    }
-
-  return LT_DLIS_RESIDENT (handle);
-}
-
-
-
-
-/* --- MODULE INFORMATION --- */
-
-const lt_dlinfo *
-lt_dlgetinfo (handle)
-     lt_dlhandle handle;
-{
-  if (!handle)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
-      return 0;
-    }
-
-  return &(handle->info);
-}
-
-lt_dlhandle
-lt_dlhandle_next (place)
-     lt_dlhandle place;
-{
-  return place ? place->next : handles;
-}
-
-int
-lt_dlforeach (func, data)
-     int (*func) LT_PARAMS ((lt_dlhandle handle, lt_ptr data));
-     lt_ptr data;
-{
-  int errors = 0;
-  lt_dlhandle cur;
-
-  LT_DLGNUNET_mutex_lock ();
-
-  cur = handles;
-  while (cur)
-    {
-      lt_dlhandle tmp = cur;
-
-      cur = cur->next;
-      if ((*func) (tmp, data))
-        {
-          ++errors;
-          break;
-        }
-    }
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-lt_dlcaller_id
-lt_dlcaller_register ()
-{
-  static lt_dlcaller_id last_caller_id = 0;
-  int result;
-
-  LT_DLGNUNET_mutex_lock ();
-  result = ++last_caller_id;
-  LT_DLGNUNET_mutex_unlock ();
-
-  return result;
-}
-
-lt_ptr
-lt_dlcaller_set_data (key, handle, data)
-     lt_dlcaller_id key;
-     lt_dlhandle handle;
-     lt_ptr data;
-{
-  int n_elements = 0;
-  lt_ptr stale = (lt_ptr) 0;
-  int i;
-
-  /* This needs to be locked so that the caller data can be updated
-     simultaneously by different threads.  */
-  LT_DLGNUNET_mutex_lock ();
-
-  if (handle->caller_data)
-    while (handle->caller_data[n_elements].key)
-      ++n_elements;
-
-  for (i = 0; i < n_elements; ++i)
-    {
-      if (handle->caller_data[i].key == key)
-        {
-          stale = handle->caller_data[i].data;
-          break;
-        }
-    }
-
-  /* Ensure that there is enough room in this handle's caller_data
-     array to accept a new element (and an empty end marker).  */
-  if (i == n_elements)
-    {
-      lt_caller_data *temp
-        = LT_DLGNUNET_realloc (lt_caller_data, handle->caller_data,
-                               2 + n_elements);
-
-      if (!temp)
-        {
-          stale = 0;
-          goto done;
-        }
-
-      handle->caller_data = temp;
-
-      /* We only need this if we needed to allocate a new caller_data.  */
-      handle->caller_data[i].key = key;
-      handle->caller_data[1 + i].key = 0;
-    }
-
-  handle->caller_data[i].data = data;
-
-done:
-  LT_DLGNUNET_mutex_unlock ();
-
-  return stale;
-}
-
-lt_ptr
-lt_dlcaller_get_data (key, handle)
-     lt_dlcaller_id key;
-     lt_dlhandle handle;
-{
-  lt_ptr result = (lt_ptr) 0;
-
-  /* This needs to be locked so that the caller data isn't updated by
-     another thread part way through this function.  */
-  LT_DLGNUNET_mutex_lock ();
-
-  /* Locate the index of the element with a matching KEY.  */
-  {
-    int i;
-    for (i = 0; handle->caller_data[i].key; ++i)
-      {
-        if (handle->caller_data[i].key == key)
-          {
-            result = handle->caller_data[i].data;
-            break;
-          }
-      }
-  }
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return result;
-}
-
-
-
-/* --- USER MODULE LOADER API --- */
-
-
-int
-lt_dlloader_add (place, dlloader, loader_name)
-     lt_dlloader *place;
-     const struct lt_user_dlloader *dlloader;
-     const char *loader_name;
-{
-  int errors = 0;
-  lt_dlloader *node = 0, *ptr = 0;
-
-  if ((dlloader == 0)           /* diagnose null parameters */
-      || (dlloader->module_open == 0)
-      || (dlloader->module_close == 0) || (dlloader->find_sym == 0))
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
-      return 1;
-    }
-
-  /* Create a new dlloader node with copies of the user callbacks.  */
-  node = LT_EGNUNET_malloc (lt_dlloader, 1);
-  if (!node)
-    return 1;
-
-  node->next = 0;
-  node->loader_name = loader_name;
-  node->sym_prefix = dlloader->sym_prefix;
-  node->dlloader_exit = dlloader->dlloader_exit;
-  node->module_open = dlloader->module_open;
-  node->module_close = dlloader->module_close;
-  node->find_sym = dlloader->find_sym;
-  node->dlloader_data = dlloader->dlloader_data;
-
-  LT_DLGNUNET_mutex_lock ();
-  if (!loaders)
-    {
-      /* If there are no loaders, NODE becomes the list! */
-      loaders = node;
-    }
-  else if (!place)
-    {
-      /* If PLACE is not set, add NODE to the end of the
-         LOADERS list. */
-      for (ptr = loaders; ptr->next; ptr = ptr->next)
-        {
-           /*NOWORK*/;
-        }
-
-      ptr->next = node;
-    }
-  else if (loaders == place)
-    {
-      /* If PLACE is the first loader, NODE goes first. */
-      node->next = place;
-      loaders = node;
-    }
-  else
-    {
-      /* Find the node immediately preceding PLACE. */
-      for (ptr = loaders; ptr->next != place; ptr = ptr->next)
-        {
-           /*NOWORK*/;
-        }
-
-      if (ptr->next != place)
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
-          ++errors;
-        }
-      else
-        {
-          /* Insert NODE between PTR and PLACE. */
-          node->next = place;
-          ptr->next = node;
-        }
-    }
-
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-int
-lt_dlloader_remove (loader_name)
-     const char *loader_name;
-{
-  lt_dlloader *place = lt_dlloader_find (loader_name);
-  lt_dlhandle handle;
-  int errors = 0;
-
-  if (!place)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
-      return 1;
-    }
-
-  LT_DLGNUNET_mutex_lock ();
-
-  /* Fail if there are any open modules which use this loader. */
-  for (handle = handles; handle; handle = handle->next)
-    {
-      if (handle->loader == place)
-        {
-          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
-          ++errors;
-          goto done;
-        }
-    }
-
-  if (place == loaders)
-    {
-      /* PLACE is the first loader in the list. */
-      loaders = loaders->next;
-    }
-  else
-    {
-      /* Find the loader before the one being removed. */
-      lt_dlloader *prev;
-      for (prev = loaders; prev->next; prev = prev->next)
-        {
-          if (!strcmp (prev->next->loader_name, loader_name))
-            {
-              break;
-            }
-        }
-
-      place = prev->next;
-      prev->next = prev->next->next;
-    }
-
-  if (place->dlloader_exit)
-    {
-      errors = place->dlloader_exit (place->dlloader_data);
-    }
-
-  LT_DLGNUNET_free (place);
-
-done:
-  LT_DLGNUNET_mutex_unlock ();
-
-  return errors;
-}
-
-lt_dlloader *
-lt_dlloader_next (place)
-     lt_dlloader *place;
-{
-  lt_dlloader *next;
-
-  LT_DLGNUNET_mutex_lock ();
-  next = place ? place->next : loaders;
-  LT_DLGNUNET_mutex_unlock ();
-
-  return next;
-}
-
-const char *
-lt_dlloader_name (place)
-     lt_dlloader *place;
-{
-  const char *name = 0;
-
-  if (place)
-    {
-      LT_DLGNUNET_mutex_lock ();
-      name = place ? place->loader_name : 0;
-      LT_DLGNUNET_mutex_unlock ();
-    }
-  else
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
-    }
-
-  return name;
-}
-
-lt_user_data *
-lt_dlloader_data (place)
-     lt_dlloader *place;
-{
-  lt_user_data *data = 0;
-
-  if (place)
-    {
-      LT_DLGNUNET_mutex_lock ();
-      data = place ? &(place->dlloader_data) : 0;
-      LT_DLGNUNET_mutex_unlock ();
-    }
-  else
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
-    }
-
-  return data;
-}
-
-lt_dlloader *
-lt_dlloader_find (loader_name)
-     const char *loader_name;
-{
-  lt_dlloader *place = 0;
-
-  LT_DLGNUNET_mutex_lock ();
-  for (place = loaders; place; place = place->next)
-    {
-      if (strcmp (place->loader_name, loader_name) == 0)
-        {
-          break;
-        }
-    }
-  LT_DLGNUNET_mutex_unlock ();
-
-  return place;
-}

Modified: GNUnet/libltdl/ltmain.sh
===================================================================
--- GNUnet/libltdl/ltmain.sh    2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/libltdl/ltmain.sh    2008-02-06 07:11:29 UTC (rev 6162)
@@ -43,7 +43,7 @@
 
 PROGRAM=ltmain.sh
 PACKAGE=libtool
-VERSION="1.5.24 Debian 1.5.24-1"
+VERSION="1.5.24 Debian 1.5.24-2"
 TIMESTAMP=" (1.1220.2.456 2007/06/24 02:25:32)"
 
 # Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).

Modified: GNUnet/src/applications/Makefile.am
===================================================================
--- GNUnet/src/applications/Makefile.am 2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/src/applications/Makefile.am 2008-02-06 07:11:29 UTC (rev 6162)
@@ -6,9 +6,6 @@
  SQLITE_DIR = sqstore_sqlite kvstore_sqlite dstore_sqlite
 endif
 
-if !MINGW
-# TESTBED_DIR = testbed
-endif
 if LINUX
  VPN_DIR = vpn
 endif
@@ -34,9 +31,7 @@
  traffic \
  transport \
  advertising \
- gap \
  dht \
  tracekit \
  $(VPN_DIR)
-# $(TESTBED_DIR) 
 # chat

Modified: GNUnet/src/applications/fs/Makefile.am
===================================================================
--- GNUnet/src/applications/fs/Makefile.am      2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/applications/fs/Makefile.am      2008-02-06 07:11:29 UTC (rev 
6162)
@@ -1,5 +1,5 @@
 SUBDIRS = \
- . module lib ecrs uritrack namespace fsui collection tools 
+ . gap lib ecrs uritrack namespace fsui collection tools 
 
 INCLUDES = -I$(top_srcdir)/src/include
 

Modified: GNUnet/src/applications/fs/ecrs/download.c
===================================================================
--- GNUnet/src/applications/fs/ecrs/download.c  2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/applications/fs/ecrs/download.c  2008-02-06 07:11:29 UTC (rev 
6162)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other 
contributing authors)
+     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 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,7 +19,7 @@
 */
 /**
  * @file applications/fs/ecrs/download.c
- * @brief GNUNET_ND_DOWNLOAD helper methods (which do the real work).
+ * @brief DOWNLOAD helper methods (which do the real work).
  * @author Christian Grothoff
  */
 
@@ -35,48 +35,114 @@
 #define DEBUG_DOWNLOAD GNUNET_NO
 
 /**
- * Highest TTL allowed? (equivalent of 25-50 HOPS distance!)
+ * Node-specific data (not shared, keep small!). 152 bytes.
+ * Nodes are kept in a doubly-linked list.
  */
-#define MAX_TTL (100 * TTL_DECREMENT)
+struct Node
+{
+  /**
+   * Pointer to shared data between all nodes (request manager,
+   * progress data, etc.).
+   */
+  struct RequestManager *ctx;
 
-/**
- * After how many retries do we print a warning?
- */
-#define MAX_TRIES 500
+  /**
+   * Previous entry in DLL.
+   */ 
+  struct Node * prev;
 
+  /**
+   * Next entry in DLL.
+   */
+  struct Node * next;
 
-/* ****************** IO context **************** */
+  /**
+   * What is the CHK for this block?
+   */
+  CHK chk;
 
+  /**
+   * At what offset (on the respective level!) is this
+   * block?
+   */
+  unsigned long long offset;
+
+  /**
+   * 0 for dblocks, >0 for iblocks.
+   */
+  unsigned int level;
+
+};
+
 /**
- * @brief IO context for reading-writing file blocks.
+ * @brief structure that keeps track of currently pending requests for
+ *        a download
  *
- * In GNUnet, files are stored in the form of a balanced tree, not
- * unlike INodes in unix filesystems. When we download files, the
- * inner nodes of the tree are stored under FILENAME.X (where X
- * characterizes the level of the node in the tree). If the download
- * is aborted and resumed later, these .X files can be used to avoid
- * downloading the inner blocks again.  The successfully received leaf
- * nodes in FILENAME (the target file) are of course also not
- * downloaded again.<p>
- *
- * The IOContext struct presents an easy api to access the various
- * dot-files. It uses function pointers to allow implementors to
- * provide a different mechanism (other than files on the drive) to
- * cache the IBlocks.
+ * Handle to the state of a request manager.  Here we keep track of
+ * which queries went out with which priorities and which nodes in
+ * the merkle-tree are waiting for the replies.
  */
-typedef struct IOContext
+struct RequestManager
 {
 
-  struct GNUNET_GE_Context *ectx;
+  /**
+   * Total number of bytes in the file.
+   */
+  unsigned long long total;
 
   /**
-   * A lock for synchronizing access.
+   * Number of bytes already obtained
    */
+  unsigned long long completed;
+  
+  /**
+   * Starting-offset in file (for partial download)
+   */
+  unsigned long long offset;
+
+  /**
+   * Length of the download (starting at offset).
+   */
+  unsigned long long length;
+
+  /**
+   * Time download was started.
+   */
+  GNUNET_CronTime startTime;
+
+  /**
+   * Mutex for synchronizing access to this struct
+   */
   struct GNUNET_Mutex *lock;
 
   /**
-   * The file handles for each level in the tree.
+   * Doubly linked list of all pending requests (head)
    */
+  struct Node * head;
+
+  /**
+   * Doubly linked list of all pending requests (tail)
+   */
+  struct Node * tail;
+
+  /**
+   * FSLIB context for issuing requests.
+   */
+  struct GNUNET_FS_SearchContext *sctx;
+
+  /**
+   * Context for error reporting.
+   */
+  struct GNUNET_GE_Context *ectx;
+
+  /**
+   * Configuration information.
+   */
+  struct GNUNET_GC_Configuration *cfg;
+
+  /**
+   * The file handles for each level in the download-tree.
+   */
   int *handles;
 
   /**
@@ -85,12 +151,51 @@
   char *filename;
 
   /**
+   * Main thread running the operation.
+   */
+  struct GNUNET_ThreadHandle * main;
+
+  /**
+   * Function to call when we make progress.
+   */
+  GNUNET_ECRS_DownloadProgressCallback dpcb;
+
+  /**
+   * Extra argument to dpcb.
+   */
+  void *dpcbClosure;
+
+  /**
+   * Identity of the peer having the content, or all-zeros
+   * if we don't know of such a peer.
+   */
+  GNUNET_PeerIdentity target;
+
+  /**
+   * Abort?  Flag that can be set at any time
+   * to abort the RM as soon as possible.
+   */
+  int abortFlag;
+
+  /**
+   * Do we have a specific peer from which we download
+   * from?
+   */
+  int have_target;
+
+  /**
+   * Desired anonymity level for the download.
+   */
+  unsigned int anonymityLevel;
+
+  /**
    * The depth of the file-tree.
    */
   unsigned int treedepth;
 
-} IOContext;
+};
 
+
 /**
  * Close the files in the IOContext and free
  * the associated resources. Does NOT free
@@ -103,30 +208,51 @@
  *     is not complete and may be resumed later.
  */
 static void
-freeIOC (IOContext * this, int unlinkTreeFiles)
+free_request_manager(struct RequestManager * rm,
+                    int unlinkTreeFiles)
 {
   int i;
   char *fn;
+  struct Node * pos;
 
-  for (i = 0; i <= this->treedepth; i++)
+  GNUNET_mutex_lock (rm->lock);
+  /* cannot hold lock during shutdown since
+     fslib may have to aquire it; but we can
+     flag that we are in the shutdown process
+     and start to ignore fslib events! */
+  rm->abortFlag = GNUNET_YES;
+  GNUNET_mutex_unlock (rm->lock);
+  GNUNET_FS_destroy_search_context(rm->sctx);
+  rm->sctx = NULL;
+  while (rm->head != NULL)
     {
-      if (this->handles[i] != -1)
+      pos = rm->head;
+      rm->head = pos->next;
+      GNUNET_free(pos);
+    }
+  rm->tail = NULL;
+  for (i = 0; i <= rm->treedepth; i++)
+    {
+      if (rm->handles[i] != -1)
         {
-          CLOSE (this->handles[i]);
-          this->handles[i] = -1;
+          CLOSE (rm->handles[i]);
+          rm->handles[i] = -1;
         }
     }
-  GNUNET_mutex_destroy (this->lock);
+  if (rm->lock != NULL)
+    GNUNET_mutex_destroy (rm->lock);
+  if (rm->main != NULL)
+    GNUNET_thread_release_self(rm->main);
   if (GNUNET_YES == unlinkTreeFiles)
     {
-      for (i = 1; i <= this->treedepth; i++)
+      for (i = 1; i <= rm->treedepth; i++)
         {
-          fn = GNUNET_malloc (strlen (this->filename) + 3);
-          strcpy (fn, this->filename);
+          fn = GNUNET_malloc (strlen (rm->filename) + 3);
+          strcpy (fn, rm->filename);
           strcat (fn, ".A");
           fn[strlen (fn) - 1] += i;
           if (0 != UNLINK (fn))
-            GNUNET_GE_LOG (this->ectx,
+            GNUNET_GE_LOG (rm->ectx,
                            GNUNET_GE_WARNING | GNUNET_GE_BULK |
                            GNUNET_GE_USER,
                            _("Could not unlink temporary file `%s': %s\n"),
@@ -134,78 +260,11 @@
           GNUNET_free (fn);
         }
     }
-  GNUNET_free (this->filename);
-  GNUNET_free (this->handles);
+  GNUNET_free_non_null (rm->filename);
+  GNUNET_free_non_null (rm->handles);
 }
 
 /**
- * Initialize an IOContext.
- *
- * @param this the context to initialize
- * @param no_temporaries disallow creation of temp files
- * @param filesize the size of the file
- * @param filename the name of the level-0 file
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-static int
-createIOContext (struct GNUNET_GE_Context *ectx,
-                 IOContext * this,
-                 int no_temporaries,
-                 unsigned long long filesize, const char *filename)
-{
-  int i;
-  char *fn;
-  struct stat st;
-
-  this->ectx = ectx;
-  GNUNET_GE_ASSERT (ectx, filename != NULL);
-  this->treedepth = GNUNET_ECRS_compute_depth (filesize);
-  this->lock = GNUNET_mutex_create (GNUNET_NO);
-  this->handles = GNUNET_malloc (sizeof (int) * (this->treedepth + 1));
-  this->filename = GNUNET_strdup (filename);
-
-  if ((0 == STAT (filename, &st)) && ((size_t) st.st_size > filesize))
-    {
-      /* if exists and oversized, truncate */
-      if (truncate (filename, filesize) != 0)
-        {
-          GNUNET_GE_LOG_STRERROR_FILE (ectx,
-                                       GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
-                                       GNUNET_GE_BULK, "truncate", filename);
-          return GNUNET_SYSERR;
-        }
-    }
-  for (i = 0; i <= this->treedepth; i++)
-    this->handles[i] = -1;
-
-  for (i = 0; i <= this->treedepth; i++)
-    {
-      if ((i == 0) || (no_temporaries != GNUNET_YES))
-        {
-          fn = GNUNET_malloc (strlen (filename) + 3);
-          strcpy (fn, filename);
-          if (i > 0)
-            {
-              strcat (fn, ".A");
-              fn[strlen (fn) - 1] += i;
-            }
-          this->handles[i] = GNUNET_disk_file_open (ectx,
-                                                    fn,
-                                                    O_CREAT | O_RDWR,
-                                                    S_IRUSR | S_IWUSR);
-          if (this->handles[i] < 0)
-            {
-              freeIOC (this, GNUNET_YES);
-              GNUNET_free (fn);
-              return GNUNET_SYSERR;
-            }
-          GNUNET_free (fn);
-        }
-    }
-  return GNUNET_OK;
-}
-
-/**
  * Read method.
  *
  * @param this reference to the IOContext
@@ -216,21 +275,16 @@
  * @return number of bytes read, GNUNET_SYSERR on error
  */
 static int
-readFromIOC (IOContext * this,
+read_from_files (struct RequestManager * this,
              unsigned int level,
              unsigned long long pos, void *buf, unsigned int len)
 {
   int ret;
 
-  GNUNET_mutex_lock (this->lock);
   if (this->handles[level] == -1)
-    {
-      GNUNET_mutex_unlock (this->lock);
-      return GNUNET_SYSERR;
-    }
+    return GNUNET_SYSERR;    
   LSEEK (this->handles[level], pos, SEEK_SET);
   ret = READ (this->handles[level], buf, len);
-  GNUNET_mutex_unlock (this->lock);
 #if DEBUG_DOWNLOAD
   GNUNET_GE_LOG (this->ectx,
                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
@@ -251,18 +305,14 @@
  * @return number of bytes written, GNUNET_SYSERR on error
  */
 static int
-writeToIOC (IOContext * this,
+write_to_files (struct RequestManager * this,
             unsigned int level,
             unsigned long long pos, void *buf, unsigned int len)
 {
   int ret;
 
-  GNUNET_mutex_lock (this->lock);
   if ((this->handles[level] == -1) && (level > 0))
-    {
-      GNUNET_mutex_unlock (this->lock);
-      return len;               /* lie -- no temps allowed... */
-    }
+    return len;               /* lie -- no temps allowed... */    
   LSEEK (this->handles[level], pos, SEEK_SET);
   ret = WRITE (this->handles[level], buf, len);
   if (ret != len)
@@ -272,400 +322,77 @@
                      _("Write(%d, %p, %d) failed: %s\n"),
                      this->handles[level], buf, len, STRERROR (errno));
     }
-  GNUNET_mutex_unlock (this->lock);
-#if DEBUG_DOWNLOAD
-  GNUNET_GE_LOG (this->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "IOC write at level %u offset %llu writes %u\n", level, pos,
-                 len);
-#endif
   return ret;
 }
 
-/* ********************* request manager **************** */
+static int
+content_receive_callback (const GNUNET_HashCode * query,
+             const GNUNET_DatastoreValue * reply, void *cls,
+             unsigned long long uid);
 
 /**
- * Node-specific data (not shared, keep small!). 56 bytes.
- */
-typedef struct
-{
-  /**
-   * Pointer to shared data between all nodes (request manager,
-   * progress data, etc.).
-   */
-  struct CommonCtx *ctx;
-
-  /**
-   * What is the CHK for this block?
-   */
-  CHK chk;
-
-  /**
-   * At what offset (on the respective level!) is this
-   * block?
-   */
-  unsigned long long offset;
-
-  /**
-   * 0 for dblocks, >0 for iblocks.
-   */
-  unsigned int level;
-} NodeClosure;
-
-/**
- * @brief Format of a request as tracked by the RequestManager.
+ * Queue a request for execution.
  *
- * This structure together with the NodeContext determine the memory
- * requirements, so try keeping it as small as possible!  (currently
- * 32 bytes, plus 56 in the NodeContext => roughly 88 byte per block!)
- *
- * Estimate: max ~12 MB memory for a 4 GB file in the end (assuming
- * maximum parallelism, which is likely, so we are really going to use
- * about 12 MB, but that should be acceptable).
- *
- * Design question: why not union RequestEntry and NodeClosure (would
- * save yet another 4 bytes / entry)?
- */
-typedef struct RequestEntry
-{
-
-  /**
-   * The node for which this entry keeps data.
-   */
-  NodeClosure *node;
-
-  /**
-   * Search handle of the last request (NULL if never
-   * requested).
-   */
-  struct GNUNET_FS_SearchHandle *searchHandle;
-
-  /**
-   * Last time the query was send.
-   */
-  GNUNET_CronTime lasttime;
-
-  /**
-   * Timeout used for the last search (ttl in request is
-   * = lastTimeout - lasttime modulo corrections in gap
-   * with respect to priority cap).
-   */
-  GNUNET_CronTime lastTimeout;
-
-  /**
-   * How long have we been actively trying this one?
-   */
-  unsigned int tries;
-
-  /**
-   * Priority used for the last request.
-   */
-  unsigned int lastPriority;
-
-} RequestEntry;
-
-/**
- * @brief structure that keeps track of currently pending requests for
- *        a download
- *
- * Handle to the state of a request manager.  Here we keep track of
- * which queries went out with which priorities and which nodes in
- * the merkle-tree are waiting for the replies.
- */
-typedef struct RequestManager
-{
-
-  /**
-   * Mutex for synchronizing access to this struct
-   */
-  struct GNUNET_Mutex *lock;
-
-  /**
-   * Current list of all pending requests
-   */
-  RequestEntry **requestList;
-
-  struct GNUNET_FS_SearchContext *sctx;
-
-  struct GNUNET_ThreadHandle *requestThread;
-
-  struct GNUNET_GE_Context *ectx;
-
-  struct GNUNET_GC_Configuration *cfg;
-
-  GNUNET_PeerIdentity target;
-
-  /**
-   * Number of pending requests (highest used index)
-   */
-  unsigned int requestListIndex;
-
-  /**
-   * Number of entries allocated for requestList
-   */
-  unsigned int requestListSize;
-
-  /**
-   * Current "good" TTL (initial) [64s].  In HOST byte order.
-   */
-  unsigned int initialTTL;
-
-  /**
-   * Congestion window.  How many messages
-   * should be pending concurrently?
-   */
-  unsigned int congestionWindow;
-
-  /**
-   * Slow-start threshold (see RFC 2001)
-   */
-  unsigned int ssthresh;
-
-  /**
-   * What was the last time we updated ssthresh?
-   */
-  GNUNET_Int32Time lastDET;
-
-  /**
-   * Abort?  Flag that can be set at any time
-   * to abort the RM as soon as possible.
-   */
-  int abortFlag;
-
-  /**
-   * Is the request manager being destroyed?
-   * (if so, accessing the request list is illegal!)
-   */
-  int shutdown;
-
-  /**
-   * Do we have a specific peer from which we download
-   * from?
-   */
-  int have_target;
-
-} RequestManager;
-
-/**
- * Create a request manager.  Will create the request manager
- * datastructures. Use destroyRequestManager to abort and/or to free
- * resources after the download is complete.
- *
- * @return NULL on error
- */
-static RequestManager *
-createRequestManager (struct GNUNET_GE_Context *ectx,
-                      struct GNUNET_GC_Configuration *cfg)
-{
-  RequestManager *rm;
-
-  rm = GNUNET_malloc (sizeof (RequestManager));
-  rm->shutdown = GNUNET_NO;
-  rm->lock = GNUNET_mutex_create (GNUNET_YES);
-  rm->sctx = GNUNET_FS_create_search_context (ectx, cfg, rm->lock);
-  if (rm->sctx == NULL)
-    {
-      GNUNET_mutex_destroy (rm->lock);
-      GNUNET_free (rm);
-      return NULL;
-    }
-  rm->ectx = ectx;
-  rm->cfg = cfg;
-  rm->requestThread = GNUNET_thread_get_self ();
-  rm->abortFlag = GNUNET_NO;
-  rm->lastDET = 0;
-  rm->requestListIndex = 0;
-  rm->requestListSize = 0;
-  rm->requestList = NULL;
-  rm->have_target = GNUNET_NO;
-  GNUNET_array_grow (rm->requestList, rm->requestListSize, 256);
-  rm->initialTTL = 5 * GNUNET_CRON_SECONDS;
-  /* RFC 2001 suggests to use 1 segment size initially;
-     Given 1500 octets per message in GNUnet, we would
-     have 2-3 queries of maximum size (552); but since
-     we are multi-casting to many peers at the same
-     time AND since queries can be much smaller,
-     we do WHAT??? */
-  rm->congestionWindow = 1;     /* RSS is 1 */
-  rm->ssthresh = 65535;
-#if DEBUG_DOWNLOAD
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "created request manager %p\n", rm);
-#endif
-  return rm;
-}
-
-/**
- * Destroy the resources associated with a request manager.
- * Invoke this method to abort the download or to clean up
- * after the download is complete.
- *
  * @param rm the request manager struct from createRequestManager
+ * @param node the node to call once a reply is received
  */
 static void
-destroyRequestManager (RequestManager * rm)
+addRequest (struct Node * node)
 {
-  int i;
+  struct RequestManager * rm = node->ctx;
 
-#if DEBUG_DOWNLOAD
-  GNUNET_GE_LOG (rm->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "destroying request manager %p\n", rm);
-#endif
-  GNUNET_mutex_lock (rm->lock);
-  /* cannot hold lock during shutdown since
-     fslib may have to aquire it; but we can
-     flag that we are in the shutdown process
-     and start to ignore fslib events! */
-  rm->shutdown = GNUNET_YES;
-  GNUNET_mutex_unlock (rm->lock);
-  for (i = 0; i < rm->requestListIndex; i++)
-    {
-      if (rm->requestList[i]->searchHandle != NULL)
-        GNUNET_FS_stop_search (rm->sctx, rm->requestList[i]->searchHandle);
-      GNUNET_free (rm->requestList[i]->node);
-      GNUNET_free (rm->requestList[i]);
-    }
-  GNUNET_array_grow (rm->requestList, rm->requestListSize, 0);
-  GNUNET_FS_destroy_search_context (rm->sctx);
-  rm->sctx = NULL;
-  GNUNET_mutex_destroy (rm->lock);
-  GNUNET_thread_release_self (rm->requestThread);
-  GNUNET_free (rm);
+  node->next = rm->head;
+  node->next->prev = node;
+  node->prev = NULL;
+  rm->head = node;
+  if (rm->tail == NULL)
+    rm->tail = node;
+  GNUNET_FS_start_search (rm->sctx,
+                         rm->have_target == GNUNET_NO ? NULL : &rm->target,
+                         GNUNET_ECRS_BLOCKTYPE_DATA, 1,
+                         &node->chk.query,
+                         rm->anonymityLevel,
+                         &content_receive_callback, 
+                         node);
 }
 
-/**
- * We are approaching the end of the download.  Cut
- * all TTLs in half.
- */
 static void
-requestManagerEndgame (RequestManager * rm)
+signal_abort(struct RequestManager * rm)
 {
-  int i;
-
-  GNUNET_mutex_lock (rm->lock);
-  if (rm->shutdown == GNUNET_NO)
-    {
-      for (i = 0; i < rm->requestListIndex; i++)
-        {
-          RequestEntry *entry = rm->requestList[i];
-          /* cut TTL in half */
-          entry->lasttime += (entry->lasttime + entry->lastTimeout) / 2;
-        }
-    }
-  GNUNET_mutex_unlock (rm->lock);
+  rm->abortFlag = GNUNET_YES;
+  GNUNET_thread_stop_sleep(rm->main);
 }
 
 /**
- * Queue a request for execution.
+ * Dequeue a request.
  *
- * @param rm the request manager struct from createRequestManager
- * @param node the node to call once a reply is received
- */
-static void
-addRequest (RequestManager * rm, NodeClosure * node)
-{
-  RequestEntry *entry;
-#if DEBUG_DOWNLOAD
-  GNUNET_EncName enc;
-
-  IF_GELOG (rm->ectx,
-            GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-            GNUNET_hash_to_enc (&node->chk.query, &enc));
-  GNUNET_GE_LOG (rm->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Queuing request (query: %s)\n", &enc);
-#endif
-
-  GNUNET_GE_ASSERT (rm->ectx, node != NULL);
-  entry = GNUNET_malloc (sizeof (RequestEntry));
-  entry->node = node;
-  entry->lasttime = 0;          /* never sent */
-  entry->lastTimeout = 0;
-  entry->tries = 0;             /* not tried so far */
-  entry->lastPriority = 0;
-  entry->searchHandle = NULL;
-  GNUNET_mutex_lock (rm->lock);
-  if (rm->shutdown == GNUNET_NO)
-    {
-      GNUNET_GE_ASSERT (rm->ectx, rm->requestListSize > 0);
-      if (rm->requestListSize == rm->requestListIndex)
-        GNUNET_array_grow (rm->requestList, rm->requestListSize,
-                           rm->requestListSize * 2);
-      rm->requestList[rm->requestListIndex++] = entry;
-    }
-  else
-    {
-      GNUNET_GE_BREAK (rm->ectx, 0);
-      GNUNET_free (entry);
-    }
-  GNUNET_mutex_unlock (rm->lock);
-}
-
-
-/**
- * Cancel a request.
- *
  * @param this the request manager struct from createRequestManager
  * @param node the block for which the request is canceled
  */
 static void
-delRequest (RequestManager * rm, NodeClosure * node)
+delete_node (struct Node * node)
 {
-  int i;
-  RequestEntry *re;
+  struct RequestManager * rm = node->ctx;
 
-  GNUNET_mutex_lock (rm->lock);
-  if (rm->shutdown == GNUNET_NO)
-    {
-      for (i = 0; i < rm->requestListIndex; i++)
-        {
-          re = rm->requestList[i];
-          if (re->node == node)
-            {
-              rm->requestList[i] = rm->requestList[--rm->requestListIndex];
-              rm->requestList[rm->requestListIndex] = NULL;
-              GNUNET_mutex_unlock (rm->lock);
-              if (NULL != re->searchHandle)
-                GNUNET_FS_stop_search (rm->sctx, re->searchHandle);
-              GNUNET_free (re);
-              return;
-            }
-        }
-    }
-  GNUNET_mutex_unlock (rm->lock);
-  GNUNET_GE_BREAK (rm->ectx, 0);        /* uh uh - at least a memory leak... */
+  if (node->prev == NULL)
+    rm->head = node->next;
+  else
+    node->prev->next = node->next;
+  if (node->next == NULL)
+    rm->tail = node->prev;
+  else
+    node->next->prev = node->prev;
+  GNUNET_free(node);
+  if (rm->head == NULL)
+    signal_abort(rm);
 }
 
-
-/* ****************** tree nodes ***************** */
-
 /**
- * Data shared between all tree nodes.
- * Design Question: integrate with IOContext?
- */
-typedef struct CommonCtx
-{
-  unsigned long long total;
-  unsigned long long completed;
-  unsigned long long offset;
-  unsigned long long length;
-  GNUNET_CronTime startTime;
-  GNUNET_CronTime TTL_DECREMENT;
-  RequestManager *rm;
-  IOContext *ioc;
-  GNUNET_ECRS_DownloadProgressCallback dpcb;
-  void *dpcbClosure;
-  unsigned int anonymityLevel;
-} CommonCtx;
-
-/**
  * Compute how many bytes of data are stored in
  * this node.
  */
 static unsigned int
-getNodeSize (const NodeClosure * node)
+get_node_size (const struct Node * node)
 {
   unsigned int i;
   unsigned int ret;
@@ -673,7 +400,7 @@
   unsigned long long spos;
   unsigned long long epos;
 
-  GNUNET_GE_ASSERT (node->ctx->rm->ectx, node->offset < node->ctx->total);
+  GNUNET_GE_ASSERT (node->ctx->ectx, node->offset < node->ctx->total);
   if (node->level == 0)
     {
       ret = DBLOCK_SIZE;
@@ -707,111 +434,38 @@
 }
 
 /**
- * Update progress information. Also updates
- * request manager structures, like ttl.
+ * Notify client about progress.
  */
 static void
-updateProgress (const NodeClosure * node, const char *data, unsigned int size)
+notify_client_about_progress (const struct Node * node, const char *data, 
unsigned int size)
 {
-  RequestManager *rm;
-  RequestEntry *entry;
-  int pos;
-  int i;
+  struct RequestManager *rm = node->ctx;
+  GNUNET_CronTime eta;
 
-  /* locking? */
-  if (node->level == 0)
-    {
-      GNUNET_CronTime eta;
-
-      node->ctx->completed += size;
-      eta = GNUNET_get_time ();
-      if (node->ctx->completed > 0)
-        {
-          eta = (GNUNET_CronTime) (node->ctx->startTime +
-                                   (((double) (eta - node->ctx->startTime) /
-                                     (double) node->ctx->completed)) *
-                                   (double) node->ctx->length);
-        }
-      if (node->ctx->dpcb != NULL)
-        {
-          node->ctx->dpcb (node->ctx->length,
-                           node->ctx->completed,
-                           eta,
-                           node->offset, data, size, node->ctx->dpcbClosure);
-        }
-    }
-  rm = node->ctx->rm;
-  GNUNET_mutex_lock (rm->lock);
-  if (rm->shutdown == GNUNET_YES)
-    {
-      GNUNET_mutex_unlock (rm->lock);
-      return;
-    }
-
-  /* check type of reply msg, fill in query */
-  pos = -1;
-  /* find which query matches the reply, call the callback
-     and recycle the slot */
-  for (i = 0; i < rm->requestListIndex; i++)
-    if (rm->requestList[i]->node == node)
-      pos = i;
-  if (pos == -1)
-    {
-      /* GNUNET_GE_BREAK(ectx, 0); *//* should never happen */
-      GNUNET_mutex_unlock (rm->lock);
-      return;
-    }
-  entry = rm->requestList[pos];
-
-  if ((entry->lasttime < GNUNET_get_time ()) && (entry->lasttime != 0))
-    {
-      unsigned int weight = 15;
-      unsigned int ettl = entry->lastTimeout - entry->lasttime;
-      if ((ettl > 4 * rm->initialTTL) &&
-          ((GNUNET_get_time () - entry->lasttime) < rm->initialTTL))
-        {
-          weight = 127;
-          /* eTTL is MUCH bigger than what we currently expect AND the time
-             between the last query and the reply was in the range of the
-             expected TTL => don't take ettl too much into account! */
-        }
-      rm->initialTTL = ((rm->initialTTL) * weight + ettl) / (weight + 1);
-
-      /* RFC 2001: increase cwnd; note that we can't really discriminate 
between
-         slow-start and cong. control mode since our RSS is too small... */
-      if (rm->congestionWindow < rm->ssthresh)
-        rm->congestionWindow += 2;      /* slow start */
-      else
-        rm->congestionWindow += 1;      /* slower start :-) */
-    }
-  if (entry->tries > 1)
-    {
-      GNUNET_Int32Time nowTT;
-
-      GNUNET_get_time_int32 (&nowTT);
-      if ((nowTT - rm->initialTTL) > rm->lastDET)
-        {
-          /* only consider congestion control every
-             "average" TTL seconds, otherwise the system
-             reacts to events that are far too old! */
-          /* we performed retransmission, treat as congestion (RFC 2001) */
-          rm->ssthresh = rm->congestionWindow / 2;
-          if (rm->ssthresh < 2)
-            rm->ssthresh = 2;
-          rm->congestionWindow = rm->ssthresh + 1;
-          rm->lastDET = nowTT;
-        }
-    }
-  GNUNET_mutex_unlock (rm->lock);
+  if ( (rm->abortFlag == GNUNET_YES) ||
+       (node->level != 0) )
+    return;    
+  rm->completed += size;
+  eta = GNUNET_get_time ();
+  if (rm->completed > 0)        
+    eta = (GNUNET_CronTime) (rm->startTime +
+                            (((double) (eta - rm->startTime) /
+                              (double) rm->completed)) *
+                            (double) rm->length);        
+  if (rm->dpcb != NULL)
+    rm->dpcb (rm->length,
+             rm->completed,
+             eta,
+             node->offset, data, size, rm->dpcbClosure);   
 }
 
 
 /**
- * GNUNET_ND_DOWNLOAD children of this IBlock.
+ * DOWNLOAD children of this IBlock.
  *
  * @param rm the node that should downloaded
  */
-static void iblock_download_children (NodeClosure * node,
+static void iblock_download_children (struct Node * node,
                                       char *data, unsigned int size);
 
 /**
@@ -829,7 +483,7 @@
  * @return GNUNET_YES if present, GNUNET_NO if not.
  */
 static int
-checkPresent (NodeClosure * node)
+check_node_present (struct Node * node)
 {
   int res;
   int ret;
@@ -837,27 +491,24 @@
   unsigned int size;
   GNUNET_HashCode hc;
 
-  size = getNodeSize (node);
-
+  size = get_node_size (node);
   /* first check if node is within range.
      For now, keeping it simple, we only do
      this for level-0 nodes */
-  if ((node->level == 0) &&
-      ((node->offset + size < node->ctx->offset) ||
-       (node->offset >= node->ctx->offset + node->ctx->length)))
+  if ( (node->level == 0) &&
+       ((node->offset + size < node->ctx->offset) ||
+       (node->offset >= node->ctx->offset + node->ctx->length)) )
     return GNUNET_YES;
-
   data = GNUNET_malloc (size);
-  res = readFromIOC (node->ctx->ioc, node->level, node->offset, data, size);
+  res = read_from_files (node->ctx, node->level, node->offset, data, size);
   if (res == size)
     {
       GNUNET_hash (data, size, &hc);
       if (0 == memcmp (&hc, &node->chk.key, sizeof (GNUNET_HashCode)))
         {
-          updateProgress (node, data, size);
+          notify_client_about_progress (node, data, size);
           if (node->level > 0)
             iblock_download_children (node, data, size);
-
           ret = GNUNET_YES;
         }
       else
@@ -866,27 +517,20 @@
   else
     ret = GNUNET_NO;
   GNUNET_free (data);
-#if DEBUG_DOWNLOAD
-  GNUNET_GE_LOG (node->ctx->rm->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Checked presence of block at %llu level %u.  Result: %s\n",
-                 node->offset, node->level, ret == GNUNET_YES ? "YES" : "NO");
-#endif
-
   return ret;
 }
 
 /**
- * GNUNET_ND_DOWNLOAD children of this IBlock.
+ * DOWNLOAD children of this IBlock.
  *
  * @param this the node that should downloaded
  */
 static void
-iblock_download_children (NodeClosure * node, char *data, unsigned int size)
+iblock_download_children (struct Node * node, char *data, unsigned int size)
 {
-  struct GNUNET_GE_Context *ectx = node->ctx->rm->ectx;
+  struct GNUNET_GE_Context *ectx = node->ctx->ectx;
   int i;
-  NodeClosure *child;
+  struct Node *child;
   unsigned int childcount;
   CHK *chks;
   unsigned int levelSize;
@@ -912,7 +556,7 @@
   chks = (CHK *) data;
   for (i = 0; i < childcount; i++)
     {
-      child = GNUNET_malloc (sizeof (NodeClosure));
+      child = GNUNET_malloc (sizeof (struct Node));      
       child->ctx = node->ctx;
       child->chk = chks[i];
       child->offset = baseOffset + i * levelSize;
@@ -920,8 +564,8 @@
       child->level = node->level - 1;
       GNUNET_GE_ASSERT (ectx, (child->level != 0) ||
                         ((child->offset % DBLOCK_SIZE) == 0));
-      if (GNUNET_NO == checkPresent (child))
-        addRequest (node->ctx->rm, child);
+      if (GNUNET_NO == check_node_present (child))
+        addRequest (child);
       else
         GNUNET_free (child);    /* done already! */
     }
@@ -938,21 +582,18 @@
  * @returns GNUNET_OK on success, GNUNET_SYSERR on error
  */
 static int
-decryptContent (const char *data,
+decrypt_content (const char *data,
                 unsigned int size, const GNUNET_HashCode * hashcode,
                 char *result)
 {
   GNUNET_AES_InitializationVector iv;
   GNUNET_AES_SessionKey skey;
 
-  GNUNET_GE_ASSERT (NULL, (data != NULL) && (hashcode != NULL)
-                    && (result != NULL));
-  /* get key and init value from the GNUNET_hash code */
+  /* get key and init value from the GNUNET_HashCode */
   GNUNET_hash_to_AES_key (hashcode, &skey, &iv);
   return GNUNET_AES_decrypt (&skey, data, size, &iv, result);
 }
 
-
 /**
  * We received a CHK reply for a block. Decrypt.  Note
  * that the caller (fslib) has already aquired the
@@ -967,362 +608,130 @@
  * @return GNUNET_OK if the reply was valid, GNUNET_SYSERR on error
  */
 static int
-nodeReceive (const GNUNET_HashCode * query,
+content_receive_callback (const GNUNET_HashCode * query,
              const GNUNET_DatastoreValue * reply, void *cls,
              unsigned long long uid)
 {
-  NodeClosure *node = cls;
-  struct GNUNET_GE_Context *ectx = node->ctx->rm->ectx;
+  struct Node *node = cls;
+  struct RequestManager * rm = node->ctx;
+  struct GNUNET_GE_Context *ectx = rm->ectx;
   GNUNET_HashCode hc;
   unsigned int size;
-  int i;
   char *data;
-#if DEBUG_DOWNLOAD
-  GNUNET_EncName enc;
 
-  IF_GELOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-            GNUNET_hash_to_enc (query, &enc));
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Receiving reply to query `%s'\n", &enc);
-#endif
+  GNUNET_mutex_lock (rm->lock);
+  if (rm->abortFlag != GNUNET_NO) {
+    GNUNET_mutex_unlock (rm->lock);
+    return GNUNET_SYSERR;
+  }
   GNUNET_GE_ASSERT (ectx,
                     0 == memcmp (query, &node->chk.query,
                                  sizeof (GNUNET_HashCode)));
   size = ntohl (reply->size) - sizeof (GNUNET_DatastoreValue);
   if ((size <= sizeof (DBlock)) ||
-      (size - sizeof (DBlock) != getNodeSize (node)))
+      (size - sizeof (DBlock) != get_node_size (node)))
     {
       GNUNET_GE_BREAK (ectx, 0);
+      GNUNET_mutex_unlock (rm->lock);
       return GNUNET_SYSERR;     /* invalid size! */
     }
   size -= sizeof (DBlock);
   data = GNUNET_malloc (size);
-  if (GNUNET_SYSERR == decryptContent ((char *) &((DBlock *) & reply[1])[1],
+  if (GNUNET_SYSERR == decrypt_content ((char *) &((DBlock *) & reply[1])[1],
                                        size, &node->chk.key, data))
     GNUNET_GE_ASSERT (ectx, 0);
   GNUNET_hash (data, size, &hc);
   if (0 != memcmp (&hc, &node->chk.key, sizeof (GNUNET_HashCode)))
     {
-      delRequest (node->ctx->rm, node);
       GNUNET_free (data);
       GNUNET_GE_BREAK (ectx, 0);
       GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
                      _("Decrypted content does not match key. "
                        "This is either a bug or a maliciously inserted "
                        "file. Download aborted.\n"));
-      node->ctx->rm->abortFlag = GNUNET_YES;
+      signal_abort(rm);
+      GNUNET_mutex_unlock (rm->lock);
       return GNUNET_SYSERR;
     }
-  if (size != writeToIOC (node->ctx->ioc,
+  if (size != write_to_files (rm,
                           node->level, node->offset, data, size))
     {
       GNUNET_GE_LOG_STRERROR (ectx,
                               GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
                               GNUNET_GE_USER | GNUNET_GE_BULK, "WRITE");
-      node->ctx->rm->abortFlag = GNUNET_YES;
+      signal_abort(rm);
+      GNUNET_mutex_unlock (rm->lock);
       return GNUNET_SYSERR;
     }
-  updateProgress (node, data, size);
+  notify_client_about_progress (node, data, size);
   if (node->level > 0)
     iblock_download_children (node, data, size);
   /* request satisfied, stop requesting! */
-  delRequest (node->ctx->rm, node);
-
-  for (i = 0; i < 10; i++)
-    {
-      if ((node->ctx->completed * 10000L >
-           node->ctx->length * (10000L - (1024 >> i))) &&
-          ((node->ctx->completed - size) * 10000L <=
-           node->ctx->length * (10000L - (1024 >> i))))
-        {
-          /* end-game boundary crossed, slaughter TTLs */
-          requestManagerEndgame (node->ctx->rm);
-        }
-    }
-  GNUNET_GE_ASSERT (node->ctx->rm->ectx,
-                    node->ctx->rm->requestThread != NULL);
-  GNUNET_thread_stop_sleep (node->ctx->rm->requestThread);
+  delete_node (node);
   GNUNET_free (data);
-  GNUNET_free (node);
+  GNUNET_mutex_unlock (rm->lock);
   return GNUNET_OK;
 }
 
 
 /**
- * Send the request from the requestList[requestIndex] out onto
- * the network.
- *
- * @param this the RequestManager
- * @param requestIndex the index of the Request to issue
+ * Helper function to sanitize filename
+ * and create necessary directories. 
  */
-static void
-issueRequest (RequestManager * rm, int requestIndex)
+static char *
+get_real_download_filename(struct GNUNET_GE_Context * ectx,
+                          const char * filename)
 {
-  static unsigned int lastmpriority;
-  static GNUNET_CronTime lastmpritime;
-  RequestEntry *entry;
-  GNUNET_CronTime now;
-  unsigned int priority;
-  unsigned int mpriority;
-  GNUNET_CronTime timeout;
-  unsigned int ttl;
-  int TTL_DECREMENT;
-#if DEBUG_DOWNLOAD
-  GNUNET_EncName enc;
-#endif
+  struct stat buf;
+  char *realFN;
+  char *path;
+  char *pos;
 
-  now = GNUNET_get_time ();
-  entry = rm->requestList[requestIndex];
-
-  /* compute priority */
-  if (lastmpritime + 10 * GNUNET_CRON_SECONDS < now)
+  if ((filename[strlen (filename) - 1] == '/') ||
+      (filename[strlen (filename) - 1] == '\\'))
     {
-      /* only update avg. priority at most every
-         10 seconds */
-      struct GNUNET_ClientServerConnection *sock;
-
-      sock = GNUNET_client_connection_create (rm->ectx, rm->cfg);
-      lastmpriority = GNUNET_FS_get_current_average_priority (sock);
-      lastmpritime = now;
-      GNUNET_client_connection_destroy (sock);
+      realFN =
+        GNUNET_malloc (strlen (filename) + strlen (GNUNET_DIRECTORY_EXT));
+      strcpy (realFN, filename);
+      realFN[strlen (filename) - 1] = '\0';
+      strcat (realFN, GNUNET_DIRECTORY_EXT);
     }
-  mpriority = lastmpriority;
-  priority =
-    entry->lastPriority + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                                             1 + entry->tries);
-  if (priority > mpriority)
-    {
-      /* mpriority is (2 * (current average priority + 2)) and
-         is used as the maximum priority that we use; if the
-         calculated tpriority is above it, we reduce tpriority
-         to random value between the average (mpriority/2) but
-         bounded by mpriority */
-      priority =
-        1 + mpriority / 2 +
-        (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 2 + mpriority / 2));
-    }
-  if (priority > 0x0FFFFFF)
-    priority = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 0xFFFFFF);       
 /* bound! */
-
-  /* compute TTL */
-
-  TTL_DECREMENT = entry->node->ctx->TTL_DECREMENT;
-
-  if (entry->lastTimeout + TTL_DECREMENT > now)
-    GNUNET_GE_BREAK (rm->ectx, 0);
-  if (entry->lasttime == 0)
-    {
-      timeout = now + rm->initialTTL;
-    }
   else
     {
-      ttl = entry->lastTimeout - entry->lasttime;
-      if (ttl > MAX_TTL)
-        {
-          ttl =
-            MAX_TTL + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                                         2 * TTL_DECREMENT);
-        }
-      else if (ttl > rm->initialTTL)
-        {
-          /* switch to slow back-off */
-          unsigned int rd;
-          if (rm->initialTTL == 0)
-            rd = ttl;
-          else
-            rd = ttl / rm->initialTTL;
-          if (rd == 0)
-            rd = 1;             /* how? */
-          rd = TTL_DECREMENT / rd;
-          if (rd == 0)
-            rd = 1;
-          ttl +=
-            GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                               50 * GNUNET_CRON_MILLISECONDS + rd);
-          /* rd == TTL_DECREMENT / (con->ttl / rm->initialTTL) + saveguards
-             50ms: minimum increment */
-        }
-      else
-        {
-          ttl += GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, ttl + 2 * 
TTL_DECREMENT);       /* exponential backoff with random factor */
-        }
-      if (ttl > (priority + 8) * TTL_DECREMENT)
-        ttl = (priority + 8) * TTL_DECREMENT;   /* see adjustTTL in gap */
-      timeout = now + ttl;
+      realFN = GNUNET_strdup (filename);
     }
-
-#if DEBUG_DOWNLOAD
-  IF_GELOG (ectx,
-            GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-            GNUNET_hash_to_enc (&entry->node->chk.query, &enc));
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Starting FS search for %s:%llu:%u `%s'\n",
-                 entry->node->ctx->ioc->filename,
-                 entry->node->offset, entry->node->level, &enc);
-#endif
-
-  if (entry->searchHandle != NULL)
-    GNUNET_FS_stop_search (rm->sctx, entry->searchHandle);
-  entry->searchHandle
-    = GNUNET_FS_start_search (rm->sctx,
-                              rm->have_target ==
-                              GNUNET_NO ? NULL : &rm->target,
-                              GNUNET_ECRS_BLOCKTYPE_DATA, 1,
-                              &entry->node->chk.query,
-                              entry->node->ctx->anonymityLevel, priority,
-                              timeout, &nodeReceive, entry->node);
-  if (entry->searchHandle != NULL)
+  path = GNUNET_malloc (strlen (realFN) * strlen (GNUNET_DIRECTORY_EXT) + 1);
+  strcpy (path, realFN);
+  pos = path;
+  while (*pos != '\0')
     {
-      entry->lastPriority = priority;
-      entry->lastTimeout = timeout;
-      entry->lasttime = now + 2 * TTL_DECREMENT;
-      if (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 1 + entry->tries) >
-          1)
+      if (*pos == DIR_SEPARATOR)
         {
-          /* do linear (in tries) extra back-off (in addition to ttl)
-             to avoid repeatedly tie-ing with other peers; rm is somewhat
-             equivalent to what ethernet is doing, only that 'tries' is our
-             (rough) indicator for collisions.  For ethernet back-off, see:
-             http://www.industrialethernetuniversity.com/courses/101_4.htm
-           */
-          entry->lasttime +=
-            GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                               TTL_DECREMENT * (1 + entry->tries));
-        }
-      entry->tries++;
-    }
-  /* warn if number of attempts goes too high */
-  if ((0 == (entry->tries % MAX_TRIES)) && (entry->tries > 0))
-    {
-      GNUNET_EncName enc;
-      IF_GELOG (rm->ectx,
-                GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                GNUNET_hash_to_enc (&entry->node->chk.key, &enc));
-      GNUNET_GE_LOG (rm->ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                     _
-                     ("Content `%s' seems to be not available on the network 
(tried %u times).\n"),
-                     &enc, entry->tries);
-    }
-}
-
-/**
- * Cron job that re-issues requests. Should compute how long to sleep
- * (min ttl until next job is ready) and re-schedule itself
- * accordingly!
- */
-static GNUNET_CronTime
-processRequests (RequestManager * rm)
-{
-  GNUNET_CronTime minSleep;
-  GNUNET_CronTime now;
-  GNUNET_CronTime delta;
-  int i;
-  unsigned int pending;
-  unsigned int *perm;
-  unsigned int TTL_DECREMENT;
-
-  GNUNET_mutex_lock (rm->lock);
-  if ((rm->shutdown == GNUNET_YES) || (rm->requestListIndex == 0))
-    {
-      GNUNET_mutex_unlock (rm->lock);
-      return 0;
-    }
-  now = GNUNET_get_time ();
-  pending = 0;
-  TTL_DECREMENT = 0;
-  if (rm->requestListIndex > 0)
-    TTL_DECREMENT = rm->requestList[0]->node->ctx->TTL_DECREMENT;
-
-  for (i = 0; i < rm->requestListIndex; i++)
-    {
-      if (rm->requestList[i]->lastTimeout >= now - TTL_DECREMENT)
-        {
-          pending++;
-        }
-      else if (rm->requestList[i]->searchHandle != NULL)
-        {
-          GNUNET_FS_stop_search (rm->sctx, rm->requestList[i]->searchHandle);
-          rm->requestList[i]->searchHandle = NULL;
-        }
-    }
-
-  minSleep = 5000 * GNUNET_CRON_MILLISECONDS;   /* max-sleep! */
-  perm = GNUNET_permute (GNUNET_RANDOM_QUALITY_WEAK, rm->requestListIndex);
-  for (i = 0; i < rm->requestListIndex; i++)
-    {
-      int j = perm[i];
-      if (rm->requestList[j]->lastTimeout + TTL_DECREMENT < now)
-        {
-          int pOCWCubed;
-          int pendingOverCWin = pending - rm->congestionWindow;
-          if (pendingOverCWin <= 0)
-            pendingOverCWin = -1;       /* avoid 0! */
-          pOCWCubed = pendingOverCWin * pendingOverCWin * pendingOverCWin;
-          if ((pOCWCubed <= 0) ||
-              (pOCWCubed * rm->requestListIndex <= 0) /* see #642 */  ||
-              /* avoid no-start: override congestionWindow occasionally... */
-              (0 ==
-               GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                                  rm->requestListIndex * pOCWCubed)))
+          *pos = '\0';
+          if ((0 == STAT (path, &buf)) && (!S_ISDIR (buf.st_mode)))
             {
-              issueRequest (rm, j);
-              delta = (rm->requestList[j]->lastTimeout - now) + TTL_DECREMENT;
-              pending++;
+              *pos = DIR_SEPARATOR;
+              memmove (pos + strlen (GNUNET_DIRECTORY_EXT),
+                       pos, strlen (pos));
+              memcpy (pos,
+                      GNUNET_DIRECTORY_EXT, strlen (GNUNET_DIRECTORY_EXT));
+              pos += strlen (GNUNET_DIRECTORY_EXT);
             }
           else
             {
-              delta = 0;
+              *pos = DIR_SEPARATOR;
             }
         }
-      else
-        {
-          delta = (rm->requestList[j]->lastTimeout + TTL_DECREMENT - now);
-        }
-      if (delta < minSleep)
-        minSleep = delta;
+      pos++;
     }
-  GNUNET_free (perm);
-  if (minSleep < GNUNET_CRON_MILLISECONDS * 100)
-    minSleep = GNUNET_CRON_MILLISECONDS * 100;  /* maximum resolution: 100ms */
-  GNUNET_mutex_unlock (rm->lock);
-  return minSleep;
+  GNUNET_free (realFN);
+  return path;  
 }
 
-
-
 /* ***************** main method **************** */
 
 /**
- * GNUNET_ND_DOWNLOAD a file.
- *
- * @param uri the URI of the file (determines what to download)
- * @param filename where to store the file
- */
-int
-GNUNET_ECRS_file_download (struct GNUNET_GE_Context *ectx,
-                           struct GNUNET_GC_Configuration *cfg,
-                           const struct GNUNET_ECRS_URI *uri,
-                           const char *filename,
-                           unsigned int anonymityLevel,
-                           GNUNET_ECRS_DownloadProgressCallback dpcb,
-                           void *dpcbClosure, GNUNET_ECRS_TestTerminate tt,
-                           void *ttClosure)
-{
-  return GNUNET_ECRS_file_download_partial (ectx,
-                                            cfg,
-                                            uri,
-                                            filename,
-                                            0,
-                                            GNUNET_ECRS_uri_get_file_size
-                                            (uri), anonymityLevel, GNUNET_NO,
-                                            dpcb, dpcbClosure, tt, ttClosure);
-}
-
-
-/**
- * GNUNET_ND_DOWNLOAD parts of a file.  Note that this will store
+ * Download parts of a file.  Note that this will store
  * the blocks at the respective offset in the given file.
  * Also, the download is still using the blocking of the
  * underlying ECRS encoding.  As a result, the download
@@ -1354,152 +763,131 @@
                                    GNUNET_ECRS_TestTerminate tt,
                                    void *ttClosure)
 {
-  IOContext ioc;
-  RequestManager *rm;
-  int ret;
-  CommonCtx ctx;
-  NodeClosure *top;
-  FileIdentifier fid;
-  GNUNET_CronTime minSleep;
-  char *realFN;
-  char *path;
-  char *pos;
+  struct RequestManager rm;
   struct stat buf;
+  struct Node *top;
+  char *fn;
+  char *rdir;
+  int ret;
+  int i;
+  int len;
 
-#if DEBUG_DOWNLOAD
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "`%s' running for file `%s'\n", __FUNCTION__, filename);
-#endif
-  GNUNET_GE_ASSERT (ectx, filename != NULL);
-  if ((filename[strlen (filename) - 1] == '/') ||
-      (filename[strlen (filename) - 1] == '\\'))
+  if ((!GNUNET_ECRS_uri_test_chk (uri)) && (!GNUNET_ECRS_uri_test_loc (uri)))
     {
-      realFN =
-        GNUNET_malloc (strlen (filename) + strlen (GNUNET_DIRECTORY_EXT));
-      strcpy (realFN, filename);
-      realFN[strlen (filename) - 1] = '\0';
-      strcat (realFN, GNUNET_DIRECTORY_EXT);
+      GNUNET_GE_BREAK (ectx, 0);
+      return GNUNET_SYSERR;
     }
-  else
-    {
-      realFN = GNUNET_strdup (filename);
-    }
-  path = GNUNET_malloc (strlen (realFN) * strlen (GNUNET_DIRECTORY_EXT) + 1);
-  strcpy (path, realFN);
-  pos = path;
-  while (*pos != '\0')
-    {
-      if (*pos == DIR_SEPARATOR)
-        {
-          *pos = '\0';
-          if ((0 == STAT (path, &buf)) && (!S_ISDIR (buf.st_mode)))
-            {
-              *pos = DIR_SEPARATOR;
-              memmove (pos + strlen (GNUNET_DIRECTORY_EXT),
-                       pos, strlen (pos));
-              memcpy (pos,
-                      GNUNET_DIRECTORY_EXT, strlen (GNUNET_DIRECTORY_EXT));
-              pos += strlen (GNUNET_DIRECTORY_EXT);
-            }
-          else
-            {
-              *pos = DIR_SEPARATOR;
-            }
-        }
-      pos++;
-    }
-  GNUNET_free (realFN);
-  realFN = path;
 
-  if (GNUNET_SYSERR == GNUNET_disk_directory_create_for_file (ectx, realFN))
+  memset(&rm, 0, sizeof(struct RequestManager));
+  rm.ectx = ectx;
+  rm.cfg = cfg;
+  rm.startTime = GNUNET_get_time ();
+  rm.anonymityLevel = anonymityLevel;
+  rm.offset = offset;
+  rm.length = length;
+  rm.dpcb = dpcb;
+  rm.dpcbClosure = dpcbClosure;
+  rm.main = GNUNET_thread_get_self();
+  rm.total = GNUNET_ntohll (uri->data.fi.file_length);
+  rm.filename = get_real_download_filename(ectx,
+                                          filename);
+ 
+  if (GNUNET_SYSERR == GNUNET_disk_directory_create_for_file (ectx, 
rm.filename))
     {
-      GNUNET_free (realFN);
+      free_request_manager(&rm, GNUNET_NO);
       return GNUNET_SYSERR;
     }
-  if (0 == GNUNET_ECRS_uri_get_file_size (uri))
+  if (0 == rm.total)
     {
       ret = GNUNET_disk_file_open (ectx,
-                                   realFN,
+                                   rm.filename,
                                    O_CREAT | O_WRONLY | O_TRUNC,
                                    S_IRUSR | S_IWUSR);
-      GNUNET_free (realFN);
       if (ret == -1)
-        return GNUNET_SYSERR;
+       {
+         free_request_manager(&rm, GNUNET_NO);
+         return GNUNET_SYSERR;
+       }
       CLOSE (ret);
-      dpcb (0, 0, GNUNET_get_time (), 0, NULL, 0, dpcbClosure);
+      dpcb (0, 0, rm.startTime, 0, NULL, 0, dpcbClosure);
+      free_request_manager(&rm, GNUNET_NO);
       return GNUNET_OK;
     }
-  fid = uri->data.fi;
-
-  if ((!GNUNET_ECRS_uri_test_chk (uri)) && (!GNUNET_ECRS_uri_test_loc (uri)))
+  rm.treedepth = GNUNET_ECRS_compute_depth (rm.total);
+  rm.handles = GNUNET_malloc (sizeof (int) * (rm.treedepth + 1));
+  for (i = 0; i <= rm.treedepth; i++)
+    rm.handles[i] = -1;
+  if ((0 == STAT (rm.filename, &buf)) && ((size_t) buf.st_size > rm.total))
     {
-      GNUNET_GE_BREAK (ectx, 0);
-      GNUNET_free (realFN);
-      return GNUNET_SYSERR;
+      /* if exists and oversized, truncate */
+      if (truncate (rm.filename, rm.total) != 0)
+        {
+          GNUNET_GE_LOG_STRERROR_FILE (ectx,
+                                       GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
+                                       GNUNET_GE_BULK, "truncate", 
rm.filename);
+         free_request_manager(&rm, GNUNET_NO);
+          return GNUNET_SYSERR;
+        }
     }
-
-  if (GNUNET_OK != createIOContext (ectx,
-                                    &ioc,
-                                    no_temporaries,
-                                    GNUNET_ntohll (fid.file_length), realFN))
+  for (i = 0; i <= rm.treedepth; i++)
     {
-#if DEBUG_DOWNLOAD
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                     "`%s' aborted for file `%s'\n", __FUNCTION__, realFN);
-#endif
-      GNUNET_free (realFN);
-      return GNUNET_SYSERR;
+      if ((i == 0) || (no_temporaries != GNUNET_YES))
+        {
+          fn = GNUNET_malloc (strlen (rm.filename) + 3);
+          strcpy (fn, rm.filename);
+          if (i > 0)
+            {
+              strcat (fn, ".A");
+              fn[strlen (fn) - 1] += i;
+            }
+          rm.handles[i] = GNUNET_disk_file_open (ectx,
+                                                 fn,
+                                                 O_CREAT | O_RDWR,
+                                                 S_IRUSR | S_IWUSR);
+          if (rm.handles[i] < 0)
+            {
+             free_request_manager(&rm, GNUNET_NO);
+              return GNUNET_SYSERR;
+            }
+          GNUNET_free (fn);
+        }
     }
-  rm = createRequestManager (ectx, cfg);
-  if (rm == NULL)
+  rm.lock = GNUNET_mutex_create (GNUNET_YES);
+  rm.sctx = GNUNET_FS_create_search_context (ectx, cfg, rm.lock);
+  if (rm.sctx == NULL)
     {
-      freeIOC (&ioc, GNUNET_YES);
-      GNUNET_free (realFN);
+      free_request_manager(&rm, GNUNET_NO);
       return GNUNET_SYSERR;
     }
   if (GNUNET_ECRS_uri_test_loc (uri))
     {
       GNUNET_hash (&uri->data.loc.peer, sizeof (GNUNET_RSA_PublicKey),
-                   &rm->target.hashPubKey);
-      rm->have_target = GNUNET_YES;
+                   &rm.target.hashPubKey);
+      rm.have_target = GNUNET_YES;
     }
 
-  ctx.startTime = GNUNET_get_time ();
-  ctx.anonymityLevel = anonymityLevel;
-  ctx.offset = offset;
-  ctx.length = length;
-  ctx.TTL_DECREMENT = 5 * GNUNET_CRON_SECONDS;  /* HACK! */
-  ctx.rm = rm;
-  ctx.ioc = &ioc;
-  ctx.dpcb = dpcb;
-  ctx.dpcbClosure = dpcbClosure;
-  ctx.total = GNUNET_ntohll (fid.file_length);
-  ctx.completed = 0;
-  top = GNUNET_malloc (sizeof (NodeClosure));
-  top->ctx = &ctx;
-  top->chk = fid.chk;
+  top = GNUNET_malloc (sizeof (struct Node));
+  memset(top, 0, sizeof(struct Node));
+  top->ctx = &rm;
+  top->chk = uri->data.fi.chk;
   top->offset = 0;
-  top->level = GNUNET_ECRS_compute_depth (ctx.total);
-  if (GNUNET_NO == checkPresent (top))
-    addRequest (rm, top);
+  top->level = rm.treedepth;
+
+  GNUNET_mutex_lock (rm.lock);
+  if (GNUNET_NO == check_node_present (top))
+    addRequest (top);
   else
     GNUNET_free (top);
-  while ((GNUNET_OK == tt (ttClosure)) &&
-         (rm->abortFlag == GNUNET_NO) && (rm->requestListIndex != 0))
+  GNUNET_mutex_unlock (rm.lock);
+  while ( (GNUNET_OK == tt (ttClosure)) &&
+         (rm.abortFlag == GNUNET_NO) && 
+         (rm.head != NULL) )
+    GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS);
+  if ((rm.head == NULL) &&
+      ((rm.completed == rm.total) ||
+       ((rm.total != rm.length) &&
+        (rm.completed >= rm.length))) && (rm.abortFlag == GNUNET_NO))
     {
-      minSleep = processRequests (rm);
-      if ((GNUNET_OK == tt (ttClosure)) &&
-          (rm->abortFlag == GNUNET_NO) && (rm->requestListIndex != 0))
-        GNUNET_thread_sleep (minSleep);
-    }
-
-  if ((rm->requestListIndex == 0) &&
-      ((ctx.completed == ctx.total) ||
-       ((ctx.total != ctx.length) &&
-        (ctx.completed >= ctx.length))) && (rm->abortFlag == GNUNET_NO))
-    {
       ret = GNUNET_OK;
     }
   else
@@ -1508,31 +896,31 @@
       GNUNET_GE_LOG (ectx,
                      GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
                      "Download ends prematurely: %d %llu == %llu %d TT: %d\n",
-                     rm->requestListIndex,
-                     ctx.completed, ctx.total, rm->abortFlag, tt (ttClosure));
+                     rm.requestListIndex,
+                     ctx.completed, ctx.total, rm.abortFlag, tt (ttClosure));
 #endif
       ret = GNUNET_SYSERR;
     }
-  destroyRequestManager (rm);
-  if (ret == GNUNET_OK)
+#if DEBUG_DOWNLOAD
+  GNUNET_GE_LOG (ectx,
+                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
+                 "`%s' terminating for file `%s' with result %s\n",
+                 __FUNCTION__, filename,
+                 ret == GNUNET_OK ? "SUCCESS" : "INCOMPLETE");
+#endif
+  if ( (ret == GNUNET_SYSERR) &&
+       (tt(ttClosure) == GNUNET_SYSERR) )
     {
-      freeIOC (&ioc, GNUNET_YES);
-    }
-  else if (tt (ttClosure) == GNUNET_SYSERR)
-    {
-      freeIOC (&ioc, GNUNET_YES);
-      if (0 != UNLINK (realFN))
+      if (0 != UNLINK (rm.filename))
         {
           GNUNET_GE_LOG_STRERROR_FILE (ectx,
                                        GNUNET_GE_WARNING | GNUNET_GE_USER |
-                                       GNUNET_GE_BULK, "unlink", realFN);
+                                       GNUNET_GE_BULK, "unlink", rm.filename);
         }
       else
-        {                       /* delete empty directories */
-          char *rdir;
-          int len;
-
-          rdir = GNUNET_strdup (realFN);
+        {
+         /* delete empty directories */
+          rdir = GNUNET_strdup (rm.filename);
           len = strlen (rdir);
           do
             {
@@ -1543,20 +931,39 @@
           while ((len > 0) && (0 == rmdir (rdir)));
           GNUNET_free (rdir);
         }
-    }
-  else
-    {
-      freeIOC (&ioc, GNUNET_NO);        /* aborted */
-    }
-#if DEBUG_DOWNLOAD
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "`%s' terminating for file `%s' with result %s\n",
-                 __FUNCTION__, filename,
-                 ret == GNUNET_OK ? "SUCCESS" : "INCOMPLETE");
-#endif
-  GNUNET_free (realFN);
+    }    
+  free_request_manager (&rm, 
+                       ( (ret == GNUNET_OK) ||
+                         (tt(ttClosure) == GNUNET_SYSERR) ) 
+                       ? GNUNET_YES 
+                       : GNUNET_NO);
   return ret;
 }
 
+/**
+ * Download a file (simplified API).
+ *
+ * @param uri the URI of the file (determines what to download)
+ * @param filename where to store the file
+ */
+int
+GNUNET_ECRS_file_download (struct GNUNET_GE_Context *ectx,
+                           struct GNUNET_GC_Configuration *cfg,
+                           const struct GNUNET_ECRS_URI *uri,
+                           const char *filename,
+                           unsigned int anonymityLevel,
+                           GNUNET_ECRS_DownloadProgressCallback dpcb,
+                           void *dpcbClosure, GNUNET_ECRS_TestTerminate tt,
+                           void *ttClosure)
+{
+  return GNUNET_ECRS_file_download_partial (ectx,
+                                            cfg,
+                                            uri,
+                                            filename,
+                                            0,
+                                            GNUNET_ECRS_uri_get_file_size
+                                            (uri), anonymityLevel, GNUNET_NO,
+                                            dpcb, dpcbClosure, tt, ttClosure);
+}
+
 /* end of download.c */

Modified: GNUnet/src/applications/fs/ecrs/search.c
===================================================================
--- GNUnet/src/applications/fs/ecrs/search.c    2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/applications/fs/ecrs/search.c    2008-02-06 07:11:29 UTC (rev 
6162)
@@ -33,42 +33,22 @@
 
 #define DEBUG_SEARCH GNUNET_NO
 
-typedef struct
+/**
+ * This struct is followed by keyCount keys of 
+ * type "GNUNET_HashCode".
+ */
+struct PendingSearch
 {
+  struct PendingSearch *next;
 
-  /**
-   * The handle for the query.
-   */
-  struct GNUNET_FS_SearchHandle *handle;
+  struct SearchContext *context;
 
   /**
-   * The keys (for the search).
-   */
-  GNUNET_HashCode *keys;
-
-  /**
-   * When does this query time-out (we may want
-   * to refresh it at that point).
-   */
-  GNUNET_CronTime timeout;
-
-  /**
-   * What was the last time we transmitted
-   * this query?
-   */
-  GNUNET_CronTime lastTransmission;
-
-  /**
    * The key (for decryption)
    */
   GNUNET_HashCode decryptKey;
 
   /**
-   * With which priority does the query run?
-   */
-  unsigned int priority;
-
-  /**
    * What type of query is it?
    */
   unsigned int type;
@@ -78,12 +58,12 @@
    */
   unsigned int keyCount;
 
-} PendingSearch;
+};
 
 /**
- * Context of the sendQueries cron-job.
+ * Context for search operation.
  */
-typedef struct
+struct SearchContext
 {
   /**
    * Time when the cron-job was first started.
@@ -101,9 +81,9 @@
   struct GNUNET_FS_SearchContext *sctx;
 
   /**
-   * queryCount pending searches.
+   * Active searches.
    */
-  PendingSearch **queries;
+  struct PendingSearch *queries;
 
   GNUNET_ECRS_SearchResultProcessor spcb;
 
@@ -117,38 +97,45 @@
 
   int aborted;
 
-  /**
-   * Number of queries running at the moment.
-   */
-  unsigned int queryCount;
+  unsigned int anonymityLevel;
 
-} SendQueriesContext;
+};
 
+static int
+receive_response_callback (const GNUNET_HashCode * key,
+                           const GNUNET_DatastoreValue * value, void *cls);
+
 /**
  * Add a query to the SQC.
  */
 static void
-addPS (unsigned int type,
-       unsigned int keyCount,
-       const GNUNET_HashCode * keys,
-       const GNUNET_HashCode * dkey, SendQueriesContext * sqc)
+add_search (unsigned int type,
+            unsigned int keyCount,
+            const GNUNET_HashCode * keys,
+            const GNUNET_HashCode * dkey, struct SearchContext *sqc)
 {
-  PendingSearch *ps;
+  struct PendingSearch *ps;
 
-  ps = GNUNET_malloc (sizeof (PendingSearch));
-  ps->timeout = 0;
-  ps->lastTransmission = 0;
-  ps->priority = 5 + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 20);
+  ps =
+    GNUNET_malloc (sizeof (struct PendingSearch) +
+                   sizeof (GNUNET_HashCode) * keyCount);
   ps->type = type;
   ps->keyCount = keyCount;
-  ps->keys = GNUNET_malloc (sizeof (GNUNET_HashCode) * keyCount);
-  memcpy (ps->keys, keys, sizeof (GNUNET_HashCode) * keyCount);
+  memcpy (&ps[1], keys, sizeof (GNUNET_HashCode) * keyCount);
   ps->decryptKey = *dkey;
-  ps->handle = NULL;
+  ps->context = sqc;
   GNUNET_mutex_lock (sqc->lock);
-  GNUNET_array_grow (sqc->queries, sqc->queryCount, sqc->queryCount + 1);
-  sqc->queries[sqc->queryCount - 1] = ps;
+  ps->next = sqc->queries;
+  sqc->queries = ps;
   GNUNET_mutex_unlock (sqc->lock);
+  GNUNET_FS_start_search (sqc->sctx,
+                          NULL,
+                          type,
+                          keyCount,
+                          keys,
+                          sqc->anonymityLevel,
+                          (GNUNET_DatastoreValueIterator) &
+                          receive_response_callback, ps);
 }
 
 /**
@@ -156,7 +143,8 @@
  * to the SQC.
  */
 static void
-addQueryForURI (const struct GNUNET_ECRS_URI *uri, SendQueriesContext * sqc)
+add_search_for_uri (const struct GNUNET_ECRS_URI *uri,
+                    struct SearchContext *sqc)
 {
   struct GNUNET_GE_Context *ectx = sqc->ectx;
 
@@ -176,8 +164,8 @@
                      &hk);
         GNUNET_hash_xor (&hk, &uri->data.sks.namespace, &keys[0]);      /* 
compute routing key r = H(identifier) ^ namespace */
         keys[1] = uri->data.sks.namespace;
-        addPS (GNUNET_ECRS_BLOCKTYPE_SIGNED, 2, &keys[0], 
&uri->data.sks.identifier,    /* identifier = decryption key */
-               sqc);
+        add_search (GNUNET_ECRS_BLOCKTYPE_SIGNED, 2, &keys[0], 
&uri->data.sks.identifier,       /* identifier = decryption key */
+                    sqc);
         break;
       }
     case ksk:
@@ -200,8 +188,8 @@
             pk = GNUNET_RSA_create_key_from_hash (&hc);
             GNUNET_RSA_get_public_key (pk, &pub);
             GNUNET_hash (&pub, sizeof (GNUNET_RSA_PublicKey), &query);
-            addPS (GNUNET_ECRS_BLOCKTYPE_ANY,   /* 
GNUNET_ECRS_BLOCKTYPE_KEYWORD, GNUNET_ECRS_BLOCKTYPE_NAMESPACE or 
GNUNET_ECRS_BLOCKTYPE_KEYWORD_FOR_NAMESPACE ok */
-                   1, &query, &hc, sqc);
+            add_search (GNUNET_ECRS_BLOCKTYPE_ANY,      /* 
GNUNET_ECRS_BLOCKTYPE_KEYWORD, GNUNET_ECRS_BLOCKTYPE_NAMESPACE or 
GNUNET_ECRS_BLOCKTYPE_KEYWORD_FOR_NAMESPACE ok */
+                        1, &query, &hc, sqc);
             GNUNET_RSA_free_key (pk);
           }
 #if DEBUG_SEARCH
@@ -234,7 +222,8 @@
  * @param c the resulting current ID (set)
  */
 static int
-computeIdAtTime (const SBlock * sb, GNUNET_Int32Time now, GNUNET_HashCode * c)
+compute_id_at_time (const SBlock * sb, GNUNET_Int32Time now,
+                    GNUNET_HashCode * c)
 {
   GNUNET_Int32Time pos;
   GNUNET_HashCode tmp;
@@ -276,9 +265,9 @@
  * namespace advertisement.
  */
 static int
-processNBlock (const NBlock * nb,
-               const GNUNET_HashCode * key,
-               unsigned int size, SendQueriesContext * sqc)
+process_nblock_result (const NBlock * nb,
+                       const GNUNET_HashCode * key,
+                       unsigned int size, struct SearchContext *sqc)
 {
   struct GNUNET_GE_Context *ectx = sqc->ectx;
   GNUNET_ECRS_FileInfo fi;
@@ -317,15 +306,15 @@
  * @return GNUNET_SYSERR if the entry is malformed
  */
 static int
-receiveReplies (const GNUNET_HashCode * key,
-                const GNUNET_DatastoreValue * value, SendQueriesContext * sqc)
+receive_response_callback (const GNUNET_HashCode * key,
+                           const GNUNET_DatastoreValue * value, void *cls)
 {
+  struct PendingSearch *ps = cls;
+  struct SearchContext *sqc = ps->context;
   struct GNUNET_GE_Context *ectx = sqc->ectx;
   unsigned int type;
   GNUNET_ECRS_FileInfo fi;
-  int i;
   unsigned int size;
-  PendingSearch *ps;
   int ret;
   GNUNET_HashCode query;
 
@@ -342,219 +331,208 @@
                                                 (const DBlock *) &value[1],
                                                 GNUNET_YES, &query))
     return GNUNET_SYSERR;
-  for (i = 0; i < sqc->queryCount; i++)
+  if (!((0 == memcmp (&query,
+                      (GNUNET_HashCode *) & ps[1], sizeof (GNUNET_HashCode)))
+        && ((ps->type == type) || (ps->type == GNUNET_ECRS_BLOCKTYPE_ANY))
+        && (GNUNET_YES ==
+            GNUNET_EC_is_block_applicable_for_query (type, size,
+                                                     (const DBlock *)
+                                                     &value[1], &query,
+                                                     ps->keyCount,
+                                                     (GNUNET_HashCode *) &
+                                                     ps[1]))))
+    return GNUNET_OK;           /* not a match */
+
+  switch (type)
     {
-      ps = sqc->queries[i];
-      if ((0 == memcmp (&query,
-                        &ps->keys[0], sizeof (GNUNET_HashCode))) &&
-          ((ps->type == type) ||
-           (ps->type == GNUNET_ECRS_BLOCKTYPE_ANY)) &&
-          (GNUNET_YES == GNUNET_EC_is_block_applicable_for_query (type,
-                                                                  size,
-                                                                  (const
-                                                                   DBlock *)
-                                                                  &value[1],
-                                                                  &query,
-                                                                  ps->
-                                                                  keyCount,
-                                                                  ps->keys)))
-        {
-          switch (type)
-            {
-            case GNUNET_ECRS_BLOCKTYPE_KEYWORD:
-              {
-                KBlock *kb;
-                const char *dstURI;
+    case GNUNET_ECRS_BLOCKTYPE_KEYWORD:
+      {
+        KBlock *kb;
+        const char *dstURI;
 #if DEBUG_SEARCH
-                GNUNET_EncName enc;
+        GNUNET_EncName enc;
 #endif
-                int j;
+        int j;
 
-                if (size < sizeof (KBlock))
-                  return GNUNET_SYSERR;
-                kb = GNUNET_malloc (size);
-                memcpy (kb, &value[1], size);
+        if (size < sizeof (KBlock))
+          return GNUNET_SYSERR;
+        kb = GNUNET_malloc (size);
+        memcpy (kb, &value[1], size);
 #if DEBUG_SEARCH
-                IF_GELOG (ectx,
-                          GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
-                          GNUNET_GE_USER, GNUNET_hash_to_enc (&ps->decryptKey,
-                                                              &enc));
-                GNUNET_GE_LOG (ectx,
-                               GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
-                               GNUNET_GE_USER,
-                               "Decrypting KBlock with key %s.\n", &enc);
+        IF_GELOG (ectx,
+                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
+                  GNUNET_GE_USER, GNUNET_hash_to_enc (&ps->decryptKey, &enc));
+        GNUNET_GE_LOG (ectx,
+                       GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
+                       GNUNET_GE_USER,
+                       "Decrypting KBlock with key %s.\n", &enc);
 #endif
-                GNUNET_ECRS_decryptInPlace (&ps->decryptKey,
-                                            &kb[1], size - sizeof (KBlock));
-                j = sizeof (KBlock);
-                while ((j < size) && (((const char *) kb)[j] != '\0'))
-                  j++;
-                if (j == size)
-                  {
-                    GNUNET_GE_BREAK (ectx, 0);  /* kblock malformed */
-                    GNUNET_free (kb);
-                    return GNUNET_SYSERR;
-                  }
-                dstURI = (const char *) &kb[1];
-                j++;
-                fi.meta = GNUNET_ECRS_meta_data_deserialize (ectx,
-                                                             &((const char *)
-                                                               kb)[j],
-                                                             size - j);
-                if (fi.meta == NULL)
-                  {
-                    GNUNET_GE_BREAK (ectx, 0);  /* kblock malformed */
-                    GNUNET_free (kb);
-                    return GNUNET_SYSERR;
-                  }
-                fi.uri = GNUNET_ECRS_string_to_uri (ectx, dstURI);
-                if (fi.uri == NULL)
-                  {
-                    GNUNET_GE_BREAK (ectx, 0);  /* kblock malformed */
-                    GNUNET_ECRS_meta_data_destroy (fi.meta);
-                    GNUNET_free (kb);
-                    return GNUNET_SYSERR;
-                  }
-                if (sqc->spcb != NULL)
-                  {
-                    ret = sqc->spcb (&fi,
-                                     &ps->decryptKey, GNUNET_NO,
-                                     sqc->spcbClosure);
-                    if (ret == GNUNET_SYSERR)
-                      sqc->aborted = GNUNET_YES;
-                  }
-                else
-                  ret = GNUNET_OK;
-                GNUNET_ECRS_uri_destroy (fi.uri);
-                GNUNET_ECRS_meta_data_destroy (fi.meta);
-                GNUNET_free (kb);
-                return ret;
-              }
-            case GNUNET_ECRS_BLOCKTYPE_NAMESPACE:
-              {
-                const NBlock *nb;
+        GNUNET_ECRS_decryptInPlace (&ps->decryptKey,
+                                    &kb[1], size - sizeof (KBlock));
+        j = sizeof (KBlock);
+        while ((j < size) && (((const char *) kb)[j] != '\0'))
+          j++;
+        if (j == size)
+          {
+            GNUNET_GE_BREAK (ectx, 0);  /* kblock malformed */
+            GNUNET_free (kb);
+            return GNUNET_SYSERR;
+          }
+        dstURI = (const char *) &kb[1];
+        j++;
+        fi.meta = GNUNET_ECRS_meta_data_deserialize (ectx,
+                                                     &((const char *)
+                                                       kb)[j], size - j);
+        if (fi.meta == NULL)
+          {
+            GNUNET_GE_BREAK (ectx, 0);  /* kblock malformed */
+            GNUNET_free (kb);
+            return GNUNET_SYSERR;
+          }
+        fi.uri = GNUNET_ECRS_string_to_uri (ectx, dstURI);
+        if (fi.uri == NULL)
+          {
+            GNUNET_GE_BREAK (ectx, 0);  /* kblock malformed */
+            GNUNET_ECRS_meta_data_destroy (fi.meta);
+            GNUNET_free (kb);
+            return GNUNET_SYSERR;
+          }
+        if (sqc->spcb != NULL)
+          {
+            ret = sqc->spcb (&fi,
+                             &ps->decryptKey, GNUNET_NO, sqc->spcbClosure);
+            if (ret == GNUNET_SYSERR)
+              sqc->aborted = GNUNET_YES;
+          }
+        else
+          ret = GNUNET_OK;
+        GNUNET_ECRS_uri_destroy (fi.uri);
+        GNUNET_ECRS_meta_data_destroy (fi.meta);
+        GNUNET_free (kb);
+        return ret;
+      }
+    case GNUNET_ECRS_BLOCKTYPE_NAMESPACE:
+      {
+        const NBlock *nb;
 
-                if (size < sizeof (NBlock))
-                  return GNUNET_SYSERR;
-                nb = (const NBlock *) &value[1];
-                return processNBlock (nb, NULL, size, sqc);
-              }
-            case GNUNET_ECRS_BLOCKTYPE_KEYWORD_FOR_NAMESPACE:
-              {
-                KNBlock *kb;
-                int ret;
+        if (size < sizeof (NBlock))
+          return GNUNET_SYSERR;
+        nb = (const NBlock *) &value[1];
+        return process_nblock_result (nb, NULL, size, sqc);
+      }
+    case GNUNET_ECRS_BLOCKTYPE_KEYWORD_FOR_NAMESPACE:
+      {
+        KNBlock *kb;
+        int ret;
 
-                if (size < sizeof (KNBlock))
-                  return GNUNET_SYSERR;
-                kb = GNUNET_malloc (size);
-                memcpy (kb, &value[1], size);
-                GNUNET_ECRS_decryptInPlace (&ps->decryptKey,
-                                            &kb->nblock,
-                                            size - sizeof (KBlock) -
-                                            sizeof (unsigned int));
-                ret =
-                  processNBlock (&kb->nblock, &ps->decryptKey,
+        if (size < sizeof (KNBlock))
+          return GNUNET_SYSERR;
+        kb = GNUNET_malloc (size);
+        memcpy (kb, &value[1], size);
+        GNUNET_ECRS_decryptInPlace (&ps->decryptKey,
+                                    &kb->nblock,
+                                    size - sizeof (KBlock) -
+                                    sizeof (unsigned int));
+        ret =
+          process_nblock_result (&kb->nblock, &ps->decryptKey,
                                  size - sizeof (KNBlock) + sizeof (NBlock),
                                  sqc);
-                GNUNET_free (kb);
-                return ret;
-              }
-            case GNUNET_ECRS_BLOCKTYPE_SIGNED:
-              {
-                SBlock *sb;
-                const char *dstURI;
-                int j;
-                GNUNET_Int32Time now;
-                GNUNET_HashCode updateId;
-                URI updateURI;
+        GNUNET_free (kb);
+        return ret;
+      }
+    case GNUNET_ECRS_BLOCKTYPE_SIGNED:
+      {
+        SBlock *sb;
+        const char *dstURI;
+        int j;
+        GNUNET_Int32Time now;
+        GNUNET_HashCode updateId;
+        URI updateURI;
 
-                if (size < sizeof (SBlock))
-                  return GNUNET_SYSERR;
-                sb = GNUNET_malloc (size);
-                memcpy (sb, &value[1], size);
-                GNUNET_ECRS_decryptInPlace (&ps->decryptKey,
-                                            &sb->creationTime,
-                                            size
-                                            - sizeof (unsigned int)
-                                            - sizeof (GNUNET_RSA_Signature)
-                                            - sizeof (GNUNET_RSA_PublicKey)
-                                            - sizeof (GNUNET_HashCode));
-                j = 0;
-                dstURI = (const char *) &sb[1];
-                while ((j < size - sizeof (SBlock)) && (dstURI[j] != '\0'))
-                  j++;
-                if (j == size - sizeof (SBlock))
-                  {
-                    GNUNET_GE_BREAK (ectx, 0);  /* sblock malformed */
-                    GNUNET_free (sb);
-                    return GNUNET_SYSERR;
-                  }
-                j++;
-                /* j == strlen(dstURI) + 1 */
-                fi.meta = GNUNET_ECRS_meta_data_deserialize (ectx,
-                                                             &dstURI[j],
-                                                             size - j -
-                                                             sizeof (SBlock));
-                if (fi.meta == NULL)
-                  {
-                    GNUNET_GE_BREAK (ectx, 0);  /* sblock malformed */
-                    GNUNET_free (sb);
-                    return GNUNET_SYSERR;
-                  }
-                fi.uri = GNUNET_ECRS_string_to_uri (ectx, dstURI);
-                if (fi.uri == NULL)
-                  {
-                    GNUNET_GE_BREAK (ectx, 0);  /* sblock malformed */
-                    GNUNET_ECRS_meta_data_destroy (fi.meta);
-                    GNUNET_free (sb);
-                    return GNUNET_SYSERR;
-                  }
-                if (sqc->spcb != NULL)
-                  {
-                    ret = sqc->spcb (&fi, NULL, GNUNET_NO, sqc->spcbClosure);
-                    if (ret == GNUNET_SYSERR)
-                      sqc->aborted = GNUNET_YES;
-                  }
-                else
-                  ret = GNUNET_OK;
-                GNUNET_ECRS_uri_destroy (fi.uri);
-                GNUNET_ECRS_meta_data_destroy (fi.meta);
+        if (size < sizeof (SBlock))
+          return GNUNET_SYSERR;
+        sb = GNUNET_malloc (size);
+        memcpy (sb, &value[1], size);
+        GNUNET_ECRS_decryptInPlace (&ps->decryptKey,
+                                    &sb->creationTime,
+                                    size
+                                    - sizeof (unsigned int)
+                                    - sizeof (GNUNET_RSA_Signature)
+                                    - sizeof (GNUNET_RSA_PublicKey)
+                                    - sizeof (GNUNET_HashCode));
+        j = 0;
+        dstURI = (const char *) &sb[1];
+        while ((j < size - sizeof (SBlock)) && (dstURI[j] != '\0'))
+          j++;
+        if (j == size - sizeof (SBlock))
+          {
+            GNUNET_GE_BREAK (ectx, 0);  /* sblock malformed */
+            GNUNET_free (sb);
+            return GNUNET_SYSERR;
+          }
+        j++;
+        /* j == strlen(dstURI) + 1 */
+        fi.meta = GNUNET_ECRS_meta_data_deserialize (ectx,
+                                                     &dstURI[j],
+                                                     size - j -
+                                                     sizeof (SBlock));
+        if (fi.meta == NULL)
+          {
+            GNUNET_GE_BREAK (ectx, 0);  /* sblock malformed */
+            GNUNET_free (sb);
+            return GNUNET_SYSERR;
+          }
+        fi.uri = GNUNET_ECRS_string_to_uri (ectx, dstURI);
+        if (fi.uri == NULL)
+          {
+            GNUNET_GE_BREAK (ectx, 0);  /* sblock malformed */
+            GNUNET_ECRS_meta_data_destroy (fi.meta);
+            GNUNET_free (sb);
+            return GNUNET_SYSERR;
+          }
+        if (sqc->spcb != NULL)
+          {
+            ret = sqc->spcb (&fi, NULL, GNUNET_NO, sqc->spcbClosure);
+            if (ret == GNUNET_SYSERR)
+              sqc->aborted = GNUNET_YES;
+          }
+        else
+          ret = GNUNET_OK;
+        GNUNET_ECRS_uri_destroy (fi.uri);
+        GNUNET_ECRS_meta_data_destroy (fi.meta);
 
-                /* compute current/NEXT URI (if updateable SBlock) and issue
-                   respective query automatically! */
-                GNUNET_get_time_int32 (&now);
-                if (GNUNET_OK != computeIdAtTime (sb, now, &updateId))
-                  {
-                    GNUNET_free (sb);
-                    return GNUNET_SYSERR;
-                  }
-                if (0 ==
-                    memcmp (&updateId, &ps->decryptKey,
-                            sizeof (GNUNET_HashCode)))
-                  {
-                    GNUNET_free (sb);
-                    return ret; /* have latest version */
-                  }
-                if (ps->keyCount != 2)
-                  {
-                    GNUNET_GE_BREAK (ectx, 0);
-                    GNUNET_free (sb);
-                    return GNUNET_SYSERR;
-                  }
+        /* compute current/NEXT URI (if updateable SBlock) and issue
+           respective query automatically! */
+        GNUNET_get_time_int32 (&now);
+        if (GNUNET_OK != compute_id_at_time (sb, now, &updateId))
+          {
+            GNUNET_free (sb);
+            return GNUNET_SYSERR;
+          }
+        if (0 ==
+            memcmp (&updateId, &ps->decryptKey, sizeof (GNUNET_HashCode)))
+          {
+            GNUNET_free (sb);
+            return ret;         /* have latest version */
+          }
+        if (ps->keyCount != 2)
+          {
+            GNUNET_GE_BREAK (ectx, 0);
+            GNUNET_free (sb);
+            return GNUNET_SYSERR;
+          }
 
-                updateURI.type = sks;
-                updateURI.data.sks.namespace = ps->keys[1];
-                updateURI.data.sks.identifier = updateId;
-                addQueryForURI (&updateURI, sqc);
-                GNUNET_free (sb);
-                return ret;
-              }
-            default:
-              GNUNET_GE_BREAK (ectx, 0);
-              break;
-            }                   /* end switch */
-        }                       /* for all matches */
-    }                           /* for all pending queries */
+        updateURI.type = sks;
+        updateURI.data.sks.namespace = ((GNUNET_HashCode *) & ps[1])[1];
+        updateURI.data.sks.identifier = updateId;
+        add_search_for_uri (&updateURI, sqc);
+        GNUNET_free (sb);
+        return ret;
+      }
+    default:
+      GNUNET_GE_BREAK (ectx, 0);
+      break;
+    }                           /* end switch */
   return GNUNET_OK;
 }
 
@@ -576,103 +554,44 @@
                     void *spcbClosure, GNUNET_ECRS_TestTerminate tt,
                     void *ttClosure)
 {
-  SendQueriesContext ctx;
-  PendingSearch *ps;
-  int i;
+  struct PendingSearch *pos;
+  struct SearchContext ctx;
   GNUNET_CronTime now;
   GNUNET_CronTime remTime;
-  GNUNET_CronTime new_ttl;
-  unsigned int new_priority;
 
-  ctx.start = GNUNET_get_time ();
   now = GNUNET_get_time ();
-  timeout += now;
+  ctx.start = now;
+  ctx.anonymityLevel = anonymityLevel;
+  if (timeout != 0)
+    timeout += now;
   ctx.ectx = ectx;
   ctx.cfg = cfg;
   ctx.timeout = timeout;
-  ctx.queryCount = 0;
   ctx.queries = NULL;
   ctx.spcb = spcb;
   ctx.spcbClosure = spcbClosure;
   ctx.aborted = GNUNET_NO;
   ctx.lock = GNUNET_mutex_create (GNUNET_YES);
   ctx.sctx = GNUNET_FS_create_search_context (ectx, cfg, ctx.lock);
-  addQueryForURI (uri, &ctx);
+  add_search_for_uri (uri, &ctx);
   while (((NULL == tt) ||
           (GNUNET_OK == tt (ttClosure))) &&
          (GNUNET_NO == GNUNET_shutdown_test ()) &&
-         (timeout > now) && (ctx.aborted == GNUNET_NO))
+         ((timeout == 0) || (timeout > now)) && (ctx.aborted == GNUNET_NO))
     {
       remTime = timeout - now;
-
-      GNUNET_mutex_lock (ctx.lock);
-      for (i = 0; i < ctx.queryCount; i++)
-        {
-          ps = ctx.queries[i];
-          if ((now < ps->timeout) && (ps->timeout != 0))
-            continue;
-          if (ps->handle != NULL)
-            GNUNET_FS_stop_search (ctx.sctx, ps->handle);
-          /* increase ttl/priority */
-          new_ttl = ps->timeout - ps->lastTransmission;
-          if (new_ttl < 4 * 5 * GNUNET_CRON_SECONDS)
-            new_ttl =
-              4 * 5 * GNUNET_CRON_SECONDS +
-              GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                                 5 * GNUNET_CRON_SECONDS);
-          new_ttl =
-            new_ttl + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                                         5 * GNUNET_CRON_SECONDS +
-                                         2 * new_ttl);
-          if (new_ttl > 0xFFFFFF)
-            new_ttl = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 
0xFFFFFF); /* if we get to large, reduce! */
-          if (remTime < new_ttl)
-            new_ttl = remTime;
-          ps->timeout = new_ttl + now;
-          new_priority = ps->priority;
-          new_priority =
-            new_priority + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK,
-                                              4 + 2 * new_priority);
-          if (new_priority > 0xFFFFFF)
-            new_priority = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 
0xFFFFFF);    /* if we get to large, reduce! */
-          ps->priority = new_priority;
-          ps->lastTransmission = now;
-#if DEBUG_SEARCH
-          GNUNET_GE_LOG (ectx,
-                         GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                         "ECRS initiating FS search with timeout %llus and 
priority %u.\n",
-                         (ps->timeout - now) / GNUNET_CRON_SECONDS,
-                         ps->priority);
-#endif
-          ps->handle
-            = GNUNET_FS_start_search (ctx.sctx,
-                                      NULL,
-                                      ps->type,
-                                      ps->keyCount,
-                                      ps->keys,
-                                      anonymityLevel,
-                                      ps->priority,
-                                      ps->timeout,
-                                      (GNUNET_DatastoreValueIterator) &
-                                      receiveReplies, &ctx);
-        }
-      GNUNET_mutex_unlock (ctx.lock);
-      if (((NULL != tt) &&
-           (GNUNET_OK != tt (ttClosure))) || (timeout <= now)
-          || (ctx.aborted != GNUNET_NO))
-        break;
-      GNUNET_thread_sleep (100 * GNUNET_CRON_MILLISECONDS);
+      if (remTime > 100 * GNUNET_CRON_MILLISECONDS)
+        remTime = 100 * GNUNET_CRON_MILLISECONDS;
+      GNUNET_thread_sleep (remTime);
       now = GNUNET_get_time ();
     }
-  for (i = 0; i < ctx.queryCount; i++)
+  GNUNET_FS_destroy_search_context (ctx.sctx);
+  while (ctx.queries != NULL)
     {
-      if (ctx.queries[i]->handle != NULL)
-        GNUNET_FS_stop_search (ctx.sctx, ctx.queries[i]->handle);
-      GNUNET_free (ctx.queries[i]->keys);
-      GNUNET_free (ctx.queries[i]);
+      pos = ctx.queries;
+      ctx.queries = pos->next;
+      GNUNET_free (pos);
     }
-  GNUNET_array_grow (ctx.queries, ctx.queryCount, 0);
-  GNUNET_FS_destroy_search_context (ctx.sctx);
   GNUNET_mutex_destroy (ctx.lock);
   return GNUNET_OK;
 }

Modified: GNUnet/src/applications/fs/gap/plan.c
===================================================================
--- GNUnet/src/applications/fs/gap/plan.c       2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/applications/fs/gap/plan.c       2008-02-06 07:11:29 UTC (rev 
6162)
@@ -410,7 +410,7 @@
   rpc.info = info;
   rpc.request = request;
   rpc.rankings = NULL;
-  total_peers = coreAPI->(rank_peers,
+  total_peers = coreAPI->forAllConnectedNodes(rank_peers,
                                              &rpc);
   /* use request type, priority, system load and
      entropy of ranking to determine number of peers

Modified: GNUnet/src/applications/fs/lib/fslib.c
===================================================================
--- GNUnet/src/applications/fs/lib/fslib.c      2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/applications/fs/lib/fslib.c      2008-02-06 07:11:29 UTC (rev 
6162)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     (C) 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing 
authors)
+     (C) 2004, 2005, 2006, 2007, 2008 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
@@ -32,47 +32,121 @@
 
 #define DEBUG_FSLIB GNUNET_NO
 
-typedef struct GNUNET_FS_SearchHandle
+/**
+ * How often should we automatically retry a request
+ * that failed? (Note that searches are retried 
+ * indefinitely in any case; this only applies
+ * to upload/delete operations).
+ */
+#define AUTO_RETRY 5
+
+/**
+ * In memory, the search handle is followed
+ * by a copy of the corresponding request of
+ * type "CS_fs_request_search_MESSAGE *".
+ */
+struct GNUNET_FS_SearchHandle
 {
-  CS_fs_request_search_MESSAGE *req;
+  /**
+   * This is a linked list.
+   */
+  struct GNUNET_FS_SearchHandle *next;
+
+  /**
+   * Function to call with results.
+   */
   GNUNET_DatastoreValueIterator callback;
+
+  /**
+   * Extra argument to pass to callback.
+   */
   void *closure;
-} SEARCH_HANDLE;
+};
 
-typedef struct GNUNET_FS_SearchContext
+/**
+ * Context for a set of search operations.
+ */
+struct GNUNET_FS_SearchContext
 {
+  /**
+   * Configuration data.
+   */
   struct GNUNET_GC_Configuration *cfg;
+
+  /**
+   * Error logging.
+   */
   struct GNUNET_GE_Context *ectx;
+
+  /**
+   * Connection to gnunetd.
+   */
   struct GNUNET_ClientServerConnection *sock;
+
+  /**
+   * Thread listening for replies.
+   */
   struct GNUNET_ThreadHandle *thread;
+
+  /**
+   * Lock for access to this struct.
+   */
   struct GNUNET_Mutex *lock;
-  SEARCH_HANDLE **handles;
-  unsigned int handleCount;
-  unsigned int handleSize;
+
+  /**
+   * List of active requests.
+   */
+  struct GNUNET_FS_SearchHandle *handles;
+
+  /**
+   * Flag to signal that we should abort.
+   */
   int abort;
-} SEARCH_CONTEXT;
+};
 
 /**
- * How often should we automatically retry if we
- * get a transient error back from gnunetd?
+ * Retransmit all of the requests to gnunetd 
+ * (used after a disconnect).
  */
-#define AUTO_RETRY 4
+static int
+reissue_requests (struct GNUNET_FS_SearchContext *ctx)
+{
+  const CS_fs_request_search_MESSAGE *req;
+  struct GNUNET_FS_SearchHandle *pos;
 
+  pos = ctx->handles;
+  while (pos != NULL)
+    {
+      req = (const CS_fs_request_search_MESSAGE *) &pos[1];
+      if (GNUNET_OK !=
+          GNUNET_client_connection_write (ctx->sock, &req->header))
+        return GNUNET_SYSERR;
+      pos = pos->next;
+    }
+  if (GNUNET_SYSERR == GNUNET_client_connection_ensure_connected (ctx->sock))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
+}
+
 /**
  * Thread that processes replies from gnunetd and
  * calls the appropriate callback.
  */
 static void *
-processReplies (void *cls)
+reply_process_thread (void *cls)
 {
-  SEARCH_CONTEXT *ctx = cls;
+  struct GNUNET_FS_SearchContext *ctx = cls;
   GNUNET_MessageHeader *hdr;
-  int i;
   int matched;
   const CS_fs_reply_content_MESSAGE *rep;
   GNUNET_HashCode query;
   unsigned int size;
   GNUNET_CronTime delay;
+  const CS_fs_request_search_MESSAGE *req;
+  GNUNET_DatastoreValue *value;
+  struct GNUNET_FS_SearchHandle *pos;
+  struct GNUNET_FS_SearchHandle *prev;
+  int unique;
 
   delay = 100 * GNUNET_CRON_MILLISECONDS;
   while (ctx->abort == GNUNET_NO)
@@ -105,44 +179,54 @@
               GNUNET_free (hdr);
               continue;
             }
+          unique =
+            GNUNET_EC_file_block_get_type (size,
+                                           (DBlock *) & rep[1]) ==
+            GNUNET_ECRS_BLOCKTYPE_DATA;
+          value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
+          value->size = htonl (size + sizeof (GNUNET_DatastoreValue));
+          value->type =
+            htonl (GNUNET_EC_file_block_get_type (size, (DBlock *) & rep[1]));
+          value->prio = htonl (0);
+          value->anonymityLevel = rep->anonymityLevel;
+          value->expirationTime = rep->expirationTime;
+          memcpy (&value[1], &rep[1], size);
           matched = 0;
           GNUNET_mutex_lock (ctx->lock);
-          for (i = ctx->handleCount - 1; i >= 0; i--)
+          prev = NULL;
+          pos = ctx->handles;
+          while (pos != NULL)
             {
+              req = (const CS_fs_request_search_MESSAGE *) &pos[1];
               if (0 ==
-                  memcmp (&query, &ctx->handles[i]->req->query[0],
-                          sizeof (GNUNET_HashCode)))
+                  memcmp (&query, &req->query[0], sizeof (GNUNET_HashCode)))
                 {
-                  GNUNET_DatastoreValue *value;
-
                   matched++;
-                  if (ctx->handles[i]->callback != NULL)
-                    {
-                      value =
-                        GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
-                      value->size =
-                        htonl (size + sizeof (GNUNET_DatastoreValue));
-                      value->type =
-                        htonl (GNUNET_EC_file_block_get_type
-                               (size, (DBlock *) & rep[1]));
-                      value->prio = htonl (0);
-                      value->anonymityLevel = rep->anonymityLevel;
-                      value->expirationTime = rep->expirationTime;
-                      memcpy (&value[1], &rep[1], size);
-                      if (GNUNET_SYSERR == ctx->handles[i]->callback (&query,
-                                                                      value,
-                                                                      ctx->
-                                                                      handles
-                                                                      [i]->
-                                                                      closure,
-                                                                      0))
-                        {
-                          ctx->handles[i]->callback = NULL;
-                        }
-                      GNUNET_free (value);
-                    }
+                  if ((pos->callback != NULL) &&
+                      (GNUNET_SYSERR == pos->callback (&query,
+                                                       value,
+                                                       pos->closure, 0)))
+                    pos->callback = NULL;
                 }
+              if (unique)
+                {
+                  if (prev == NULL)
+                    ctx->handles = pos->next;
+                  else
+                    prev->next = pos->next;
+                  GNUNET_free (pos);
+                  if (prev == NULL)
+                    pos = ctx->handles;
+                  else
+                    pos = prev->next;
+                }
+              else
+                {
+                  prev = pos;
+                  pos = pos->next;
+                }
             }
+          GNUNET_free (value);
           GNUNET_mutex_unlock (ctx->lock);
 #if DEBUG_FSLIB
           if (matched == 0)
@@ -154,32 +238,32 @@
         }
       else
         {
-#if DEBUG_FSLIB
-          GNUNET_GE_LOG (ctx->ectx,
-                         GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                         "FSLIB: error communicating with gnunetd; sleeping 
for %ums\n",
-                         delay);
-#endif
-          if (ctx->abort == GNUNET_NO)
-            GNUNET_thread_sleep (delay);
-          delay *= 2;
-          if (delay > 5 * GNUNET_CRON_SECONDS)
-            delay = 5 * GNUNET_CRON_SECONDS;
+          while (GNUNET_NO == ctx->abort)
+            {
+              GNUNET_thread_sleep (delay);
+              delay *= 2;
+              if (delay > 5 * GNUNET_CRON_SECONDS)
+                delay = 5 * GNUNET_CRON_SECONDS;
+              if ((GNUNET_OK ==
+                   GNUNET_client_connection_ensure_connected (ctx->sock))
+                  && (GNUNET_OK == reissue_requests (ctx)))
+                break;          /* we're back, continue outer loop! */
+            }
         }
       GNUNET_free_non_null (hdr);
     }
   return NULL;
 }
 
-SEARCH_CONTEXT *
-GNUNET_FS_create_search_context (struct GNUNET_GE_Context * ectx,
-                                 struct GNUNET_GC_Configuration * cfg,
-                                 struct GNUNET_Mutex * lock)
+struct GNUNET_FS_SearchContext *
+GNUNET_FS_create_search_context (struct GNUNET_GE_Context *ectx,
+                                 struct GNUNET_GC_Configuration *cfg,
+                                 struct GNUNET_Mutex *lock)
 {
-  SEARCH_CONTEXT *ret;
+  struct GNUNET_FS_SearchContext *ret;
 
   GNUNET_GE_ASSERT (ectx, lock != NULL);
-  ret = GNUNET_malloc (sizeof (SEARCH_CONTEXT));
+  ret = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchContext));
   ret->ectx = ectx;
   ret->cfg = cfg;
   ret->lock = lock;
@@ -190,10 +274,8 @@
       return NULL;
     }
   ret->handles = NULL;
-  ret->handleCount = 0;
-  ret->handleSize = 0;
   ret->abort = GNUNET_NO;
-  ret->thread = GNUNET_thread_create (&processReplies, ret, 128 * 1024);
+  ret->thread = GNUNET_thread_create (&reply_process_thread, ret, 128 * 1024);
   if (ret->thread == NULL)
     GNUNET_GE_DIE_STRERROR (ectx,
                             GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
@@ -205,9 +287,9 @@
 GNUNET_FS_destroy_search_context (struct GNUNET_FS_SearchContext *ctx)
 {
   void *unused;
+  struct GNUNET_FS_SearchHandle *pos;
 
   GNUNET_mutex_lock (ctx->lock);
-  GNUNET_GE_ASSERT (ctx->ectx, ctx->handleCount == 0);
   ctx->abort = GNUNET_YES;
   GNUNET_client_connection_close_forever (ctx->sock);
   GNUNET_mutex_unlock (ctx->lock);
@@ -215,7 +297,12 @@
   GNUNET_thread_join (ctx->thread, &unused);
   ctx->lock = NULL;
   GNUNET_client_connection_destroy (ctx->sock);
-  GNUNET_array_grow (ctx->handles, ctx->handleSize, 0);
+  while (ctx->handles != NULL)
+    {
+      pos = ctx->handles;
+      ctx->handles = pos->next;
+      GNUNET_free (pos);
+    }
   GNUNET_free (ctx);
 }
 
@@ -229,140 +316,51 @@
  * @param callback method to call for each result
  * @param prio priority to use for the search
  */
-SEARCH_HANDLE *
-GNUNET_FS_start_search (SEARCH_CONTEXT * ctx,
+int
+GNUNET_FS_start_search (struct GNUNET_FS_SearchContext *ctx,
                         const GNUNET_PeerIdentity * target,
                         unsigned int type,
                         unsigned int keyCount,
                         const GNUNET_HashCode * keys,
                         unsigned int anonymityLevel,
-                        unsigned int prio,
-                        GNUNET_CronTime timeout,
                         GNUNET_DatastoreValueIterator callback, void *closure)
 {
-  SEARCH_HANDLE *ret;
+  struct GNUNET_FS_SearchHandle *ret;
   CS_fs_request_search_MESSAGE *req;
 #if DEBUG_FSLIB
   GNUNET_EncName enc;
 #endif
 
-  ret = GNUNET_malloc (sizeof (SEARCH_HANDLE));
+  ret = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchHandle) +
+                       sizeof (CS_fs_request_search_MESSAGE) +
+                       (keyCount - 1) * sizeof (GNUNET_HashCode));
+  req = (CS_fs_request_search_MESSAGE *) & ret[1];
 #if DEBUG_FSLIB
   GNUNET_GE_LOG (ctx->ectx,
                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
                  "FSLIB: start search (%p)\n", ret);
 #endif
-  req =
-    GNUNET_malloc (sizeof (CS_fs_request_search_MESSAGE) +
-                   (keyCount - 1) * sizeof (GNUNET_HashCode));
   req->header.size =
     htons (sizeof (CS_fs_request_search_MESSAGE) +
            (keyCount - 1) * sizeof (GNUNET_HashCode));
   req->header.type = htons (GNUNET_CS_PROTO_GAP_QUERY_START);
-  req->prio = htonl (prio);
   req->anonymityLevel = htonl (anonymityLevel);
-  req->expiration = GNUNET_htonll (timeout);
   req->type = htonl (type);
   if (target != NULL)
     req->target = *target;
   else
     memset (&req->target, 0, sizeof (GNUNET_PeerIdentity));
   memcpy (&req->query[0], keys, keyCount * sizeof (GNUNET_HashCode));
-  ret->req = req;
   ret->callback = callback;
   ret->closure = closure;
   GNUNET_mutex_lock (ctx->lock);
-  if (ctx->handleCount == ctx->handleSize)
-    {
-      GNUNET_array_grow (ctx->handles, ctx->handleSize,
-                         ctx->handleSize * 2 + 4);
-    }
-  ctx->handles[ctx->handleCount++] = ret;
+  ret->next = ctx->handles;
+  ctx->handles = ret;
   GNUNET_mutex_unlock (ctx->lock);
-#if DEBUG_FSLIB
-  IF_GELOG (ctx->ectx,
-            GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-            GNUNET_hash_to_enc (&req->query[0], &enc));
-  GNUNET_GE_LOG (ctx->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "FSLIB: initiating search for `%s' of type %u\n", &enc,
-                 type);
-#endif
-  GNUNET_GE_ASSERT (NULL, ctx->sock != NULL);
-  if (GNUNET_OK != GNUNET_client_connection_write (ctx->sock, &req->header))
-    {
-      GNUNET_FS_stop_search (ctx, ret);
-      return NULL;
-    }
-#if DEBUG_FSLIB
-  GNUNET_GE_LOG (ctx->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "FSLIB: search started (%p)\n", ret);
-#endif
-  return ret;
+  return GNUNET_OK;
 }
 
 /**
- * Stop searching.
- */
-void
-GNUNET_FS_stop_search (SEARCH_CONTEXT * ctx, SEARCH_HANDLE * handle)
-{
-  int i;
-
-#if DEBUG_FSLIB
-  GNUNET_GE_LOG (ctx->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "FSLIB: stop search (%p)\n", handle);
-#endif
-  handle->req->header.type = htons (GNUNET_CS_PROTO_GAP_QUERY_STOP);
-  GNUNET_GE_ASSERT (NULL, ctx->sock != NULL);
-  if (GNUNET_OK !=
-      GNUNET_client_connection_write (ctx->sock, &handle->req->header))
-    {
-      GNUNET_GE_LOG (ctx->ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_REQUEST |
-                     GNUNET_GE_DEVELOPER,
-                     "FSLIB: failed to request stop search with gnunetd\n");
-    }
-  GNUNET_mutex_lock (ctx->lock);
-  for (i = ctx->handleCount - 1; i >= 0; i--)
-    if (ctx->handles[i] == handle)
-      {
-        ctx->handles[i] = ctx->handles[--ctx->handleCount];
-        break;
-      }
-  GNUNET_mutex_unlock (ctx->lock);
-  GNUNET_free (handle->req);
-#if DEBUG_FSLIB
-  GNUNET_GE_LOG (ctx->ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "FSLIB: search stopped (%p)\n", handle);
-#endif
-  GNUNET_free (handle);
-}
-
-/**
- * What is the current average priority of entries
- * in the routing table like?  Returns -1 on error.
- */
-int
-GNUNET_FS_get_current_average_priority (struct GNUNET_ClientServerConnection
-                                        *sock)
-{
-  GNUNET_MessageHeader req;
-  int ret;
-
-  req.size = htons (sizeof (GNUNET_MessageHeader));
-  req.type = htons (GNUNET_CS_PROTO_GAP_GET_AVG_PRIORITY);
-  if (GNUNET_OK != GNUNET_client_connection_write (sock, &req))
-    return -1;
-  if (GNUNET_OK != GNUNET_client_connection_read_result (sock, &ret))
-    return -1;
-  return ret;
-}
-
-/**
  * Insert a block.
  *
  * @param block the block (properly encoded and all)
@@ -590,10 +588,10 @@
 GNUNET_FS_test_indexed (struct GNUNET_ClientServerConnection *sock,
                         const GNUNET_HashCode * hc)
 {
-  RequestTestindex ri;
+  CS_fs_request_test_index_MESSAGE ri;
   int ret;
 
-  ri.header.size = htons (sizeof (RequestTestindex));
+  ri.header.size = htons (sizeof (CS_fs_request_test_index_MESSAGE));
   ri.header.type = htons (GNUNET_CS_PROTO_GAP_TESTINDEX);
   ri.reserved = htonl (0);
   ri.fileId = *hc;

Modified: GNUnet/src/applications/stats/clientapi.c
===================================================================
--- GNUnet/src/applications/stats/clientapi.c   2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/applications/stats/clientapi.c   2008-02-06 07:11:29 UTC (rev 
6162)
@@ -164,9 +164,8 @@
     case GNUNET_CS_PROTO_GAP_QUERY_START:
       name = "CS_PROTO_gap_QUERY_START";
       break;
-    case GNUNET_CS_PROTO_GAP_QUERY_STOP:
-      /* case GNUNET_CS_PROTO_GAP_RESULT : */
-      name = "CS_PROTO_gap_QUERY_STOP or CS_PROTO_gap_RESULT";
+    case GNUNET_CS_PROTO_GAP_RESULT : 
+      name = "CS_PROTO_gap_RESULT";
       break;
     case GNUNET_CS_PROTO_GAP_INSERT:
       name = "CS_PROTO_gap_INSERT";
@@ -183,9 +182,6 @@
     case GNUNET_CS_PROTO_GAP_TESTINDEX:
       name = "CS_PROTO_gap_TESTINDEX";
       break;
-    case GNUNET_CS_PROTO_GAP_GET_AVG_PRIORITY:
-      name = "CS_PROTO_gap_GET_AVG_PRIORITY";
-      break;
     case GNUNET_CS_PROTO_GAP_INIT_INDEX:
       name = "CS_PROTO_gap_INIT_INDEX";
       break;

Modified: GNUnet/src/include/Makefile.am
===================================================================
--- GNUnet/src/include/Makefile.am      2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/src/include/Makefile.am      2008-02-06 07:11:29 UTC (rev 6162)
@@ -26,7 +26,6 @@
   gnunet_fragmentation_service.h \
   gnunet_fs_lib.h \
   gnunet_fsui_lib.h \
-  gnunet_gap_service.h \
   gnunet_getoption_lib.h \
   gnunet_identity_lib.h \
   gnunet_identity_service.h \

Modified: GNUnet/src/include/ecrs_core.h
===================================================================
--- GNUnet/src/include/ecrs_core.h      2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/src/include/ecrs_core.h      2008-02-06 07:11:29 UTC (rev 6162)
@@ -247,6 +247,8 @@
 /**
  * Get the query that will be used to query for
  * a certain block of data.
+ *
+ * @param db the block in plaintext
  */
 void GNUNET_EC_file_block_get_query (const DBlock * data,
                                      unsigned int len,
@@ -287,7 +289,7 @@
  * Verify that the given Datum is a valid response
  * to a given query.
  *
- * @param type the type of the queryo
+ * @param type the type of the query
  * @param size the size of the data
  * @param data the encoded data
  * @param knownDatumQuery result of GNUNET_EC_file_block_check_and_get_query

Modified: GNUnet/src/include/fs.h
===================================================================
--- GNUnet/src/include/fs.h     2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/src/include/fs.h     2008-02-06 07:11:29 UTC (rev 6162)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and 
other contributing authors)
+     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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
@@ -20,13 +20,13 @@
 
 /**
  * @file applications/fs/module/fs.h
- * @brief FS Client-Server messages
+ * @brief FS Client-Server and P2P message formats
  * @author Christian Grothoff
  */
 #ifndef FS_H
 #define FS_H
 
-#include "gnunet_blockstore.h"
+#include "gnunet_util.h"
 
 /**
  * Client to server: search for content.  Variable
@@ -39,16 +39,11 @@
   GNUNET_MessageHeader header;
 
   /**
-   * Priority of the search.
+   * Should be zero.
    */
-  unsigned int prio;
+  int reserved;
 
   /**
-   * At what time does the search expire?
-   */
-  GNUNET_CronTime expiration;
-
-  /**
    * Type of the content that we're looking for.
    * 0 for any.
    */
@@ -77,15 +72,22 @@
 
 /**
  * Server to client: content (in response to a CS_fs_request_search_MESSAGE).  
The
- * header is followed by variable size data (the data portion
- * of the GNUNET_DatastoreValue).
+ * header is followed by the variable size data of a DBlock (as 
+ * defined in ecrs_core.h).
  */
 typedef struct
 {
   GNUNET_MessageHeader header;
 
+  /** 
+   * Anonymity level for the content, maybe
+   * 0 if not known.
+   */
   unsigned int anonymityLevel;
 
+  /**
+   * Expiration time of the response (relative to now).
+   */
   GNUNET_CronTime expirationTime;
 
 } CS_fs_reply_content_MESSAGE;
@@ -94,21 +96,21 @@
 /**
  * Client to server: insert content.
  * This struct is followed by a variable
- * number of bytes of content.
+ * number of bytes of content (a DBlock).
  */
 typedef struct
 {
   GNUNET_MessageHeader header;
 
   /**
-   * Priority for the on-demand encoded entry.
+   * Reserved (should be zero).  For alignment.
    */
-  unsigned int prio;
+  int reserved;
 
   /**
-   * At what time does the entry expire?
+   * Priority for the on-demand encoded entry.
    */
-  GNUNET_CronTime expiration;
+  unsigned int prio;
 
   /**
    * What are the anonymity requirements for this content?
@@ -117,6 +119,11 @@
    */
   unsigned int anonymityLevel;
 
+  /**
+   * At what time does the entry expire?
+   */
+  GNUNET_CronTime expiration;
+
 } CS_fs_request_insert_MESSAGE;
 
 /**
@@ -148,11 +155,23 @@
   GNUNET_MessageHeader header;
 
   /**
+   * Reserved (should be zero).  For alignment.
+   */
+  int reserved;
+
+  /**
    * Priority for the on-demand encoded entry.
    */
   unsigned int prio;
 
   /**
+   * What are the anonymity requirements for this content?
+   * Use 0 if anonymity is not required (enables direct
+   * sharing / DHT routing).
+   */
+  unsigned int anonymityLevel;
+
+  /**
    * At what time does the entry expire?
    */
   GNUNET_CronTime expiration;
@@ -170,26 +189,23 @@
    */
   GNUNET_HashCode fileId;
 
-  /**
-   * What are the anonymity requirements for this content?
-   * Use 0 if anonymity is not required (enables direct
-   * sharing / DHT routing).
-   */
-  unsigned int anonymityLevel;
-
 } CS_fs_request_index_MESSAGE;
 
 /**
- * Client to server: delete content.  This struct is followed by a
- * variable number of bytes of the content that is to be deleted.
+ * Client to server: delete content.  This struct is followed by 
+ * the DBlock (of variable size) of the content that is to be deleted.
  */
 typedef struct
 {
   GNUNET_MessageHeader header;
 
+  /**
+   * Reserved (should be zero).  For alignment.
+   */
+  int reserved;
+
 } CS_fs_request_delete_MESSAGE;
 
-
 /**
  * Client to server: unindex file.
  */
@@ -225,20 +241,208 @@
    */
   GNUNET_HashCode fileId;
 
-} RequestTestindex;
+} CS_fs_request_test_index_MESSAGE;
 
 
 /**
- * Encapsulation of the data in the format that is passed through gap.
- * We essentially add the timeout value since that part is supposed to
- * be communicated to other peers.
+ * Request for content. The number of queries can
+ * be determined from the header.  This struct
+ * maybe followed by a bloom filter (size determined
+ * by the header) which includes hashes of responses
+ * that should NOT be returned.  If there is no 
+ * bloom filter, the filter_mutator
+ * should be zero.
  */
 typedef struct
 {
-  GNUNET_DataContainer dc;
-  unsigned int reserved;        /* for 64-bit alignment */
-  unsigned long long timeout;
-} GapWrapper;
+  GNUNET_MessageHeader header;
 
+  /**
+   * Type of the query (block type).
+   */
+  unsigned int type;
 
+  /**
+   * How important is this request (network byte order)
+   */
+  unsigned int priority;
+
+  /**
+   * Relative time to live in GNUNET_CRON_MILLISECONDS (network byte order)
+   */
+  int ttl;
+
+  /**
+   * The content hash should be mutated using this value
+   * before checking against the bloomfilter (used to
+   * get many different filters for the same hash codes).
+   */
+  int filter_mutator;
+
+  /**
+   * How many queries do we have (should be 
+   * greater than zero).
+   */
+  unsigned int number_of_queries;
+
+  /**
+   * To whom to return results?
+   */
+  GNUNET_PeerIdentity returnTo;
+
+  /**
+   * Hashcodes of the file(s) we're looking for.
+   * Details depend on the query type.
+   */
+  GNUNET_HashCode queries[1];
+
+} P2P_gap_query_MESSAGE;
+
+/**
+ * Return message for search result.  This struct
+ * is always followed by a DBlock (see ecrs_core.h) 
+ * which contains the GNUNET_ECRS_BLOCKTYPE followed
+ * by the actual (encrypted) data.
+ */
+typedef struct
+{
+  GNUNET_MessageHeader header;
+
+  /**
+   * Always zero (for now).
+   */
+  unsigned int reserved; /* for 64-bit alignment */
+
+  /**
+   * When does this result expire?  The given time
+   * is relative (and in big-endian).
+   */
+  unsigned long long expiration; 
+
+} P2P_gap_reply_MESSAGE;
+
+
+/* ***************** policy constants **************** */
+
+/**
+ * Bandwidth value of an (effectively) 0-priority query.
+ */
+#define QUERY_BANDWIDTH_VALUE 0.001
+
+/**
+ * Bandwidth value of a 0-priority content (must be
+ * fairly high compared to query since content is
+ * typically significantly larger -- and more valueable
+ * since it can take many queries to get one piece of
+ * content).
+ */
+#define CONTENT_BANDWIDTH_VALUE 0.8
+
+/**
+ * By which amount do we decrement the TTL for simple forwarding /
+ * indirection of the query; in milli-seconds.  Set somewhat in
+ * accordance to your network latency (above the time it'll take you
+ * to send a packet and get a reply).
+ */
+#define TTL_DECREMENT (5 * GNUNET_CRON_SECONDS)
+
+/**
+ * Until which load do we consider the peer idle and do not
+ * charge at all? (should be larger than GNUNET_IDLE_LOAD_THRESHOLD used
+ * by the rest of the code)!
+ */
+#define GAP_IDLE_LOAD_THRESHOLD ((100 + GNUNET_IDLE_LOAD_THRESHOLD) / 2)
+
+/**
+ * How many bits should we have per entry in the
+ * bloomfilter?
+ */
+#define GAP_BLOOMFILTER_K 16
+
+/**
+ * Minimum size of the GAP routing table.
+ */
+#define MIN_INDIRECTION_TABLE_SIZE 4
+
+
+/**
+ * How much is a response worth 'in general'.  Since replies are
+ * roughly 1k and should be much (factor of 4) preferred over queries
+ * (which have a base priority of 20, which yields a base unit of
+ * roughly 1 per byte).  Thus if we set this value to 4092 we'd rather
+ * send a reply instead of a query unless the queries have (on
+ * average) a priority that is more than double the reply priority
+ * (note that querymanager multiplies the query priority with 2 to
+ * compute the scheduling priority).
+ */
+#define BASE_REPLY_PRIORITY 4092
+
+/**
+ * What is the maximum time that any peer
+ * should delay forwarding a response (when
+ * waiting for bandwidth).
+ */
+#define MAX_GAP_DELAY (60 * GNUNET_CRON_SECONDS)
+
+
+/**
+ * How long should DHT requests live?
+ */
+#define MAX_DHT_DELAY (60 * GNUNET_CRON_SECONDS)
+
+
+/**
+ * What is the maximum expiration time for migrated content?
+ *
+ * This is a non-trivial issue.  If we have a ceiling for migration
+ * time, it would violate anonymity if we send out content with an
+ * expiration time above that ceiling (since it would expose the
+ * content to originate from this peer).  But we want to store a
+ * higher expiration time for our content in the DB.
+ *
+ * A first idea would be to pick a random time smaller than the limit
+ * for outgoing content; that does not _quite_ work since that could
+ * also expose us as the originator: only for our own content the
+ * expiration time would randomly go up and down.
+ *
+ * The current best solution is to first bound the expiration time by
+ * this ceiling (for inbound and outbound ETs, not for the database
+ * entries locally) using modulo (to, in practice, get a constant
+ * bound for the local content just like for the migrated content).
+ * Then that number is randomized for _all_ outgoing content.  This
+ * way, the time left changes for all entries, but statistically
+ * always decreases on average as time progresses (also for all
+ * entries).
+ *
+ * Now, for local content eventually modulo will rebound to the MAX
+ * (whereas for migrated content it will hit 0 and disappear).  But
+ * that is GNUNET_OK: the adversary cannot distinguish the modulo wraparound
+ * from content migration (refresh with higher lifetime) which could
+ * plausibly happen from the original node (and in fact would happen
+ * around the same time!).  This design also achieves the design goal
+ * that if the original node disappears, the migrated content will
+ * eventually time-out (which is good since we don't want dangling
+ * search results to stay around).
+ *
+ * However, this does NOT mean that migrated content cannot live
+ * longer than 1 month -- remember, GNUnet peers discard expired
+ * content _if they run out of space_.  So it is perfectly plausible
+ * that content stays around longer.  Finally, clients (UI) may want
+ * to filter / rank / display search results with their current
+ * expiration to give the user some indication about availability.
+ *
+ */
+#define MAX_MIGRATION_EXP (1L * GNUNET_CRON_MONTHS)
+
+/**
+ * Estimated size of most blocks transported with
+ * the GAP protocol.  32k DBlocks plus overhead.
+ */
+#define GNUNET_GAP_ESTIMATED_DATA_SIZE (33*1024)
+
+
+
+
+
+
 #endif

Modified: GNUnet/src/include/gnunet_core.h
===================================================================
--- GNUnet/src/include/gnunet_core.h    2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/src/include/gnunet_core.h    2008-02-06 07:11:29 UTC (rev 6162)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     (C) 2004, 2005, 2006, 2008 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
@@ -49,7 +49,7 @@
  * roughly the main GNUnet version scheme, but is
  * more a compatibility ID.
  */
-#define GNUNET_CORE_VERSION 0x00070300
+#define GNUNET_CORE_VERSION 0x00070399
 
 
 /**
@@ -164,20 +164,6 @@
                                             unsigned short len);
 
 /**
- * Send a message to the client identified by the handle.  Note that
- * the core will typically buffer these messages as much as possible
- * and only return GNUNET_SYSERR if it runs out of buffers.  Returning 
GNUNET_OK
- * on the other hand does NOT confirm delivery since the actual
- * transfer happens asynchronously.
- *
- * @param force GNUNET_YES if this message MUST be queued
- */
-typedef int (*GNUNET_SendToClientCallback) (struct GNUNET_ClientHandle *
-                                            handle,
-                                            const GNUNET_MessageHeader *
-                                            message, int force);
-
-/**
  * GNUnet CORE API for applications and services that are implemented
  * on top of the GNUnet core.
  */
@@ -215,33 +201,9 @@
   struct GNUNET_CronManager *cron;
 
 
-  /* ****************** services and applications **************** */
+  /* ****************** services **************** */
 
   /**
-   * Load an application module.  This function must be called
-   * while cron is suspended.  Note that the initialization and
-   * shutdown function of modules are always run while cron is
-   * disabled, so suspending cron is not necesary if modules
-   * are loaded or unloaded inside the module initialization or
-   * shutdown code.
-   *
-   * @return GNUNET_OK on success, GNUNET_SYSERR on error
-   */
-  int (*loadApplicationModule) (const char *name);
-
-  /**
-   * Unload an application module.  This function must be called
-   * while cron is suspended.  Note that the initialization and
-   * shutdown function of modules are always run while cron is
-   * disabled, so suspending cron is not necesary if modules
-   * are loaded or unloaded inside the module initialization or
-   * shutdown code.
-   *
-   * @return GNUNET_OK on success, GNUNET_SYSERR on error
-   */
-  int (*unloadApplicationModule) (const char *name);
-
-  /**
    * Load a service module of the given name. This function must be
    * called while cron is suspended.  Note that the initialization and
    * shutdown function of modules are always run while cron is
@@ -266,6 +228,19 @@
   /* ****************** P2P data exchange **************** */
 
   /**
+   * Send an encrypted message to another node.
+   *
+   * @param receiver the target node
+   * @param msg the message to send, NULL to tell
+   *   the core to try to establish a session
+   * @param importance how important is the message?
+   * @param maxdelay how long can the message be delayed?
+   */
+  void (*unicast) (const GNUNET_PeerIdentity * receiver,
+                   const GNUNET_MessageHeader * msg,
+                   unsigned int importance, unsigned int maxdelay);
+
+  /**
    * Send a plaintext message to another node.  This is
    * not the usual way for communication and should ONLY be
    * used by modules that are responsible for setting up
@@ -281,19 +256,6 @@
                                     const char *msg, unsigned int size);
 
   /**
-   * Send an encrypted message to another node.
-   *
-   * @param receiver the target node
-   * @param msg the message to send, NULL to tell
-   *   the core to try to establish a session
-   * @param importance how important is the message?
-   * @param maxdelay how long can the message be delayed?
-   */
-  void (*unicast) (const GNUNET_PeerIdentity * receiver,
-                   const GNUNET_MessageHeader * msg,
-                   unsigned int importance, unsigned int maxdelay);
-
-  /**
    * Send an encrypted, on-demand build message to another node.
    *
    * @param receiver the target node
@@ -312,15 +274,6 @@
                                           unsigned int importance,
                                           unsigned int maxdelay);
 
-  /**
-   * Perform an operation for all connected hosts.
-   * No synchronization or other checks are performed.
-   *
-   * @param method the method to invoke (NULL for counting only)
-   * @param arg the second argument to the method
-   * @return the number of connected hosts
-   */
-  int (*forAllConnectedNodes) (GNUNET_NodeIteratorCallback method, void *arg);
 
   /**
    * Register a callback method that should be invoked whenever a message
@@ -362,7 +315,28 @@
                                               GNUNET_BufferFillCallback
                                               callback);
 
+  /* *********************** notifications ********************* */
+
   /**
+   * Call the given function whenever we get
+   * disconnected from a particular peer.
+   *
+   * @return GNUNET_OK
+   */
+  int (*register_notify_peer_disconnect)(GNUNET_NodeIteratorCallback callback,
+                                        void * cls);
+
+  /**
+   * Stop calling the given function whenever we get
+   * disconnected from a particular peer.
+   *
+   * @return GNUNET_OK on success, GNUNET_SYSERR
+   *         if this callback is not registered
+   */
+  int (*unregister_notify_peer_disconnect)(GNUNET_NodeIteratorCallback 
callback,
+                                          void * cls);
+
+  /**
    * Register a handler that is to be called for each
    * message that leaves the peer.
    *
@@ -454,7 +428,34 @@
 
   /* ***************** traffic management ******************* */
 
+
   /**
+   * Perform an operation for all connected hosts.
+   * No synchronization or other checks are performed.
+   *
+   * @param method the method to invoke (NULL for counting only)
+   * @param arg the second argument to the method
+   * @return the number of connected hosts
+   */
+  int (*forAllConnectedNodes) (GNUNET_NodeIteratorCallback method, void *arg);
+
+  /**
+   * Try to reserve downstream bandwidth for a particular peer.
+   *
+   * @param peer with whom should bandwidth be reserved?
+   * @param amount how many bytes should we expect to receive?
+   *        (negative amounts can be used to undo a (recent)
+   *        reservation request
+   * @param timeframe in what time interval should the other
+   *        peer be able to transmit the amount?  Use zero
+   *        when undoing a reservation
+   * @return amount that could actually be reserved 
+   */
+  int (*reserve_downstream_bandwidth)(const GNUNET_NodeIteratorCallback * peer,
+                                     int amount,
+                                     GNUNET_CronTime timeframe);
+
+  /**
    * Offer the core a session for communication with the
    * given peer.  This is useful after establishing a connection
    * with another peer to hand it of to the core.  Note that
@@ -559,8 +560,23 @@
    * and only return GNUNET_SYSERR if it runs out of buffers.  Returning 
GNUNET_OK
    * on the other hand does NOT confirm delivery since the actual
    * transfer happens asynchronously.
+   *
+   * @param force GNUNET_YES if this message MUST be queued
    */
-  GNUNET_SendToClientCallback cs_send_to_client;
+  int (*cs_send_to_client)(struct GNUNET_ClientHandle *
+                          handle,
+                          const GNUNET_MessageHeader *
+                          message, int force);
+  
+  /**
+   * Send a message to the client identified by the handle.  Note that
+   * the core will typically buffer these messages as much as possible
+   * and only return GNUNET_SYSERR if it runs out of buffers.  Returning 
GNUNET_OK
+   * on the other hand does NOT confirm delivery since the actual
+   * transfer happens asynchronously.
+   */
+  int (*sendErrorMessageToClient) (struct GNUNET_ClientHandle * handle,
+                                   GNUNET_GE_KIND kind, const char *value);
 
   /**
    * Register a method as a handler for specific message
@@ -609,7 +625,14 @@
   void (*cs_terminate_client_connection) (struct
                                           GNUNET_ClientHandle * handle);
 
+  /**
+   * Create a log context that will transmit errors to the
+   * given client.
+   */
+  struct GNUNET_GE_Context
+    *(*cs_create_client_log_context) (struct GNUNET_ClientHandle * handle);
 
+
   /* ************************ MISC ************************ */
 
   /**
@@ -665,21 +688,10 @@
                                                * peer,
                                                GNUNET_CronTime * time);
 
-  /* here for binary compatibility (for now) */
-
   /**
-   * Send a message to the client identified by the handle.  Note that
-   * the core will typically buffer these messages as much as possible
-   * and only return GNUNET_SYSERR if it runs out of buffers.  Returning 
GNUNET_OK
-   * on the other hand does NOT confirm delivery since the actual
-   * transfer happens asynchronously.
+   * Assert that the given tsession is no longer
+   * in use by the core.
    */
-  int (*sendErrorMessageToClient) (struct GNUNET_ClientHandle * handle,
-                                   GNUNET_GE_KIND kind, const char *value);
-
-  struct GNUNET_GE_Context
-    *(*cs_create_client_log_context) (struct GNUNET_ClientHandle * handle);
-
   int (*connection_assert_tsession_unused) (GNUNET_TSession * tsession);
 
 } GNUNET_CoreAPIForPlugins;

Modified: GNUnet/src/include/gnunet_dht_service.h
===================================================================
--- GNUnet/src/include/gnunet_dht_service.h     2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/include/gnunet_dht_service.h     2008-02-06 07:11:29 UTC (rev 
6162)
@@ -51,14 +51,10 @@
 {
 
   /**
-   * Perform an asynchronous GET operation on the DHT identified by
-   * 'table' using 'key' as the key.  The peer does not have to be part
-   * of the table (if so, we will attempt to locate a peer that is!)
+   * Perform an asynchronous GET operation on the DHT identified.
    *
-   * @param table table to use for the lookup
+   * @param type expected type of the response object
    * @param key the key to look up
-   * @param timeout how long to wait until this operation should
-   *        automatically time-out
    * @param callback function to call on each result
    * @param closure extra argument to callback
    * @return handle to stop the async get

Modified: GNUnet/src/include/gnunet_fs_lib.h
===================================================================
--- GNUnet/src/include/gnunet_fs_lib.h  2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/src/include/gnunet_fs_lib.h  2008-02-06 07:11:29 UTC (rev 6162)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     (C) 2004, 2005, 2006, 2008 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
@@ -46,66 +46,48 @@
 
 struct GNUNET_FS_SearchContext;
 
-struct GNUNET_FS_SearchContext *GNUNET_FS_create_search_context (struct
-                                                                 
GNUNET_GE_Context
-                                                                 *ectx,
-                                                                 struct
-                                                                 
GNUNET_GC_Configuration
-                                                                 *cfg,
-                                                                 struct
-                                                                 GNUNET_Mutex
-                                                                 *lock);
+struct GNUNET_FS_SearchContext *
+GNUNET_FS_create_search_context (struct
+                                GNUNET_GE_Context
+                                *ectx,
+                                struct
+                                GNUNET_GC_Configuration
+                                *cfg,
+                                struct
+                                GNUNET_Mutex
+                                *lock);
 
 void GNUNET_FS_destroy_search_context (struct GNUNET_FS_SearchContext *ctx);
 
-struct GNUNET_FS_SearchHandle;
-
 /**
  * Search for blocks matching the given key and type.
  *
  * @param target identity of host known to have the
  *        content, NULL if no such identity is known
- * @param timeout how long to search
  * @param anonymityLevel what are the anonymity
  *        requirements for this request? 0 for no
  *        anonymity (DHT/direct transfer ok)
  * @param callback method to call for each result
- * @param prio priority to use for the search
+ * @return GNUNET_OK
  */
-struct GNUNET_FS_SearchHandle *GNUNET_FS_start_search (struct
-                                                       GNUNET_FS_SearchContext
-                                                       *ctx,
-                                                       const
-                                                       GNUNET_PeerIdentity *
-                                                       target,
-                                                       unsigned int type,
-                                                       unsigned int keyCount,
-                                                       const GNUNET_HashCode *
-                                                       keys,
-                                                       unsigned int
-                                                       anonymityLevel,
-                                                       unsigned int prio,
-                                                       GNUNET_CronTime
-                                                       timeout,
-                                                       
GNUNET_DatastoreValueIterator
-                                                       callback,
-                                                       void *closure);
+int
+GNUNET_FS_start_search (struct
+                       GNUNET_FS_SearchContext
+                       *ctx,
+                       const
+                       GNUNET_PeerIdentity *
+                       target,
+                       unsigned int type,
+                       unsigned int keyCount,
+                       const GNUNET_HashCode *
+                       keys,
+                       unsigned int
+                       anonymityLevel,
+                       GNUNET_DatastoreValueIterator
+                       callback,
+                       void *closure);
 
 /**
- * Stop searching.
- */
-void GNUNET_FS_stop_search (struct GNUNET_FS_SearchContext *ctx,
-                            struct GNUNET_FS_SearchHandle *handle);
-
-/**
- * What is the current average priority of entries
- * in the routing table like?  Returns -1 on error.
- */
-int GNUNET_FS_get_current_average_priority (struct
-                                            GNUNET_ClientServerConnection
-                                            *sock);
-
-/**
  * Insert a block.  Note that while the API is VERY similar to
  * GNUNET_FS_index in terms of signature, the block for GNUNET_FS_index must 
be in
  * plaintext, whereas the block passed to GNUNET_FS_insert must be encrypted!

Deleted: GNUnet/src/include/gnunet_gap_service.h
===================================================================
--- GNUnet/src/include/gnunet_gap_service.h     2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/include/gnunet_gap_service.h     2008-02-06 07:11:29 UTC (rev 
6162)
@@ -1,148 +0,0 @@
-/*
-      This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
-
-      GNUnet is free software; you can redistribute it and/or modify
-      it under the terms of the GNU General Public License as published
-      by the Free Software Foundation; either version 2, or (at your
-      option) any later version.
-
-      GNUnet is distributed in the hope that it will be useful, but
-      WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-      General Public License for more details.
-
-      You should have received a copy of the GNU General Public License
-      along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
- */
-
-/**
- * @file include/gnunet_gap_service.h
- * @brief API to the GAP-module.  This API is what will be used by
- *     GAP clients that run as modules within gnunetd.  GAP is
- *     currently not supposed to be used directly by clients,
- *     look at the gnunet_fs_lib.h for the lowest-level client API.
- * @author Christian Grothoff
- */
-
-#ifndef GAP_SERVICE_API_H
-#define GAP_SERVICE_API_H
-
-#include "gnunet_core.h"
-#include "gnunet_blockstore.h"
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-/**
- * Estimated size of most blocks transported with
- * the GAP protocol.  32k DBlocks plus overhead.
- */
-#define GNUNET_GAP_ESTIMATED_DATA_SIZE (33*1024)
-
-/**
- * Function that helps the routing code to find out if
- * a given reply is the one and only reply for a given
- * request.
- * @param verify check that content is valid? (GNUNET_YES/GNUNET_NO)
- */
-typedef int (*GNUNET_UniqueReplyIdentifierCallback) (const
-                                                     GNUNET_DataContainer *
-                                                     content,
-                                                     unsigned int query_type,
-                                                     int verify,
-                                                     const GNUNET_HashCode *
-                                                     primaryKey);
-
-/**
- * Given some content, compute the unique
- * GNUNET_hash of the content that can then be used
- * to sort out duplicates.
- */
-typedef int (*GNUNET_ReplyHashingCallback) (const GNUNET_DataContainer * data,
-                                            GNUNET_HashCode * hc);
-
-/**
- * Functions of the GAP Service API.
- */
-typedef struct
-{
-
-  /**
-   * Start GAP.
-   *
-   * @param datastore the storage callbacks to use for storing data
-   * @return GNUNET_SYSERR on error, GNUNET_OK on success
-   */
-  int (*init) (GNUNET_Blockstore * datastore,
-               GNUNET_UniqueReplyIdentifierCallback uri,
-               GNUNET_ReplyHashingCallback rhf);
-
-  /**
-   * Perform a GET operation using 'key' as the key.  Note that no
-   * callback is given for the results since GAP just calls PUT on the
-   * datastore on anything that is received, and the caller will be
-   * listening for these puts.
-   *
-   * @param target peer to ask primarily (maybe NULL)
-   * @param type the type of the block that we're looking for
-   * @param keys the keys to query for
-   * @param timeout how long to wait until this operation should
-   *        automatically time-out
-   * @return GNUNET_OK if we will start to query, GNUNET_SYSERR if all of our
-   *  buffers are full or other error
-   */
-  int (*get_start) (const GNUNET_PeerIdentity * target,
-                    unsigned int type,
-                    unsigned int anonymityLevel,
-                    unsigned int keyCount,
-                    const GNUNET_HashCode * keys,
-                    GNUNET_CronTime timeout, unsigned int prio);
-
-  /**
-   * Stop sending out queries for a given key.  GAP will automatically
-   * stop sending queries at some point, but this method can be used
-   * to stop it earlier.
-   */
-  int (*get_stop) (unsigned int type,
-                   unsigned int keyCount, const GNUNET_HashCode * keys);
-
-  /**
-   * Try to migrate the given content.
-   *
-   * @param data the content to migrate
-   * @param position where to write the message
-   * @param padding the maximum size that the message may be
-   * @return the number of bytes written to
-   *   that buffer (must be a positive number).
-   */
-  unsigned int (*tryMigrate) (const GNUNET_DataContainer * data,
-                              const GNUNET_HashCode * primaryKey,
-                              char *position, unsigned int padding);
-
-  /**
-   * What is the average priority of requests that we
-   * are currently routing?
-   */
-  unsigned int (*getAvgPriority) (void);
-
-} GNUNET_GAP_ServiceAPI;
-
-
-#if 0                           /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* GAP_SERVICE_API_H */

Modified: GNUnet/src/include/gnunet_protocols.h
===================================================================
--- GNUnet/src/include/gnunet_protocols.h       2008-02-06 06:52:39 UTC (rev 
6161)
+++ GNUnet/src/include/gnunet_protocols.h       2008-02-06 07:11:29 UTC (rev 
6162)
@@ -135,11 +135,6 @@
 #define GNUNET_CS_PROTO_GAP_QUERY_START 8
 
 /**
- * client to gnunetd: stop query
- */
-#define GNUNET_CS_PROTO_GAP_QUERY_STOP 9
-
-/**
  * gnunetd to client: here is your answer
  */
 #define GNUNET_CS_PROTO_GAP_RESULT 9
@@ -170,12 +165,6 @@
 #define GNUNET_CS_PROTO_GAP_TESTINDEX 14
 
 /**
- * Client to gnunetd: what is the average priority of entries in the
- * routing table?
- */
-#define GNUNET_CS_PROTO_GAP_GET_AVG_PRIORITY 15
-
-/**
  * client to gnunetd: initialize to index file
  */
 #define GNUNET_CS_PROTO_GAP_INIT_INDEX 16
@@ -375,12 +364,12 @@
 /**
  * Query for content.
  */
-#define GNUNET_P2P_PROTO_GAP_QUERY 16
+#define GNUNET_P2P_PROTO_GAP_QUERY 8
 
 /**
  * receive content
  */
-#define GNUNET_P2P_PROTO_GAP_RESULT 17
+#define GNUNET_P2P_PROTO_GAP_RESULT 9
 
 /************** p2p DHT application messages ************/
 
@@ -485,7 +474,21 @@
 #define GNUNET_ECRS_BLOCKTYPE_ONDEMAND_OLD 0xFFFFFFFF
 
 
+/* ************* priorities for poll-content ************ */
 
+/* note that the absolute values do not matter;
+   highest priority first is the rule!
+   The naming-prefix used is after the name of
+   the module using the respective constant.  */
+
+#define GNUNET_FS_GAP_QUERY_POLL_PRIORITY 100
+
+#define GNUNET_DHT_QUERY_POLL_PRIORITY 2
+
+#define GNUNET_FS_GAP_CONTENT_MIGRATION_PRIORITY 1
+
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: GNUnet/src/server/core.c
===================================================================
--- GNUnet/src/server/core.c    2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/src/server/core.c    2008-02-06 07:11:29 UTC (rev 6162)
@@ -530,8 +530,6 @@
   applicationCore.cron = cron;
   applicationCore.version = 0;
   applicationCore.myIdentity = NULL;    /* for now */
-  applicationCore.loadApplicationModule = &loadApplicationModule;       /* 
core.c */
-  applicationCore.unloadApplicationModule = &unloadApplicationModule;   /* 
core.c */
   applicationCore.request_service = &GNUNET_CORE_request_service;       /* 
core.c */
   applicationCore.release_service = &GNUNET_CORE_release_service;       /* 
core.c */
 

Modified: GNUnet/todo
===================================================================
--- GNUnet/todo 2008-02-06 06:52:39 UTC (rev 6161)
+++ GNUnet/todo 2008-02-06 07:11:29 UTC (rev 6162)
@@ -13,6 +13,7 @@
   gnunet-insert only if the file is actually needed!)
 - power insert [#854]
 - RPC API and testcase
+- switch libgcrypt to not use entropy during testcases
 
 
 1.0.0 (aka "userfriendly"):





reply via email to

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