[Top][All Lists]
[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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r21755 - gnunet-fuse/src/fuse,
gnunet <=