gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r8844 - in gnunet: . src/fs src/include src/util


From: gnunet
Subject: [GNUnet-SVN] r8844 - in gnunet: . src/fs src/include src/util
Date: Mon, 24 Aug 2009 03:26:47 -0600

Author: grothoff
Date: 2009-08-24 03:26:47 -0600 (Mon, 24 Aug 2009)
New Revision: 8844

Added:
   gnunet/src/include/gnunet_bio_lib.h
   gnunet/src/util/bio.c
Modified:
   gnunet/TODO
   gnunet/src/fs/Makefile.am
   gnunet/src/fs/fs.h
   gnunet/src/fs/fs_file_information.c
   gnunet/src/include/Makefile.am
   gnunet/src/include/gnunet_disk_lib.h
   gnunet/src/include/gnunet_fs_service.h
   gnunet/src/include/gnunet_util_lib.h
   gnunet/src/util/Makefile.am
   gnunet/src/util/container_bloomfilter.c
   gnunet/src/util/disk.c
   gnunet/src/util/pseudonym.c
Log:
hxing

Modified: gnunet/TODO
===================================================================
--- gnunet/TODO 2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/TODO 2009-08-24 09:26:47 UTC (rev 8844)
@@ -1,6 +1,7 @@
 Implementable right now (but not necessarily important), with caveats
 (unavailable components that will limit what can be implemented right
 away), in order in which they will likely be done:
+* Buffered IO library (extend gnunet_disk_lib.h?)
 * TESTING
 * FS (DHT not available)
 * SETUP

Modified: gnunet/src/fs/Makefile.am
===================================================================
--- gnunet/src/fs/Makefile.am   2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/src/fs/Makefile.am   2009-08-24 09:26:47 UTC (rev 8844)
@@ -24,6 +24,7 @@
 
 libgnunetfs_la_LIBADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
+  -lextractor \
   $(GN_LIBINTL) $(XLIB)
 
 libgnunetfs_la_LDFLAGS = \

Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h  2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/src/fs/fs.h  2009-08-24 09:26:47 UTC (rev 8844)
@@ -116,14 +116,37 @@
        * (only in URI-strings).
        */
       char **keywords;
+      
+      /**
+       * Size of the keywords array.
+       */
       unsigned int keywordCount;
     } ksk;
+
     struct
     {
+      /**
+       * Hash of the public key for the namespace.
+       */
       GNUNET_HashCode namespace;
+
+      /**
+       * Human-readable identifier chosen for this
+       * entry in the namespace.
+       */
       char *identifier;
     } sks;
+
+    /**
+     * Information needed to retrieve a file (content-hash-key
+     * plus file size).
+     */
     struct FileIdentifier chk;
+
+    /**
+     * Information needed to retrieve a file including signed
+     * location (identity of a peer) of the content.
+     */
     struct Location loc;
   } data;
 
@@ -134,10 +157,125 @@
  * Information for a file or directory that is
  * about to be published.
  */
-struct GNUNET_FS_FileInformation 
+struct GNUNET_FS_FileInformation
 {
 
+  /**
+   * Files in a directory are kept as a linked list.
+   */
+  struct GNUNET_FS_FileInformation *next;
 
+  /**
+   * If this is a file in a directory, "dir" refers to
+   * the directory; otherwise NULL.
+   */
+  struct GNUNET_FS_FileInformation *dir;
+
+  /**
+   * Pointer kept for the client.
+   */
+  void *client_info;
+
+  /**
+   * Metadata to use for the file.
+   */
+  struct GNUNET_CONTAINER_MetaData *meta;
+
+  /**
+   * Keywords to use for KBlocks.
+   */
+  struct GNUNET_FS_Uri *keywords;
+
+  /**
+   * At what time should the content expire?
+   */
+  struct GNUNET_TIME_Absolute expirationTime;
+
+  /**
+   * Under what filename is this struct serialized
+   * (for operational persistence).
+   */
+  char *serialization;
+
+  /**
+   * How many bytes of this file or directory have been
+   * published so far?
+   */
+  uint64_t publish_offset;
+
+  /**
+   * Data describing either the file or the directory.
+   */
+  union
+  {
+
+    /**
+     * Data for a file.
+     */
+    struct {
+
+      /**
+       * Function that can be used to read the data for the file.
+       */
+      GNUNET_FS_DataReader reader;
+
+      /**
+       * Closure for reader.
+       */
+      void *reader_cls;
+
+      /**
+       * Size of the file (in bytes).
+       */
+      uint64_t file_size;
+
+      /**
+       * Should the file be indexed or inserted?
+       */
+      int do_index;
+
+    } file;
+
+    /**
+     * Data for a directory.
+     */
+    struct {
+      
+      /**
+       * Name of the directory.
+       */
+      char *dirname;
+      
+      /**
+       * Linked list of entries in the directory.
+       */
+      struct GNUNET_FS_FileInformation *entries;
+
+      /**
+       * Size of the directory itself (in bytes); 0 if the
+       * size has not yet been calculated.
+       */
+      uint64_t dir_size;
+
+    } dir;
+
+  } data;
+
+  /**
+   * Is this struct for a file or directory?
+   */
+  int is_directory;
+
+  /**
+   * Desired anonymity level.
+   */
+  unsigned int anonymity;
+
+  /**
+   * Desired priority (for keeping the content in the DB).
+   */
+  unsigned int priority;
+
 };
 
 

Modified: gnunet/src/fs/fs_file_information.c
===================================================================
--- gnunet/src/fs/fs_file_information.c 2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/src/fs/fs_file_information.c 2009-08-24 09:26:47 UTC (rev 8844)
@@ -22,16 +22,141 @@
  * @file fs/fs_file_information.c
  * @brief  Manage information for publishing directory hierarchies
  * @author Christian Grothoff
+ *
+ * TODO:
+ * - publishing progress update API (increment offset, serialize)
+ * - serialization/deserialization (& deserialization API)
+ * - metadata filename clean up code
+ * - metadata/ksk generation for directories from contained files
  */
 #include "platform.h"
+#include <extractor.h>
 #include "gnunet_fs_service.h"
 #include "fs.h"
 
 
 /**
+ * Create a temporary file disk to store the current
+ * state of "fi" in.
+ */
+static void
+fi_sync (struct GNUNET_FS_FileInformation * fi)
+{
+  if (NULL == fi->serialization)
+    {
+      fi->serialization = NULL; // FIXME
+    }
+  // FIXME...
+}
+
+
+/**
+ * Load file information from the file to which
+ * it was sync'ed.
+ *
+ * @param filename name of the file to use
+ * @return NULL on error
+ */
+static struct GNUNET_FS_FileInformation *
+fi_load (const char *filename)
+{
+  struct GNUNET_FS_FileInformation *ret;
+  // FIXME!
+  return NULL;
+}
+
+
+/**
+ * Closure for "data_reader_file".
+ */
+struct FileInfo
+{
+  /**
+   * Name of the file to read.
+   */
+  char *filename;
+
+  /**
+   * File descriptor, NULL if it has not yet been opened.
+   */
+  struct GNUNET_DISK_FileHandle *fd;
+};
+
+
+/**
+ * Function that provides data by reading from a file.
+ *
+ * @param cls closure (points to the file information)
+ * @param offset offset to read from; it is possible
+ *            that the caller might need to go backwards
+ *            a bit at times
+ * @param max maximum number of bytes that should be 
+ *            copied to buf; readers are not allowed
+ *            to provide less data unless there is an error;
+ *            a value of "0" will be used at the end to allow
+ *            the reader to clean up its internal state
+ * @param buf where the reader should write the data
+ * @param emsg location for the reader to store an error message
+ * @return number of bytes written, usually "max", 0 on error
+ */
+static size_t
+data_reader_file(void *cls, 
+                uint64_t offset,
+                size_t max, 
+                void *buf,
+                char **emsg)
+{
+  struct FileInfo *fi = cls;
+  ssize_t ret;
+
+  if (max == 0)
+    {
+      if (fi->fd != NULL)
+       GNUNET_DISK_file_close (fi->fd);
+      GNUNET_free (fi->filename);
+      GNUNET_free (fi);
+      return 0;
+    }  
+  if (fi->fd == NULL)
+    {
+      fi->fd = GNUNET_DISK_file_open (fi->filename,
+                                     GNUNET_DISK_OPEN_READ);
+      if (fi->fd == NULL)
+       {
+         GNUNET_asprintf (emsg, 
+                          _("Could not open file `%s': %s"),
+                          fi->filename,
+                          STRERROR (errno));
+         return 0;
+       }
+    }
+  GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET);
+  ret = GNUNET_DISK_file_read (fi->fd, buf, max);
+  if (ret == -1)
+    {
+      GNUNET_asprintf (emsg, 
+                      _("Could not read file `%s': %s"),
+                      fi->filename,
+                      STRERROR (errno));
+      return 0;
+    }
+  if (ret != max)
+    {
+      GNUNET_asprintf (emsg, 
+                      _("Short read reading from file `%s'!"),
+                      fi->filename);
+      return 0;
+    }
+  return max;
+}
+
+
+/**
  * Create an entry for a file in a publish-structure.
  *
  * @param filename name of the file or directory to publish
+ * @param keywords under which keywords should this file be available
+ *         directly; can be NULL
  * @param meta metadata for the file
  * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
  *                GNUNET_SYSERR for simulation
@@ -45,21 +170,80 @@
 struct GNUNET_FS_FileInformation *
 GNUNET_FS_file_information_create_from_file (void *client_info,
                                             const char *filename,
+                                            const struct GNUNET_FS_Uri 
*keywords,
                                             const struct 
GNUNET_CONTAINER_MetaData *meta,
                                             int do_index,
                                             unsigned int anonymity,
                                             unsigned int priority,
                                             struct GNUNET_TIME_Absolute 
expirationTime)
 {
-  return NULL;
+  struct FileInfo *fi;
+  struct stat sbuf;
+
+  if (0 != STAT (filename, &sbuf))
+    {
+      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                               "stat",
+                               filename);
+      return NULL;
+    }
+  fi = GNUNET_malloc (sizeof(struct FileInfo));
+  fi->filename = GNUNET_strdup (filename);
+  return GNUNET_FS_file_information_create_from_reader (client_info,
+                                                       sbuf.st_size,
+                                                       &data_reader_file,
+                                                       fi,
+                                                       keywords,
+                                                       meta,
+                                                       do_index,
+                                                       anonymity,
+                                                       priority,
+                                                       expirationTime);
 }
 
+
 /**
+ * Function that provides data by copying from a buffer.
+ *
+ * @param cls closure (points to the buffer)
+ * @param offset offset to read from; it is possible
+ *            that the caller might need to go backwards
+ *            a bit at times
+ * @param max maximum number of bytes that should be 
+ *            copied to buf; readers are not allowed
+ *            to provide less data unless there is an error;
+ *            a value of "0" will be used at the end to allow
+ *            the reader to clean up its internal state
+ * @param buf where the reader should write the data
+ * @param emsg location for the reader to store an error message
+ * @return number of bytes written, usually "max", 0 on error
+ */
+static size_t
+data_reader_copy(void *cls, 
+                uint64_t offset,
+                size_t max, 
+                void *buf,
+                char **emsg)
+{
+  char *data = cls;
+  if (max == 0)
+    {
+      GNUNET_free (data);
+      return 0;
+    }  
+  memcpy (buf, &data[offset], max);
+  return max;
+}
+
+
+/**
  * Create an entry for a file in a publish-structure.
  *
  * @param length length of the file
  * @param data data for the file (should not be used afterwards by
  *        the caller; caller will "free")
+ * @param keywords under which keywords should this file be available
+ *         directly; can be NULL
  * @param meta metadata for the file
  * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
  *                GNUNET_SYSERR for simulation
@@ -74,13 +258,23 @@
 GNUNET_FS_file_information_create_from_data (void *client_info,
                                             uint64_t length,
                                             void *data,
+                                            const struct GNUNET_FS_Uri 
*keywords,
                                             const struct 
GNUNET_CONTAINER_MetaData *meta,
                                             int do_index,
                                             unsigned int anonymity,
                                             unsigned int priority,
                                             struct GNUNET_TIME_Absolute 
expirationTime)
 {
-  return NULL;
+  return GNUNET_FS_file_information_create_from_reader (client_info,
+                                                       length,
+                                                       &data_reader_copy,
+                                                       data,
+                                                       keywords,
+                                                       meta,
+                                                       do_index,
+                                                       anonymity,
+                                                       priority,
+                                                       expirationTime);
 }
 
 
@@ -114,12 +308,153 @@
                                               unsigned int priority,
                                               struct GNUNET_TIME_Absolute 
expirationTime)
 {
-  return NULL;
+  struct GNUNET_FS_FileInformation *ret;
+
+  ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
+  ret->client_info = client_info;
+  ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
+  ret->keywords = (keywords == NULL) ? NULL : GNUNET_FS_uri_dup (keywords);
+  ret->expirationTime = expirationTime;
+  ret->data.file.reader = reader; 
+  ret->data.file.reader_cls = reader_cls;
+  ret->data.file.do_index = do_index;
+  ret->anonymity = anonymity;
+  ret->priority = priority;
+  fi_sync (ret);
+  return ret;
 }
 
 
+/**
+ * Closure for "dir_scan_cb".
+ */
+struct DirScanCls 
+{
+  /**
+   * Metadata extractors to use.
+   */
+  struct EXTRACTOR_Extractor *extractors;
 
+  /**
+   * Function to call on each directory entry.
+   */
+  GNUNET_FS_FileProcessor proc;
+  
+  /**
+   * Closure for proc.
+   */
+  void *proc_cls;
+
+  /**
+   * Scanner to use for subdirectories.
+   */
+  GNUNET_FS_DirectoryScanner scanner;
+
+  /**
+   * Closure for scanner.
+   */
+  void *scanner_cls;
+
+  /**
+   * Set to an error message (if any).
+   */
+  char *emsg; 
+
+  /**
+   * Should files be indexed?
+   */ 
+  int do_index;
+
+  /**
+   * Desired anonymity level.
+   */
+  unsigned int anonymity;
+
+  /**
+   * Desired publishing priority.
+   */
+  unsigned int priority;
+
+  /**
+   * Expiration time for publication.
+   */
+  struct GNUNET_TIME_Absolute expiration;
+};
+
+
 /**
+ * Function called on each entry in a file to
+ * cause default-publishing.
+ * @param cls closure (struct DirScanCls)
+ * @param filename name of the file to be published
+ * @return GNUNET_OK on success, GNUNET_SYSERR to abort
+ */
+static int
+dir_scan_cb (void *cls,
+            const char *filename)
+{
+  struct DirScanCls *dsc = cls;  
+  struct stat sbuf;
+  struct GNUNET_FS_FileInformation *fi;
+  struct GNUNET_FS_Uri *ksk_uri;
+  struct GNUNET_FS_Uri *keywords;
+  struct GNUNET_CONTAINER_MetaData *meta;
+
+  if (0 != STAT (filename, &sbuf))
+    {
+      GNUNET_asprintf (&dsc->emsg,
+                      _("`%s' failed on file `%s': %s"),
+                      "stat",
+                      filename,
+                      STRERROR (errno));
+      return GNUNET_SYSERR;
+    }
+  if (S_ISDIR (sbuf.st_mode))
+    {
+      fi = GNUNET_FS_file_information_create_from_directory (NULL,
+                                                            filename,
+                                                            dsc->scanner,
+                                                            dsc->scanner_cls,
+                                                            dsc->do_index,
+                                                            dsc->anonymity,
+                                                            dsc->priority,
+                                                            dsc->expiration,
+                                                            &dsc->emsg);
+      if (NULL == fi)
+       {
+         GNUNET_assert (NULL != dsc->emsg);
+         return GNUNET_SYSERR;
+       }
+    }
+  else
+    {
+      meta = GNUNET_CONTAINER_meta_data_create ();
+      GNUNET_CONTAINER_meta_data_extract_from_file (meta,
+                                                   filename,
+                                                   dsc->extractors);
+      // FIXME: remove path from filename in metadata!
+      keywords = GNUNET_FS_uri_ksk_create_from_meta_data (meta);
+      ksk_uri = GNUNET_FS_uri_ksk_canonicalize (keywords);
+      fi = GNUNET_FS_file_information_create_from_file (NULL,
+                                                       filename,
+                                                       ksk_uri,
+                                                       meta,
+                                                       dsc->do_index,
+                                                       dsc->anonymity,
+                                                       dsc->priority,
+                                                       dsc->expiration);
+      GNUNET_CONTAINER_meta_data_destroy (meta);
+      GNUNET_FS_uri_destroy (keywords);
+      GNUNET_FS_uri_destroy (ksk_uri);
+    }
+  dsc->proc (dsc->proc_cls,
+            filename,
+            fi);
+  return GNUNET_OK;
+}
+
+
+/**
  * Simple, useful default implementation of a directory scanner
  * (GNUNET_FS_DirectoryScanner).  This implementation expects to get a
  * UNIX filename, will publish all files in the directory except hidden
@@ -132,6 +467,10 @@
  *
  * @param cls must be of type "struct EXTRACTOR_Extractor*"
  * @param dirname name of the directory to scan
+ * @param do_index should files be indexed or inserted
+ * @param anonymity desired anonymity level
+ * @param priority priority for publishing
+ * @param expirationTime expiration for publication
  * @param proc function called on each entry
  * @param proc_cls closure for proc
  * @param emsg where to store an error message (on errors)
@@ -140,14 +479,74 @@
 int
 GNUNET_FS_directory_scanner_default (void *cls,
                                     const char *dirname,
+                                    int do_index,
+                                    unsigned int anonymity,
+                                    unsigned int priority,
+                                    struct GNUNET_TIME_Absolute expirationTime,
                                     GNUNET_FS_FileProcessor proc,
-                                    void *proc_cls)
+                                    void *proc_cls,
+                                    char **emsg)
 {
-  return GNUNET_SYSERR;
+  struct EXTRACTOR_Extractor *ex = cls;
+  struct DirScanCls dsc;
+
+  dsc.extractors = ex;
+  dsc.proc = proc;
+  dsc.proc_cls = proc_cls;
+  dsc.scanner = &GNUNET_FS_directory_scanner_default;
+  dsc.scanner_cls = cls;
+  dsc.do_index = do_index;
+  dsc.anonymity = anonymity;
+  dsc.priority = priority;
+  dsc.expiration = expirationTime;
+  if (-1 == GNUNET_DISK_directory_scan (dirname,
+                                       &dir_scan_cb,
+                                       &dsc))
+    {
+      GNUNET_assert (NULL != dsc.emsg);
+      *emsg = dsc.emsg;
+      return GNUNET_SYSERR;
+    }
+  return GNUNET_OK;
 }
 
 
 /**
+ * Closure for dirproc function.
+ */
+struct EntryProcCls
+{
+  /**
+   * Linked list of directory entries that is being
+   * created.
+   */
+  struct GNUNET_FS_FileInformation *entries;
+
+};
+
+
+/**
+ * Function that processes a directory entry that
+ * was obtained from the scanner.
+ * @param cls our closure
+ * @param filename name of the file (unused, why there???)
+ * @param fi information for publishing the file
+ */
+static void
+dirproc (void *cls,
+        const char *filename,
+        struct GNUNET_FS_FileInformation *fi)
+{
+  struct EntryProcCls *dc = cls;
+
+  GNUNET_assert (fi->next == NULL);
+  GNUNET_assert (fi->dir == NULL);
+  fi->next = dc->entries;
+  dc->entries = fi;
+}
+
+
+/**
  * Create a publish-structure from an existing file hierarchy, inferring
  * and organizing keywords and metadata as much as possible.  This
  * function primarily performs the recursive build and re-organizes
@@ -160,22 +559,61 @@
  * @param filename name of the top-level file or directory
  * @param scanner function used to get a list of files in a directory
  * @param scanner_cls closure for scanner
+ * @param do_index should files in the hierarchy be indexed?
  * @param anonymity what is the desired anonymity level for sharing?
  * @param priority what is the priority for OUR node to
  *   keep this file available?  Use 0 for maximum anonymity and
  *   minimum reliability...
  * @param expirationTime when should this content expire?
+ * @param emsg where to store an error message
  * @return publish structure entry for the directory, NULL on error
  */
 struct GNUNET_FS_FileInformation *
 GNUNET_FS_file_information_create_from_directory (void *client_info,
+                                                 const char *filename,
                                                  GNUNET_FS_DirectoryScanner 
scanner,
                                                  void *scanner_cls,
+                                                 int do_index,
                                                  unsigned int anonymity,
                                                  unsigned int priority,
-                                                 struct GNUNET_TIME_Absolute 
expirationTime)
+                                                 struct GNUNET_TIME_Absolute 
expirationTime,
+                                                 char **emsg)
 {
-  return NULL;
+  struct GNUNET_FS_FileInformation *ret;
+  struct EntryProcCls dc;
+  struct GNUNET_FS_Uri *ksk;
+  struct GNUNET_CONTAINER_MetaData *meta;
+
+  dc.entries = NULL;
+  meta = GNUNET_CONTAINER_meta_data_create ();
+  GNUNET_FS_meta_data_make_directory (meta);
+  
+  scanner (scanner_cls,
+          filename,
+          do_index,
+          anonymity,
+          priority,
+          expirationTime,
+          &dirproc,
+          &dc,
+          emsg);
+  ksk = NULL; // FIXME...
+  // FIXME: create meta!
+  ret = GNUNET_FS_file_information_create_empty_directory (client_info,
+                                                          meta,
+                                                          ksk,
+                                                          anonymity,
+                                                          priority,
+                                                          expirationTime);
+  ret->data.dir.entries = dc.entries;
+  while (dc.entries != NULL)
+    {
+      dc.entries->dir = ret;
+      fi_sync (dc.entries);
+      dc.entries = dc.entries->next;
+    }
+  fi_sync (ret);
+  return ret;
 }
 
 
@@ -203,7 +641,18 @@
                                                   unsigned int priority,
                                                   struct GNUNET_TIME_Absolute 
expirationTime)
 {
-  return NULL;
+  struct GNUNET_FS_FileInformation *ret;
+
+  ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
+  ret->client_info = client_info;
+  ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
+  ret->keywords = GNUNET_FS_uri_dup (keywords);
+  ret->expirationTime = expirationTime;
+  ret->is_directory = GNUNET_YES;
+  ret->anonymity = anonymity;
+  ret->priority = priority;
+  fi_sync (ret);
+  return ret;
 }
 
 
@@ -213,16 +662,30 @@
  * "GNUNET_FS_publish_start" already.
  *
  * @param dir the directory
- * @param end the entry to add; the entry must not have been
+ * @param ent the entry to add; the entry must not have been
  *            added to any other directory at this point and 
  *            must not include "dir" in its structure
  * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
 int
 GNUNET_FS_file_information_add (struct GNUNET_FS_FileInformation *dir,
-                               struct GNUNET_FS_FileInformation *end)
+                               struct GNUNET_FS_FileInformation *ent)
 {
-  return GNUNET_SYSERR;
+  if ( (ent->dir != NULL) ||
+       (ent->next != NULL) ||
+       (! dir->is_directory) )
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+  ent->dir = dir;
+  ent->next = dir->data.dir.entries;
+  dir->data.dir.entries = ent;
+  dir->data.dir.dir_size = 0;
+  dir->publish_offset = 0;
+  fi_sync (ent);
+  fi_sync (dir);
+  return GNUNET_OK;
 }
 
 
@@ -245,6 +708,46 @@
                                    GNUNET_FS_FileInformationProcessor proc,
                                    void *proc_cls)
 {
+  struct GNUNET_FS_FileInformation *pos;
+
+  if (dir->is_directory)
+    {
+      proc (proc_cls, 
+           dir,
+           dir->data.dir.dir_size,
+           dir->meta,
+           &dir->keywords,
+           &dir->anonymity,
+           &dir->priority,
+           &dir->expirationTime,
+           &dir->client_info);
+      pos = dir->data.dir.entries;
+      while (pos != NULL)
+       {
+         proc (proc_cls, 
+               pos,
+               pos->data.dir.dir_size,
+               pos->meta,
+               &pos->keywords,
+               &pos->anonymity,
+               &pos->priority,
+               &pos->expirationTime,
+               &pos->client_info);
+         pos = pos->next;
+       }
+    }
+  else
+    {
+      proc (proc_cls, 
+           dir,
+           dir->data.file.file_size,
+           dir->meta,
+           &dir->keywords,
+           &dir->anonymity,
+           &dir->priority,
+           &dir->expirationTime,
+           &dir->client_info);
+    }
 }
 
 
@@ -263,6 +766,53 @@
                                    GNUNET_FS_FileInformationProcessor cleaner,
                                    void *cleaner_cls)
 {
+  struct GNUNET_FS_FileInformation *pos;
+
+  if (fi->is_directory)
+    {
+      /* clean up directory */
+      while (NULL != (pos = fi->data.dir.entries))
+       {
+         fi->data.dir.entries = pos->next;
+         GNUNET_FS_file_information_destroy (pos, cleaner, cleaner_cls);
+       }
+      /* clean up client-info */
+      cleaner (cleaner_cls, 
+              fi,
+              fi->data.dir.dir_size,
+              fi->meta,
+              &fi->keywords,
+              &fi->anonymity,
+              &fi->priority,
+              &fi->expirationTime,
+              &fi->client_info);
+      GNUNET_free (fi->data.dir.dirname);
+    }
+  else
+    {
+      /* call clean-up function of the reader */
+      fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL);
+      /* clean up client-info */
+      cleaner (cleaner_cls, 
+              fi,
+              fi->data.file.file_size,
+              fi->meta,
+              &fi->keywords,
+              &fi->anonymity,
+              &fi->priority,
+              &fi->expirationTime,
+              &fi->client_info);
+    }
+
+  /* clean up serialization */
+  if (0 != UNLINK (fi->serialization))
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                             "unlink",
+                             fi->serialization);
+  GNUNET_FS_uri_destroy (fi->keywords);
+  GNUNET_CONTAINER_meta_data_destroy (fi->meta);
+  GNUNET_free (fi->serialization);
+  GNUNET_free (fi);
 }
 
 

Modified: gnunet/src/include/Makefile.am
===================================================================
--- gnunet/src/include/Makefile.am      2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/src/include/Makefile.am      2009-08-24 09:26:47 UTC (rev 8844)
@@ -13,6 +13,7 @@
 
 gnunetinclude_HEADERS = \
   gnunet_arm_service.h \
+  gnunet_bio_lib.h \
   gnunet_client_lib.h \
   gnunet_common.h \
   gnunet_constants.h \

Added: gnunet/src/include/gnunet_bio_lib.h
===================================================================
--- gnunet/src/include/gnunet_bio_lib.h                         (rev 0)
+++ gnunet/src/include/gnunet_bio_lib.h 2009-08-24 09:26:47 UTC (rev 8844)
@@ -0,0 +1,281 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009 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_bio_lib.h
+ * @brief buffered IO API
+ * @author Christian Grothoff
+ */
+
+#ifndef GNUNET_BIO_LIB_H
+#define GNUNET_BIO_LIB_H
+
+#include "gnunet_container_lib.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0                           /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+/**
+ * Handle for buffered reading.
+ */
+struct GNUNET_BIO_ReadHandle;
+
+
+/**
+ * Open a file for reading.
+ *
+ * @param fn file name to be opened
+ * @return IO handle on success, NULL on error
+ */
+struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn);
+
+
+/**
+ * Close an open file.  Reports if any errors reading
+ * from the file were encountered.
+ *
+ * @param h file handle
+ * @param emsg set to the error message
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
+                          char **emsg);
+
+
+/**
+ * Read the contents of a binary file into a buffer.
+ *
+ * @param h handle to an open file
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to write the result to
+ * @param len the number of bytes to read
+ * @return len on success, GNUNET_SYSERR on failure
+ */
+ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, 
+                        const char *what,
+                        void *result, 
+                        size_t len);
+
+/**
+ * Read 0-terminated string from a file.
+ *
+ * @param h handle to an open file
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to store a pointer to the (allocated) string to
+ *        (note that *result could be set to NULL as well)
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, 
+                           const char *what,
+                           char **result);
+
+
+/**
+ * Read metadata container from a file.
+ *
+ * @param h handle to an open file
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to store a pointer to the (allocated) metadata
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, 
+                              const char *what,
+                              struct GNUNET_CONTAINER_MetaData **result);
+
+
+/**
+ * Read a float.
+ *
+ * @param h hande to open file
+ * @param f address of float to read
+ */ 
+#define GNUNET_BIO_read_float(h, f) (sizeof(float) == GNUNET_BIO_read (h, 
__FILE__ "##__LINE__##", f, sizeof(float)))
+
+
+
+/**
+ * Read a double.
+ *
+ * @param h hande to open file
+ * @param f address of double to read
+ */ 
+#define GNUNET_BIO_read_double(h, f) (sizeof(double) == GNUNET_BIO_read (h, 
__FILE__ "##__LINE__##", f, sizeof(double)))
+
+
+/**
+ * Read an (u)int32_t.
+ *
+ * @param h hande to open file
+ * @param what describes what is being read (for error message creation)
+ * @param i address of 32-bit integer to read
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, 
+                            const char *what,
+                            int32_t *i);
+
+
+/**
+ * Read an (u)int32_t.
+ *
+ * @param h hande to open file
+ * @param i address of 32-bit integer to read
+ */ 
+#define GNUNET_BIO_read_int32(h, i) GNUNET_BIO_read_int32__ (h, __FILE__ 
"##__LINE__##", (int32_t*) i)
+
+
+/**
+ * Read an (u)int64_t.
+ *
+ * @param h hande to open file
+ * @param what describes what is being read (for error message creation)
+ * @param i address of 64-bit integer to read
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, 
+                            const char *what,
+                            int64_t *i);
+
+
+/**
+ * Read an (u)int64_t.
+ *
+ * @param h hande to open file
+ * @param i address of 64-bit integer to read
+ */ 
+#define GNUNET_BIO_read_int64(h, i) (sizeof(int64_t) == GNUNET_BIO_read (h, 
__FILE__ "##__LINE__##", (int64_t*) i, sizeof(int64_t)))
+
+
+/**
+ * Handle for buffered writing.
+ */
+struct GNUNET_BIO_WriteHandle;
+/**
+ * Open a file for writing.
+ *
+ * @param fn file name to be opened
+ * @return IO handle on success, NULL on error
+ */
+struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn);
+
+
+/**
+ * Close an open file for writing.
+ *
+ * @param h file handle
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
+
+
+/**
+ * Write a buffer to a file.
+ *
+ * @param h handle to open file
+ * @param buffer the data to write
+ * @param n number of bytes to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, 
+                         const void *buffer,
+                         size_t n);
+
+
+/**
+ * Write a string to a file.
+ *
+ * @param h handle to open file
+ * @param s string to write (can be NULL)
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, 
+                            const char *s);
+
+
+
+
+/**
+ * Write metadata container to a file.
+ *
+ * @param h handle to open file
+ * @param m metadata to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, 
+                               const struct GNUNET_CONTAINER_MetaData *m);
+
+
+
+/**
+ * Write a float.
+ *
+ * @param h hande to open file
+ * @param f float to write (must be a variable)
+ */ 
+#define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, 
&f, sizeof(float)))
+
+
+
+/**
+ * Write a double.
+ *
+ * @param h hande to open file
+ * @param f double to write (must be a variable)
+ */ 
+#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, 
&f, sizeof(double)))
+
+
+/**
+ * Write an (u)int32_t.
+ *
+ * @param h hande to open file
+ * @param i address of 32-bit integer to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h, 
+                           int32_t i);
+
+
+/**
+ * Write an (u)int64_t.
+ *
+ * @param h hande to open file
+ * @param i address of 64-bit integer to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h, 
+                           int64_t i);
+
+
+#if 0                           /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* ifndef GNUNET_BIO_LIB_H */
+#endif
+/* end of gnunet_bio_lib.h */

Modified: gnunet/src/include/gnunet_disk_lib.h
===================================================================
--- gnunet/src/include/gnunet_disk_lib.h        2009-08-23 22:11:49 UTC (rev 
8843)
+++ gnunet/src/include/gnunet_disk_lib.h        2009-08-24 09:26:47 UTC (rev 
8844)
@@ -72,7 +72,12 @@
 #define GNUNET_DISK_PERM_OTHER_WRITE    128
 #define GNUNET_DISK_PERM_OTHER_EXEC     256
 
-enum GNUNET_DISK_Seek {GNUNET_SEEK_SET, GNUNET_SEEK_CUR, GNUNET_SEEK_END};
+enum GNUNET_DISK_Seek 
+  {
+    GNUNET_DISK_SEEK_SET, 
+    GNUNET_DISK_SEEK_CUR, 
+    GNUNET_DISK_SEEK_END
+  };
 
 struct GNUNET_DISK_FileHandle;
 
@@ -250,7 +255,8 @@
  * @return the number of files found, -1 on error
  */
 int GNUNET_DISK_directory_scan (const char *dirName,
-                                GNUNET_FileNameCallback callback, void *data);
+                                GNUNET_FileNameCallback callback, 
+                               void *data);
 
 
 /**

Modified: gnunet/src/include/gnunet_fs_service.h
===================================================================
--- gnunet/src/include/gnunet_fs_service.h      2009-08-23 22:11:49 UTC (rev 
8843)
+++ gnunet/src/include/gnunet_fs_service.h      2009-08-24 09:26:47 UTC (rev 
8844)
@@ -1418,6 +1418,8 @@
  * Create an entry for a file in a publish-structure.
  *
  * @param filename name of the file or directory to publish
+ * @param keywords under which keywords should this file be available
+ *         directly; can be NULL
  * @param meta metadata for the file
  * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
  *                GNUNET_SYSERR for simulation
@@ -1431,6 +1433,7 @@
 struct GNUNET_FS_FileInformation *
 GNUNET_FS_file_information_create_from_file (void *client_info,
                                             const char *filename,
+                                            const struct GNUNET_FS_Uri 
*keywords,
                                             const struct 
GNUNET_CONTAINER_MetaData *meta,
                                             int do_index,
                                             unsigned int anonymity,
@@ -1444,6 +1447,8 @@
  * @param length length of the file
  * @param data data for the file (should not be used afterwards by
  *        the caller; caller will "free")
+ * @param keywords under which keywords should this file be available
+ *         directly; can be NULL
  * @param meta metadata for the file
  * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
  *                GNUNET_SYSERR for simulation
@@ -1458,6 +1463,7 @@
 GNUNET_FS_file_information_create_from_data (void *client_info,
                                             uint64_t length,
                                             void *data,
+                                            const struct GNUNET_FS_Uri 
*keywords,
                                             const struct 
GNUNET_CONTAINER_MetaData *meta,
                                             int do_index,
                                             unsigned int anonymity,
@@ -1539,6 +1545,10 @@
  * 
  * @param cls closure
  * @param dirname name of the directory to scan
+ * @param do_index should files be indexed or inserted
+ * @param anonymity desired anonymity level
+ * @param priority priority for publishing
+ * @param expirationTime expiration for publication
  * @param proc function to call on each entry
  * @param proc_cls closure for proc
  * @param emsg where to store an error message (on errors)
@@ -1546,6 +1556,10 @@
  */
 typedef int (*GNUNET_FS_DirectoryScanner)(void *cls,
                                          const char *dirname,
+                                         int do_index,
+                                         unsigned int anonymity,
+                                         unsigned int priority,
+                                         struct GNUNET_TIME_Absolute 
expirationTime,
                                          GNUNET_FS_FileProcessor proc,
                                          void *proc_cls,
                                          char **emsg);
@@ -1565,6 +1579,10 @@
  *
  * @param cls must be of type "struct EXTRACTOR_Extractor*"
  * @param dirname name of the directory to scan
+ * @param do_index should files be indexed or inserted
+ * @param anonymity desired anonymity level
+ * @param priority priority for publishing
+ * @param expirationTime expiration for publication
  * @param proc function called on each entry
  * @param proc_cls closure for proc
  * @param emsg where to store an error message (on errors)
@@ -1573,8 +1591,13 @@
 int
 GNUNET_FS_directory_scanner_default (void *cls,
                                     const char *dirname,
+                                    int do_index,
+                                    unsigned int anonymity,
+                                    unsigned int priority,
+                                    struct GNUNET_TIME_Absolute expirationTime,
                                     GNUNET_FS_FileProcessor proc,
-                                    void *proc_cls);
+                                    void *proc_cls,
+                                    char **emsg);
 
 
 /**
@@ -1590,20 +1613,25 @@
  * @param filename name of the top-level file or directory
  * @param scanner function used to get a list of files in a directory
  * @param scanner_cls closure for scanner
+ * @param do_index should files in the hierarchy be indexed?
  * @param anonymity what is the desired anonymity level for sharing?
  * @param priority what is the priority for OUR node to
  *   keep this file available?  Use 0 for maximum anonymity and
  *   minimum reliability...
  * @param expirationTime when should this content expire?
+ * @param emsg where to store an error message
  * @return publish structure entry for the directory, NULL on error
  */
 struct GNUNET_FS_FileInformation *
 GNUNET_FS_file_information_create_from_directory (void *client_info,
+                                                 const char *filename,
                                                  GNUNET_FS_DirectoryScanner 
scanner,
                                                  void *scanner_cls,
+                                                 int do_index,
                                                  unsigned int anonymity,
                                                  unsigned int priority,
-                                                 struct GNUNET_TIME_Absolute 
expirationTime);
+                                                 struct GNUNET_TIME_Absolute 
expirationTime,
+                                                 char **emsg);
 
 
 /**

Modified: gnunet/src/include/gnunet_util_lib.h
===================================================================
--- gnunet/src/include/gnunet_util_lib.h        2009-08-23 22:11:49 UTC (rev 
8843)
+++ gnunet/src/include/gnunet_util_lib.h        2009-08-24 09:26:47 UTC (rev 
8844)
@@ -37,6 +37,7 @@
 #endif
 
 #include "gnunet_common.h"
+#include "gnunet_bio_lib.h"
 #include "gnunet_client_lib.h"
 #include "gnunet_configuration_lib.h"
 #include "gnunet_connection_lib.h"

Modified: gnunet/src/util/Makefile.am
===================================================================
--- gnunet/src/util/Makefile.am 2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/src/util/Makefile.am 2009-08-24 09:26:47 UTC (rev 8844)
@@ -15,6 +15,7 @@
 lib_LTLIBRARIES = libgnunetutil.la
 
 libgnunetutil_la_SOURCES = \
+  bio.c \
   client.c \
   common_allocation.c \
   common_endian.c \

Added: gnunet/src/util/bio.c
===================================================================
--- gnunet/src/util/bio.c                               (rev 0)
+++ gnunet/src/util/bio.c       2009-08-24 09:26:47 UTC (rev 8844)
@@ -0,0 +1,545 @@
+/*
+     This file is part of GNUnet.
+     (C) 2006, 2009 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+
+/**
+ * @file util/bio.c
+ * @brief functions for buffering IO
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_bio_lib.h"
+
+
+/**
+ * Handle for buffered reading.
+ */
+struct GNUNET_BIO_ReadHandle
+{
+};
+
+
+/**
+ * Open a file for reading.
+ *
+ * @param fn file name to be opened
+ * @return IO handle on success, NULL on error
+ */
+struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn)
+{
+  return NULL;
+}
+
+
+/**
+ * Close an open file.  Reports if any errors reading
+ * from the file were encountered.
+ *
+ * @param h file handle
+ * @param emsg set to the error message
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
+                          char **emsg)
+{
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Read the contents of a binary file into a buffer.
+ *
+ * @param h handle to an open file
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to write the result to
+ * @param len the number of bytes to read
+ * @return len on success, GNUNET_SYSERR on failure
+ */
+ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, 
+                        const char *what,
+                        void *result, 
+                        size_t len)
+{
+}
+
+
+/**
+ * Read 0-terminated string from a file.
+ *
+ * @param h handle to an open file
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to store a pointer to the (allocated) string to
+ *        (note that *result could be set to NULL as well)
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, 
+                           const char *what,
+                           char **result)
+{
+}
+
+
+/**
+ * Read metadata container from a file.
+ *
+ * @param h handle to an open file
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to store a pointer to the (allocated) metadata
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, 
+                              const char *what,
+                              struct GNUNET_CONTAINER_MetaData **result)
+{
+}
+
+
+/**
+ * Read an (u)int32_t.
+ *
+ * @param h hande to open file
+ * @param what describes what is being read (for error message creation)
+ * @param i address of 32-bit integer to read
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, 
+                            const char *what,
+                            int32_t *i);
+
+
+/**
+ * Read an (u)int64_t.
+ *
+ * @param h hande to open file
+ * @param what describes what is being read (for error message creation)
+ * @param i address of 64-bit integer to read
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, 
+                            const char *what,
+                            int64_t *i);
+
+/**
+ * Handle for buffered writing.
+ */
+struct GNUNET_BIO_WriteHandle
+{
+};
+
+
+/**
+ * Open a file for writing.
+ *
+ * @param fn file name to be opened
+ * @return IO handle on success, NULL on error
+ */
+struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn)
+{
+  return NULL;
+}
+
+
+/**
+ * Close an open file for writing.
+ *
+ * @param h file handle
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
+
+
+/**
+ * Write a buffer to a file.
+ *
+ * @param h handle to open file
+ * @param buffer the data to write
+ * @param n number of bytes to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, 
+                         const void *buffer,
+                         size_t n);
+
+
+/**
+ * Write a string to a file.
+ *
+ * @param h handle to open file
+ * @param s string to write (can be NULL)
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, 
+                            const char *s);
+
+
+
+
+/**
+ * Write metadata container to a file.
+ *
+ * @param h handle to open file
+ * @param m metadata to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, 
+                               const struct GNUNET_CONTAINER_MetaData *m);
+
+
+
+/**
+ * Write a float.
+ *
+ * @param h hande to open file
+ * @param f float to write (must be a variable)
+ */ 
+#define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, 
&f, sizeof(float)))
+
+
+
+/**
+ * Write a double.
+ *
+ * @param h hande to open file
+ * @param f double to write (must be a variable)
+ */ 
+#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, 
&f, sizeof(double)))
+
+
+/**
+ * Write an (u)int32_t.
+ *
+ * @param h hande to open file
+ * @param i address of 32-bit integer to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h, 
+                           int32_t i);
+
+
+/**
+ * Write an (u)int64_t.
+ *
+ * @param h hande to open file
+ * @param i address of 64-bit integer to write
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */ 
+int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h, 
+                           int64_t i);
+
+
+
+
+
+typedef struct
+{
+  int fd;
+  unsigned int have;
+  unsigned int size;
+  char *buffer;
+} WriteBuffer;
+
+static void
+write_buffered (WriteBuffer * wb, const void *s, unsigned int size)
+{
+  const char *src = s;
+  unsigned int min;
+  unsigned int pos;
+  int ret;
+
+  if (wb->fd == -1)
+    return;
+  pos = 0;
+  do
+    {
+      /* first, just use buffer */
+      min = wb->size - wb->have;
+      if (min > size - pos)
+        min = size - pos;
+      memcpy (&wb->buffer[wb->have], &src[pos], min);
+      pos += min;
+      wb->have += min;
+      if (pos == size)
+        return;                 /* done */
+      GNUNET_GE_ASSERT (NULL, wb->have == wb->size);
+      ret = WRITE (wb->fd, wb->buffer, wb->size);
+      if (ret != wb->size)
+        {
+          CLOSE (wb->fd);
+          wb->fd = -1;
+          return;               /* error */
+        }
+      wb->have = 0;
+    }
+  while (pos < size);           /* should always be true */
+}
+
+
+static void
+WRITEINT (WriteBuffer * wb, int val)
+{
+  int big;
+  big = htonl (val);
+  write_buffered (wb, &big, sizeof (int));
+}
+
+static void
+WRITELONG (WriteBuffer * wb, long long val)
+{
+  long long big;
+  big = GNUNET_htonll (val);
+  write_buffered (wb, &big, sizeof (long long));
+}
+
+static void
+writeURI (WriteBuffer * wb, const struct GNUNET_ECRS_URI *uri)
+{
+  char *buf;
+  unsigned int size;
+
+  buf = GNUNET_ECRS_uri_to_string (uri);
+  size = strlen (buf);
+  WRITEINT (wb, size);
+  write_buffered (wb, buf, size);
+  GNUNET_free (buf);
+}
+
+static void
+WRITESTRING (WriteBuffer * wb, const char *name)
+{
+  GNUNET_GE_BREAK (NULL, name != NULL);
+  WRITEINT (wb, strlen (name));
+  write_buffered (wb, name, strlen (name));
+}
+
+static void
+writeMetaData (struct GNUNET_GE_Context *ectx,
+               WriteBuffer * wb, const struct GNUNET_MetaData *meta)
+{
+  unsigned int size;
+  char *buf;
+
+  size = GNUNET_meta_data_get_serialized_size (meta,
+                                               GNUNET_SERIALIZE_FULL
+                                               |
+                                               GNUNET_SERIALIZE_NO_COMPRESS);
+  if (size > 1024 * 1024)
+    size = 1024 * 1024;
+  buf = GNUNET_malloc (size);
+  GNUNET_meta_data_serialize (ectx,
+                              meta,
+                              buf,
+                              size,
+                              GNUNET_SERIALIZE_PART |
+                              GNUNET_SERIALIZE_NO_COMPRESS);
+  WRITEINT (wb, size);
+  write_buffered (wb, buf, size);
+  GNUNET_free (buf);
+}
+
+
+static void
+writeFileInfo (struct GNUNET_GE_Context *ectx, WriteBuffer * wb,
+               const GNUNET_ECRS_FileInfo * fi)
+{
+  writeMetaData (ectx, wb, fi->meta);
+  writeURI (wb, fi->uri);
+}
+
+
+
+
+typedef struct
+{
+  int fd;
+  unsigned int have;
+  unsigned int size;
+  unsigned int pos;
+  char *buffer;
+} ReadBuffer;
+
+static int
+read_buffered (ReadBuffer * rb, void *d, unsigned int size)
+{
+  char *dst = d;
+  unsigned int min;
+  unsigned int pos;
+  int ret;
+
+  if (rb->fd == -1)
+    return -1;
+  pos = 0;
+  do
+    {
+      /* first, use buffer */
+      min = rb->have - rb->pos;
+      if (min > 0)
+        {
+          if (min > size - pos)
+            min = size - pos;
+          memcpy (&dst[pos], &rb->buffer[rb->pos], min);
+          rb->pos += min;
+          pos += min;
+        }
+      if (pos == size)
+        return pos;             /* done! */
+      GNUNET_GE_ASSERT (NULL, rb->have == rb->pos);
+      /* fill buffer */
+      ret = READ (rb->fd, rb->buffer, rb->size);
+      if (ret == -1)
+        {
+          CLOSE (rb->fd);
+          rb->fd = -1;
+          return -1;
+        }
+      if (ret == 0)
+        return 0;
+      rb->pos = 0;
+      rb->have = ret;
+    }
+  while (pos < size);           /* should always be true */
+  return pos;
+}
+
+
+static int
+read_int (ReadBuffer * rb, int *val)
+{
+  int big;
+
+  if (sizeof (int) != read_buffered (rb, &big, sizeof (int)))
+    return GNUNET_SYSERR;
+  *val = ntohl (big);
+  return GNUNET_OK;
+}
+
+static unsigned int
+read_uint (ReadBuffer * rb, unsigned int *val)
+{
+  unsigned int big;
+
+  if (sizeof (unsigned int) !=
+      read_buffered (rb, &big, sizeof (unsigned int)))
+    return GNUNET_SYSERR;
+  *val = ntohl (big);
+  return GNUNET_OK;
+}
+
+#define READINT(a) if (GNUNET_OK != read_int(rb, (int*) &a)) return 
GNUNET_SYSERR;
+
+static int
+read_long (ReadBuffer * rb, long long *val)
+{
+  long long big;
+
+  if (sizeof (long long) != read_buffered (rb, &big, sizeof (long long)))
+    return GNUNET_SYSERR;
+  *val = GNUNET_ntohll (big);
+  return GNUNET_OK;
+}
+
+#define READLONG(a) if (GNUNET_OK != read_long(rb, (long long*) &a)) return 
GNUNET_SYSERR;
+
+static struct GNUNET_ECRS_URI *
+read_uri (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
+{
+  char *buf;
+  struct GNUNET_ECRS_URI *ret;
+  unsigned int size;
+
+  if (GNUNET_OK != read_uint (rb, &size))
+    return NULL;
+  buf = GNUNET_malloc (size + 1);
+  buf[size] = '\0';
+  if (size != read_buffered (rb, buf, size))
+    {
+      GNUNET_free (buf);
+      return NULL;
+    }
+  ret = GNUNET_ECRS_string_to_uri (ectx, buf);
+  GNUNET_GE_BREAK (ectx, ret != NULL);
+  GNUNET_free (buf);
+  return ret;
+}
+
+#define READURI(u) if (NULL == (u = read_uri(ectx, rb))) return GNUNET_SYSERR;
+
+static char *
+read_string (ReadBuffer * rb, unsigned int maxLen)
+{
+  char *buf;
+  unsigned int big;
+
+  if (GNUNET_OK != read_uint (rb, &big))
+    return NULL;
+  if (big > maxLen)
+    return NULL;
+  buf = GNUNET_malloc (big + 1);
+  buf[big] = '\0';
+  if (big != read_buffered (rb, buf, big))
+    {
+      GNUNET_free (buf);
+      return NULL;
+    }
+  return buf;
+}
+
+#define READSTRING(c, max) if (NULL == (c = read_string(rb, max))) return 
GNUNET_SYSERR;
+
+/**
+ * Read file info from file.
+ *
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+static struct GNUNET_MetaData *
+read_meta (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
+{
+  unsigned int size;
+  char *buf;
+  struct GNUNET_MetaData *meta;
+
+  if (read_uint (rb, &size) != GNUNET_OK)
+    {
+      GNUNET_GE_BREAK (ectx, 0);
+      return NULL;
+    }
+  if (size > 1024 * 1024)
+    {
+      GNUNET_GE_BREAK (ectx, 0);
+      return NULL;
+    }
+  buf = GNUNET_malloc (size);
+  if (size != read_buffered (rb, buf, size))
+    {
+      GNUNET_free (buf);
+      GNUNET_GE_BREAK (ectx, 0);
+      return NULL;
+    }
+  meta = GNUNET_meta_data_deserialize (ectx, buf, size);
+  if (meta == NULL)
+    {
+      GNUNET_free (buf);
+      GNUNET_GE_BREAK (ectx, 0);
+      return NULL;
+    }
+  GNUNET_free (buf);
+  return meta;
+}
+
+/* end of bio.c */

Modified: gnunet/src/util/container_bloomfilter.c
===================================================================
--- gnunet/src/util/container_bloomfilter.c     2009-08-23 22:11:49 UTC (rev 
8843)
+++ gnunet/src/util/container_bloomfilter.c     2009-08-24 09:26:47 UTC (rev 
8844)
@@ -157,7 +157,7 @@
   fileSlot = bitIdx / 2;
   targetLoc = bitIdx % 2;
 
-  GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, 
fileSlot, GNUNET_SEEK_SET));
+  GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, 
fileSlot, GNUNET_DISK_SEEK_SET));
   if (1 != GNUNET_DISK_file_read (fh, &value, 1))
     value = 0;
   low = value & 0xF;
@@ -174,7 +174,7 @@
         high++;
     }
   value = ((high << 4) | low);
-  GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, 
fileSlot, GNUNET_SEEK_SET));
+  GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, 
fileSlot, GNUNET_DISK_SEEK_SET));
   GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1));
 }
 
@@ -200,7 +200,7 @@
   /* Each char slot in the counter file holds two 4 bit counters */
   fileSlot = bitIdx / 2;
   targetLoc = bitIdx % 2;
-  GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET);
+  GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET);
   if (1 != GNUNET_DISK_file_read (fh, &value, 1))
     value = 0;
   low = value & 0xF;
@@ -226,7 +226,7 @@
         }
     }
   value = ((high << 4) | low);
-  GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET);
+  GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET);
   GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1));
 }
 
@@ -250,7 +250,7 @@
     return GNUNET_SYSERR;
   buffer = GNUNET_malloc (BUFFSIZE);
   memset (buffer, 0, BUFFSIZE);
-  GNUNET_DISK_file_seek (fh, 0, GNUNET_SEEK_SET);
+  GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET);
 
   while (bytesleft > 0)
     {

Modified: gnunet/src/util/disk.c
===================================================================
--- gnunet/src/util/disk.c      2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/src/util/disk.c      2009-08-24 09:26:47 UTC (rev 8844)
@@ -150,8 +150,8 @@
 
 #ifdef MINGW
   DWORD ret;
-  static DWORD t[] = { [GNUNET_SEEK_SET] = FILE_BEGIN,
-      [GNUNET_SEEK_CUR] = FILE_CURRENT, [GNUNET_SEEK_END] = FILE_END };
+  static DWORD t[] = { [GNUNET_DISK_SEEK_SET] = FILE_BEGIN,
+      [GNUNET_DISK_SEEK_CUR] = FILE_CURRENT, [GNUNET_DISK_SEEK_END] = FILE_END 
};
 
   ret = SetFilePointer (h->h, offset, NULL, t[whence]);
   if (ret == INVALID_SET_FILE_POINTER)
@@ -161,8 +161,8 @@
     }
   return ret;
 #else
-  static int t[] = { [GNUNET_SEEK_SET] = SEEK_SET,
-      [GNUNET_SEEK_CUR] = SEEK_CUR, [GNUNET_SEEK_END] = SEEK_END };
+  static int t[] = { [GNUNET_DISK_SEEK_SET] = SEEK_SET,
+      [GNUNET_DISK_SEEK_CUR] = SEEK_CUR, [GNUNET_DISK_SEEK_END] = SEEK_END };
 
   return lseek (h->fd, offset, t[whence]);
 #endif

Modified: gnunet/src/util/pseudonym.c
===================================================================
--- gnunet/src/util/pseudonym.c 2009-08-23 22:11:49 UTC (rev 8843)
+++ gnunet/src/util/pseudonym.c 2009-08-24 09:26:47 UTC (rev 8844)
@@ -391,7 +391,7 @@
       | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ
       | GNUNET_DISK_PERM_USER_WRITE);
   GNUNET_free (fn);
-  GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode), GNUNET_SEEK_SET);
+  GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode), 
GNUNET_DISK_SEEK_SET);
   if (sizeof (GNUNET_HashCode) != GNUNET_DISK_file_read (fh, nsid, sizeof 
(GNUNET_HashCode)))
     {
       GNUNET_DISK_file_close (fh);





reply via email to

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