gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r6452 - in GNUnet: . src/applications/fs/ecrs src/applicati


From: gnunet
Subject: [GNUnet-SVN] r6452 - in GNUnet: . src/applications/fs/ecrs src/applications/fs/fsui src/applications/fs/tools src/include src/util/disk
Date: Mon, 25 Feb 2008 00:06:55 -0700 (MST)

Author: grothoff
Date: 2008-02-25 00:06:55 -0700 (Mon, 25 Feb 2008)
New Revision: 6452

Modified:
   GNUnet/ChangeLog
   GNUnet/src/applications/fs/ecrs/download.c
   GNUnet/src/applications/fs/fsui/download.c
   GNUnet/src/applications/fs/fsui/downloadtest.c
   GNUnet/src/applications/fs/fsui/fsui.h
   GNUnet/src/applications/fs/fsui/serializetest.c
   GNUnet/src/applications/fs/fsui/serializetest2.c
   GNUnet/src/applications/fs/fsui/serializetest3.c
   GNUnet/src/applications/fs/fsui/serializetest4.c
   GNUnet/src/applications/fs/tools/gnunet-insert.c
   GNUnet/src/include/gnunet_ecrs_lib.h
   GNUnet/src/util/disk/storage.c
   GNUnet/todo
Log:
use lstat

Modified: GNUnet/ChangeLog
===================================================================
--- GNUnet/ChangeLog    2008-02-25 06:12:45 UTC (rev 6451)
+++ GNUnet/ChangeLog    2008-02-25 07:06:55 UTC (rev 6452)
@@ -1,3 +1,9 @@
+Mon Feb 25 00:01:27 MST 2008
+       Added asynchronous search and download methods for 
+       ECRS library.  FSUI now can do with only one thread
+       per search or download (until now, we had two 
+       threads per search / download).
+
 Tue Feb 19 20:35:28 MST 2008
        Updated database schemata to support O(1) operations
        even if there are N files under the same keywords.

Modified: GNUnet/src/applications/fs/ecrs/download.c
===================================================================
--- GNUnet/src/applications/fs/ecrs/download.c  2008-02-25 06:12:45 UTC (rev 
6451)
+++ GNUnet/src/applications/fs/ecrs/download.c  2008-02-25 07:06:55 UTC (rev 
6452)
@@ -44,7 +44,7 @@
    * Pointer to shared data between all nodes (request manager,
    * progress data, etc.).
    */
-  struct RequestManager *ctx;
+  struct GNUNET_ECRS_DownloadContext *ctx;
 
   /**
    * Previous entry in DLL.
@@ -82,7 +82,7 @@
  * which queries went out with which priorities and which nodes in
  * the merkle-tree are waiting for the replies.
  */
-struct RequestManager
+struct GNUNET_ECRS_DownloadContext
 {
 
   /**
@@ -208,7 +208,7 @@
  *     is not complete and may be resumed later.
  */
 static void
-free_request_manager (struct RequestManager *rm, int unlinkTreeFiles)
+free_request_manager (struct GNUNET_ECRS_DownloadContext *rm, int 
unlinkTreeFiles)
 {
   int i;
   char *fn;
@@ -261,6 +261,7 @@
     }
   GNUNET_free_non_null (rm->filename);
   GNUNET_free_non_null (rm->handles);
+  GNUNET_free(rm);
 }
 
 /**
@@ -274,7 +275,7 @@
  * @return number of bytes read, GNUNET_SYSERR on error
  */
 static int
-read_from_files (struct RequestManager *this,
+read_from_files (struct GNUNET_ECRS_DownloadContext *this,
                  unsigned int level,
                  unsigned long long pos, void *buf, unsigned int len)
 {
@@ -304,7 +305,7 @@
  * @return number of bytes written, GNUNET_SYSERR on error
  */
 static int
-write_to_files (struct RequestManager *this,
+write_to_files (struct GNUNET_ECRS_DownloadContext *this,
                 unsigned int level,
                 unsigned long long pos, void *buf, unsigned int len)
 {
@@ -338,7 +339,7 @@
 static void
 addRequest (struct Node *node)
 {
-  struct RequestManager *rm = node->ctx;
+  struct GNUNET_ECRS_DownloadContext *rm = node->ctx;
 
   node->next = rm->head;
   if (node->next != NULL)
@@ -356,9 +357,14 @@
 }
 
 static void
-signal_abort (struct RequestManager *rm)
+signal_abort (struct GNUNET_ECRS_DownloadContext *rm,
+             const char * msg)
 {
   rm->abortFlag = GNUNET_YES;
+  if ( (rm->head != NULL) &&
+       (rm->dpcb != NULL) )
+    rm->dpcb (rm->length+1,
+              0, 0, 0, msg, 0, rm->dpcbClosure);
   GNUNET_thread_stop_sleep (rm->main);
 }
 
@@ -371,7 +377,7 @@
 static void
 delete_node (struct Node *node)
 {
-  struct RequestManager *rm = node->ctx;
+  struct GNUNET_ECRS_DownloadContext *rm = node->ctx;
 
   if (node->prev == NULL)
     rm->head = node->next;
@@ -383,7 +389,7 @@
     node->next->prev = node->prev;
   GNUNET_free (node);
   if (rm->head == NULL)
-    signal_abort (rm);
+    signal_abort (rm, NULL);
 }
 
 /**
@@ -439,7 +445,7 @@
 notify_client_about_progress (const struct Node *node, const char *data,
                               unsigned int size)
 {
-  struct RequestManager *rm = node->ctx;
+  struct GNUNET_ECRS_DownloadContext *rm = node->ctx;
   GNUNET_CronTime eta;
 
   if ((rm->abortFlag == GNUNET_YES) || (node->level != 0))
@@ -610,7 +616,7 @@
                           unsigned long long uid)
 {
   struct Node *node = cls;
-  struct RequestManager *rm = node->ctx;
+  struct GNUNET_ECRS_DownloadContext *rm = node->ctx;
   struct GNUNET_GE_Context *ectx = rm->ectx;
   GNUNET_HashCode hc;
   unsigned int size;
@@ -643,11 +649,10 @@
     {
       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"));
-      signal_abort (rm);
+      signal_abort (rm,
+                   _("Decrypted content does not match key. "
+                     "This is either a bug or a maliciously inserted "
+                     "file. Download aborted.\n"));
       GNUNET_mutex_unlock (rm->lock);
       return GNUNET_SYSERR;
     }
@@ -656,7 +661,7 @@
       GNUNET_GE_LOG_STRERROR (ectx,
                               GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
                               GNUNET_GE_USER | GNUNET_GE_BULK, "WRITE");
-      signal_abort (rm);
+      signal_abort (rm, _("IO error."));
       GNUNET_mutex_unlock (rm->lock);
       return GNUNET_SYSERR;
     }
@@ -727,6 +732,7 @@
 
 /* ***************** main method **************** */
 
+
 /**
  * Download parts of a file.  Note that this will store
  * the blocks at the respective offset in the given file.
@@ -746,177 +752,169 @@
  * @param start starting offset
  * @param length length of the download (starting at offset)
  */
-int
-GNUNET_ECRS_file_download_partial (struct GNUNET_GE_Context *ectx,
-                                   struct GNUNET_GC_Configuration *cfg,
-                                   const struct GNUNET_ECRS_URI *uri,
-                                   const char *filename,
-                                   unsigned long long offset,
-                                   unsigned long long length,
-                                   unsigned int anonymityLevel,
-                                   int no_temporaries,
-                                   GNUNET_ECRS_DownloadProgressCallback dpcb,
-                                   void *dpcbClosure,
-                                   GNUNET_ECRS_TestTerminate tt,
-                                   void *ttClosure)
+struct GNUNET_ECRS_DownloadContext *
+GNUNET_ECRS_file_download_partial_start (struct GNUNET_GE_Context *ectx,
+                                        struct GNUNET_GC_Configuration *cfg,
+                                        const struct GNUNET_ECRS_URI *uri,
+                                        const char *filename,
+                                        unsigned long long offset,
+                                        unsigned long long length,
+                                        unsigned int anonymityLevel,
+                                        int no_temporaries,
+                                        GNUNET_ECRS_DownloadProgressCallback 
dpcb,
+                                        void *dpcbClosure)
 {
-  struct RequestManager rm;
+  struct GNUNET_ECRS_DownloadContext * rm;
   struct stat buf;
   struct Node *top;
   char *fn;
-  char *rdir;
   int ret;
   int i;
-  int len;
 
   if ((!GNUNET_ECRS_uri_test_chk (uri)) && (!GNUNET_ECRS_uri_test_loc (uri)))
     {
       GNUNET_GE_BREAK (ectx, 0);
-      return GNUNET_SYSERR;
+      return NULL;
     }
+  rm = GNUNET_malloc(sizeof (struct GNUNET_ECRS_DownloadContext));
+  memset (rm, 0,
+         sizeof (struct GNUNET_ECRS_DownloadContext));
+  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);
 
-  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_disk_directory_create_for_file (ectx, rm->filename))
     {
-      free_request_manager (&rm, GNUNET_NO);
-      return GNUNET_SYSERR;
+      free_request_manager (rm, GNUNET_NO);
+      return NULL;
     }
-  if (0 == rm.total)
+  if (0 == rm->total)
     {
       ret = GNUNET_disk_file_open (ectx,
-                                   rm.filename,
+                                   rm->filename,
                                    O_CREAT | O_WRONLY | O_TRUNC,
                                    S_IRUSR | S_IWUSR);
       if (ret == -1)
         {
-          free_request_manager (&rm, GNUNET_NO);
-          return GNUNET_SYSERR;
+          free_request_manager (rm, GNUNET_NO);
+          return NULL;
         }
       CLOSE (ret);
-      dpcb (0, 0, rm.startTime, 0, NULL, 0, dpcbClosure);
-      free_request_manager (&rm, GNUNET_NO);
-      return GNUNET_OK;
+      dpcb (0, 0, rm->startTime, 0, NULL, 0, dpcbClosure);
+      free_request_manager (rm, GNUNET_NO);
+      return NULL;
     }
-  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))
+  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))
     {
       /* if exists and oversized, truncate */
-      if (truncate (rm.filename, rm.total) != 0)
+      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;
+                                       rm->filename);
+          free_request_manager (rm, GNUNET_NO);
+          return NULL;
         }
     }
-  for (i = 0; i <= rm.treedepth; i++)
+  for (i = 0; i <= rm->treedepth; i++)
     {
       if ((i == 0) || (no_temporaries != GNUNET_YES))
         {
-          fn = GNUNET_malloc (strlen (rm.filename) + 3);
-          strcpy (fn, rm.filename);
+          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,
+          rm->handles[i] = GNUNET_disk_file_open (ectx,
                                                  fn,
                                                  O_CREAT | O_RDWR,
                                                  S_IRUSR | S_IWUSR);
           GNUNET_free (fn);
-          if (rm.handles[i] < 0)
+          if (rm->handles[i] < 0)
             {
-              free_request_manager (&rm, GNUNET_NO);
-              return GNUNET_SYSERR;
+              free_request_manager (rm, GNUNET_NO);
+              return NULL;
             }
         }
     }
-  rm.lock = GNUNET_mutex_create (GNUNET_YES);
-  rm.sctx = GNUNET_FS_create_search_context (ectx, cfg, rm.lock);
-  if (rm.sctx == NULL)
+  rm->lock = GNUNET_mutex_create (GNUNET_YES);
+  rm->sctx = GNUNET_FS_create_search_context (ectx, cfg, rm->lock);
+  if (rm->sctx == NULL)
     {
-      free_request_manager (&rm, GNUNET_NO);
-      return GNUNET_SYSERR;
+      free_request_manager (rm, GNUNET_NO);
+      return NULL;
     }
   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;
     }
 
   top = GNUNET_malloc (sizeof (struct Node));
   memset (top, 0, sizeof (struct Node));
-  top->ctx = &rm;
+  top->ctx = rm;
   top->chk = uri->data.fi.chk;
   top->offset = 0;
-  top->level = rm.treedepth;
+  top->level = rm->treedepth;
 
-  GNUNET_mutex_lock (rm.lock);
+  GNUNET_mutex_lock (rm->lock);
   if (GNUNET_NO == check_node_present (top))
     addRequest (top);
   else
     GNUNET_free (top);
-  GNUNET_mutex_unlock (rm.lock);
-  while ((GNUNET_OK == tt (ttClosure)) &&
-         (GNUNET_YES != GNUNET_shutdown_test ()) &&
-         (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))))
+  GNUNET_mutex_unlock (rm->lock);
+  return rm;
+}
+
+int
+GNUNET_ECRS_file_download_partial_stop (struct GNUNET_ECRS_DownloadContext * 
rm) 
+{
+  int ret;
+  char * rdir;
+  int len;
+
+  if ((rm->head == NULL) &&
+      ((rm->completed == rm->total) ||
+       ((rm->total != rm->length) && (rm->completed >= rm->length))))
     {
       ret = GNUNET_OK;
     }
   else
     {
 #if 0
-      GNUNET_GE_LOG (ectx,
+      GNUNET_GE_LOG (rm->ectx,
                      GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
                      "Download ends prematurely: %d %llu == %llu %d TT: %d\n",
-                     rm.requestListIndex,
-                     rm.completed, rm.total, rm.abortFlag, tt (ttClosure));
+                     rm->requestListIndex,
+                     rm->completed, rm->total, rm->abortFlag, tt (ttClosure));
 #endif
-      ret = GNUNET_SYSERR;
-    }
-#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))
-    {
-      if (0 != UNLINK (rm.filename))
+      if (0 != UNLINK (rm->filename))
         {
-          GNUNET_GE_LOG_STRERROR_FILE (ectx,
+          GNUNET_GE_LOG_STRERROR_FILE (rm->ectx,
                                        GNUNET_GE_WARNING | GNUNET_GE_USER |
-                                       GNUNET_GE_BULK, "unlink", rm.filename);
+                                       GNUNET_GE_BULK, "unlink", rm->filename);
         }
       else
         {
           /* delete empty directories */
-          rdir = GNUNET_strdup (rm.filename);
+          rdir = GNUNET_strdup (rm->filename);
           len = strlen (rdir);
           do
             {
@@ -927,15 +925,75 @@
           while ((len > 0) && (0 == rmdir (rdir)));
           GNUNET_free (rdir);
         }
+      ret = GNUNET_SYSERR;
     }
-  free_request_manager (&rm,
-                        ((ret == GNUNET_OK) ||
-                         (tt (ttClosure) == GNUNET_SYSERR))
-                        ? GNUNET_YES : GNUNET_NO);
+#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
+  free_request_manager (rm,
+                        (ret == GNUNET_OK) ? GNUNET_YES : GNUNET_NO);
   return ret;
 }
 
 /**
+ * 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
+ * may *write* outside of the given boundaries (if offset
+ * and length do not match the 32k ECRS block boundaries).
+ * <p>
+ *
+ * This function should be used to focus a download towards a
+ * particular portion of the file (optimization), not to strictly
+ * limit the download to exactly those bytes.
+ *
+ * @param uri the URI of the file (determines what to download)
+ * @param filename where to store the file
+ * @param no_temporaries set to GNUNET_YES to disallow generation of temporary 
files
+ * @param start starting offset
+ * @param length length of the download (starting at offset)
+ */
+int
+GNUNET_ECRS_file_download_partial (struct GNUNET_GE_Context *ectx,
+                                   struct GNUNET_GC_Configuration *cfg,
+                                   const struct GNUNET_ECRS_URI *uri,
+                                   const char *filename,
+                                   unsigned long long offset,
+                                   unsigned long long length,
+                                   unsigned int anonymityLevel,
+                                   int no_temporaries,
+                                   GNUNET_ECRS_DownloadProgressCallback dpcb,
+                                   void *dpcbClosure,
+                                   GNUNET_ECRS_TestTerminate tt,
+                                   void *ttClosure)
+{
+  struct GNUNET_ECRS_DownloadContext * rm;
+
+  rm = GNUNET_ECRS_file_download_partial_start (ectx,
+                                               cfg,
+                                               uri,
+                                               filename,
+                                               offset,
+                                               length,
+                                               anonymityLevel,
+                                               no_temporaries,
+                                               dpcb,
+                                               dpcbClosure);
+  if (rm == NULL)
+    return (length == 0) ? GNUNET_OK : GNUNET_SYSERR;
+  while ((GNUNET_OK == tt (ttClosure)) &&
+         (GNUNET_YES != GNUNET_shutdown_test ()) &&
+         (rm->abortFlag == GNUNET_NO) && (rm->head != NULL))
+    GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS);
+  return GNUNET_ECRS_file_download_partial_stop(rm);
+}
+
+/**
  * Download a file (simplified API).
  *
  * @param uri the URI of the file (determines what to download)

Modified: GNUnet/src/applications/fs/fsui/download.c
===================================================================
--- GNUnet/src/applications/fs/fsui/download.c  2008-02-25 06:12:45 UTC (rev 
6451)
+++ GNUnet/src/applications/fs/fsui/download.c  2008-02-25 07:06:55 UTC (rev 
6452)
@@ -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
@@ -138,6 +138,74 @@
 }
 
 /**
+ * Trigger recursive download.
+ */
+static void 
+download_recursive (GNUNET_FSUI_DownloadList *dl)
+{
+  char *dirBlock;
+  int fd;
+  char *fn;
+  size_t totalBytes;
+  struct GNUNET_ECRS_MetaData *md;
+  
+  totalBytes = GNUNET_ECRS_uri_get_file_size (dl->fi.uri);
+  fn =
+    GNUNET_malloc (strlen (dl->filename) + strlen (GNUNET_DIRECTORY_EXT) +
+                  1);
+  strcpy (fn, dl->filename);
+  fd = strlen (fn) - 1;
+  if (fn[fd] == '/' || fn[fd] == '\\')
+    {
+      fn[fd] = '\0';
+      strcat (fn, GNUNET_DIRECTORY_EXT);
+    }
+  fd = GNUNET_disk_file_open (dl->ctx->ectx, fn, O_LARGEFILE | O_RDONLY);
+  if (fd != -1)
+    {
+      dirBlock = MMAP (NULL, totalBytes, PROT_READ, MAP_SHARED, fd, 0);
+      if (MAP_FAILED == dirBlock)
+       {
+         GNUNET_GE_LOG_STRERROR_FILE (dl->ctx->ectx,
+                                      GNUNET_GE_ERROR | GNUNET_GE_BULK |
+                                      GNUNET_GE_ADMIN | GNUNET_GE_USER,
+                                      "mmap", fn);
+       }
+      else
+       {
+         md = NULL;
+         GNUNET_ECRS_directory_list_contents (dl->ctx->ectx,
+                                              dirBlock,
+                                              totalBytes,
+                                              &md,
+                                              &listURIfoundDirectory,
+                                              dl);
+         if (md != NULL)
+           GNUNET_ECRS_meta_data_destroy (md);   
+         if (dl->is_recursive)
+           {
+             /* load directory, start downloads */
+             md = NULL;
+             GNUNET_mutex_lock (dl->ctx->lock);
+             GNUNET_ECRS_directory_list_contents (dl->ctx->ectx,
+                                                  dirBlock,
+                                                  totalBytes,
+                                                  &md,
+                                                  &triggerRecursiveDownload,
+                                                  dl);
+             GNUNET_mutex_unlock (dl->ctx->lock);
+             GNUNET_ECRS_meta_data_destroy (md);
+             MUNMAP (dirBlock, totalBytes);
+           }
+       }
+      CLOSE (fd);
+    }
+  GNUNET_free (fn);
+}
+
+
+
+/**
  * Progress notification from ECRS.  Tell FSUI client.
  */
 static void
@@ -154,6 +222,26 @@
   GNUNET_CronTime now;
   GNUNET_CronTime run_time;
 
+  if (dl->total + 1 == totalBytes)
+    {
+      /* error! */
+      dl->state = GNUNET_FSUI_ERROR;
+      event.type = GNUNET_FSUI_download_error;
+      event.data.DownloadError.dc.pos = dl;
+      event.data.DownloadError.dc.cctx = dl->cctx;
+      event.data.DownloadError.dc.ppos =
+        dl->parent == &dl->ctx->activeDownloads ? NULL : dl->parent;
+      event.data.DownloadError.dc.pcctx = dl->parent->cctx;
+      event.data.DownloadError.dc.spos = dl->search;
+      event.data.DownloadError.dc.sctx =
+        dl->search == NULL ? NULL : dl->search->cctx;
+      event.data.DownloadError.message = lastBlock;
+      GNUNET_URITRACK_add_state (dl->ctx->ectx,
+                                 dl->ctx->cfg, dl->fi.uri,
+                                 GNUNET_URITRACK_DOWNLOAD_ABORTED);
+      dl->ctx->ecb (dl->ctx->ecbClosure, &event);
+      return;
+    }
   GNUNET_GE_ASSERT (dl->ctx->ectx, dl->total == totalBytes);
   dl->completed = completedBytes;
   event.type = GNUNET_FSUI_download_progress;
@@ -221,56 +309,7 @@
       if (md != NULL)
         GNUNET_ECRS_meta_data_destroy (md);
     }
-}
-
-/**
- * Check if termination of this download is desired.
- */
-static int
-testTerminate (void *cls)
-{
-  GNUNET_FSUI_DownloadList *dl = cls;
-
-  if ((dl->state == GNUNET_FSUI_ERROR) || (dl->state == GNUNET_FSUI_ABORTED))
-    return GNUNET_SYSERR;       /* aborted - delete! */
-  if (dl->state != GNUNET_FSUI_ACTIVE)
-    return GNUNET_NO;           /* suspended */
-  return GNUNET_OK;
-}
-
-/**
- * Thread that downloads a file.
- */
-static void *
-downloadThread (void *cls)
-{
-  GNUNET_FSUI_DownloadList *dl = cls;
-  int ret;
-  GNUNET_FSUI_Event event;
-  struct GNUNET_GE_Context *ectx;
-  struct GNUNET_GE_Memory *mem;
-  struct GNUNET_GE_Context *ee;
-
-  dl->startTime = GNUNET_get_time () - dl->runTime;
-  ectx = dl->ctx->ectx;
-#if DEBUG_DTM
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Download thread for `%s' started...\n", dl->filename);
-#endif
-  GNUNET_GE_ASSERT (ectx, dl->ctx != NULL);
-  GNUNET_GE_ASSERT (ectx, dl->filename != NULL);
-  mem = GNUNET_GE_memory_create (2);
-  ee =
-    GNUNET_GE_create_context_memory (GNUNET_GE_USER | GNUNET_GE_ADMIN |
-                                     GNUNET_GE_ERROR | GNUNET_GE_WARNING |
-                                     GNUNET_GE_FATAL | GNUNET_GE_BULK |
-                                     GNUNET_GE_IMMEDIATE, mem);
-  ret =
-    GNUNET_ECRS_file_download (ee, dl->ctx->cfg, dl->fi.uri, dl->filename,
-                               dl->anonymityLevel, &downloadProgressCallback,
-                               dl, &testTerminate, dl);
-  if (ret == GNUNET_OK)
+  if (totalBytes == completedBytes)
     {
       dl->state = GNUNET_FSUI_COMPLETED;
       event.type = GNUNET_FSUI_download_completed;
@@ -289,128 +328,11 @@
                                  dl->ctx->cfg,
                                  dl->fi.uri,
                                  GNUNET_URITRACK_DOWNLOAD_COMPLETED);
-      dl->ctx->ecb (dl->ctx->ecbClosure, &event);
-    }
-  else if (dl->state == GNUNET_FSUI_ACTIVE)
-    {
-      const char *error;
-
-      /* ECRS error */
-      dl->state = GNUNET_FSUI_ERROR;
-      event.type = GNUNET_FSUI_download_error;
-      event.data.DownloadError.dc.pos = dl;
-      event.data.DownloadError.dc.cctx = dl->cctx;
-      event.data.DownloadError.dc.ppos =
-        dl->parent == &dl->ctx->activeDownloads ? NULL : dl->parent;
-      event.data.DownloadError.dc.pcctx = dl->parent->cctx;
-      event.data.DownloadError.dc.spos = dl->search;
-      event.data.DownloadError.dc.sctx =
-        dl->search == NULL ? NULL : dl->search->cctx;
-      error = GNUNET_GE_memory_get (mem, 0);
-      if (error == NULL)
-        error = _("Download failed (no reason given)");
-      event.data.DownloadError.message = error;
-      GNUNET_URITRACK_add_state (dl->ctx->ectx,
-                                 dl->ctx->cfg, dl->fi.uri,
-                                 GNUNET_URITRACK_DOWNLOAD_ABORTED);
-      dl->ctx->ecb (dl->ctx->ecbClosure, &event);
-    }
-  else if (dl->state == GNUNET_FSUI_ABORTED)
-    {                           /* aborted */
-      event.type = GNUNET_FSUI_download_aborted;
-      event.data.DownloadAborted.dc.pos = dl;
-      event.data.DownloadAborted.dc.cctx = dl->cctx;
-      event.data.DownloadAborted.dc.ppos =
-        dl->parent == &dl->ctx->activeDownloads ? NULL : dl->parent;
-      event.data.DownloadAborted.dc.pcctx = dl->parent->cctx;
-      event.data.DownloadAborted.dc.spos = dl->search;
-      event.data.DownloadAborted.dc.sctx =
-        dl->search == NULL ? NULL : dl->search->cctx;
-      GNUNET_URITRACK_add_state (dl->ctx->ectx, dl->ctx->cfg, dl->fi.uri,
-                                 GNUNET_URITRACK_DOWNLOAD_ABORTED);
-      dl->ctx->ecb (dl->ctx->ecbClosure, &event);
-    }
-  else
-    {
-      /* else: suspended */
-      GNUNET_GE_BREAK (NULL, dl->state == GNUNET_FSUI_SUSPENDING);
-    }
-
-
-  if ((ret == GNUNET_OK) &&
-      (dl->is_directory == GNUNET_YES)
-      && (GNUNET_ECRS_uri_get_file_size (dl->fi.uri) > 0))
-    {
-      char *dirBlock;
-      int fd;
-      char *fn;
-      size_t totalBytes;
-      struct GNUNET_ECRS_MetaData *md;
-
-      totalBytes = GNUNET_ECRS_uri_get_file_size (dl->fi.uri);
-      fn =
-        GNUNET_malloc (strlen (dl->filename) + strlen (GNUNET_DIRECTORY_EXT) +
-                       1);
-      strcpy (fn, dl->filename);
-      fd = strlen (fn) - 1;
-      if (fn[fd] == '/' || fn[fd] == '\\')
-        {
-          fn[fd] = '\0';
-          strcat (fn, GNUNET_DIRECTORY_EXT);
-        }
-      fd = GNUNET_disk_file_open (ectx, fn, O_LARGEFILE | O_RDONLY);
-      if (fd != -1)
-        {
-          dirBlock = MMAP (NULL, totalBytes, PROT_READ, MAP_SHARED, fd, 0);
-          if (MAP_FAILED == dirBlock)
-            {
-              GNUNET_GE_LOG_STRERROR_FILE (ectx,
-                                           GNUNET_GE_ERROR | GNUNET_GE_BULK |
-                                           GNUNET_GE_ADMIN | GNUNET_GE_USER,
-                                           "mmap", fn);
-            }
-          else
-            {
-              md = NULL;
-              GNUNET_ECRS_directory_list_contents (dl->ctx->ectx,
-                                                   dirBlock,
-                                                   totalBytes,
-                                                   &md,
-                                                   &listURIfoundDirectory,
-                                                   dl);
-              if (md != NULL)
-                GNUNET_ECRS_meta_data_destroy (md);
-
-              if (dl->is_recursive)
-                {
-                  /* load directory, start downloads */
-                  md = NULL;
-                  GNUNET_mutex_lock (dl->ctx->lock);
-                  GNUNET_ECRS_directory_list_contents (dl->ctx->ectx,
-                                                       dirBlock,
-                                                       totalBytes,
-                                                       &md,
-                                                       
&triggerRecursiveDownload,
-                                                       dl);
-                  GNUNET_mutex_unlock (dl->ctx->lock);
-                  GNUNET_ECRS_meta_data_destroy (md);
-                  MUNMAP (dirBlock, totalBytes);
-                }
-            }
-          CLOSE (fd);
-        }
-      GNUNET_free (fn);
-    }
-#if DEBUG_DTM
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Download thread for `%s' terminated (%s)...\n",
-                 dl->filename, ret == GNUNET_OK ? "COMPLETED" : "ABORTED");
-#endif
-  dl->runTime = GNUNET_get_time () - dl->startTime;
-  GNUNET_GE_free_context (ee);
-  GNUNET_GE_memory_free (mem);
-  return NULL;
+      dl->ctx->ecb (dl->ctx->ecbClosure, &event); 
+      if ( (dl->is_directory == GNUNET_YES) &&
+          (GNUNET_ECRS_uri_get_file_size (dl->fi.uri) > 0) )
+       download_recursive(dl);
+    }  
 }
 
 /**
@@ -525,7 +447,6 @@
 {
   struct GNUNET_GE_Context *ectx;
   GNUNET_FSUI_DownloadList *dpos;
-  void *unused;
   int ret;
 
   if (list == NULL)
@@ -553,19 +474,18 @@
                      list->filename);
 #endif
       list->state = GNUNET_FSUI_ACTIVE;
-      list->handle = GNUNET_thread_create (&downloadThread, list, 128 * 1024);
+      list->startTime = GNUNET_get_time() - list->runTime;
+      list->handle = GNUNET_ECRS_file_download_partial_start(list->ctx->ectx, 
list->ctx->cfg, list->fi.uri, list->filename,
+                                                            0,
+                                                            
GNUNET_ECRS_uri_get_file_size(list->fi.uri),
+                                                            
list->anonymityLevel, 
+                                                            GNUNET_NO,
+                                                            
&downloadProgressCallback,
+                                                            list);
       if (list->handle != NULL)
-        {
-          list->ctx->activeDownloadThreads++;
-        }
+       list->ctx->activeDownloadThreads++;
       else
-        {
-          GNUNET_GE_LOG_STRERROR (ectx,
-                                  GNUNET_GE_ADMIN | GNUNET_GE_USER |
-                                  GNUNET_GE_BULK | GNUNET_GE_ERROR,
-                                  "pthread_create");
-          list->state = GNUNET_FSUI_ERROR_JOINED;
-        }
+       list->state = GNUNET_FSUI_ERROR_JOINED;
     }
 
   /* should this one be stopped? */
@@ -583,8 +503,7 @@
 #endif
       list->state = GNUNET_FSUI_SUSPENDING;
       GNUNET_GE_ASSERT (ectx, list->handle != NULL);
-      GNUNET_thread_stop_sleep (list->handle);
-      GNUNET_thread_join (list->handle, &unused);
+      GNUNET_ECRS_file_download_partial_stop(list->handle);
       list->handle = NULL;
       list->ctx->activeDownloadThreads--;
       list->state = GNUNET_FSUI_PENDING;
@@ -602,8 +521,7 @@
                      "Download thread manager collects inactive download of 
file `%s'\n",
                      list->filename);
 #endif
-      GNUNET_thread_stop_sleep (list->handle);
-      GNUNET_thread_join (list->handle, &unused);
+      GNUNET_ECRS_file_download_partial_stop(list->handle);
       list->handle = NULL;
       list->ctx->activeDownloadThreads--;
       list->state++;            /* adds _JOINED */
@@ -632,6 +550,7 @@
                             struct GNUNET_FSUI_DownloadList *dl)
 {
   struct GNUNET_FSUI_DownloadList *c;
+  GNUNET_FSUI_Event event;
 
   GNUNET_GE_ASSERT (ctx->ectx, dl != NULL);
   c = dl->child;
@@ -644,8 +563,22 @@
     return GNUNET_NO;
   if (dl->state == GNUNET_FSUI_ACTIVE)
     {
-      dl->state = GNUNET_FSUI_ABORTED;
-      GNUNET_thread_stop_sleep (dl->handle);
+      dl->state = GNUNET_FSUI_ABORTED_JOINED;
+      GNUNET_ECRS_file_download_partial_stop(dl->handle);
+      dl->handle = NULL;
+      dl->runTime = GNUNET_get_time () - dl->startTime;
+      event.type = GNUNET_FSUI_download_aborted;
+      event.data.DownloadAborted.dc.pos = dl;
+      event.data.DownloadAborted.dc.cctx = dl->cctx;
+      event.data.DownloadAborted.dc.ppos =
+        dl->parent == &dl->ctx->activeDownloads ? NULL : dl->parent;
+      event.data.DownloadAborted.dc.pcctx = dl->parent->cctx;
+      event.data.DownloadAborted.dc.spos = dl->search;
+      event.data.DownloadAborted.dc.sctx =
+        dl->search == NULL ? NULL : dl->search->cctx;
+      GNUNET_URITRACK_add_state (dl->ctx->ectx, dl->ctx->cfg, dl->fi.uri,
+                                 GNUNET_URITRACK_DOWNLOAD_ABORTED);
+      dl->ctx->ecb (dl->ctx->ecbClosure, &event);
     }
   else
     {
@@ -664,7 +597,6 @@
 GNUNET_FSUI_download_stop (struct GNUNET_FSUI_Context *ctx,
                            struct GNUNET_FSUI_DownloadList *dl)
 {
-  void *unused;
   struct GNUNET_FSUI_DownloadList *prev;
   GNUNET_FSUI_Event event;
   int i;
@@ -695,8 +627,9 @@
       (dl->state == GNUNET_FSUI_ABORTED) || (dl->state == GNUNET_FSUI_ERROR))
     {
       GNUNET_GE_ASSERT (ctx->ectx, dl->handle != NULL);
-      GNUNET_thread_stop_sleep (dl->handle);
-      GNUNET_thread_join (dl->handle, &unused);
+      GNUNET_ECRS_file_download_partial_stop(dl->handle);
+      dl->handle = NULL;
+      dl->runTime = GNUNET_get_time () - dl->startTime;
       GNUNET_mutex_lock (ctx->lock);
       dl->ctx->activeDownloadThreads--;
       GNUNET_mutex_unlock (ctx->lock);

Modified: GNUnet/src/applications/fs/fsui/downloadtest.c
===================================================================
--- GNUnet/src/applications/fs/fsui/downloadtest.c      2008-02-25 06:12:45 UTC 
(rev 6451)
+++ GNUnet/src/applications/fs/fsui/downloadtest.c      2008-02-25 07:06:55 UTC 
(rev 6452)
@@ -81,16 +81,6 @@
 #endif
       download = event->data.DownloadResumed.dc.pos;
       break;
-    case GNUNET_FSUI_search_completed:
-#if DEBUG_VERBOSE
-      printf ("Search completed\n");
-#endif
-      if (download == NULL)
-        {
-          fprintf (stderr,
-                   "ERROR: Search completed but download not started!\n");
-        }
-      break;
     case GNUNET_FSUI_search_result:
 #if DEBUG_VERBOSE
       printf ("Received search result\n");
@@ -173,7 +163,6 @@
     case GNUNET_FSUI_unindex_error:
     case GNUNET_FSUI_upload_error:
     case GNUNET_FSUI_download_error:
-    case GNUNET_FSUI_search_error:
       fprintf (stderr, "Received ERROR: %d\n", event->type);
       GNUNET_GE_BREAK (ectx, 0);
       break;

Modified: GNUnet/src/applications/fs/fsui/fsui.h
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.h      2008-02-25 06:12:45 UTC (rev 
6451)
+++ GNUnet/src/applications/fs/fsui/fsui.h      2008-02-25 07:06:55 UTC (rev 
6452)
@@ -193,9 +193,9 @@
   void *cctx;
 
   /**
-   * Currently assigned thread (if any).
+   * Currently assigned ECRS context (if any).
    */
-  struct GNUNET_ThreadHandle *handle;
+  struct GNUNET_ECRS_DownloadContext *handle;
 
   /**
    * FIs of completed sub-downloads.

Modified: GNUnet/src/applications/fs/fsui/serializetest.c
===================================================================
--- GNUnet/src/applications/fs/fsui/serializetest.c     2008-02-25 06:12:45 UTC 
(rev 6451)
+++ GNUnet/src/applications/fs/fsui/serializetest.c     2008-02-25 07:06:55 UTC 
(rev 6452)
@@ -91,7 +91,6 @@
     case GNUNET_FSUI_unindex_error:
     case GNUNET_FSUI_upload_error:
     case GNUNET_FSUI_download_error:
-    case GNUNET_FSUI_search_error:
       fprintf (stderr, "Received ERROR: %d\n", event->type);
       GNUNET_GE_BREAK (ectx, 0);
       break;

Modified: GNUnet/src/applications/fs/fsui/serializetest2.c
===================================================================
--- GNUnet/src/applications/fs/fsui/serializetest2.c    2008-02-25 06:12:45 UTC 
(rev 6451)
+++ GNUnet/src/applications/fs/fsui/serializetest2.c    2008-02-25 07:06:55 UTC 
(rev 6452)
@@ -233,12 +233,6 @@
                event->type, event->data.DownloadError.message);
       GNUNET_GE_BREAK (ectx, 0);
       break;
-    case GNUNET_FSUI_search_error:
-      fprintf (stderr,
-               "Received ERROR: %d %s\n",
-               event->type, event->data.SearchError.message);
-      GNUNET_GE_BREAK (ectx, 0);
-      break;
     case GNUNET_FSUI_download_aborted:
 #if DEBUG_VERBOSE
       printf ("Received download aborted event.\n");

Modified: GNUnet/src/applications/fs/fsui/serializetest3.c
===================================================================
--- GNUnet/src/applications/fs/fsui/serializetest3.c    2008-02-25 06:12:45 UTC 
(rev 6451)
+++ GNUnet/src/applications/fs/fsui/serializetest3.c    2008-02-25 07:06:55 UTC 
(rev 6452)
@@ -86,7 +86,6 @@
     case GNUNET_FSUI_unindex_error:
     case GNUNET_FSUI_upload_error:
     case GNUNET_FSUI_download_error:
-    case GNUNET_FSUI_search_error:
       fprintf (stderr, "Received ERROR: %d\n", event->type);
       GNUNET_GE_BREAK (ectx, 0);
       break;
@@ -106,7 +105,6 @@
     case GNUNET_FSUI_search_started:
     case GNUNET_FSUI_search_aborted:
     case GNUNET_FSUI_search_stopped:
-    case GNUNET_FSUI_search_completed:
     case GNUNET_FSUI_unindex_started:
     case GNUNET_FSUI_unindex_stopped:
       break;

Modified: GNUnet/src/applications/fs/fsui/serializetest4.c
===================================================================
--- GNUnet/src/applications/fs/fsui/serializetest4.c    2008-02-25 06:12:45 UTC 
(rev 6451)
+++ GNUnet/src/applications/fs/fsui/serializetest4.c    2008-02-25 07:06:55 UTC 
(rev 6452)
@@ -203,7 +203,6 @@
     case GNUNET_FSUI_unindex_error:
     case GNUNET_FSUI_upload_error:
     case GNUNET_FSUI_download_error:
-    case GNUNET_FSUI_search_error:
       fprintf (stderr, "Received ERROR: %d\n", event->type);
       GNUNET_GE_BREAK (ectx, 0);
       break;

Modified: GNUnet/src/applications/fs/tools/gnunet-insert.c
===================================================================
--- GNUnet/src/applications/fs/tools/gnunet-insert.c    2008-02-25 06:12:45 UTC 
(rev 6451)
+++ GNUnet/src/applications/fs/tools/gnunet-insert.c    2008-02-25 07:06:55 UTC 
(rev 6452)
@@ -398,6 +398,8 @@
     }
   if (uri_string == NULL)
     filename = argv[i];
+  else
+    filename = NULL;
 
   if (extract_only)
     {

Modified: GNUnet/src/include/gnunet_ecrs_lib.h
===================================================================
--- GNUnet/src/include/gnunet_ecrs_lib.h        2008-02-25 06:12:45 UTC (rev 
6451)
+++ GNUnet/src/include/gnunet_ecrs_lib.h        2008-02-25 07:06:55 UTC (rev 
6452)
@@ -722,7 +722,11 @@
  * operation.
  *
  * @param totalBytes number of bytes that will need to be downloaded,
- *        excluding inner blocks
+ *        excluding inner blocks; the value given here will
+ *        be one larger than the requested download size to signal
+ *        an error.  In that case, all other values will be 0, 
+ *        except form "lastBlock" which will point to an error
+ *        message describing the problem.
  * @param completedBytes number of bytes that have been obtained
  * @param eta absolute estimated time for the completion of the operation
  * @param lastBlockOffset offset of the last block that was downloaded,
@@ -738,7 +742,45 @@
    unsigned long long lastBlockOffset,
    const char *lastBlock, unsigned int lastBlockSize, void *closure);
 
+struct GNUNET_ECRS_DownloadContext;
+
 /**
+ * Download parts of a file ASYNCHRONOUSLY.  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 may *write* outside of the
+ * given boundaries (if offset and length do not match the 32k ECRS
+ * block boundaries).  <p>
+ *
+ * This function should be used to focus a download towards a
+ * particular portion of the file (optimization), not to strictly
+ * limit the download to exactly those bytes.
+ *
+ * @param uri the URI of the file (determines what to download)
+ * @param filename where to store the file
+ * @param no_temporaries set to GNUNET_YES to disallow generation of temporary 
files
+ * @param start starting offset
+ * @param length length of the download (starting at offset)
+ */
+struct GNUNET_ECRS_DownloadContext *
+GNUNET_ECRS_file_download_partial_start (struct GNUNET_GE_Context *ectx,
+                                        struct GNUNET_GC_Configuration *cfg,
+                                        const struct GNUNET_ECRS_URI *uri,
+                                        const char *filename,
+                                        unsigned long long offset,
+                                        unsigned long long length,
+                                        unsigned int anonymityLevel,
+                                        int no_temporaries,
+                                        GNUNET_ECRS_DownloadProgressCallback 
dpcb,
+                                        void *dpcbClosure);
+
+/**
+ * Stop a download (aborts if download is incomplete).
+ */
+int
+GNUNET_ECRS_file_download_partial_stop (struct GNUNET_ECRS_DownloadContext * 
rm);
+
+/**
  * DOWNLOAD a file.
  *
  * @param uri the URI of the file (determines what to download)

Modified: GNUnet/src/util/disk/storage.c
===================================================================
--- GNUnet/src/util/disk/storage.c      2008-02-25 06:12:45 UTC (rev 6451)
+++ GNUnet/src/util/disk/storage.c      2008-02-25 07:06:55 UTC (rev 6452)
@@ -609,7 +609,7 @@
 {
   struct stat istat;
 
-  if (0 != STAT (fileName, &istat))
+  if (0 != LSTAT (fileName, &istat))
     return GNUNET_NO;           /* file may not exist... */
   if (UNLINK (fileName) == 0)
     return GNUNET_OK;

Modified: GNUnet/todo
===================================================================
--- GNUnet/todo 2008-02-25 06:12:45 UTC (rev 6451)
+++ GNUnet/todo 2008-02-25 07:06:55 UTC (rev 6452)
@@ -4,17 +4,20 @@
   RC == Release Critical
   PRE == to be done before a pre-release
 
-0.8.0 [6'08] (aka "advanced features"):
+0.8.0pre0 [2'08]:
+- make sure "make check" passes
+- make tcpserver IPv6 compatible
+- gnunet-gtk ready?
+- more IPv6 testing
+
+0.8.0 [4'08] (aka "advanced features"):
 - clean up VPN code
-- asynchronous ECRS API [?]
 - tune GAP query planning code [RC]
-- HTTP transport sometimes goes crazy with CPU usage
-- gnunet-chat (CS-only)
-- make tcpserver IPv6 compatible
-
-TESTING:
+- HTTP transport sometimes goes crazy with CPU usage [RC]
+- gnunet-chat (CS-only) [RC]
 - test RPC code (write a small demo)
-- test GAP code in general (still have one unexplained crazy crash!)
+- test new asynchronous ECRS API (and resulting FSUI changes)
+- test GAP code in general; still have one unexplained crazy crash:
   Program terminated with signal 11, Segmentation fault.
  #0  0xb4e8e73a in GNUNET_FS_SHARED_test_valid_new_response (rl=0x8060,
      primary_key=0xb343f1c8, size=820, data=0xb0b8f0e8, hc=0xb343f134) at 
shared.c:94





reply via email to

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