LRN: fix gnuent_fs_Start arguments
[oweals/gnunet.git] / src / fs / fs_directory.c
index e037130c81ff53e8382fe68d1ecafaa5f2b14b38..f43fe14a713fb6b60db5c1351a7cabe63258e537 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      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
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 #include "gnunet_fs_service.h"
 #include "fs.h"
 
 #include "gnunet_fs_service.h"
 #include "fs.h"
 
-#ifndef EXTRACTOR_GNUNET_FULL_DATA
-#define EXTRACTOR_GNUNET_FULL_DATA 137
-#endif
-
 /**
  * String that is used to indicate that a file
  * is a GNUnet directory.
 /**
  * String that is used to indicate that a file
  * is a GNUnet directory.
  * @return GNUNET_YES if it is, GNUNET_NO if it is not, GNUNET_SYSERR if
  *  we have no mime-type information (treat as 'GNUNET_NO')
  */
  * @return GNUNET_YES if it is, GNUNET_NO if it is not, GNUNET_SYSERR if
  *  we have no mime-type information (treat as 'GNUNET_NO')
  */
-int 
-GNUNET_FS_meta_data_test_for_directory (const struct GNUNET_CONTAINER_MetaData *md)
+int
+GNUNET_FS_meta_data_test_for_directory (const struct GNUNET_CONTAINER_MetaData
+                                        *md)
 {
   char *mime;
   int ret;
 {
   char *mime;
   int ret;
-  
-  mime = GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_MIMETYPE);
+
+  if (NULL == md)
+    return GNUNET_SYSERR;
+  mime =
+      GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE);
   if (mime == NULL)
     return GNUNET_SYSERR;
   ret = (0 == strcmp (mime, GNUNET_FS_DIRECTORY_MIME)) ? GNUNET_YES : GNUNET_NO;
   GNUNET_free (mime);
   if (mime == NULL)
     return GNUNET_SYSERR;
   ret = (0 == strcmp (mime, GNUNET_FS_DIRECTORY_MIME)) ? GNUNET_YES : GNUNET_NO;
   GNUNET_free (mime);
-  return ret; 
+  return ret;
 }
 
 
 /**
  * Set the MIMETYPE information for the given
  * metadata to "application/gnunet-directory".
 }
 
 
 /**
  * Set the MIMETYPE information for the given
  * metadata to "application/gnunet-directory".
- * 
+ *
  * @param md metadata to add mimetype to
  */
 void
 GNUNET_FS_meta_data_make_directory (struct GNUNET_CONTAINER_MetaData *md)
 {
   char *mime;
  * @param md metadata to add mimetype to
  */
 void
 GNUNET_FS_meta_data_make_directory (struct GNUNET_CONTAINER_MetaData *md)
 {
   char *mime;
-  
-  mime = GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_MIMETYPE);
+
+  mime =
+      GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE);
   if (mime != NULL)
   if (mime != NULL)
+  {
+    GNUNET_break (0 == strcmp (mime, GNUNET_FS_DIRECTORY_MIME));
+    GNUNET_free (mime);
+    return;
+  }
+  GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>",
+                                     EXTRACTOR_METATYPE_MIMETYPE,
+                                     EXTRACTOR_METAFORMAT_UTF8, "text/plain",
+                                     GNUNET_FS_DIRECTORY_MIME,
+                                     strlen (GNUNET_FS_DIRECTORY_MIME) + 1);
+}
+
+
+/**
+ * Closure for 'find_full_data'.
+ */
+struct GetFullDataClosure
+{
+
+  /**
+   * Extracted binary meta data.
+   */
+  void *data;
+
+  /**
+   * Number of bytes stored in data.
+   */
+  size_t size;
+};
+
+
+/**
+ * Type of a function that libextractor calls for each
+ * meta data item found.
+ *
+ * @param cls closure (user-defined)
+ * @param plugin_name name of the plugin that produced this value;
+ *        special values can be used (i.e. '&lt;zlib&gt;' for zlib being
+ *        used in the main libextractor library and yielding
+ *        meta data).
+ * @param type libextractor-type describing the meta data
+ * @param format basic format information about data
+ * @param data_mime_type mime-type of data (not of the original file);
+ *        can be NULL (if mime-type is not known)
+ * @param data actual meta-data found
+ * @param data_len number of bytes in data
+ * @return 0 to continue extracting, 1 to abort
+ */
+static int
+find_full_data (void *cls, const char *plugin_name,
+                enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format,
+                const char *data_mime_type, const char *data, size_t data_len)
+{
+  struct GetFullDataClosure *gfdc = cls;
+
+  if (type == EXTRACTOR_METATYPE_GNUNET_FULL_DATA)
+  {
+    gfdc->size = data_len;
+    if (data_len > 0)
     {
     {
-      GNUNET_break (0 == strcmp (mime,
-                                GNUNET_FS_DIRECTORY_MIME));
-      GNUNET_free (mime);
-      return;
+      gfdc->data = GNUNET_malloc (data_len);
+      memcpy (gfdc->data, data, data_len);
     }
     }
-  GNUNET_CONTAINER_meta_data_insert (md, 
-                                    EXTRACTOR_MIMETYPE,
-                                    GNUNET_FS_DIRECTORY_MIME);
+    return 1;
+  }
+  return 0;
 }
 
 
 }
 
 
@@ -115,16 +173,18 @@ GNUNET_FS_meta_data_make_directory (struct GNUNET_CONTAINER_MetaData *md)
  * @param offset offset of data in the directory
  * @param dep function to call on each entry
  * @param dep_cls closure for dep
  * @param offset offset of data in the directory
  * @param dep function to call on each entry
  * @param dep_cls closure for dep
+ * @return GNUNET_OK if this could be a block in a directory,
+ *         GNUNET_NO if this could be part of a directory (but not 100% OK)
+ *         GNUNET_SYSERR if 'data' does not represent a directory
  */
  */
-void 
-GNUNET_FS_directory_list_contents (size_t size,
-                                  const void *data,
-                                  uint64_t offset,
-                                  GNUNET_FS_DirectoryEntryProcessor dep, 
-                                  void *dep_cls)
+int
+GNUNET_FS_directory_list_contents (size_t size, const void *data,
+                                   uint64_t offset,
+                                   GNUNET_FS_DirectoryEntryProcessor dep,
+                                   void *dep_cls)
 {
 {
+  struct GetFullDataClosure full_data;
   const char *cdata = data;
   const char *cdata = data;
-  char *file_data;
   char *emsg;
   uint64_t pos;
   uint64_t align;
   char *emsg;
   uint64_t pos;
   uint64_t align;
@@ -134,112 +194,111 @@ GNUNET_FS_directory_list_contents (size_t size,
   struct GNUNET_CONTAINER_MetaData *md;
   char *filename;
 
   struct GNUNET_CONTAINER_MetaData *md;
   char *filename;
 
+  if ((offset == 0) &&
+      ((size < 8 + sizeof (uint32_t)) ||
+       (0 != memcmp (cdata, GNUNET_FS_DIRECTORY_MAGIC, 8))))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("MAGIC mismatch.  This is not a GNUnet directory.\n"));
+    return GNUNET_SYSERR;
+  }
   pos = offset;
   pos = offset;
-  if ( (pos == 0) && 
-       (size >= 8 + sizeof (uint32_t)) &&
-       (0 == memcmp (cdata, GNUNET_FS_DIRECTORY_MAGIC, 8)) )
+  if (offset == 0)
+  {
+    memcpy (&mdSize, &cdata[8], sizeof (uint32_t));
+    mdSize = ntohl (mdSize);
+    if (mdSize > size - 8 - sizeof (uint32_t))
     {
     {
-      memcpy (&mdSize, &cdata[8], sizeof (uint32_t));
-      mdSize = ntohl (mdSize);
-      if (mdSize > size - 8 - sizeof (uint32_t))
-       {
-         /* invalid size */
-         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                     _("Not a GNUnet directory.\n"));
-         return;
-       }
-      md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 +
-                                                        sizeof (uint32_t)],
-                                                  mdSize);
-      if (md == NULL)
-        {
-          GNUNET_break (0);
-          return; /* malformed ! */
-        }
-      dep (dep_cls,
-          NULL,
-          NULL,                                
-          md,
-          0,
-          NULL);
-      GNUNET_CONTAINER_meta_data_destroy (md);
-      pos = 8 + sizeof (uint32_t) + mdSize;
+      /* invalid size */
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _("MAGIC mismatch.  This is not a GNUnet directory.\n"));
+      return GNUNET_SYSERR;
+    }
+    md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 + sizeof (uint32_t)],
+                                                 mdSize);
+    if (md == NULL)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;     /* malformed ! */
     }
     }
+    dep (dep_cls, NULL, NULL, md, 0, NULL);
+    GNUNET_CONTAINER_meta_data_destroy (md);
+    pos = 8 + sizeof (uint32_t) + mdSize;
+  }
   while (pos < size)
   while (pos < size)
+  {
+    /* find end of URI */
+    if (cdata[pos] == '\0')
     {
     {
-      /* find end of URI */
-      if (cdata[pos] == '\0')
-        {
-          /* URI is never empty, must be end of block,
-             skip to next alignment */
-          align =
-            ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE;
-          if (align == pos)
-            {
-              /* if we were already aligned, still skip a block! */
-              align += DBLOCK_SIZE;
-            }
-          pos = align;
-          if (pos >= size)
-            {
-              /* malformed - or partial download... */
-              break;
-            }
-        }
-      epos = pos;
-      while ((epos < size) && (cdata[epos] != '\0'))
-        epos++;
-      if (epos >= size)
-        return;   /* malformed - or partial download */
-      
-      uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg);
-      pos = epos + 1;
-      if (uri == NULL)
-        {
-         GNUNET_free (emsg);
-          pos--;                /* go back to '\0' to force going to next alignment */
-          continue;
-        }
-      if (GNUNET_FS_uri_test_ksk (uri))
-        {
-          GNUNET_FS_uri_destroy (uri);
-          GNUNET_break (0);
-          return; /* illegal in directory! */
-        }
+      /* URI is never empty, must be end of block,
+       * skip to next alignment */
+      align = ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE;
+      if (align == pos)
+      {
+        /* if we were already aligned, still skip a block! */
+        align += DBLOCK_SIZE;
+      }
+      pos = align;
+      if (pos >= size)
+      {
+        /* malformed - or partial download... */
+        break;
+      }
+    }
+    epos = pos;
+    while ((epos < size) && (cdata[epos] != '\0'))
+      epos++;
+    if (epos >= size)
+      return GNUNET_NO;         /* malformed - or partial download */
+
+    uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg);
+    pos = epos + 1;
+    if (uri == NULL)
+    {
+      GNUNET_free (emsg);
+      pos--;                    /* go back to '\0' to force going to next alignment */
+      continue;
+    }
+    if (GNUNET_FS_uri_test_ksk (uri))
+    {
+      GNUNET_FS_uri_destroy (uri);
+      GNUNET_break (0);
+      return GNUNET_NO;         /* illegal in directory! */
+    }
 
 
-      memcpy (&mdSize, &cdata[pos], sizeof (uint32_t));
-      mdSize = ntohl (mdSize);
-      pos += sizeof (uint32_t);
-      if (pos + mdSize > size)
-        {
-          GNUNET_FS_uri_destroy (uri);
-          return; /* malformed - or partial download */
-        }
+    memcpy (&mdSize, &cdata[pos], sizeof (uint32_t));
+    mdSize = ntohl (mdSize);
+    pos += sizeof (uint32_t);
+    if (pos + mdSize > size)
+    {
+      GNUNET_FS_uri_destroy (uri);
+      return GNUNET_NO;         /* malformed - or partial download */
+    }
 
 
-      md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], mdSize);
-      if (md == NULL)
-        {
-          GNUNET_FS_uri_destroy (uri);
-          GNUNET_break (0);
-          return; /* malformed ! */
-        }
-      pos += mdSize;
-      filename = GNUNET_CONTAINER_meta_data_get_by_type (md,
-                                                        EXTRACTOR_FILENAME);
-      file_data = GNUNET_CONTAINER_meta_data_get_by_type (md,
-                                                         EXTRACTOR_GNUNET_FULL_DATA);
-      if (dep != NULL) 
-         dep (dep_cls,
-             filename,
-             uri,
-             md,
-             (file_data != NULL) ? strlen(file_data) : 0,
-             file_data);
-      GNUNET_free_non_null (file_data);
-      GNUNET_free_non_null (filename);
-      GNUNET_CONTAINER_meta_data_destroy (md);
+    md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], mdSize);
+    if (md == NULL)
+    {
       GNUNET_FS_uri_destroy (uri);
       GNUNET_FS_uri_destroy (uri);
+      GNUNET_break (0);
+      return GNUNET_NO;         /* malformed ! */
     }
     }
+    pos += mdSize;
+    filename =
+        GNUNET_CONTAINER_meta_data_get_by_type (md,
+                                                EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME);
+    full_data.size = 0;
+    full_data.data = NULL;
+    GNUNET_CONTAINER_meta_data_iterate (md, &find_full_data, &full_data);
+    if (dep != NULL)
+    {
+      dep (dep_cls, filename, uri, md, full_data.size, full_data.data);
+    }
+    GNUNET_free_non_null (full_data.data);
+    GNUNET_free_non_null (filename);
+    GNUNET_CONTAINER_meta_data_destroy (md);
+    GNUNET_FS_uri_destroy (uri);
+  }
+  return GNUNET_OK;
 }
 
 /**
 }
 
 /**
@@ -251,7 +310,7 @@ struct BuilderEntry
    * This is a linked list.
    */
   struct BuilderEntry *next;
    * This is a linked list.
    */
   struct BuilderEntry *next;
-  
+
   /**
    * Length of this entry.
    */
   /**
    * Length of this entry.
    */
@@ -282,16 +341,20 @@ struct GNUNET_FS_DirectoryBuilder
 
 /**
  * Create a directory builder.
 
 /**
  * Create a directory builder.
- * 
+ *
  * @param mdir metadata for the directory
  */
 struct GNUNET_FS_DirectoryBuilder *
  * @param mdir metadata for the directory
  */
 struct GNUNET_FS_DirectoryBuilder *
-GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir)
+GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData
+                                    *mdir)
 {
   struct GNUNET_FS_DirectoryBuilder *ret;
 
 {
   struct GNUNET_FS_DirectoryBuilder *ret;
 
-  ret = GNUNET_malloc(sizeof(struct GNUNET_FS_DirectoryBuilder));
-  ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir);
+  ret = GNUNET_malloc (sizeof (struct GNUNET_FS_DirectoryBuilder));
+  if (mdir != NULL)
+    ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir);
+  else
+    ret->meta = GNUNET_CONTAINER_meta_data_create ();
   GNUNET_FS_meta_data_make_directory (ret->meta);
   return ret;
 }
   GNUNET_FS_meta_data_make_directory (ret->meta);
   return ret;
 }
@@ -299,7 +362,7 @@ GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir
 
 /**
  * Add an entry to a directory.
 
 /**
  * Add an entry to a directory.
- * 
+ *
  * @param bld directory to extend
  * @param uri uri of the entry (must not be a KSK)
  * @param md metadata of the entry
  * @param bld directory to extend
  * @param uri uri of the entry (must not be a KSK)
  * @param md metadata of the entry
@@ -309,9 +372,9 @@ GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir
  */
 void
 GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
  */
 void
 GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
-                                const struct GNUNET_FS_Uri *uri,
-                                const struct GNUNET_CONTAINER_MetaData *md,
-                                const void *data)
+                                 const struct GNUNET_FS_Uri *uri,
+                                 const struct GNUNET_CONTAINER_MetaData *md,
+                                 const void *data)
 {
   struct GNUNET_FS_Uri *curi;
   struct BuilderEntry *e;
 {
   struct GNUNET_FS_Uri *curi;
   struct BuilderEntry *e;
@@ -322,64 +385,67 @@ GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
   size_t mdxs;
   char *uris;
   char *ser;
   size_t mdxs;
   char *uris;
   char *ser;
+  char *sptr;
   size_t slen;
   struct GNUNET_CONTAINER_MetaData *meta;
   const struct GNUNET_CONTAINER_MetaData *meta_use;
 
   size_t slen;
   struct GNUNET_CONTAINER_MetaData *meta;
   const struct GNUNET_CONTAINER_MetaData *meta_use;
 
-  GNUNET_assert (! GNUNET_FS_uri_test_ksk (uri));
+  GNUNET_assert (!GNUNET_FS_uri_test_ksk (uri));
   if (NULL != data)
   if (NULL != data)
+  {
+    GNUNET_assert (!GNUNET_FS_uri_test_sks (uri));
     if (GNUNET_FS_uri_test_chk (uri))
     if (GNUNET_FS_uri_test_chk (uri))
+    {
       fsize = GNUNET_FS_uri_chk_get_file_size (uri);
       fsize = GNUNET_FS_uri_chk_get_file_size (uri);
+    }
     else
     else
-      {
-       curi = GNUNET_FS_uri_loc_get_uri (uri);
-       fsize = GNUNET_FS_uri_chk_get_file_size (curi);
-       GNUNET_FS_uri_destroy (curi);
-      }
+    {
+      curi = GNUNET_FS_uri_loc_get_uri (uri);
+      GNUNET_assert (NULL != curi);
+      fsize = GNUNET_FS_uri_chk_get_file_size (curi);
+      GNUNET_FS_uri_destroy (curi);
+    }
+  }
   else
   else
-    fsize = 0; /* not given */
+  {
+    fsize = 0;                  /* not given */
+  }
   if (fsize > MAX_INLINE_SIZE)
   if (fsize > MAX_INLINE_SIZE)
-    fsize = 0; /* too large */
-  if ( (NULL == data) ||
-       (NULL != memchr (data, 0, fsize)) )
-    fsize = 0; /* must not have 0's in data! */
+    fsize = 0;                  /* too large */
   uris = GNUNET_FS_uri_to_string (uri);
   slen = strlen (uris) + 1;
   uris = GNUNET_FS_uri_to_string (uri);
   slen = strlen (uris) + 1;
-  mds =
-    GNUNET_CONTAINER_meta_data_get_serialized_size (md,
-                                                   GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);  
+  mds = GNUNET_CONTAINER_meta_data_get_serialized_size (md);
   meta_use = md;
   meta = NULL;
   if (fsize > 0)
   meta_use = md;
   meta = NULL;
   if (fsize > 0)
+  {
+    meta = GNUNET_CONTAINER_meta_data_duplicate (md);
+    GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>",
+                                       EXTRACTOR_METATYPE_GNUNET_FULL_DATA,
+                                       EXTRACTOR_METAFORMAT_BINARY, NULL, data,
+                                       fsize);
+    mdxs = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
+    if ((slen + sizeof (uint32_t) + mdxs - 1) / DBLOCK_SIZE ==
+        (slen + sizeof (uint32_t) + mds - 1) / DBLOCK_SIZE)
     {
     {
-      meta = GNUNET_CONTAINER_meta_data_duplicate (md);
-      GNUNET_CONTAINER_meta_data_insert (meta,
-                                        EXTRACTOR_GNUNET_FULL_DATA,
-                                        data);
-      mdxs =
-       GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
-                                                       GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);  
-      if ( (slen + sizeof (uint32_t) + mdxs - 1) / DBLOCK_SIZE ==
-          (slen + sizeof (uint32_t) + mds - 1) / DBLOCK_SIZE)
-       {
-         /* adding full data would not cause us to cross
-            additional blocks, so add it! */
-         meta_use = meta;
-         mds = mdxs;
-       }
+      /* adding full data would not cause us to cross
+       * additional blocks, so add it! */
+      meta_use = meta;
+      mds = mdxs;
     }
     }
+  }
 
   if (mds > GNUNET_MAX_MALLOC_CHECKED / 2)
     mds = GNUNET_MAX_MALLOC_CHECKED / 2;
 
   if (mds > GNUNET_MAX_MALLOC_CHECKED / 2)
     mds = GNUNET_MAX_MALLOC_CHECKED / 2;
-  e = GNUNET_malloc (sizeof(struct BuilderEntry) + 
-                    slen + mds + sizeof (uint32_t));
-  ser = (char*) &e[1];
+  e = GNUNET_malloc (sizeof (struct BuilderEntry) + slen + mds +
+                     sizeof (uint32_t));
+  ser = (char *) &e[1];
   memcpy (ser, uris, slen);
   GNUNET_free (uris);
   memcpy (ser, uris, slen);
   GNUNET_free (uris);
-  ret = GNUNET_CONTAINER_meta_data_serialize (meta_use,
-                                             &ser[slen + sizeof(uint32_t)],
-                                             mds,
-                                             GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
+  sptr = &ser[slen + sizeof (uint32_t)];
+  ret =
+      GNUNET_CONTAINER_meta_data_serialize (meta_use, &sptr, mds,
+                                            GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
   if (NULL != meta)
     GNUNET_CONTAINER_meta_data_destroy (meta);
   if (ret == -1)
   if (NULL != meta)
     GNUNET_CONTAINER_meta_data_destroy (meta);
   if (ret == -1)
@@ -401,11 +467,10 @@ GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
  * after alignment to the DBLOCK_SIZE.
  */
 static size_t
  * after alignment to the DBLOCK_SIZE.
  */
 static size_t
-do_align (size_t start_position, 
-         size_t end_position)
+do_align (size_t start_position, size_t end_position)
 {
   size_t align;
 {
   size_t align;
-  
+
   align = (end_position / DBLOCK_SIZE) * DBLOCK_SIZE;
   if ((start_position < align) && (end_position > align))
     return align + end_position - start_position;
   align = (end_position / DBLOCK_SIZE) * DBLOCK_SIZE;
   if ((start_position < align) && (end_position > align))
     return align + end_position - start_position;
@@ -423,10 +488,8 @@ do_align (size_t start_position,
  * @param perm the permutation of the blocks (updated)
  */
 static void
  * @param perm the permutation of the blocks (updated)
  */
 static void
-block_align (size_t start,
-             unsigned int count, 
-            const size_t *sizes,
-            unsigned int *perm)
+block_align (size_t start, unsigned int count, const size_t * sizes,
+             unsigned int *perm)
 {
   unsigned int i;
   unsigned int j;
 {
   unsigned int i;
   unsigned int j;
@@ -440,50 +503,46 @@ block_align (size_t start,
 
   cpos = start;
   for (i = 0; i < count; i++)
 
   cpos = start;
   for (i = 0; i < count; i++)
+  {
+    start = cpos;
+    badness = 0x7FFFFFFF;
+    best = -1;
+    for (j = i; j < count; j++)
     {
     {
-      start = cpos;
-      badness = 0x7FFFFFFF;
-      best = -1;
-      for (j = i; j < count; j++)
+      cval = perm[j];
+      cend = cpos + sizes[cval];
+      if (cpos % DBLOCK_SIZE == 0)
+      {
+        /* prefer placing the largest blocks first */
+        cbad = -(cend % DBLOCK_SIZE);
+      }
+      else
+      {
+        if (cpos / DBLOCK_SIZE == cend / DBLOCK_SIZE)
+        {
+          /* Data fits into the same block! Prefer small left-overs! */
+          cbad = DBLOCK_SIZE - cend % DBLOCK_SIZE;
+        }
+        else
         {
         {
-          cval = perm[j];
-          cend = cpos + sizes[cval];
-          if (cpos % DBLOCK_SIZE == 0)
-            {
-              /* prefer placing the largest blocks first */
-              cbad = -(cend % DBLOCK_SIZE);
-            }
-          else
-            {
-              if (cpos / DBLOCK_SIZE ==
-                  cend / DBLOCK_SIZE)
-                {
-                  /* Data fits into the same block! Prefer small left-overs! */
-                  cbad =
-                    DBLOCK_SIZE - cend % DBLOCK_SIZE;
-                }
-              else
-                {
-                  /* Would have to waste space to re-align, add big factor, this
-                     case is a real loss (proportional to space wasted)! */
-                  cbad =
-                    DBLOCK_SIZE * (DBLOCK_SIZE -
-                                            cpos %
-                                            DBLOCK_SIZE);
-                }
-            }
-          if (cbad < badness)
-            {
-              best = j;
-              badness = cbad;
-            }
+          /* Would have to waste space to re-align, add big factor, this
+           * case is a real loss (proportional to space wasted)! */
+          cbad = DBLOCK_SIZE * (DBLOCK_SIZE - cpos % DBLOCK_SIZE);
         }
         }
-      tmp = perm[i];
-      perm[i] = perm[best];
-      perm[best] = tmp;
-      cpos += sizes[perm[i]];
-      cpos = do_align (start, cpos);
+      }
+      if (cbad < badness)
+      {
+        best = j;
+        badness = cbad;
+      }
     }
     }
+    GNUNET_assert (best != -1);
+    tmp = perm[i];
+    perm[i] = perm[best];
+    perm[best] = tmp;
+    cpos += sizes[perm[i]];
+    cpos = do_align (start, cpos);
+  }
 }
 
 
 }
 
 
@@ -499,10 +558,10 @@ block_align (size_t start,
  */
 int
 GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld,
  */
 int
 GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld,
-                                   size_t *rsize,
-                                   void **rdata)
+                                    size_t * rsize, void **rdata)
 {
   char *data;
 {
   char *data;
+  char *sptr;
   size_t *sizes;
   unsigned int *perm;
   unsigned int i;
   size_t *sizes;
   unsigned int *perm;
   unsigned int i;
@@ -515,75 +574,71 @@ GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld,
   ssize_t ret;
   uint32_t big;
 
   ssize_t ret;
   uint32_t big;
 
-  size = 8 + sizeof (uint32_t);
-  size += GNUNET_CONTAINER_meta_data_get_serialized_size (bld->meta, 
-                                                         GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
+  size = strlen (GNUNET_DIRECTORY_MAGIC) + sizeof (uint32_t);
+  size += GNUNET_CONTAINER_meta_data_get_serialized_size (bld->meta);
   sizes = NULL;
   perm = NULL;
   bes = NULL;
   if (0 < bld->count)
   sizes = NULL;
   perm = NULL;
   bes = NULL;
   if (0 < bld->count)
+  {
+    sizes = GNUNET_malloc (bld->count * sizeof (size_t));
+    perm = GNUNET_malloc (bld->count * sizeof (unsigned int));
+    bes = GNUNET_malloc (bld->count * sizeof (struct BuilderEntry *));
+    pos = bld->head;
+    for (i = 0; i < bld->count; i++)
     {
     {
-      sizes = GNUNET_malloc (bld->count * sizeof (size_t));
-      perm = GNUNET_malloc (bld->count * sizeof (unsigned int));
-      bes = GNUNET_malloc (bld->count * sizeof (struct BuilderEntry *));
-      pos = bld->head;
-      for (i = 0; i < bld->count; i++)
-       {
-         perm[i] = i;
-         bes[i] = pos;
-         sizes[i] = pos->len;
-         pos = pos->next;
-       }
-      block_align (size,
-                  bld->count,
-                  sizes,
-                  perm);
-      /* compute final size with alignment */
-      for (i = 0; i < bld->count; i++)
-       {
-         psize = size;
-         size += sizes[perm[i]];
-         size = do_align (psize, size);
-       }
+      perm[i] = i;
+      bes[i] = pos;
+      sizes[i] = pos->len;
+      pos = pos->next;
     }
     }
+    block_align (size, bld->count, sizes, perm);
+    /* compute final size with alignment */
+    for (i = 0; i < bld->count; i++)
+    {
+      psize = size;
+      size += sizes[perm[i]];
+      size = do_align (psize, size);
+    }
+  }
   *rsize = size;
   data = GNUNET_malloc_large (size);
   if (data == NULL)
   *rsize = size;
   data = GNUNET_malloc_large (size);
   if (data == NULL)
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                          "malloc");
-      *rsize = 0;
-      *rdata = NULL;
-      return GNUNET_SYSERR;
-    }
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc");
+    *rsize = 0;
+    *rdata = NULL;
+    GNUNET_free_non_null (sizes);
+    GNUNET_free_non_null (perm);
+    GNUNET_free_non_null (bes);
+    return GNUNET_SYSERR;
+  }
   *rdata = data;
   *rdata = data;
-  memcpy (data, GNUNET_DIRECTORY_MAGIC, 8);
-  off = 8;
-
-  ret = GNUNET_CONTAINER_meta_data_serialize (bld->meta,
-                                             &data[off +
-                                                   sizeof (uint32_t)],
-                                             size - off - sizeof (uint32_t),
-                                             GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
+  memcpy (data, GNUNET_DIRECTORY_MAGIC, strlen (GNUNET_DIRECTORY_MAGIC));
+  off = strlen (GNUNET_DIRECTORY_MAGIC);
+
+  sptr = &data[off + sizeof (uint32_t)];
+  ret =
+      GNUNET_CONTAINER_meta_data_serialize (bld->meta, &sptr,
+                                            size - off - sizeof (uint32_t),
+                                            GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
   GNUNET_assert (ret != -1);
   GNUNET_assert (ret != -1);
-  big = htonl (ret);  
-  memcpy (&data[8], &big, sizeof (uint32_t));
+  big = htonl (ret);
+  memcpy (&data[off], &big, sizeof (uint32_t));
   off += sizeof (uint32_t) + ret;
   for (j = 0; j < bld->count; j++)
   off += sizeof (uint32_t) + ret;
   for (j = 0; j < bld->count; j++)
-    {
-      i = perm[j];
-      psize = off;
-      off += sizes[i];
-      off = do_align (psize, off);
-      memcpy (&data[off - sizes[i]], 
-             &(bes[i])[1],
-             sizes[i]);
-      GNUNET_free (bes[i]);
-    }
+  {
+    i = perm[j];
+    psize = off;
+    off += sizes[i];
+    off = do_align (psize, off);
+    memcpy (&data[off - sizes[i]], &(bes[i])[1], sizes[i]);
+    GNUNET_free (bes[i]);
+  }
   GNUNET_free_non_null (sizes);
   GNUNET_free_non_null (perm);
   GNUNET_free_non_null (bes);
   GNUNET_free_non_null (sizes);
   GNUNET_free_non_null (perm);
   GNUNET_free_non_null (bes);
-  GNUNET_assert (off == size);  
+  GNUNET_assert (off == size);
   GNUNET_CONTAINER_meta_data_destroy (bld->meta);
   GNUNET_free (bld);
   return GNUNET_OK;
   GNUNET_CONTAINER_meta_data_destroy (bld->meta);
   GNUNET_free (bld);
   return GNUNET_OK;