fix
[oweals/gnunet.git] / src / fs / fs_file_information.c
index 8a5360db1af587b25391862f88a66b6b6445d3d4..d9acc959563b1a8f6c2916a0f440a7cd1ad9defa 100644 (file)
 #include "fs_tree.h"
 
 
-/**
- * Create a temporary file on disk to store the current
- * state of "fi" in.
- *
- * @param fi file information to sync with disk
- */
-void
-GNUNET_FS_file_information_sync (struct GNUNET_FS_FileInformation * fi)
-{
-  if (NULL == fi->serialization)
-    {
-      fi->serialization = NULL; // FIXME -- need cfg!
-    }
-  // FIXME...
-}
-
-
-/**
- * Load file information from the file to which
- * it was sync'ed.
- *
- * @param fn name of the file to use
- * @return NULL on error
- */
-struct GNUNET_FS_FileInformation *
-GNUNET_FS_file_information_recover (const char *fn)
-{
-  struct GNUNET_FS_FileInformation *ret;
-  ret = NULL;
-  // FIXME!
-  return ret;
-}
-
-
 /**
  * Obtain the name under which this file information
  * structure is stored on disk.  Only works for top-level
@@ -88,95 +54,10 @@ GNUNET_FS_file_information_get_id (struct GNUNET_FS_FileInformation *s)
 }
 
 
-/**
- * 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,
-                                     GNUNET_DISK_PERM_NONE);
-      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 h handle to the file sharing subsystem
  * @param client_info initial value for the client-info value for this entry
  * @param filename name of the file or directory to publish
  * @param keywords under which keywords should this file be available
@@ -192,7 +73,8 @@ data_reader_file(void *cls,
  * @return publish structure entry for the file
  */
 struct GNUNET_FS_FileInformation *
-GNUNET_FS_file_information_create_from_file (void *client_info,
+GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h,
+                                            void *client_info,
                                             const char *filename,
                                             const struct GNUNET_FS_Uri *keywords,
                                             const struct GNUNET_CONTAINER_MetaData *meta,
@@ -214,16 +96,16 @@ GNUNET_FS_file_information_create_from_file (void *client_info,
                                filename);
       return NULL;
     }
-  fi = GNUNET_malloc (sizeof(struct FileInfo));
-  fi->filename = GNUNET_STRINGS_filename_expand (filename);
-  if (fi->filename == NULL)
+  fi = GNUNET_FS_make_file_reader_context_ (filename);
+  if (fi == NULL)
     {
-      GNUNET_free (fi);
+      GNUNET_break (0);
       return NULL;
     }
-  ret = GNUNET_FS_file_information_create_from_reader (client_info,
+  ret = GNUNET_FS_file_information_create_from_reader (h,
+                                                      client_info,
                                                       sbuf.st_size,
-                                                      &data_reader_file,
+                                                      &GNUNET_FS_data_reader_file_,
                                                       fi,
                                                       keywords,
                                                       meta,
@@ -231,6 +113,7 @@ GNUNET_FS_file_information_create_from_file (void *client_info,
                                                       anonymity,
                                                       priority,
                                                       expirationTime);
+  ret->h = h;
   ret->filename = GNUNET_strdup (filename);
   fn = filename;
   while (NULL != (ss = strstr (fn,
@@ -247,44 +130,10 @@ GNUNET_FS_file_information_create_from_file (void *client_info,
 }
 
 
-/**
- * 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 h handle to the file sharing subsystem
  * @param client_info initial value for the client-info value for this entry
  * @param length length of the file
  * @param data data for the file (should not be used afterwards by
@@ -302,7 +151,8 @@ data_reader_copy(void *cls,
  * @return publish structure entry for the file
  */
 struct GNUNET_FS_FileInformation *
-GNUNET_FS_file_information_create_from_data (void *client_info,
+GNUNET_FS_file_information_create_from_data (struct GNUNET_FS_Handle *h,
+                                            void *client_info,
                                             uint64_t length,
                                             void *data,
                                             const struct GNUNET_FS_Uri *keywords,
@@ -312,9 +162,15 @@ GNUNET_FS_file_information_create_from_data (void *client_info,
                                             uint32_t priority,
                                             struct GNUNET_TIME_Absolute expirationTime)
 {
-  return GNUNET_FS_file_information_create_from_reader (client_info,
+  if (GNUNET_YES == do_index)        
+    {
+      GNUNET_break (0);
+      return NULL;
+    }
+  return GNUNET_FS_file_information_create_from_reader (h,
+                                                       client_info,
                                                        length,
-                                                       &data_reader_copy,
+                                                       &GNUNET_FS_data_reader_copy_,
                                                        data,
                                                        keywords,
                                                        meta,
@@ -328,6 +184,7 @@ GNUNET_FS_file_information_create_from_data (void *client_info,
 /**
  * Create an entry for a file in a publish-structure.
  *
+ * @param h handle to the file sharing subsystem
  * @param client_info initial value for the client-info value for this entry
  * @param length length of the file
  * @param reader function that can be used to obtain the data for the file 
@@ -345,7 +202,8 @@ GNUNET_FS_file_information_create_from_data (void *client_info,
  * @return publish structure entry for the file
  */
 struct GNUNET_FS_FileInformation *
-GNUNET_FS_file_information_create_from_reader (void *client_info,
+GNUNET_FS_file_information_create_from_reader (struct GNUNET_FS_Handle *h,
+                                              void *client_info,
                                               uint64_t length,
                                               GNUNET_FS_DataReader reader,
                                               void *reader_cls,
@@ -358,7 +216,14 @@ GNUNET_FS_file_information_create_from_reader (void *client_info,
 {
   struct GNUNET_FS_FileInformation *ret;
 
+  if ( (GNUNET_YES == do_index) &&
+       (reader != &GNUNET_FS_data_reader_file_) )
+    {
+      GNUNET_break (0);
+      return NULL;
+    }
   ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
+  ret->h = h;
   ret->client_info = client_info;  
   ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
   if (ret->meta == NULL)
@@ -371,7 +236,6 @@ GNUNET_FS_file_information_create_from_reader (void *client_info,
   ret->data.file.file_size = length;
   ret->anonymity = anonymity;
   ret->priority = priority;
-  GNUNET_FS_file_information_sync (ret);
   return ret;
 }
 
@@ -386,6 +250,11 @@ struct DirScanCls
    */
   struct EXTRACTOR_PluginList *extractors;
 
+  /**
+   * Master context.
+   */ 
+  struct GNUNET_FS_Handle *h;
+
   /**
    * Function to call on each directory entry.
    */
@@ -462,7 +331,8 @@ dir_scan_cb (void *cls,
     }
   if (S_ISDIR (sbuf.st_mode))
     {
-      fi = GNUNET_FS_file_information_create_from_directory (NULL,
+      fi = GNUNET_FS_file_information_create_from_directory (dsc->h,
+                                                            NULL,
                                                             filename,
                                                             dsc->scanner,
                                                             dsc->scanner_cls,
@@ -486,7 +356,8 @@ dir_scan_cb (void *cls,
       // 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,
+      fi = GNUNET_FS_file_information_create_from_file (dsc->h,
+                                                       NULL,
                                                        filename,
                                                        ksk_uri,
                                                        meta,
@@ -517,6 +388,7 @@ dir_scan_cb (void *cls,
  * convenience function.
  *
  * @param cls must be of type "struct EXTRACTOR_Extractor*"
+ * @param h handle to the file sharing subsystem
  * @param dirname name of the directory to scan
  * @param do_index should files be indexed or inserted
  * @param anonymity desired anonymity level
@@ -529,6 +401,7 @@ dir_scan_cb (void *cls,
  */
 int
 GNUNET_FS_directory_scanner_default (void *cls,
+                                    struct GNUNET_FS_Handle *h,
                                     const char *dirname,
                                     int do_index,
                                     uint32_t anonymity,
@@ -541,6 +414,7 @@ GNUNET_FS_directory_scanner_default (void *cls,
   struct EXTRACTOR_PluginList *ex = cls;
   struct DirScanCls dsc;
 
+  dsc.h = h;
   dsc.extractors = ex;
   dsc.proc = proc;
   dsc.proc_cls = proc_cls;
@@ -607,6 +481,7 @@ dirproc (void *cls,
  * passed (GNUNET_FS_directory_scanner_default).  This is strictly a
  * convenience function.
  *
+ * @param h handle to the file sharing subsystem
  * @param client_info initial value for the client-info value for this entry
  * @param filename name of the top-level file or directory
  * @param scanner function used to get a list of files in a directory
@@ -621,7 +496,8 @@ dirproc (void *cls,
  * @return publish structure entry for the directory, NULL on error
  */
 struct GNUNET_FS_FileInformation *
-GNUNET_FS_file_information_create_from_directory (void *client_info,
+GNUNET_FS_file_information_create_from_directory (struct GNUNET_FS_Handle *h,
+                                                 void *client_info,
                                                  const char *filename,
                                                  GNUNET_FS_DirectoryScanner scanner,
                                                  void *scanner_cls,
@@ -642,6 +518,7 @@ GNUNET_FS_file_information_create_from_directory (void *client_info,
   meta = GNUNET_CONTAINER_meta_data_create ();
   GNUNET_FS_meta_data_make_directory (meta);
   scanner (scanner_cls,
+          h,
           filename,
           do_index,
           anonymity,
@@ -652,7 +529,8 @@ GNUNET_FS_file_information_create_from_directory (void *client_info,
           emsg);
   ksk = NULL; // FIXME...
   // FIXME: create meta!
-  ret = GNUNET_FS_file_information_create_empty_directory (client_info,
+  ret = GNUNET_FS_file_information_create_empty_directory (h,
+                                                          client_info,
                                                           ksk,
                                                           meta,
                                                           anonymity,
@@ -663,7 +541,6 @@ GNUNET_FS_file_information_create_from_directory (void *client_info,
   while (dc.entries != NULL)
     {
       dc.entries->dir = ret;
-      GNUNET_FS_file_information_sync (dc.entries);
       dc.entries = dc.entries->next;
     }
   fn = filename;
@@ -678,7 +555,6 @@ GNUNET_FS_file_information_create_from_directory (void *client_info,
                                     fn,
                                     strlen (fn) + 1);
   ret->filename = GNUNET_strdup (filename);
-  GNUNET_FS_file_information_sync (ret);
   return ret;
 }
 
@@ -689,6 +565,7 @@ GNUNET_FS_file_information_create_from_directory (void *client_info,
  * use of "GNUNET_FS_file_information_create_from_directory"
  * is not appropriate.
  *
+ * @param h handle to the file sharing subsystem
  * @param client_info initial value for the client-info value for this entry
  * @param meta metadata for the directory
  * @param keywords under which keywords should this directory be available
@@ -701,7 +578,8 @@ GNUNET_FS_file_information_create_from_directory (void *client_info,
  * @return publish structure entry for the directory , NULL on error
  */
 struct GNUNET_FS_FileInformation *
-GNUNET_FS_file_information_create_empty_directory (void *client_info,
+GNUNET_FS_file_information_create_empty_directory (struct GNUNET_FS_Handle *h,
+                                                  void *client_info,
                                                   const struct GNUNET_FS_Uri *keywords,
                                                   const struct GNUNET_CONTAINER_MetaData *meta,
                                                   uint32_t anonymity,
@@ -711,6 +589,7 @@ GNUNET_FS_file_information_create_empty_directory (void *client_info,
   struct GNUNET_FS_FileInformation *ret;
 
   ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
+  ret->h = h;
   ret->client_info = client_info;
   ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
   ret->keywords = GNUNET_FS_uri_dup (keywords);
@@ -718,7 +597,6 @@ GNUNET_FS_file_information_create_empty_directory (void *client_info,
   ret->is_directory = GNUNET_YES;
   ret->anonymity = anonymity;
   ret->priority = priority;
-  GNUNET_FS_file_information_sync (ret);
   return ret;
 }
 
@@ -749,8 +627,6 @@ GNUNET_FS_file_information_add (struct GNUNET_FS_FileInformation *dir,
   ent->next = dir->data.dir.entries;
   dir->data.dir.entries = ent;
   dir->data.dir.dir_size = 0;
-  GNUNET_FS_file_information_sync (ent);
-  GNUNET_FS_file_information_sync (dir);
   return GNUNET_OK;
 }
 
@@ -849,7 +725,9 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi,
   else
     {
       /* call clean-up function of the reader */
-      fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL);
+      if (fi->data.file.reader != NULL)
+       fi->data.file.reader (fi->data.file.reader_cls, 0, 0, 
+                             NULL, NULL);
       /* clean up client-info */
       if (NULL != cleaner)
        cleaner (cleaner_cls, 
@@ -863,7 +741,6 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi,
                 &fi->client_info);
     }
   GNUNET_free_non_null (fi->filename);
-  GNUNET_free_non_null (fi->serialization);
   GNUNET_free_non_null (fi->emsg);
   GNUNET_free_non_null (fi->chk_uri);
   /* clean up serialization */
@@ -874,7 +751,8 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi,
                              fi->serialization);
   if (NULL != fi->keywords)
     GNUNET_FS_uri_destroy (fi->keywords);
-  GNUNET_CONTAINER_meta_data_destroy (fi->meta);
+  if (NULL != fi->meta)
+    GNUNET_CONTAINER_meta_data_destroy (fi->meta);
   GNUNET_free_non_null (fi->serialization);
   if (fi->te != NULL)
     {