gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r11136 - gnunet/src/fs


From: gnunet
Subject: [GNUnet-SVN] r11136 - gnunet/src/fs
Date: Fri, 30 Apr 2010 15:16:03 +0200

Author: grothoff
Date: 2010-04-30 15:16:03 +0200 (Fri, 30 Apr 2010)
New Revision: 11136

Modified:
   gnunet/src/fs/fs.c
   gnunet/src/fs/fs.h
   gnunet/src/fs/fs_file_information.c
Log:
finishing initial coding of fs-publish serialization/deserialization

Modified: gnunet/src/fs/fs.c
===================================================================
--- gnunet/src/fs/fs.c  2010-04-30 13:11:34 UTC (rev 11135)
+++ gnunet/src/fs/fs.c  2010-04-30 13:16:03 UTC (rev 11136)
@@ -20,7 +20,7 @@
 
 /**
  * @file fs/fs.c
- * @brief main FS functions
+ * @brief main FS functions (master initialization, serialization, 
deserialization, shared code)
  * @author Christian Grothoff
  */
 
@@ -214,7 +214,117 @@
 }
 
 
+
+
 /**
+ * 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
+ */
+size_t
+GNUNET_FS_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 the closure for the 'GNUNET_FS_data_reader_file_' callback.
+ *
+ * @param filename file to read
+ * @return closure to use, NULL on error
+ */
+void *
+GNUNET_FS_make_file_reader_context_ (const char *filename)
+{
+  struct FileInfo *fi;
+
+  fi = GNUNET_malloc (sizeof(struct FileInfo));
+  fi->filename = GNUNET_STRINGS_filename_expand (filename);
+  if (fi->filename == NULL)
+    {
+      GNUNET_free (fi);
+      return NULL;
+    }
+  return fi;
+}
+
+
+/**
  * Return the full filename where we would store state information
  * (for serialization/deserialization).
  *
@@ -422,6 +532,8 @@
         files (!?) */
       break;
     case 1: /* file-index, no hash */
+      if (NULL == ret->filename)
+       goto cleanup;
       if (GNUNET_OK !=
          GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size))
        goto cleanup;
@@ -429,11 +541,12 @@
       ret->data.file.do_index = GNUNET_YES;
       ret->data.file.have_hash = GNUNET_NO;
       ret->data.file.index_start_confirmed = GNUNET_NO;
-      /* FIXME: what's our approach for dealing with the
-        'reader' and 'reader_cls' fields? 
-        (should be easy for indexing since we must have a file) */
+      ret->data.file.reader = &GNUNET_FS_data_reader_file_;
+      ret->data.file.reader_cls = GNUNET_FS_make_file_reader_context_ 
(ret->filename);
       break;
     case 2: /* file-index-with-hash */
+      if (NULL == ret->filename)
+       goto cleanup;
       if ( (GNUNET_OK !=
            GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) ||
           (GNUNET_OK !=
@@ -443,23 +556,24 @@
       ret->data.file.do_index = GNUNET_YES;
       ret->data.file.have_hash = GNUNET_YES;
       ret->data.file.index_start_confirmed = GNUNET_NO;
-      /* FIXME: what's our approach for dealing with the
-        'reader' and 'reader_cls' fields? 
-        (should be easy for indexing since we must have a file) */
+      ret->data.file.reader = &GNUNET_FS_data_reader_file_;
+      ret->data.file.reader_cls = GNUNET_FS_make_file_reader_context_ 
(ret->filename);
       break;
     case 3: /* file-index-with-hash-confirmed */
+      if (NULL == ret->filename)
+       goto cleanup;
       if ( (GNUNET_OK !=
            GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) ||
           (GNUNET_OK !=
            GNUNET_BIO_read (rh, "fileid", &ret->data.file.file_id, sizeof 
(GNUNET_HashCode))) )
        goto cleanup;
+
       ret->is_directory = GNUNET_NO;
       ret->data.file.do_index = GNUNET_YES;
       ret->data.file.have_hash = GNUNET_YES;
       ret->data.file.index_start_confirmed = GNUNET_YES;
-      /* FIXME: what's our approach for dealing with the
-        'reader' and 'reader_cls' fields? 
-        (should be easy for indexing since we must have a file) */
+      ret->data.file.reader = &GNUNET_FS_data_reader_file_;
+      ret->data.file.reader_cls = GNUNET_FS_make_file_reader_context_ 
(ret->filename);
       break;
     case 4: /* directory */
       if ( (GNUNET_OK !=
@@ -507,7 +621,6 @@
   GNUNET_free_non_null (filename);
   GNUNET_FS_file_information_destroy (ret, NULL, NULL);
   return NULL;
-   
 }
 
 
@@ -581,7 +694,8 @@
 
 
 /**
- * Create a new random name for serialization.
+ * Create a new random name for serialization.  Also checks if persistence
+ * is enabled and returns NULL if not.
  *
  * @param h master context
  * @param ext component of the path 
@@ -595,7 +709,8 @@
   char *dn;
   char *ret;
 
-  /* FIXME: check if persistence option was set! */
+  if (0 == (h->flags & GNUNET_FS_FLAGS_PERSISTENCE))
+    return NULL; /* persistence not requested */
   dn = get_serialization_file_name (h, ext, "");
   fn = GNUNET_DISK_mktemp (dn);
   GNUNET_free (dn);
@@ -608,6 +723,44 @@
 
 
 /**
+ * Copy all of the data from the reader to the write handle.
+ *
+ * @param wh write handle
+ * @param fi file with reader
+ * @return GNUNET_OK on success
+ */
+static int
+copy_from_reader (struct GNUNET_BIO_WriteHandle *wh,
+                 struct GNUNET_FS_FileInformation * fi)
+{
+  char buf[32 * 1024];
+  uint64_t off;
+  size_t ret;
+  char *emsg;
+
+  emsg = NULL;
+  off = 0;
+  while (off < fi->data.file.file_size)
+    {
+      ret = fi->data.file.reader (fi->data.file.reader_cls,
+                                 off, sizeof (buf),
+                                 buf,
+                                 &emsg);
+      if (ret == 0)
+       {
+         GNUNET_free (emsg);
+         return GNUNET_SYSERR;
+       }
+      if (GNUNET_OK != 
+         GNUNET_BIO_write (wh, buf, ret))
+       return GNUNET_SYSERR;
+      off += ret;
+    }
+  return GNUNET_OK;
+}
+
+
+/**
  * Create a temporary file on disk to store the current
  * state of "fi" in.
  *
@@ -622,7 +775,6 @@
   char *ksks;
   char *chks;
 
-  /* FIXME: check if persistence option was set! */
   if (NULL == fi->serialization)    
     fi->serialization = make_serialization_file_name (fi->h, "publish-fi");
   if (NULL == fi->serialization)
@@ -684,27 +836,28 @@
       if (GNUNET_OK !=
          GNUNET_BIO_write_int64 (wh, fi->data.file.file_size))
        goto cleanup;
-      /* FIXME: what's our approach for dealing with the
-        'reader' and 'reader_cls' fields?  I guess the only
-        good way would be to dump "small" files into 
-        'rh' and to not support serialization of "large"
-        files (!?) */
+      if ( (GNUNET_NO == fi->is_published) &&
+          (NULL == fi->filename) )     
+       if (GNUNET_OK != 
+           copy_from_reader (wh, fi))
+         goto cleanup;
       break;
     case 1: /* file-index, no hash */
+      if (NULL == fi->filename)
+       goto cleanup;
       if (GNUNET_OK !=
          GNUNET_BIO_write_int64 (wh, fi->data.file.file_size))
        goto cleanup;
       break;
     case 2: /* file-index-with-hash */
     case 3: /* file-index-with-hash-confirmed */
+      if (NULL == fi->filename)
+       goto cleanup;
       if ( (GNUNET_OK !=
            GNUNET_BIO_write_int64 (wh, fi->data.file.file_size)) ||
           (GNUNET_OK !=
            GNUNET_BIO_write (wh, &fi->data.file.file_id, sizeof 
(GNUNET_HashCode))) )
        goto cleanup;
-      /* FIXME: what's our approach for dealing with the
-        'reader' and 'reader_cls' fields? 
-        (should be easy for indexing since we must have a file) */
       break;
     case 4: /* directory */
       if ( (GNUNET_OK !=

Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h  2010-04-30 13:11:34 UTC (rev 11135)
+++ gnunet/src/fs/fs.h  2010-04-30 13:16:03 UTC (rev 11136)
@@ -431,11 +431,6 @@
   } data;
 
   /**
-   * Is this struct for a file or directory?
-   */
-  int is_directory;
-
-  /**
    * Desired anonymity level.
    */
   uint32_t anonymity;
@@ -445,6 +440,16 @@
    */
   uint32_t priority;
 
+  /**
+   * Is this struct for a file or directory?
+   */
+  int is_directory;
+
+  /**
+   * Are we done publishing this file?
+   */
+  int is_published;
+
 };
 
 
@@ -563,8 +568,41 @@
 GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh);
 
 
+/**
+ * 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
+ */
+size_t
+GNUNET_FS_data_reader_file_(void *cls, 
+                           uint64_t offset,
+                           size_t max, 
+                           void *buf,
+                           char **emsg);
 
+
 /**
+ * Create the closure for the 'GNUNET_FS_data_reader_file_' callback.
+ *
+ * @param filename file to read
+ * @return closure to use
+ */
+void *
+GNUNET_FS_make_file_reader_context_ (const char *filename);
+
+
+/**
  * Notification of FS that a search probe has made progress.
  * This function is used INSTEAD of the client's event handler
  * for downloads where the GNUNET_FS_DOWNLOAD_IS_PROBE flag is set.

Modified: gnunet/src/fs/fs_file_information.c
===================================================================
--- gnunet/src/fs/fs_file_information.c 2010-04-30 13:11:34 UTC (rev 11135)
+++ gnunet/src/fs/fs_file_information.c 2010-04-30 13:16:03 UTC (rev 11136)
@@ -55,92 +55,6 @@
 
 
 /**
- * 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
@@ -182,17 +96,16 @@
                                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 (h,
                                                       client_info,
                                                       sbuf.st_size,
-                                                      &data_reader_file,
+                                                      
&GNUNET_FS_data_reader_file_,
                                                       fi,
                                                       keywords,
                                                       meta,
@@ -284,6 +197,11 @@
                                             uint32_t priority,
                                             struct GNUNET_TIME_Absolute 
expirationTime)
 {
+  if (GNUNET_YES == do_index)        
+    {
+      GNUNET_break (0);
+      return NULL;
+    }
   return GNUNET_FS_file_information_create_from_reader (h,
                                                        client_info,
                                                        length,
@@ -333,6 +251,12 @@
 {
   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;  





reply via email to

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