gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r21755 - gnunet-fuse/src/fuse


From: gnunet
Subject: [GNUnet-SVN] r21755 - gnunet-fuse/src/fuse
Date: Mon, 4 Jun 2012 15:03:36 +0200

Author: grothoff
Date: 2012-06-04 15:03:36 +0200 (Mon, 04 Jun 2012)
New Revision: 21755

Added:
   gnunet-fuse/src/fuse/gfs_download.c
   gnunet-fuse/src/fuse/gfs_download.h
Modified:
   gnunet-fuse/src/fuse/Makefile.am
   gnunet-fuse/src/fuse/gnunet-fuse.c
   gnunet-fuse/src/fuse/gnunet-fuse.h
   gnunet-fuse/src/fuse/readdir.c
Log:
-towards downloading files

Modified: gnunet-fuse/src/fuse/Makefile.am
===================================================================
--- gnunet-fuse/src/fuse/Makefile.am    2012-06-04 12:13:15 UTC (rev 21754)
+++ gnunet-fuse/src/fuse/Makefile.am    2012-06-04 13:03:36 UTC (rev 21755)
@@ -10,7 +10,9 @@
 
 gnunet_fuse_SOURCES = \
   gnunet-fuse.c \
+  gfs_download.c gfs_download.h \
   mutex.c mutex.h \
+       readdir.c \
        mkdir.c \
        mknod.c \
        release.c \
@@ -20,7 +22,6 @@
        unlink.c \
        utimens.c \
        write.c \
-       readdir.c \
        read.c \
        open.c \
        getattr.c

Added: gnunet-fuse/src/fuse/gfs_download.c
===================================================================
--- gnunet-fuse/src/fuse/gfs_download.c                         (rev 0)
+++ gnunet-fuse/src/fuse/gfs_download.c 2012-06-04 13:03:36 UTC (rev 21755)
@@ -0,0 +1,223 @@
+/*
+  This file is part of gnunet-fuse.
+  (C) 2012 Christian Grothoff (and other contributing authors)
+  
+  gnunet-fuse 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 3, or (at your
+  option) any later version.
+ 
+  gnunet-fuse 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 this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+/**
+ * @file fuse/gfs_download.h
+ * @brief download files using FS
+ * @author Christian Grothoff
+ */
+#include "gfs_download.h"
+
+
+struct Context
+{
+
+  struct GNUNET_FUSE_PathInfo *path_info;
+
+  struct GNUNET_FS_DownloadContext *dc;
+
+  struct GNUNET_FS_Handle *fs;
+
+  char *emsg;
+
+  off_t start_offset;
+
+  uint64_t length;
+
+  int ret;
+
+};
+
+
+/**
+ * Task run when we shut down.
+ */
+static void
+shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct Context *ctx = cls;
+
+  if (NULL != ctx->dc)
+  {
+    GNUNET_FS_download_stop (ctx->dc, GNUNET_YES);
+    ctx->dc = NULL;
+  }
+  if (NULL != ctx->fs)
+  {
+    GNUNET_FS_stop (ctx->fs);
+    ctx->fs = NULL;
+  }
+}
+
+
+/**
+ * Function called from FS with progress information.
+ *
+ * @param cls our 'struct Context'
+ * @param info progress information
+ * @return NULL
+ */
+static void *
+progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
+{
+  struct Context *ctx = cls;
+  char *s;
+
+  switch (info->status)
+    {
+    case GNUNET_FS_STATUS_DOWNLOAD_START:
+      GNUNET_break (info->value.download.dc == ctx->dc);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Started download `%s'.\n",
+                 info->value.download.filename);
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
+      GNUNET_break (info->value.download.dc == ctx->dc);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,                
+                 "Downloading `%s' at %llu/%llu\n",
+                 info->value.download.filename,
+                 (unsigned long long) info->value.download.completed,
+                 (unsigned long long) info->value.download.size);
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_ERROR:
+      GNUNET_break (info->value.download.dc == ctx->dc);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Error downloading: %s.\n",
+                 info->value.download.specifics.error.message);
+      GNUNET_SCHEDULER_shutdown ();
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
+      GNUNET_break (info->value.download.dc == ctx->dc);
+      s =
+       GNUNET_STRINGS_byte_size_fancy (info->value.download.completed *
+                                       1000 /
+                                       (info->value.download.
+                                        duration.rel_value + 1));
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Downloading `%s' done (%s/s).\n",
+                 info->value.download.filename, s);
+      GNUNET_free (s);
+      ctx->ret = 0;
+      GNUNET_SCHEDULER_shutdown ();
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_STOPPED:
+      GNUNET_SCHEDULER_shutdown ();
+      break;
+    case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
+    case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
+      break;
+    default:
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
+                 _("Unexpected status: %d\n"), info->status);
+      break;
+    }
+  return NULL;
+}
+
+
+/**
+ * Main task run by the helper process which downloads the file.
+ *
+ * @param cls 'struct Context' with information about the download
+ * @param tc scheduler context
+ */
+static void
+download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct Context *ctx = cls;
+
+  ctx->fs = GNUNET_FS_start (cfg, "gnunet-fuse", &progress_cb, ctx,
+                            GNUNET_FS_FLAGS_NONE,
+                            GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM, 1,
+                            GNUNET_FS_OPTIONS_REQUEST_PARALLELISM, 1, 
+                            GNUNET_FS_OPTIONS_END);
+  if (NULL == ctx->fs)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not initialize `%s' 
subsystem.\n"), "FS");
+    return;
+  }
+  ctx->dc = GNUNET_FS_download_start (ctx->fs, 
+                                     ctx->path_info->uri, 
ctx->path_info->meta, 
+                                     ctx->path_info->tmpfile, NULL, 
+                                     (uint64_t) ctx->start_offset,
+                                     ctx->length,
+                                     anonymity_level, 
+                                     GNUNET_FS_DOWNLOAD_OPTION_NONE, 
+                                     NULL, NULL);
+  if (NULL == ctx->dc)
+  {
+    GNUNET_FS_stop (ctx->fs);
+    ctx->fs = NULL;
+    return;
+  }
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+                               &shutdown_task, ctx);
+}
+
+
+/**
+ * Download a file.  Blocks until we're done.
+ *
+ * @param path_info information about the file to download
+ * @param start_offset offset of the first byte to download
+ * @param length number of bytes to download from 'start_offset'
+ * @return GNUNET_OK on success
+ */
+int
+GNUNET_FUSE_download_file (struct GNUNET_FUSE_PathInfo *path_info,
+                          off_t start_offset,
+                          uint64_t length)
+{
+  struct Context ctx;
+  pid_t pid;
+  int status;
+  int ret;
+
+  pid = fork ();
+  if (-1 == pid)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+    return GNUNET_SYSERR;
+  }
+  if (0 != pid)
+  {
+    while ( (0 != (ret = waitpid (pid, &status, 0))) &&
+           (EINTR == errno) ) ;
+    if (0 != ret)
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "waitpid");
+      (void) kill (pid, SIGKILL);
+      (void) waitpid (pid, &status, 0);
+      return GNUNET_SYSERR;
+    }
+    if ( (WIFEXITED (status)) &&
+        (0 == WEXITSTATUS (status)) )
+      return GNUNET_OK;
+    return GNUNET_SYSERR;
+  }
+  memset (&ctx, 0, sizeof (ctx));
+  ctx.ret = 1;
+  ctx.path_info = path_info;
+  ctx.start_offset = start_offset;
+  ctx.length = length;
+  GNUNET_SCHEDULER_run (&download_task, &ctx);
+  _exit (ret);
+}
+
+/* end of fs_download.c */

Added: gnunet-fuse/src/fuse/gfs_download.h
===================================================================
--- gnunet-fuse/src/fuse/gfs_download.h                         (rev 0)
+++ gnunet-fuse/src/fuse/gfs_download.h 2012-06-04 13:03:36 UTC (rev 21755)
@@ -0,0 +1,43 @@
+/*
+  This file is part of gnunet-fuse.
+  (C) 2012 Christian Grothoff (and other contributing authors)
+  
+  gnunet-fuse 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 3, or (at your
+  option) any later version.
+ 
+  gnunet-fuse 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 this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+/**
+ * @file fuse/gfs_download.h
+ * @brief download files using FS
+ * @author Christian Grothoff
+ */
+#ifndef GFS_DOWNLOAD_H
+#define GFS_DOWNLOAD_H
+
+#include "gnunet-fuse.h"
+
+/**
+ * Download a file.  Blocks until we're done.
+ *
+ * @param path_info information about the file to download
+ * @param start_offset offset of the first byte to download
+ * @param length number of bytes to download from 'start_offset'
+ * @return GNUNET_OK on success
+ */
+int
+GNUNET_FUSE_download_file (struct GNUNET_FUSE_PathInfo *path_info,
+                          off_t start_offset,
+                          uint64_t length);
+
+#endif

Modified: gnunet-fuse/src/fuse/gnunet-fuse.c
===================================================================
--- gnunet-fuse/src/fuse/gnunet-fuse.c  2012-06-04 12:13:15 UTC (rev 21754)
+++ gnunet-fuse/src/fuse/gnunet-fuse.c  2012-06-04 13:03:36 UTC (rev 21755)
@@ -26,8 +26,17 @@
  */
 #include "gnunet-fuse.h"
 
+/**
+ * Anonymity level to use.
+ */
+unsigned int anonymity_level;
 
 /**
+ * Configuration to use.
+ */
+const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
  * Return code from 'main' (0 on success).
  */
 static int ret;
@@ -66,7 +75,7 @@
  * @return NULL if no such path entry exists
  */
 struct GNUNET_FUSE_PathInfo *
-GNUNET_FUSE_get_path_info (const char *path)
+GNUNET_FUSE_path_info_get (const char *path)
 {
   struct GNUNET_FUSE_PathInfo *pi;
   GNUNET_HashCode path_hash;
@@ -210,12 +219,12 @@
  * @param cls closure
  * @param args remaining command-line arguments
  * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
- * @param cfg configuration
+ * @param c configuration
  */
 static void
 run (void *cls,
      char *const *args,
-     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
+     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 {
   static struct fuse_operations fops = {
     //  .mkdir = gn_mkdir,
@@ -239,6 +248,7 @@
   const char *path = "/";
   struct GNUNET_FUSE_PathInfo *pi;
 
+  cfg = c;
   ret = 0;
   if (NULL == source)
     {

Modified: gnunet-fuse/src/fuse/gnunet-fuse.h
===================================================================
--- gnunet-fuse/src/fuse/gnunet-fuse.h  2012-06-04 12:13:15 UTC (rev 21754)
+++ gnunet-fuse/src/fuse/gnunet-fuse.h  2012-06-04 13:03:36 UTC (rev 21755)
@@ -37,6 +37,17 @@
 
 
 /**
+ * Anonymity level to use.
+ */
+extern unsigned int anonymity_level;
+
+/**
+ * Configuration to use.
+ */
+extern const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+
+/**
  * struct containing mapped Path, with URI and other Information like 
Attributes etc. 
  */
 struct GNUNET_FUSE_PathInfo
@@ -47,6 +58,11 @@
   struct GNUNET_FS_Uri *uri;
 
   /**
+   * meta data to corresponding path (can be NULL)
+   */
+  struct GNUNET_CONTAINER_MetaData *meta;
+
+  /**
    * pathname 
    */
   char* path;

Modified: gnunet-fuse/src/fuse/readdir.c
===================================================================
--- gnunet-fuse/src/fuse/readdir.c      2012-06-04 12:13:15 UTC (rev 21754)
+++ gnunet-fuse/src/fuse/readdir.c      2012-06-04 13:03:36 UTC (rev 21755)
@@ -46,206 +46,8 @@
  * Introduced in version 2.3
  */
 #include "gnunet-fuse.h"
+#include "gfs_download.h"
 
-
-static int ret;
-
-static int verbose;
-
-static int delete_incomplete;
-
-static struct GNUNET_FS_DownloadContext *dc;
-
-static unsigned int parallelism = 16;
-
-static unsigned int request_parallelism = 4092;
-
-static int do_recursive;
-
-static int local_only;
-
-static const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-static unsigned int anonymity = 1;
-
-struct GNUNET_FS_Handle *fs;
-
-static struct GNUNET_FS_Handle *ctx;
-
-struct GNUNET_CONTAINER_MultiHashMap *map;
-
-struct GNUNET_FS_Uri *uri;
-
-char *emsg;
-
-struct GNUNET_FUSE_PathInfo *r;
-
-
-
-
-static void
-cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  GNUNET_FS_stop (ctx);
-  ctx = NULL;
-}
-
-static void
-shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct GNUNET_FS_DownloadContext *d;
-
-  if (dc != NULL)
-    {
-      d = dc;
-      dc = NULL;
-      GNUNET_FS_download_stop (d, delete_incomplete);
-    }
-}
-
-
-/* callback function */
-static void *
-progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
-{
-
-  char *s;
-  char *s2;
-  char *t;
-
-  switch (info->status)
-    {
-    case GNUNET_FS_STATUS_DOWNLOAD_START:
-      if (verbose > 1)
-       FPRINTF (stderr, _("Starting download `%s'.\n"),
-                info->value.download.filename);
-      break;
-    case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
-      if (verbose)
-       {
-         s =
-           GNUNET_STRINGS_relative_time_to_string (info->value.download.eta);
-         if (info->value.download.specifics.progress.
-             block_download_duration.rel_value ==
-             GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
-           s2 = GNUNET_strdup (_("<unknown time>"));
-         else
-           s2 =
-             GNUNET_STRINGS_relative_time_to_string (info->value.
-                                                     download.specifics.
-                                                     
progress.block_download_duration);
-         t =
-           GNUNET_STRINGS_byte_size_fancy (info->value.download.completed *
-                                           1000LL /
-                                           (info->value.download.
-                                            duration.rel_value + 1));
-         FPRINTF (stdout,
-                  _
-                  ("Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block 
took %s to download\n"),
-                  info->value.download.filename,
-                  (unsigned long long) info->value.download.completed,
-                  (unsigned long long) info->value.download.size, s, t, s2);
-         GNUNET_free (s);
-         GNUNET_free (s2);
-         GNUNET_free (t);
-       }
-      break;
-    case GNUNET_FS_STATUS_DOWNLOAD_ERROR:
-      FPRINTF (stderr, _("Error downloading: %s.\n"),
-              info->value.download.specifics.error.message);
-      GNUNET_SCHEDULER_shutdown ();
-      break;
-    case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
-      s =
-       GNUNET_STRINGS_byte_size_fancy (info->value.download.completed *
-                                       1000 /
-                                       (info->value.download.
-                                        duration.rel_value + 1));
-      FPRINTF (stdout, _("Downloading `%s' done (%s/s).\n"),
-              info->value.download.filename, s);
-      GNUNET_free (s);
-      if (info->value.download.dc == dc)
-       GNUNET_SCHEDULER_shutdown ();
-      break;
-    case GNUNET_FS_STATUS_DOWNLOAD_STOPPED:
-      if (info->value.download.dc == dc)
-       GNUNET_SCHEDULER_add_continuation (&cleanup_task, NULL,
-                                          GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-      break;
-    case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
-    case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
-      break;
-    default:
-      FPRINTF (stderr, _("Unexpected status: %d\n"), info->status);
-      break;
-    }
-
-  return NULL;
-}
-
-
-void
-readdir_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  enum GNUNET_FS_DownloadOptions options;
-
-  if (NULL == uri)
-    {
-      FPRINTF (stderr, _("Failed to parse URI: %s\n"), emsg);
-      GNUNET_free (emsg);
-      GNUNET_FS_stop (ctx);    // ?? hmmm....stop before start ??
-    }
-
-
-  fs = GNUNET_FS_start (cfg, "gnunet-fuse", &progress_cb, NULL,
-                       GNUNET_FS_FLAGS_NONE,
-                       GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM, parallelism,
-                       GNUNET_FS_OPTIONS_REQUEST_PARALLELISM,
-                       request_parallelism, GNUNET_FS_OPTIONS_END);
-
-  if (NULL == fs)
-    {
-      FPRINTF (stderr, _("Could not initialize `%s' subsystem.\n"), "FS");
-      GNUNET_FS_uri_destroy (uri);
-      ret = 1;
-      return;
-    }
-
-  options = GNUNET_FS_DOWNLOAD_OPTION_NONE;
-  if (do_recursive)
-    options |= GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE;
-  if (local_only)
-    options |= GNUNET_FS_DOWNLOAD_OPTION_LOOPBACK_ONLY;
-
-  struct GNUNET_FS_DownloadContext *dc;
-  dc = GNUNET_FS_download_start (fs, uri, NULL, r->tmpfile, NULL, 0,
-                                GNUNET_FS_uri_chk_get_file_size (uri),
-                                anonymity, options, NULL, NULL);
-
-  GNUNET_FS_uri_destroy (uri);
-  if (dc == NULL)
-    {
-      GNUNET_FS_stop (ctx);
-      ctx = NULL;
-      return;
-    }
-
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
-                               NULL);
-
-}
-
-
-static void
-download_file (struct GNUNET_FUSE_PathInfo *path_info,
-              off_t start_offset,
-              uint64_t length)
-{
-  // FIXME: not implemented...
-  GNUNET_break (0);
-}
-
-
 /**
  * Closure for 'process_directory_entry'.
  */
@@ -317,7 +119,6 @@
 gn_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
            off_t offset, struct fuse_file_info *fi)
 {
-  GNUNET_HashCode path_hash;
   struct GNUNET_FUSE_PathInfo *path_info;
   struct DepContext dc;
   size_t size;
@@ -326,8 +127,7 @@
   struct GNUNET_DISK_MapHandle *mh;
   struct GNUNET_DISK_FileHandle *fh;
 
-  GNUNET_CRYPTO_hash (path, strlen (path), &path_hash);
-  path_info = GNUNET_CONTAINER_multihashmap_get (map, &path_hash);
+  path_info = GNUNET_FUSE_path_info_get (path);
   if (NULL == path_info)
     {
       /* FIXME: we might need to check which of the ancestors
@@ -340,11 +140,17 @@
     {
       /* store to temporary file */
       path_info->tmpfile = GNUNET_DISK_mktemp ("gnunet-fuse-tempfile");
-      download_file (path_info, 
-                    0,
-                    GNUNET_FS_uri_chk_get_file_size (path_info->uri));
-    }
-  
+      if (GNUNET_OK != GNUNET_FUSE_download_file (path_info, 
+                                                 0,
+                                                 
GNUNET_FS_uri_chk_get_file_size (path_info->uri)))
+      {
+       UNLINK (path_info->tmpfile);
+       GNUNET_free (path_info->tmpfile);
+       path_info->tmpfile = NULL;
+       GNUNET_FUSE_path_info_done (path_info);
+       return - EIO; /* low level IO error */
+      }
+    } 
 
   dc.filler = filler;
   dc.path = path;
@@ -353,7 +159,10 @@
                              GNUNET_DISK_OPEN_READ,
                              GNUNET_DISK_PERM_NONE);                         
   if (NULL == fh)
+  {
+    GNUNET_FUSE_path_info_done (path_info);
     return -EBADF;
+  }
   data = GNUNET_DISK_file_map (fh, 
                               &mh,
                               GNUNET_DISK_MAP_TYPE_READ,
@@ -361,6 +170,7 @@
   if (NULL == data)
   {
     GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
+    GNUNET_FUSE_path_info_done (path_info);
     return -EBADF;
   }
   if (GNUNET_OK !=
@@ -377,5 +187,6 @@
     }
   GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_unmap (mh));
   GNUNET_DISK_file_close (fh);
+  GNUNET_FUSE_path_info_done (path_info);
   return ret;    
 }




reply via email to

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