[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r20389 - in gnunet-fuse: . gnunet-fuse-v8
From: |
gnunet |
Subject: |
[GNUnet-SVN] r20389 - in gnunet-fuse: . gnunet-fuse-v8 |
Date: |
Fri, 9 Mar 2012 09:38:55 +0100 |
Author: mauricio
Date: 2012-03-09 09:38:54 +0100 (Fri, 09 Mar 2012)
New Revision: 20389
Added:
gnunet-fuse/gnunet-fuse-v8/
gnunet-fuse/gnunet-fuse-v8/directory.c
gnunet-fuse/gnunet-fuse-v8/dirent.c
gnunet-fuse/gnunet-fuse-v8/file.c
gnunet-fuse/gnunet-fuse-v8/getattr.c
gnunet-fuse/gnunet-fuse-v8/main.c
gnunet-fuse/gnunet-fuse-v8/mkdir.c
gnunet-fuse/gnunet-fuse-v8/mknod.c
gnunet-fuse/gnunet-fuse-v8/open.c
gnunet-fuse/gnunet-fuse-v8/read.c
gnunet-fuse/gnunet-fuse-v8/readdir.c
gnunet-fuse/gnunet-fuse-v8/release.c
gnunet-fuse/gnunet-fuse-v8/rename.c
gnunet-fuse/gnunet-fuse-v8/rmdir.c
gnunet-fuse/gnunet-fuse-v8/special_file.c
gnunet-fuse/gnunet-fuse-v8/truncate.c
gnunet-fuse/gnunet-fuse-v8/unlink.c
gnunet-fuse/gnunet-fuse-v8/utimens.c
gnunet-fuse/gnunet-fuse-v8/write.c
Removed:
gnunet-fuse/directory.c
gnunet-fuse/dirent.c
gnunet-fuse/file.c
gnunet-fuse/getattr.c
gnunet-fuse/main.c
gnunet-fuse/mkdir.c
gnunet-fuse/mknod.c
gnunet-fuse/open.c
gnunet-fuse/read.c
gnunet-fuse/readdir.c
gnunet-fuse/release.c
gnunet-fuse/rename.c
gnunet-fuse/rmdir.c
gnunet-fuse/special_file.c
gnunet-fuse/truncate.c
gnunet-fuse/unlink.c
gnunet-fuse/utimens.c
gnunet-fuse/write.c
Log:
moving old fuse code to backup directory
Deleted: gnunet-fuse/directory.c
===================================================================
--- gnunet-fuse/directory.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/directory.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,429 +0,0 @@
-/*
- * directory.c - stuff you want to do with directories
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <sys/mman.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <glib.h>
-#include <GNUnet/gnunet_ecrs_lib.h>
-#include "gnfs.h"
-
-static void dpcb(unsigned long long totalBytes,
- unsigned long long completedBytes, GNUNET_CronTime eta,
- unsigned long long lastBlockOffset, const char *lastBlock,
- unsigned int lastBlockSize, void *cls)
-{
- (void)totalBytes;
- (void)completedBytes;
- (void)eta;
- memcpy((char *)cls + lastBlockOffset, lastBlock, lastBlockSize);
-}
-
-static int tt(void *cls)
-{
- (void)cls;
- if(closing)
- return GNUNET_OK;
- if(fuse_interrupted())
- return GNUNET_SYSERR;
- return GNUNET_OK;
-}
-
-static int dir_cache_cb(const GNUNET_ECRS_FileInfo *fi, const GNUNET_HashCode
*key,
- int isRoot, void *data)
-{
- struct dirent *de, *deparent = data;
- gchar *filename, *path, *newpath, type;
- size_t len, rlen;
-
- (void)key;
-
- if(isRoot == GNUNET_YES)
- return GNUNET_OK;
-
- /* Figure out the filename and type from metadata */
- filename = GNUNET_meta_data_get_by_type(fi->meta, EXTRACTOR_FILENAME);
- if(filename == NULL)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_WARNING,
- "%s: dirent has no filename\n", __FUNCTION__);
- return GNUNET_OK;
- }
- len = strlen(filename);
- if(GNUNET_meta_data_test_for_directory(fi->meta) == GNUNET_YES)
- {
- if(filename[len - 1] == '/' || filename[len - 1] == '\\')
- filename[len - 1] = '\0';
- type = DE_DIR;
- }
- else
- type = DE_FILE;
-
- /* Create newpath, the path to this entry */
- path = gn_dirent_path_get(deparent);
- rlen = strlen(path);
- newpath = GNUNET_malloc(rlen + len + 1);
- strcpy(newpath, path);
- if(path[rlen - 1] != G_DIR_SEPARATOR)
- strcat(newpath, G_DIR_SEPARATOR_S);
- GNUNET_free(path);
- strcat(newpath, filename);
-
- /* Create a new dirent for this entry only if one doesn't already exist
- * and the only place that can be is in the cache */
- de = gn_dirent_get(newpath);
- if(de == NULL)
- {
- de = gn_dirent_new(newpath, fi->uri, fi->meta, type);
-
- /* Add it to the cache (creates its own ref)*/
- /* NB: the lock on deparent is enough to guarantee that another
- * thread hasn't added this dirent to the cache in the time
- * between the above check and this insert */
- gn_dirent_cache_insert(de);
- }
-
- /* Add it to the directory's list (steals our ref)*/
- GNUNET_mutex_lock(de->de_path_mutex);
- GNUNET_GE_ASSERT(ectx,
- !g_hash_table_lookup(deparent->de_dir_hash, de->de_basename));
- g_hash_table_replace(deparent->de_dir_hash, de->de_basename, de);
- GNUNET_mutex_unlock(de->de_path_mutex);
-
- /* Clean up */
- GNUNET_free(filename);
- GNUNET_free(newpath);
- return GNUNET_OK;
-}
-
-static int directory_cache_locked(struct dirent *de)
-{
- struct GNUNET_MetaData *md;
- void *mem;
- int ret;
- guint64 len;
-
- len = GNUNET_ECRS_uri_get_file_size(de->de_fi.uri);
- mem = GNUNET_malloc(len);
- ret = GNUNET_ECRS_file_download_partial(ectx, cfg, de->de_fi.uri,
- "/dev/null", 0, len, anonymity, GNUNET_YES, dpcb, mem, tt,
- NULL);
- if(ret != GNUNET_OK)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_ERROR,
- "%s: failed to download directory\n",
- __FUNCTION__);
- GNUNET_free(mem);
- return -1;
- }
- de->de_dir_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)gn_dirent_put);
- GNUNET_ECRS_directory_list_contents(ectx, mem, len, NULL, &md,
dir_cache_cb, de);
- GNUNET_free(mem);
- GNUNET_meta_data_destroy(md);
- de->de_cached = 1;
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: cached %d entries\n", __FUNCTION__,
- g_hash_table_size(de->de_dir_hash));
- return 0;
-}
-
-struct dir_foreach_data
-{
- gn_dir_foreach_callback cb;
- void *data;
-};
-
-static gboolean dir_foreach_callback(gpointer key, gpointer value,
- gpointer data)
-{
- struct dirent *de = value;
- struct dir_foreach_data *d = data;
-
- (void)key;
- return d->cb(de, d->data) == -1;
-}
-
-/*
- * Call cb for each element in a directory
- */
-int gn_directory_foreach(struct dirent *de, gn_dir_foreach_callback cb,
- void *data)
-{
- struct dir_foreach_data d;
- int ret = 0;
-
- if(de->de_type != DE_DIR)
- return -1;
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
- return -1;
- if(!de->de_cached)
- {
- ret = directory_cache_locked(de);
- if(ret == -1)
- goto out;
- }
- d.cb = cb;
- d.data = data;
- g_hash_table_find(de->de_dir_hash, dir_foreach_callback, &d);
-out:
- GNUNET_semaphore_up(de->de_sema);
- return ret;
-}
-
-/*
- * Finds 'filename' in directory 'de' and returns a reference or NULL
- */
-struct dirent *gn_directory_find(struct dirent *de, const gchar *filename)
-{
- struct dirent *ret = NULL;
-
- if(de->de_type != DE_DIR)
- return NULL;
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
- return NULL;
- if(!de->de_cached)
- {
- if(directory_cache_locked(de) == -1)
- goto out;
- }
- ret = g_hash_table_lookup(de->de_dir_hash, filename);
- if(ret != NULL)
- gn_dirent_ref(ret);
-out:
- GNUNET_semaphore_up(de->de_sema);
- return ret;
-}
-
-int gn_directory_insert(struct dirent *de, struct dirent *dechild)
-{
- /* Lock our path */
- if(gn_lock_path(de) == -1)
- return -1;
-
- /* Cache ourselfs (because we're going to become dirty) */
- if(!de->de_cached)
- {
- if(directory_cache_locked(de) == -1)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER | GNUNET_GE_DEBUG,
- "%s: failed to cache parent dir\n",
- __FUNCTION__);
- gn_unlock_path(de, GN_UNLOCK_CLEAN);
- return -1;
- }
- }
-
- /* If we're already in there, bail out */
- GNUNET_mutex_lock(dechild->de_path_mutex);
- if(g_hash_table_lookup(de->de_dir_hash, dechild->de_basename))
- {
- GNUNET_mutex_unlock(dechild->de_path_mutex);
- gn_unlock_path(de, GN_UNLOCK_CLEAN);
- return -1;
- }
-
- /* Insert the child in our de_dir_hash */
- gn_dirent_ref(dechild);
- g_hash_table_replace(de->de_dir_hash, dechild->de_basename, dechild);
- GNUNET_mutex_unlock(dechild->de_path_mutex);
-
- /* Cache the dirent */
- gn_dirent_cache_insert(dechild);
-
- /* Mark our path dirty */
- gn_unlock_path(de, GN_UNLOCK_ALL_DIRTY);
- return 0;
-}
-
-int gn_directory_remove(struct dirent *de, struct dirent *dechild)
-{
- /* Lock our path */
- if(gn_lock_path(de) == -1)
- return -1;
-
- /* Cache ourselfs (because we're going to become dirty) */
- if(!de->de_cached)
- {
- if(directory_cache_locked(de) == -1)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER | GNUNET_GE_ERROR,
- "%s: failed to cache parent dir\n",
- __FUNCTION__);
- goto out_err;
- }
- }
-
- /* Remove from dir_hash */
- GNUNET_mutex_lock(dechild->de_path_mutex);
- if(!g_hash_table_remove(de->de_dir_hash, dechild->de_basename))
- {
- GNUNET_mutex_unlock(dechild->de_path_mutex);
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: not found in dir_hash\n",
- __FUNCTION__);
- goto out_err;
- }
- GNUNET_mutex_unlock(dechild->de_path_mutex);
-
- /* Remove from dirent cache */
- gn_dirent_cache_remove(dechild);
-
- /* Mark our path dirty */
- gn_unlock_path(de, GN_UNLOCK_ALL_DIRTY);
- return 0;
-out_err:
- gn_unlock_path(de, GN_UNLOCK_CLEAN);
- return -1;
-}
-
-static void upcb(unsigned long long totalBytes,
- unsigned long long completedBytes, GNUNET_CronTime eta,
- void *closure)
-{
- (void)totalBytes;
- (void)completedBytes;
- (void)eta;
- (void)closure;
-}
-
-struct dir_upload_data
-{
- GNUNET_ECRS_FileInfo *fis;
- int count;
- int failed;
-};
-
-static gboolean dir_upload_callback(gpointer key, gpointer value, gpointer
data)
-{
- struct dirent *de = value;
- struct dir_upload_data *d = data;
- int ret = 0;
-
- (void)key;
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
- {
- d->failed = 1;
- return 1;
- }
- if(de->de_dirty)
- {
- if(de->de_type == DE_FILE)
- {
- if(de->de_fi.uri == NULL)
- {
- goto out;
- }
- }
- else
- {
- if(gn_directory_upload_locked(de) == -1)
- {
- d->failed = 1;
- ret = 1;
- goto out;
- }
- }
- }
- d->fis[d->count].uri = GNUNET_ECRS_uri_duplicate(de->de_fi.uri);
- d->fis[d->count].meta = GNUNET_meta_data_duplicate(de->de_fi.meta);
- d->count++;
-out:
- GNUNET_semaphore_up(de->de_sema);
- return ret;
-}
-
-/*
- * Make a directory clean, de_sema must be locked
- */
-int gn_directory_upload_locked(struct dirent *de)
-{
- int i, ret, fd;
- char *buf, filename[] = GN_MKSTEMP_FILE;
- unsigned long long len;
- struct GNUNET_ECRS_URI *uri;
- struct dir_upload_data d;
-
- /* We may be already clean */
- if(!de->de_dirty)
- return 0;
-
- /* Collect FileInfo from hash table and make a GNUnet directory */
- d.fis = GNUNET_malloc(g_hash_table_size(de->de_dir_hash) *
sizeof(*d.fis));
- d.count = 0;
- d.failed = 0;
- g_hash_table_find(de->de_dir_hash, dir_upload_callback, &d);
- if(d.failed)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: failed\n", __FUNCTION__);
- return -1;
- }
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: creating dir of %d elements\n", __FUNCTION__, d.count);
- ret = GNUNET_ECRS_directory_create(ectx, &buf, &len, d.count, d.fis,
- de->de_fi.meta);
- for(i = 0; i < d.count; i++)
- {
- GNUNET_ECRS_uri_destroy(d.fis[i].uri);
- GNUNET_meta_data_destroy(d.fis[i].meta);
- }
- GNUNET_free(d.fis);
- if(ret == GNUNET_SYSERR)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: GNUNET_ECRS_directory_create failed\n",
- __FUNCTION__);
- return -1;
- }
-
- /* Write the GNUnet directory out to a file and upload it */
- fd = mkstemp(filename);
- if(fd == -1)
- {
- GNUNET_GE_LOG_STRERROR_FILE(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER
- | GNUNET_GE_ERROR, "mkstemp", filename);
- return -1;
- }
- write(fd, buf, len);
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: wrote to %lld bytes to '%s'\n", __FUNCTION__, len,
- filename);
- ret = GNUNET_ECRS_file_upload(ectx, cfg, filename, GNUNET_NO,
anonymity, priority,
- -1, upcb, NULL, tt, NULL, &uri);
- close(fd);
- unlink(filename);
- if(ret == GNUNET_SYSERR)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: GNUNET_ECRS_file_upload failed\n", __FUNCTION__);
- return -1;
- }
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: done\n", __FUNCTION__);
- /* Update the dirent info with our new URI and mark it clean */
- if(de->de_fi.uri != NULL)
- GNUNET_ECRS_uri_destroy(de->de_fi.uri);
- de->de_fi.uri = uri;
- de->de_dirty = 0;
- return 0;
-}
Deleted: gnunet-fuse/dirent.c
===================================================================
--- gnunet-fuse/dirent.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/dirent.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,385 +0,0 @@
-/*
- * dirent.c - stuff for directory entries
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <unistd.h>
-#include <glib.h>
-#include <string.h>
-#include <errno.h>
-#include "gnfs.h"
-
-GHashTable *path_hash;
-struct GNUNET_Semaphore *path_sema;
-
-/*
- * Reference a dirent, call gn_dirent_put when finished
- */
-void gn_dirent_ref(struct dirent *de)
-{
- GNUNET_mutex_lock(de->de_refs_mutex);
- de->de_refs++;
- GNUNET_mutex_unlock(de->de_refs_mutex);
-}
-
-/*
- * Reference a dirent from the cache, call gn_dirent_put when finished with it
- */
-struct dirent *gn_dirent_get(const gchar *path)
-{
- struct dirent *de;
-
- if(GNUNET_semaphore_down(path_sema, GNUNET_YES) == GNUNET_SYSERR)
- return NULL;
- de = g_hash_table_lookup(path_hash, path);
- if(de != NULL)
- gn_dirent_ref(de);
- GNUNET_semaphore_up(path_sema);
- return de;
-}
-
-/*
- * Release a reference to a dirent
- */
-void gn_dirent_put(struct dirent *de)
-{
- GNUNET_mutex_lock(de->de_refs_mutex);
- de->de_refs--;
- if(de->de_refs >= 1)
- {
- GNUNET_mutex_unlock(de->de_refs_mutex);
- return;
- }
- GNUNET_mutex_unlock(de->de_refs_mutex);
- GNUNET_mutex_destroy(de->de_path_mutex);
- GNUNET_free(de->de_path);
- GNUNET_mutex_destroy(de->de_refs_mutex);
- GNUNET_semaphore_destroy(de->de_sema);
- if(de->de_fi.uri != NULL)
- GNUNET_ECRS_uri_destroy(de->de_fi.uri);
- if(de->de_fi.meta != NULL)
- GNUNET_meta_data_destroy(de->de_fi.meta);
- if(de->de_type == DE_DIR)
- {
- if(de->de_cached)
- {
- g_hash_table_destroy(de->de_dir_hash);
- }
- }
- else
- {
- if(de->de_cached)
- {
- close(de->de_fd);
- unlink(de->de_filename);
- GNUNET_free(de->de_filename);
- }
- }
- GNUNET_free(de);
-}
-
-char *gn_dirent_path_get(struct dirent *de)
-{
- char *ret;
-
- GNUNET_mutex_lock(de->de_path_mutex);
- ret = GNUNET_strdup(de->de_path);
- GNUNET_mutex_unlock(de->de_path_mutex);
- return ret;
-}
-
-/*
- * DON'T call this if the dirent is ref'd by a hash
- */
-void gn_dirent_path_set(struct dirent *de, const char *path)
-{
- GNUNET_mutex_lock(de->de_path_mutex);
- GNUNET_free(de->de_path);
- de->de_path = GNUNET_strdup(path);
- de->de_basename = strrchr(de->de_path, G_DIR_SEPARATOR) + 1;
- GNUNET_mutex_unlock(de->de_path_mutex);
-}
-
-void gn_dirent_cache_init(void)
-{
- path_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)gn_dirent_put);
- path_sema = GNUNET_semaphore_create(1);
-}
-
-/*
- * Create a new dirent with a reference, path and uri are copied
- */
-struct dirent *gn_dirent_new(const gchar *path, struct GNUNET_ECRS_URI *uri,
- struct GNUNET_MetaData *meta, gchar type)
-{
- struct dirent *de;
-
- de = GNUNET_malloc(sizeof(*de));
- de->de_path_mutex = GNUNET_mutex_create(0);
- de->de_path = GNUNET_strdup(path);
- de->de_basename = strrchr(de->de_path, G_DIR_SEPARATOR) + 1;
- de->de_refs_mutex = GNUNET_mutex_create(0);
- de->de_refs = 1;
- de->de_type = type;
- de->de_sema = GNUNET_semaphore_create(1);
- if(uri != NULL)
- {
- de->de_dirty = 0;
- de->de_cached = 0;
- de->de_fi.uri = GNUNET_ECRS_uri_duplicate(uri);
- }
- else
- {
- de->de_dirty = 1;
- de->de_cached = 1;
- if(type == DE_FILE)
- {
- char filename[] = GN_MKSTEMP_FILE;
-
- de->de_fd = mkstemp(filename);
- de->de_filename = GNUNET_strdup(filename);
- }
- else
- {
- de->de_dir_hash = g_hash_table_new_full(g_str_hash,
- g_str_equal, NULL,
- (GDestroyNotify)gn_dirent_put);
- }
- }
- if(meta == NULL)
- de->de_fi.meta = GNUNET_meta_data_create();
- else
- de->de_fi.meta = GNUNET_meta_data_duplicate(meta);
- return de;
-}
-
-/*
- * Add a dirent to the cache
- */
-void gn_dirent_cache_insert(struct dirent *de)
-{
- /* TODO: Here we need to see if the cache has gotten too big and empty
- * it.
- * XXX: But what about diry entries?? */
- if(GNUNET_semaphore_down(path_sema, GNUNET_YES) == GNUNET_SYSERR)
- return;
- GNUNET_mutex_lock(de->de_path_mutex);
- GNUNET_GE_ASSERT(ectx, !g_hash_table_lookup(path_hash, de->de_path));
- g_hash_table_replace(path_hash, de->de_path, de);
- GNUNET_mutex_unlock(de->de_path_mutex);
- gn_dirent_ref(de);
- GNUNET_semaphore_up(path_sema);
-}
-
-/*
- * Remove a dirent from the cache
- */
-void gn_dirent_cache_remove(struct dirent *de)
-{
- if(GNUNET_semaphore_down(path_sema, GNUNET_YES) == GNUNET_SYSERR)
- return;
- /* This is safe because we still hold a ref */
- GNUNET_mutex_lock(de->de_path_mutex);
- g_hash_table_remove(path_hash, de->de_path);
- GNUNET_mutex_unlock(de->de_path_mutex);
- GNUNET_semaphore_up(path_sema);
-}
-
-/*
- * Call 'cb' for each element in 'path', treats the empty string as "/"
- */
-int gn_path_foreach(const gchar *path, gn_dir_foreach_callback cb, void *data)
-{
- struct dirent *de, *next_de;
- size_t len, plen;
- gchar *ppath, *filename;
-
- /* Start de off at the root */
- de = root_de;
- gn_dirent_ref(de);
-
- /* Allocate partial path buffer */
- len = strlen(path);
- ppath = GNUNET_malloc(len + 1);
- plen = 0;
-
- /* Loop through each path element */
- for( ; ; )
- {
- /* Do callback for current element */
- if(cb(de, data))
- break;
-
- /* Do we have any more work to do? */
- if(plen >= len || path[plen + 1] == '\0'
- || path[plen + 1] == G_DIR_SEPARATOR)
- {
- break;
- }
-
- /* Save pointer to ppath end */
- filename = &ppath[plen + 1];
-
- /* Cat next path component */
- ppath[plen] = G_DIR_SEPARATOR;
- for(plen++; path[plen] != '\0' && path[plen] != G_DIR_SEPARATOR;
- plen++)
- {
- ppath[plen] = path[plen];
- }
- ppath[plen] = '\0';
-
- /* Look it up in the cache first */
- next_de = gn_dirent_get(ppath);
-
- /* If we found it then continue */
- if(next_de != NULL)
- {
- gn_dirent_put(de);
- de = next_de;
- continue;
- }
-
- /* We need to find it by listing its parent directory, de */
- next_de = gn_directory_find(de, filename);
-
- /* Not found? */
- if(next_de == NULL)
- {
- gn_dirent_put(de);
- de = NULL;
- break;
- }
-
- /* Continue to the next path element */
- gn_dirent_put(de);
- de = next_de;
- }
-
- /* Done */
- GNUNET_free(ppath);
- if(de == NULL)
- return -1;
- gn_dirent_put(de);
- return 0;
-}
-
-static gboolean dirent_find_callback(struct dirent *de, void *data)
-{
- struct dirent **d = data;
-
- if(*d != NULL)
- gn_dirent_put(*d);
- *d = de;
- gn_dirent_ref(*d);
- return 0;
-}
-
-/*
- * Retrieve a dirent with a reference given it's (normalized) path.
- */
-struct dirent *gn_dirent_find(const gchar *path)
-{
- struct dirent *de = NULL;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: called for '%s'\n", __FUNCTION__, path);
- if(gn_path_foreach(path, dirent_find_callback, &de) == -1)
- {
- if(de != NULL)
- gn_dirent_put(de);
- return NULL;
- }
- return de;
-}
-
-static gboolean lock_path_callback(struct dirent *de, void *data)
-{
- struct dirent **detmp = data;
-
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == -1)
- return 1;
- gn_dirent_ref(de);
- *detmp = de;
- return 0;
-}
-
-/*
- * Locks each element in a path.
- */
-int gn_lock_path(struct dirent *de)
-{
- struct dirent *detmp = NULL;
- char *path;
-
- path = gn_dirent_path_get(de);
- if(gn_path_foreach(path, lock_path_callback, &detmp) == -1)
- {
- GNUNET_free(path);
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: failed!\n", __FUNCTION__);
- /* Back out all the locks we aquired */
- if(detmp != NULL)
- gn_unlock_path(detmp, GN_UNLOCK_CLEAN);
- return -1;
- }
- GNUNET_free(path);
- return 0;
-}
-
-struct unlock_path_data
-{
- int dirty;
- struct dirent *de;
-};
-
-static gboolean unlock_path_callback(struct dirent *de, void *data)
-{
- struct unlock_path_data *d = data;
-
- if(d->dirty == GN_UNLOCK_ALL_DIRTY)
- de->de_dirty = 1;
- else if(d->dirty == GN_UNLOCK_ANCESTORS_DIRTY && de != d->de)
- de->de_dirty = 1;
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- return 0;
-}
-
-/*
- * Un-lock each element in a path and set the dirty state
- */
-int gn_unlock_path(struct dirent *de, int dirty)
-{
- struct unlock_path_data d;
- char *path;
-
- d.dirty = dirty;
- d.de = de;
- path = gn_dirent_path_get(de);
- if(gn_path_foreach(path, unlock_path_callback, &d) == -1)
- {
- GNUNET_free(path);
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: failed!\n", __FUNCTION__);
- return -1;
- }
- GNUNET_free(path);
- return 0;
-}
Deleted: gnunet-fuse/file.c
===================================================================
--- gnunet-fuse/file.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/file.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,126 +0,0 @@
-/*
- * file.c - operations on files
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <sys/mman.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <glib.h>
-#include <GNUnet/gnunet_ecrs_lib.h>
-#include "gnfs.h"
-
-static int tt(void *cls)
-{
- (void)cls;
- if(closing)
- return GNUNET_OK;
- if(fuse_interrupted())
- return GNUNET_SYSERR;
- return GNUNET_OK;
-}
-
-static void upcb(unsigned long long totalBytes,
- unsigned long long completedBytes, GNUNET_CronTime eta,
- void *closure)
-{
- (void)totalBytes;
- (void)completedBytes;
- (void)eta;
- (void)closure;
-}
-
-static void dpcb(unsigned long long totalBytes,
- unsigned long long completedBytes, GNUNET_CronTime eta,
- unsigned long long lastBlockOffset, const char *lastBlock,
- unsigned int lastBlockSize, void *cls)
-{
- (void)totalBytes;
- (void)completedBytes;
- (void)eta;
- (void)lastBlockOffset;
- (void)lastBlock;
- (void)lastBlockSize;
- (void)cls;
-}
-
-/*
- * Download a file for writing, de_sema must be held.
- */
-int gn_file_download_locked(struct dirent *de)
-{
- char filename[] = GN_MKSTEMP_FILE;
-
- /* We may already be cached */
- if(de->de_cached)
- return 0;
-
- /* Do the download */
- de->de_fd = mkstemp(filename);
- if(de->de_fd == -1)
- {
- GNUNET_GE_LOG_STRERROR_FILE(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER
- | GNUNET_GE_ERROR, "mkstemp", filename);
- return -1;
- }
- de->de_filename = GNUNET_strdup(filename);
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: downloading '%s'\n", __FUNCTION__, de->de_filename);
- if(GNUNET_ECRS_file_download(ectx, cfg, de->de_fi.uri, filename,
anonymity,
- dpcb, NULL, tt, NULL) == GNUNET_SYSERR)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: download failed\n", __FUNCTION__);
- close(de->de_fd);
- unlink(de->de_filename);
- GNUNET_free(de->de_filename);
- return -1;
- }
-
- /* Mark ourselves cached */
- de->de_cached = 1;
- return 0;
-}
-
-int gn_file_upload_locked(struct dirent *de)
-{
- struct GNUNET_ECRS_URI *uri;
-
- /* If we're not dirty then we're done */
- if(!de->de_dirty)
- return 0;
-
- if(GNUNET_ECRS_file_upload(ectx, cfg, de->de_filename, GNUNET_NO,
anonymity, priority,
- -1, upcb, NULL, tt, NULL, &uri) == GNUNET_SYSERR)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
- "%s: upload failed\n", __FUNCTION__);
- return -1;
- }
- if(de->de_fi.uri != NULL)
- GNUNET_ECRS_uri_destroy(de->de_fi.uri);
- de->de_fi.uri = uri;
- de->de_cached = 0;
- de->de_dirty = 0;
- close(de->de_fd);
- unlink(de->de_filename);
- GNUNET_free(de->de_filename);
- return 0;
-}
Deleted: gnunet-fuse/getattr.c
===================================================================
--- gnunet-fuse/getattr.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/getattr.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,86 +0,0 @@
-/*
- * getattr.c - FUSE getattr function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_getattr(const char *path, struct stat *stbuf)
-{
- struct dirent *de;
- int ret = 0;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* Check to see if this is a special file */
- if(gn_exists_special_file(path))
- {
- memset(stbuf, 0, sizeof(*stbuf));
- stbuf->st_mode = 0555 | S_IFREG;
- stbuf->st_nlink = 1;
- /* sysfs uses 4096 for variable sized files */
- stbuf->st_size = 4096;
- return 0;
- }
-
- /* Fill in dirent stat info */
- de = gn_dirent_find(path);
- if(de == NULL)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_DEBUG,
- "%s: could not find path '%s'\n", __FUNCTION__, path);
- return -ENOENT;
- }
-
- /* If it's a cached file just call stat */
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
- {
- gn_dirent_put(de);
- return -EIO;
- }
- if(de->de_cached && de->de_type == DE_FILE)
- {
- ret = stat(de->de_filename, stbuf);
- if(ret == -1)
- {
- ret = -errno;
- GNUNET_GE_LOG_STRERROR(ectx, GNUNET_GE_BULK |
GNUNET_GE_USER | GNUNET_GE_ERROR,
- "stat");
- goto out;
- }
- goto out;
- }
-
- memset(stbuf, 0, sizeof(*stbuf));
- stbuf->st_mode = 0777;
- stbuf->st_mode |= de->de_type == DE_DIR ? S_IFDIR : S_IFREG;
- stbuf->st_nlink = 1;
- if(de->de_fi.uri != NULL)
- stbuf->st_size = GNUNET_ECRS_uri_get_file_size(de->de_fi.uri);
- else
- stbuf->st_size = 0;
-out:
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- return ret;
-}
Copied: gnunet-fuse/gnunet-fuse-v8/directory.c (from rev 20388,
gnunet-fuse/directory.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/directory.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/directory.c 2012-03-09 08:38:54 UTC (rev
20389)
@@ -0,0 +1,429 @@
+/*
+ * directory.c - stuff you want to do with directories
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <GNUnet/gnunet_ecrs_lib.h>
+#include "gnfs.h"
+
+static void dpcb(unsigned long long totalBytes,
+ unsigned long long completedBytes, GNUNET_CronTime eta,
+ unsigned long long lastBlockOffset, const char *lastBlock,
+ unsigned int lastBlockSize, void *cls)
+{
+ (void)totalBytes;
+ (void)completedBytes;
+ (void)eta;
+ memcpy((char *)cls + lastBlockOffset, lastBlock, lastBlockSize);
+}
+
+static int tt(void *cls)
+{
+ (void)cls;
+ if(closing)
+ return GNUNET_OK;
+ if(fuse_interrupted())
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
+}
+
+static int dir_cache_cb(const GNUNET_ECRS_FileInfo *fi, const GNUNET_HashCode
*key,
+ int isRoot, void *data)
+{
+ struct dirent *de, *deparent = data;
+ gchar *filename, *path, *newpath, type;
+ size_t len, rlen;
+
+ (void)key;
+
+ if(isRoot == GNUNET_YES)
+ return GNUNET_OK;
+
+ /* Figure out the filename and type from metadata */
+ filename = GNUNET_meta_data_get_by_type(fi->meta, EXTRACTOR_FILENAME);
+ if(filename == NULL)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_WARNING,
+ "%s: dirent has no filename\n", __FUNCTION__);
+ return GNUNET_OK;
+ }
+ len = strlen(filename);
+ if(GNUNET_meta_data_test_for_directory(fi->meta) == GNUNET_YES)
+ {
+ if(filename[len - 1] == '/' || filename[len - 1] == '\\')
+ filename[len - 1] = '\0';
+ type = DE_DIR;
+ }
+ else
+ type = DE_FILE;
+
+ /* Create newpath, the path to this entry */
+ path = gn_dirent_path_get(deparent);
+ rlen = strlen(path);
+ newpath = GNUNET_malloc(rlen + len + 1);
+ strcpy(newpath, path);
+ if(path[rlen - 1] != G_DIR_SEPARATOR)
+ strcat(newpath, G_DIR_SEPARATOR_S);
+ GNUNET_free(path);
+ strcat(newpath, filename);
+
+ /* Create a new dirent for this entry only if one doesn't already exist
+ * and the only place that can be is in the cache */
+ de = gn_dirent_get(newpath);
+ if(de == NULL)
+ {
+ de = gn_dirent_new(newpath, fi->uri, fi->meta, type);
+
+ /* Add it to the cache (creates its own ref)*/
+ /* NB: the lock on deparent is enough to guarantee that another
+ * thread hasn't added this dirent to the cache in the time
+ * between the above check and this insert */
+ gn_dirent_cache_insert(de);
+ }
+
+ /* Add it to the directory's list (steals our ref)*/
+ GNUNET_mutex_lock(de->de_path_mutex);
+ GNUNET_GE_ASSERT(ectx,
+ !g_hash_table_lookup(deparent->de_dir_hash, de->de_basename));
+ g_hash_table_replace(deparent->de_dir_hash, de->de_basename, de);
+ GNUNET_mutex_unlock(de->de_path_mutex);
+
+ /* Clean up */
+ GNUNET_free(filename);
+ GNUNET_free(newpath);
+ return GNUNET_OK;
+}
+
+static int directory_cache_locked(struct dirent *de)
+{
+ struct GNUNET_MetaData *md;
+ void *mem;
+ int ret;
+ guint64 len;
+
+ len = GNUNET_ECRS_uri_get_file_size(de->de_fi.uri);
+ mem = GNUNET_malloc(len);
+ ret = GNUNET_ECRS_file_download_partial(ectx, cfg, de->de_fi.uri,
+ "/dev/null", 0, len, anonymity, GNUNET_YES, dpcb, mem, tt,
+ NULL);
+ if(ret != GNUNET_OK)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_ERROR,
+ "%s: failed to download directory\n",
+ __FUNCTION__);
+ GNUNET_free(mem);
+ return -1;
+ }
+ de->de_dir_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)gn_dirent_put);
+ GNUNET_ECRS_directory_list_contents(ectx, mem, len, NULL, &md,
dir_cache_cb, de);
+ GNUNET_free(mem);
+ GNUNET_meta_data_destroy(md);
+ de->de_cached = 1;
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: cached %d entries\n", __FUNCTION__,
+ g_hash_table_size(de->de_dir_hash));
+ return 0;
+}
+
+struct dir_foreach_data
+{
+ gn_dir_foreach_callback cb;
+ void *data;
+};
+
+static gboolean dir_foreach_callback(gpointer key, gpointer value,
+ gpointer data)
+{
+ struct dirent *de = value;
+ struct dir_foreach_data *d = data;
+
+ (void)key;
+ return d->cb(de, d->data) == -1;
+}
+
+/*
+ * Call cb for each element in a directory
+ */
+int gn_directory_foreach(struct dirent *de, gn_dir_foreach_callback cb,
+ void *data)
+{
+ struct dir_foreach_data d;
+ int ret = 0;
+
+ if(de->de_type != DE_DIR)
+ return -1;
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
+ return -1;
+ if(!de->de_cached)
+ {
+ ret = directory_cache_locked(de);
+ if(ret == -1)
+ goto out;
+ }
+ d.cb = cb;
+ d.data = data;
+ g_hash_table_find(de->de_dir_hash, dir_foreach_callback, &d);
+out:
+ GNUNET_semaphore_up(de->de_sema);
+ return ret;
+}
+
+/*
+ * Finds 'filename' in directory 'de' and returns a reference or NULL
+ */
+struct dirent *gn_directory_find(struct dirent *de, const gchar *filename)
+{
+ struct dirent *ret = NULL;
+
+ if(de->de_type != DE_DIR)
+ return NULL;
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
+ return NULL;
+ if(!de->de_cached)
+ {
+ if(directory_cache_locked(de) == -1)
+ goto out;
+ }
+ ret = g_hash_table_lookup(de->de_dir_hash, filename);
+ if(ret != NULL)
+ gn_dirent_ref(ret);
+out:
+ GNUNET_semaphore_up(de->de_sema);
+ return ret;
+}
+
+int gn_directory_insert(struct dirent *de, struct dirent *dechild)
+{
+ /* Lock our path */
+ if(gn_lock_path(de) == -1)
+ return -1;
+
+ /* Cache ourselfs (because we're going to become dirty) */
+ if(!de->de_cached)
+ {
+ if(directory_cache_locked(de) == -1)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER | GNUNET_GE_DEBUG,
+ "%s: failed to cache parent dir\n",
+ __FUNCTION__);
+ gn_unlock_path(de, GN_UNLOCK_CLEAN);
+ return -1;
+ }
+ }
+
+ /* If we're already in there, bail out */
+ GNUNET_mutex_lock(dechild->de_path_mutex);
+ if(g_hash_table_lookup(de->de_dir_hash, dechild->de_basename))
+ {
+ GNUNET_mutex_unlock(dechild->de_path_mutex);
+ gn_unlock_path(de, GN_UNLOCK_CLEAN);
+ return -1;
+ }
+
+ /* Insert the child in our de_dir_hash */
+ gn_dirent_ref(dechild);
+ g_hash_table_replace(de->de_dir_hash, dechild->de_basename, dechild);
+ GNUNET_mutex_unlock(dechild->de_path_mutex);
+
+ /* Cache the dirent */
+ gn_dirent_cache_insert(dechild);
+
+ /* Mark our path dirty */
+ gn_unlock_path(de, GN_UNLOCK_ALL_DIRTY);
+ return 0;
+}
+
+int gn_directory_remove(struct dirent *de, struct dirent *dechild)
+{
+ /* Lock our path */
+ if(gn_lock_path(de) == -1)
+ return -1;
+
+ /* Cache ourselfs (because we're going to become dirty) */
+ if(!de->de_cached)
+ {
+ if(directory_cache_locked(de) == -1)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER | GNUNET_GE_ERROR,
+ "%s: failed to cache parent dir\n",
+ __FUNCTION__);
+ goto out_err;
+ }
+ }
+
+ /* Remove from dir_hash */
+ GNUNET_mutex_lock(dechild->de_path_mutex);
+ if(!g_hash_table_remove(de->de_dir_hash, dechild->de_basename))
+ {
+ GNUNET_mutex_unlock(dechild->de_path_mutex);
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: not found in dir_hash\n",
+ __FUNCTION__);
+ goto out_err;
+ }
+ GNUNET_mutex_unlock(dechild->de_path_mutex);
+
+ /* Remove from dirent cache */
+ gn_dirent_cache_remove(dechild);
+
+ /* Mark our path dirty */
+ gn_unlock_path(de, GN_UNLOCK_ALL_DIRTY);
+ return 0;
+out_err:
+ gn_unlock_path(de, GN_UNLOCK_CLEAN);
+ return -1;
+}
+
+static void upcb(unsigned long long totalBytes,
+ unsigned long long completedBytes, GNUNET_CronTime eta,
+ void *closure)
+{
+ (void)totalBytes;
+ (void)completedBytes;
+ (void)eta;
+ (void)closure;
+}
+
+struct dir_upload_data
+{
+ GNUNET_ECRS_FileInfo *fis;
+ int count;
+ int failed;
+};
+
+static gboolean dir_upload_callback(gpointer key, gpointer value, gpointer
data)
+{
+ struct dirent *de = value;
+ struct dir_upload_data *d = data;
+ int ret = 0;
+
+ (void)key;
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
+ {
+ d->failed = 1;
+ return 1;
+ }
+ if(de->de_dirty)
+ {
+ if(de->de_type == DE_FILE)
+ {
+ if(de->de_fi.uri == NULL)
+ {
+ goto out;
+ }
+ }
+ else
+ {
+ if(gn_directory_upload_locked(de) == -1)
+ {
+ d->failed = 1;
+ ret = 1;
+ goto out;
+ }
+ }
+ }
+ d->fis[d->count].uri = GNUNET_ECRS_uri_duplicate(de->de_fi.uri);
+ d->fis[d->count].meta = GNUNET_meta_data_duplicate(de->de_fi.meta);
+ d->count++;
+out:
+ GNUNET_semaphore_up(de->de_sema);
+ return ret;
+}
+
+/*
+ * Make a directory clean, de_sema must be locked
+ */
+int gn_directory_upload_locked(struct dirent *de)
+{
+ int i, ret, fd;
+ char *buf, filename[] = GN_MKSTEMP_FILE;
+ unsigned long long len;
+ struct GNUNET_ECRS_URI *uri;
+ struct dir_upload_data d;
+
+ /* We may be already clean */
+ if(!de->de_dirty)
+ return 0;
+
+ /* Collect FileInfo from hash table and make a GNUnet directory */
+ d.fis = GNUNET_malloc(g_hash_table_size(de->de_dir_hash) *
sizeof(*d.fis));
+ d.count = 0;
+ d.failed = 0;
+ g_hash_table_find(de->de_dir_hash, dir_upload_callback, &d);
+ if(d.failed)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: failed\n", __FUNCTION__);
+ return -1;
+ }
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: creating dir of %d elements\n", __FUNCTION__, d.count);
+ ret = GNUNET_ECRS_directory_create(ectx, &buf, &len, d.count, d.fis,
+ de->de_fi.meta);
+ for(i = 0; i < d.count; i++)
+ {
+ GNUNET_ECRS_uri_destroy(d.fis[i].uri);
+ GNUNET_meta_data_destroy(d.fis[i].meta);
+ }
+ GNUNET_free(d.fis);
+ if(ret == GNUNET_SYSERR)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: GNUNET_ECRS_directory_create failed\n",
+ __FUNCTION__);
+ return -1;
+ }
+
+ /* Write the GNUnet directory out to a file and upload it */
+ fd = mkstemp(filename);
+ if(fd == -1)
+ {
+ GNUNET_GE_LOG_STRERROR_FILE(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER
+ | GNUNET_GE_ERROR, "mkstemp", filename);
+ return -1;
+ }
+ write(fd, buf, len);
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: wrote to %lld bytes to '%s'\n", __FUNCTION__, len,
+ filename);
+ ret = GNUNET_ECRS_file_upload(ectx, cfg, filename, GNUNET_NO,
anonymity, priority,
+ -1, upcb, NULL, tt, NULL, &uri);
+ close(fd);
+ unlink(filename);
+ if(ret == GNUNET_SYSERR)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: GNUNET_ECRS_file_upload failed\n", __FUNCTION__);
+ return -1;
+ }
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: done\n", __FUNCTION__);
+ /* Update the dirent info with our new URI and mark it clean */
+ if(de->de_fi.uri != NULL)
+ GNUNET_ECRS_uri_destroy(de->de_fi.uri);
+ de->de_fi.uri = uri;
+ de->de_dirty = 0;
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/dirent.c (from rev 20388,
gnunet-fuse/dirent.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/dirent.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/dirent.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,385 @@
+/*
+ * dirent.c - stuff for directory entries
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <unistd.h>
+#include <glib.h>
+#include <string.h>
+#include <errno.h>
+#include "gnfs.h"
+
+GHashTable *path_hash;
+struct GNUNET_Semaphore *path_sema;
+
+/*
+ * Reference a dirent, call gn_dirent_put when finished
+ */
+void gn_dirent_ref(struct dirent *de)
+{
+ GNUNET_mutex_lock(de->de_refs_mutex);
+ de->de_refs++;
+ GNUNET_mutex_unlock(de->de_refs_mutex);
+}
+
+/*
+ * Reference a dirent from the cache, call gn_dirent_put when finished with it
+ */
+struct dirent *gn_dirent_get(const gchar *path)
+{
+ struct dirent *de;
+
+ if(GNUNET_semaphore_down(path_sema, GNUNET_YES) == GNUNET_SYSERR)
+ return NULL;
+ de = g_hash_table_lookup(path_hash, path);
+ if(de != NULL)
+ gn_dirent_ref(de);
+ GNUNET_semaphore_up(path_sema);
+ return de;
+}
+
+/*
+ * Release a reference to a dirent
+ */
+void gn_dirent_put(struct dirent *de)
+{
+ GNUNET_mutex_lock(de->de_refs_mutex);
+ de->de_refs--;
+ if(de->de_refs >= 1)
+ {
+ GNUNET_mutex_unlock(de->de_refs_mutex);
+ return;
+ }
+ GNUNET_mutex_unlock(de->de_refs_mutex);
+ GNUNET_mutex_destroy(de->de_path_mutex);
+ GNUNET_free(de->de_path);
+ GNUNET_mutex_destroy(de->de_refs_mutex);
+ GNUNET_semaphore_destroy(de->de_sema);
+ if(de->de_fi.uri != NULL)
+ GNUNET_ECRS_uri_destroy(de->de_fi.uri);
+ if(de->de_fi.meta != NULL)
+ GNUNET_meta_data_destroy(de->de_fi.meta);
+ if(de->de_type == DE_DIR)
+ {
+ if(de->de_cached)
+ {
+ g_hash_table_destroy(de->de_dir_hash);
+ }
+ }
+ else
+ {
+ if(de->de_cached)
+ {
+ close(de->de_fd);
+ unlink(de->de_filename);
+ GNUNET_free(de->de_filename);
+ }
+ }
+ GNUNET_free(de);
+}
+
+char *gn_dirent_path_get(struct dirent *de)
+{
+ char *ret;
+
+ GNUNET_mutex_lock(de->de_path_mutex);
+ ret = GNUNET_strdup(de->de_path);
+ GNUNET_mutex_unlock(de->de_path_mutex);
+ return ret;
+}
+
+/*
+ * DON'T call this if the dirent is ref'd by a hash
+ */
+void gn_dirent_path_set(struct dirent *de, const char *path)
+{
+ GNUNET_mutex_lock(de->de_path_mutex);
+ GNUNET_free(de->de_path);
+ de->de_path = GNUNET_strdup(path);
+ de->de_basename = strrchr(de->de_path, G_DIR_SEPARATOR) + 1;
+ GNUNET_mutex_unlock(de->de_path_mutex);
+}
+
+void gn_dirent_cache_init(void)
+{
+ path_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)gn_dirent_put);
+ path_sema = GNUNET_semaphore_create(1);
+}
+
+/*
+ * Create a new dirent with a reference, path and uri are copied
+ */
+struct dirent *gn_dirent_new(const gchar *path, struct GNUNET_ECRS_URI *uri,
+ struct GNUNET_MetaData *meta, gchar type)
+{
+ struct dirent *de;
+
+ de = GNUNET_malloc(sizeof(*de));
+ de->de_path_mutex = GNUNET_mutex_create(0);
+ de->de_path = GNUNET_strdup(path);
+ de->de_basename = strrchr(de->de_path, G_DIR_SEPARATOR) + 1;
+ de->de_refs_mutex = GNUNET_mutex_create(0);
+ de->de_refs = 1;
+ de->de_type = type;
+ de->de_sema = GNUNET_semaphore_create(1);
+ if(uri != NULL)
+ {
+ de->de_dirty = 0;
+ de->de_cached = 0;
+ de->de_fi.uri = GNUNET_ECRS_uri_duplicate(uri);
+ }
+ else
+ {
+ de->de_dirty = 1;
+ de->de_cached = 1;
+ if(type == DE_FILE)
+ {
+ char filename[] = GN_MKSTEMP_FILE;
+
+ de->de_fd = mkstemp(filename);
+ de->de_filename = GNUNET_strdup(filename);
+ }
+ else
+ {
+ de->de_dir_hash = g_hash_table_new_full(g_str_hash,
+ g_str_equal, NULL,
+ (GDestroyNotify)gn_dirent_put);
+ }
+ }
+ if(meta == NULL)
+ de->de_fi.meta = GNUNET_meta_data_create();
+ else
+ de->de_fi.meta = GNUNET_meta_data_duplicate(meta);
+ return de;
+}
+
+/*
+ * Add a dirent to the cache
+ */
+void gn_dirent_cache_insert(struct dirent *de)
+{
+ /* TODO: Here we need to see if the cache has gotten too big and empty
+ * it.
+ * XXX: But what about diry entries?? */
+ if(GNUNET_semaphore_down(path_sema, GNUNET_YES) == GNUNET_SYSERR)
+ return;
+ GNUNET_mutex_lock(de->de_path_mutex);
+ GNUNET_GE_ASSERT(ectx, !g_hash_table_lookup(path_hash, de->de_path));
+ g_hash_table_replace(path_hash, de->de_path, de);
+ GNUNET_mutex_unlock(de->de_path_mutex);
+ gn_dirent_ref(de);
+ GNUNET_semaphore_up(path_sema);
+}
+
+/*
+ * Remove a dirent from the cache
+ */
+void gn_dirent_cache_remove(struct dirent *de)
+{
+ if(GNUNET_semaphore_down(path_sema, GNUNET_YES) == GNUNET_SYSERR)
+ return;
+ /* This is safe because we still hold a ref */
+ GNUNET_mutex_lock(de->de_path_mutex);
+ g_hash_table_remove(path_hash, de->de_path);
+ GNUNET_mutex_unlock(de->de_path_mutex);
+ GNUNET_semaphore_up(path_sema);
+}
+
+/*
+ * Call 'cb' for each element in 'path', treats the empty string as "/"
+ */
+int gn_path_foreach(const gchar *path, gn_dir_foreach_callback cb, void *data)
+{
+ struct dirent *de, *next_de;
+ size_t len, plen;
+ gchar *ppath, *filename;
+
+ /* Start de off at the root */
+ de = root_de;
+ gn_dirent_ref(de);
+
+ /* Allocate partial path buffer */
+ len = strlen(path);
+ ppath = GNUNET_malloc(len + 1);
+ plen = 0;
+
+ /* Loop through each path element */
+ for( ; ; )
+ {
+ /* Do callback for current element */
+ if(cb(de, data))
+ break;
+
+ /* Do we have any more work to do? */
+ if(plen >= len || path[plen + 1] == '\0'
+ || path[plen + 1] == G_DIR_SEPARATOR)
+ {
+ break;
+ }
+
+ /* Save pointer to ppath end */
+ filename = &ppath[plen + 1];
+
+ /* Cat next path component */
+ ppath[plen] = G_DIR_SEPARATOR;
+ for(plen++; path[plen] != '\0' && path[plen] != G_DIR_SEPARATOR;
+ plen++)
+ {
+ ppath[plen] = path[plen];
+ }
+ ppath[plen] = '\0';
+
+ /* Look it up in the cache first */
+ next_de = gn_dirent_get(ppath);
+
+ /* If we found it then continue */
+ if(next_de != NULL)
+ {
+ gn_dirent_put(de);
+ de = next_de;
+ continue;
+ }
+
+ /* We need to find it by listing its parent directory, de */
+ next_de = gn_directory_find(de, filename);
+
+ /* Not found? */
+ if(next_de == NULL)
+ {
+ gn_dirent_put(de);
+ de = NULL;
+ break;
+ }
+
+ /* Continue to the next path element */
+ gn_dirent_put(de);
+ de = next_de;
+ }
+
+ /* Done */
+ GNUNET_free(ppath);
+ if(de == NULL)
+ return -1;
+ gn_dirent_put(de);
+ return 0;
+}
+
+static gboolean dirent_find_callback(struct dirent *de, void *data)
+{
+ struct dirent **d = data;
+
+ if(*d != NULL)
+ gn_dirent_put(*d);
+ *d = de;
+ gn_dirent_ref(*d);
+ return 0;
+}
+
+/*
+ * Retrieve a dirent with a reference given it's (normalized) path.
+ */
+struct dirent *gn_dirent_find(const gchar *path)
+{
+ struct dirent *de = NULL;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: called for '%s'\n", __FUNCTION__, path);
+ if(gn_path_foreach(path, dirent_find_callback, &de) == -1)
+ {
+ if(de != NULL)
+ gn_dirent_put(de);
+ return NULL;
+ }
+ return de;
+}
+
+static gboolean lock_path_callback(struct dirent *de, void *data)
+{
+ struct dirent **detmp = data;
+
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == -1)
+ return 1;
+ gn_dirent_ref(de);
+ *detmp = de;
+ return 0;
+}
+
+/*
+ * Locks each element in a path.
+ */
+int gn_lock_path(struct dirent *de)
+{
+ struct dirent *detmp = NULL;
+ char *path;
+
+ path = gn_dirent_path_get(de);
+ if(gn_path_foreach(path, lock_path_callback, &detmp) == -1)
+ {
+ GNUNET_free(path);
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: failed!\n", __FUNCTION__);
+ /* Back out all the locks we aquired */
+ if(detmp != NULL)
+ gn_unlock_path(detmp, GN_UNLOCK_CLEAN);
+ return -1;
+ }
+ GNUNET_free(path);
+ return 0;
+}
+
+struct unlock_path_data
+{
+ int dirty;
+ struct dirent *de;
+};
+
+static gboolean unlock_path_callback(struct dirent *de, void *data)
+{
+ struct unlock_path_data *d = data;
+
+ if(d->dirty == GN_UNLOCK_ALL_DIRTY)
+ de->de_dirty = 1;
+ else if(d->dirty == GN_UNLOCK_ANCESTORS_DIRTY && de != d->de)
+ de->de_dirty = 1;
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ return 0;
+}
+
+/*
+ * Un-lock each element in a path and set the dirty state
+ */
+int gn_unlock_path(struct dirent *de, int dirty)
+{
+ struct unlock_path_data d;
+ char *path;
+
+ d.dirty = dirty;
+ d.de = de;
+ path = gn_dirent_path_get(de);
+ if(gn_path_foreach(path, unlock_path_callback, &d) == -1)
+ {
+ GNUNET_free(path);
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: failed!\n", __FUNCTION__);
+ return -1;
+ }
+ GNUNET_free(path);
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/file.c (from rev 20388, gnunet-fuse/file.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/file.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/file.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,126 @@
+/*
+ * file.c - operations on files
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <GNUnet/gnunet_ecrs_lib.h>
+#include "gnfs.h"
+
+static int tt(void *cls)
+{
+ (void)cls;
+ if(closing)
+ return GNUNET_OK;
+ if(fuse_interrupted())
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
+}
+
+static void upcb(unsigned long long totalBytes,
+ unsigned long long completedBytes, GNUNET_CronTime eta,
+ void *closure)
+{
+ (void)totalBytes;
+ (void)completedBytes;
+ (void)eta;
+ (void)closure;
+}
+
+static void dpcb(unsigned long long totalBytes,
+ unsigned long long completedBytes, GNUNET_CronTime eta,
+ unsigned long long lastBlockOffset, const char *lastBlock,
+ unsigned int lastBlockSize, void *cls)
+{
+ (void)totalBytes;
+ (void)completedBytes;
+ (void)eta;
+ (void)lastBlockOffset;
+ (void)lastBlock;
+ (void)lastBlockSize;
+ (void)cls;
+}
+
+/*
+ * Download a file for writing, de_sema must be held.
+ */
+int gn_file_download_locked(struct dirent *de)
+{
+ char filename[] = GN_MKSTEMP_FILE;
+
+ /* We may already be cached */
+ if(de->de_cached)
+ return 0;
+
+ /* Do the download */
+ de->de_fd = mkstemp(filename);
+ if(de->de_fd == -1)
+ {
+ GNUNET_GE_LOG_STRERROR_FILE(ectx, GNUNET_GE_BULK |
GNUNET_GE_DEVELOPER
+ | GNUNET_GE_ERROR, "mkstemp", filename);
+ return -1;
+ }
+ de->de_filename = GNUNET_strdup(filename);
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: downloading '%s'\n", __FUNCTION__, de->de_filename);
+ if(GNUNET_ECRS_file_download(ectx, cfg, de->de_fi.uri, filename,
anonymity,
+ dpcb, NULL, tt, NULL) == GNUNET_SYSERR)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: download failed\n", __FUNCTION__);
+ close(de->de_fd);
+ unlink(de->de_filename);
+ GNUNET_free(de->de_filename);
+ return -1;
+ }
+
+ /* Mark ourselves cached */
+ de->de_cached = 1;
+ return 0;
+}
+
+int gn_file_upload_locked(struct dirent *de)
+{
+ struct GNUNET_ECRS_URI *uri;
+
+ /* If we're not dirty then we're done */
+ if(!de->de_dirty)
+ return 0;
+
+ if(GNUNET_ECRS_file_upload(ectx, cfg, de->de_filename, GNUNET_NO,
anonymity, priority,
+ -1, upcb, NULL, tt, NULL, &uri) == GNUNET_SYSERR)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_ERROR,
+ "%s: upload failed\n", __FUNCTION__);
+ return -1;
+ }
+ if(de->de_fi.uri != NULL)
+ GNUNET_ECRS_uri_destroy(de->de_fi.uri);
+ de->de_fi.uri = uri;
+ de->de_cached = 0;
+ de->de_dirty = 0;
+ close(de->de_fd);
+ unlink(de->de_filename);
+ GNUNET_free(de->de_filename);
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/getattr.c (from rev 20388,
gnunet-fuse/getattr.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/getattr.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/getattr.c 2012-03-09 08:38:54 UTC (rev
20389)
@@ -0,0 +1,86 @@
+/*
+ * getattr.c - FUSE getattr function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_getattr(const char *path, struct stat *stbuf)
+{
+ struct dirent *de;
+ int ret = 0;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check to see if this is a special file */
+ if(gn_exists_special_file(path))
+ {
+ memset(stbuf, 0, sizeof(*stbuf));
+ stbuf->st_mode = 0555 | S_IFREG;
+ stbuf->st_nlink = 1;
+ /* sysfs uses 4096 for variable sized files */
+ stbuf->st_size = 4096;
+ return 0;
+ }
+
+ /* Fill in dirent stat info */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_DEBUG,
+ "%s: could not find path '%s'\n", __FUNCTION__, path);
+ return -ENOENT;
+ }
+
+ /* If it's a cached file just call stat */
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
+ {
+ gn_dirent_put(de);
+ return -EIO;
+ }
+ if(de->de_cached && de->de_type == DE_FILE)
+ {
+ ret = stat(de->de_filename, stbuf);
+ if(ret == -1)
+ {
+ ret = -errno;
+ GNUNET_GE_LOG_STRERROR(ectx, GNUNET_GE_BULK |
GNUNET_GE_USER | GNUNET_GE_ERROR,
+ "stat");
+ goto out;
+ }
+ goto out;
+ }
+
+ memset(stbuf, 0, sizeof(*stbuf));
+ stbuf->st_mode = 0777;
+ stbuf->st_mode |= de->de_type == DE_DIR ? S_IFDIR : S_IFREG;
+ stbuf->st_nlink = 1;
+ if(de->de_fi.uri != NULL)
+ stbuf->st_size = GNUNET_ECRS_uri_get_file_size(de->de_fi.uri);
+ else
+ stbuf->st_size = 0;
+out:
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ return ret;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/main.c (from rev 20388, gnunet-fuse/main.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/main.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/main.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,232 @@
+/*
+ * main.c - program start
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <glib.h>
+#include <fuse.h>
+#include <GNUnet/gnunet_directories.h>
+#include <GNUnet/gnunet_util.h>
+#include <GNUnet/gnunet_ecrs_lib.h>
+#include "gnfs.h"
+#include "gettext.h"
+
+struct GNUNET_GC_Configuration *cfg;
+struct GNUNET_GE_Context *ectx;
+static char *cfgFilename = GNUNET_DEFAULT_CLIENT_CONFIG_FILE;
+static char *cfgLogfile = "/tmp/gnunet_fuse.log";
+
+/* Flag to indicate that we are shutting down */
+int closing = 0;
+
+/* Level of anonymity for downloading and uploading files */
+unsigned int anonymity = 1;
+
+/* Priority for uploaded files */
+unsigned int priority = 1000;
+
+/* Flag for including .uri files in readdir() */
+int uri_files = 0;
+
+/* argv and argc to pass to fuse, filled in by main and getopt_configure_argv
*/
+char **fuse_argv;
+int fuse_argc;
+
+/* Root directory entry, currently used by the dirent cache when asked for / */
+int root_fd;
+struct dirent *root_de;
+
+int getopt_configure_argv(GNUNET_CommandLineProcessorContext *ctx, void *scls,
+ const char *cmdLineOption, const char *value)
+{
+ (void)ctx;
+ (void)scls;
+ (void)cmdLineOption;
+
+ fuse_argv[fuse_argc] = (char *)value;
+ fuse_argc++;
+ fuse_argv[fuse_argc] = NULL;
+ return GNUNET_OK;
+}
+
+static struct fuse_operations fops =
+{
+ .getattr = gn_getattr,
+ .mknod = gn_mknod,
+ .mkdir = gn_mkdir,
+ .unlink = gn_unlink,
+ .rmdir = gn_rmdir,
+ .rename = gn_rename,
+ .truncate = gn_truncate,
+ .open = gn_open,
+ .read = gn_read,
+ .write = gn_write,
+ .release = gn_release,
+ .readdir = gn_readdir,
+ .utimens = gn_utimens,
+};
+
+static struct GNUNET_CommandLineOption gn_options[] =
+{
+ GNUNET_COMMAND_LINE_OPTION_HELP("GNUnet filesystem"),
+ GNUNET_COMMAND_LINE_OPTION_CFG_FILE(&cfgFilename), /* -c */
+ GNUNET_COMMAND_LINE_OPTION_LOGGING, /* -L */
+ { 'l', "logfile", "FILE", "set logfile name", 1,
+ &GNUNET_getopt_configure_set_string, &cfgLogfile },
+ { 'a', "anonymity", "LEVEL",
+ "set the desired LEVEL of sender-anonymity", 1,
+ &GNUNET_getopt_configure_set_uint, &anonymity },
+ { 'p', "priority", "LEVEL",
+ "set the desired LEVEL of priority", 1,
+ &GNUNET_getopt_configure_set_uint, &priority },
+ { 'u', "uri-files", NULL, "Make .uri files visible", 0,
+ &GNUNET_getopt_configure_set_one, &uri_files },
+ { 'x', "Xfuse", NULL, "Escape fuse option", 1,
+ &getopt_configure_argv, NULL },
+ GNUNET_COMMAND_LINE_OPTION_END,
+};
+
+int main(int argc, char **argv)
+{
+ int i, ret;
+ struct GNUNET_ECRS_URI *uri;
+ char *buf;
+
+ /* Initialize fuse options */
+ fuse_argc = 1;
+ fuse_argv = GNUNET_malloc(sizeof(char *) * argc);
+ fuse_argv[0] = argv[0];
+ fuse_argv[1] = NULL;
+
+ /* Parse gnunet options */
+ i = GNUNET_init(argc, argv,
+ "gnunet-fuse [OPTIONS] <URI FILE> <MOUNT-POINT>",
+ &cfgFilename, gn_options, &ectx, &cfg);
+ if(i == -1)
+ {
+ ret = -1;
+ goto quit;
+ }
+
+ /* Set up log file */
+ GNUNET_disk_directory_create_for_file(ectx, cfgLogfile);
+ ectx = GNUNET_GE_create_context_logfile(ectx, GNUNET_GE_ALL,
cfgLogfile, NULL, GNUNET_YES, 0);
+ GNUNET_GE_setDefaultContext(ectx);
+
+ /* There should be exactly two extra arguments */
+ if(i + 2 != argc)
+ {
+ printf("You must specify a URI to mount and mountpoint\n");
+ ret = -1;
+ goto quit;
+ }
+
+ /* Set URI as our root directory entry */
+ gn_dirent_cache_init();
+ if(GNUNET_disk_file_test(ectx, argv[i]) == GNUNET_YES)
+ {
+ unsigned long long len;
+ char *uribuf;
+
+ root_fd = GNUNET_disk_file_open(ectx, argv[i], O_RDWR | O_SYNC);
+ if(root_fd == -1)
+ {
+ printf("Unable to open URI file: %s\n", argv[i]);
+ ret = -1;
+ goto quit;
+ }
+ if(GNUNET_disk_file_size(ectx, argv[i], &len, GNUNET_YES) ==
GNUNET_SYSERR)
+ {
+ printf("Unable to determine URI file size\n");
+ ret = -1;
+ goto out_close_root;
+ }
+ uribuf = GNUNET_malloc(len + 1);
+ read(root_fd, uribuf, len);
+ uribuf[len] = '\0';
+ uri = GNUNET_ECRS_string_to_uri(ectx, uribuf);
+ GNUNET_free(uribuf);
+ if(uri == NULL)
+ {
+ printf("URI cannot be parsed\n");
+ ret = -1;
+ goto out_close_root;
+ }
+ if(!GNUNET_ECRS_uri_test_chk(uri))
+ {
+ struct GNUNET_ECRS_URI *new_uri;
+
+ new_uri = GNUNET_ECRS_uri_get_content_uri_from_loc(uri);
+ if(new_uri == NULL)
+ {
+ printf("URI cannot be mounted\n");
+ ret = -1;
+ goto out_close_root;
+ }
+ GNUNET_ECRS_uri_destroy(uri);
+ uri = new_uri;
+ }
+ root_de = gn_dirent_new(G_DIR_SEPARATOR_S, uri, NULL, DE_DIR);
+ GNUNET_ECRS_uri_destroy(uri);
+ }
+ else
+ {
+ /* In the case where the file does not exist, let's mount an
+ * empty directory and create the file to store its URI */
+ root_fd = GNUNET_disk_file_open(ectx, argv[i], O_RDWR | O_SYNC
+ | O_CREAT, 0666);
+ if(root_fd == -1)
+ {
+ printf("Unable to create URI file: %s\n", argv[i]);
+ ret = -1;
+ goto quit;
+ }
+ root_de = gn_dirent_new(G_DIR_SEPARATOR_S, NULL, NULL, DE_DIR);
+ }
+
+ /* Add mount point as the last fuse option */
+ fuse_argv = GNUNET_realloc(fuse_argv, sizeof(char *) * (fuse_argc + 2));
+ fuse_argv[fuse_argc] = argv[i + 1];
+ fuse_argc++;
+ fuse_argv[fuse_argc] = NULL;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER | GNUNET_GE_DEBUG,
"calling fuse_main\n");
+ ret = fuse_main(fuse_argc, fuse_argv, &fops, NULL);
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER | GNUNET_GE_DEBUG,
"fuse_main returned\n");
+
+ /* Save root uri */
+ closing = 1;
+ buf = gn_get_special_file(G_DIR_SEPARATOR_S URI_FILE);
+ if(buf != NULL)
+ {
+ ftruncate(root_fd, 0);
+ lseek(root_fd, SEEK_SET, 0);
+ write(root_fd, buf, strlen(buf));
+ GNUNET_free(buf);
+ }
+out_close_root:
+ GNUNET_disk_file_close(ectx, argv[i], root_fd);
+quit:
+ GNUNET_free(fuse_argv);
+ GNUNET_fini(ectx, cfg);
+ return ret;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/mkdir.c (from rev 20388, gnunet-fuse/mkdir.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/mkdir.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/mkdir.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,71 @@
+/*
+ * mkdir.c - FUSE mkdir function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_mkdir(const char *path, mode_t mode)
+{
+ struct dirent *de, *newde;
+ struct GNUNET_MetaData *meta;
+ char *parent, *file;
+ int ret;
+
+ (void)mode;
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -EEXIST;
+
+ /* Check for existing file */
+ de = gn_dirent_find(path);
+ if(de != NULL)
+ {
+ gn_dirent_put(de);
+ return -EEXIST;
+ }
+
+ /* Create new directory */
+ parent = gn_dirname(path, &file);
+ de = gn_dirent_find(parent);
+ if(de == NULL)
+ {
+ GNUNET_free(parent);
+ return -ENOENT;
+ }
+ meta = GNUNET_meta_data_create();
+ GNUNET_meta_data_insert(meta, EXTRACTOR_FILENAME, file);
+ GNUNET_meta_data_insert(meta, EXTRACTOR_MIMETYPE,
GNUNET_DIRECTORY_MIME);
+ newde = gn_dirent_new(path, NULL, meta, DE_DIR);
+ GNUNET_meta_data_destroy(meta);
+ ret = gn_directory_insert(de, newde);
+ gn_dirent_put(de);
+ gn_dirent_put(newde);
+ GNUNET_free(parent);
+ if(ret == -1)
+ return -EIO;
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/mknod.c (from rev 20388, gnunet-fuse/mknod.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/mknod.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/mknod.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,77 @@
+/*
+ * mknod.c - FUSE mknod function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_mknod(const char *path, mode_t mode, dev_t rdev)
+{
+ struct dirent *de, *newde;
+ struct GNUNET_ECRS_URI *uri;
+ struct GNUNET_MetaData *meta;
+ char *parent, *file;
+ int ret;
+
+ (void)rdev;
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* We only support regular files */
+ if(!S_ISREG(mode))
+ return -ENOTSUP;
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -EEXIST;
+
+ /* Check for existing file */
+ de = gn_dirent_find(path);
+ if(de != NULL)
+ {
+ gn_dirent_put(de);
+ return -EEXIST;
+ }
+
+ /* Create new file */
+ parent = gn_dirname(path, &file);
+ de = gn_dirent_find(parent);
+ if(de == NULL)
+ {
+ GNUNET_free(parent);
+ return -ENOENT;
+ }
+ uri = GNUNET_ECRS_string_to_uri(ectx, GN_EMPTY_FILE_URI);
+ meta = GNUNET_meta_data_create();
+ GNUNET_meta_data_insert(meta, EXTRACTOR_FILENAME, file);
+ GNUNET_free(parent);
+ newde = gn_dirent_new(path, uri, meta, DE_FILE);
+ GNUNET_meta_data_destroy(meta);
+ GNUNET_ECRS_uri_destroy(uri);
+ ret = gn_directory_insert(de, newde);
+ gn_dirent_put(de);
+ gn_dirent_put(newde);
+ if(ret == -1)
+ return -EIO;
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/open.c (from rev 20388, gnunet-fuse/open.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/open.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/open.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,60 @@
+/*
+ * open.c - FUSE open function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_open(const char *path, struct fuse_file_info *fi)
+{
+ struct dirent *de;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ {
+ if(fi->flags & O_WRONLY)
+ return -EACCES;
+ if((fi->flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+ return -EEXIST;
+ return 0;
+ }
+
+ /* Check for existing file */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ return -ENOENT;
+ if(de->de_type != DE_FILE)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: not a file\n", __FUNCTION__);
+ gn_dirent_put(de);
+ return -ENOENT;
+ }
+ gn_dirent_put(de);
+ if((fi->flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+ return -EEXIST;
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/read.c (from rev 20388, gnunet-fuse/read.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/read.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/read.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,168 @@
+/*
+ * read.c - FUSE read function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#define _XOPEN_SOURCE 500
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+struct read_data
+{
+ char *buf;
+ guint size;
+ guint64 offset;
+};
+
+static void dpcb(unsigned long long totalBytes,
+ unsigned long long completedBytes, GNUNET_CronTime eta,
+ unsigned long long lastBlockOffset, const char *lastBlock,
+ unsigned int lastBlockSize, void *cls)
+{
+ struct read_data *d = cls;
+ guint64 block_end = lastBlockOffset + lastBlockSize;
+ guint64 buf_end = d->offset + d->size;
+
+ (void)totalBytes;
+ (void)completedBytes;
+ (void)eta;
+
+ /* Check if this block is entirely before the buffer */
+ if(block_end < d->offset)
+ return;
+
+ /* Check if this block is entirely after the buffer */
+ if(lastBlockOffset > buf_end)
+ return;
+
+ /* Chop off residue at beginning of block */
+ if(lastBlockOffset < d->offset)
+ {
+ lastBlock += d->offset - lastBlockOffset;
+ lastBlockSize -= d->offset - lastBlockOffset;
+ lastBlockOffset = d->offset;
+ }
+ /* Chop off residue at end of block */
+ if(block_end > buf_end)
+ {
+ lastBlockSize -= block_end - buf_end;
+ }
+ memcpy(d->buf + (lastBlockOffset - d->offset), lastBlock,
+ lastBlockSize);
+}
+
+static int tt(void *cls)
+{
+ (void)cls;
+ return fuse_interrupted() ? GNUNET_SYSERR : GNUNET_OK;
+}
+
+int gn_read(const char *path, char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
+{
+ struct dirent *de;
+ struct read_data d;
+ char *special;
+ int ret;
+ ssize_t slen;
+ guint64 len;
+
+ (void)fi;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: called for '%s' %u bytes %lld offset\n", __FUNCTION__,
+ path, size, offset);
+
+ /* Check for special file */
+ special = gn_get_special_file(path);
+ if(special != NULL)
+ {
+ slen = strlen(special);
+ if(offset >= slen)
+ {
+ GNUNET_free(special);
+ return 0;
+ }
+ if( ((ssize_t) (offset + size)) > slen)
+ {
+ size = slen - offset;
+ }
+ memcpy(buf, special + offset, size);
+ GNUNET_free(special);
+ return size;
+ }
+
+ /* Lookup dirent for path */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: file not found\n", __FUNCTION__);
+ return -ENOENT;
+ }
+ if(de->de_type != DE_FILE)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: not a file\n", __FUNCTION__);
+ size = -ENOENT;
+ goto out;
+ }
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
+ {
+ size = -EIO;
+ goto out;
+ }
+ if(de->de_cached)
+ {
+ slen = pread(de->de_fd, buf, size, offset);
+ if(slen == -1)
+ size = -errno;
+ else
+ size = slen;
+ goto out_sema_up;
+ }
+ len = GNUNET_ECRS_uri_get_file_size(de->de_fi.uri);
+ if((guint64)offset >= len)
+ {
+ size = 0;
+ goto out_sema_up;
+ }
+ if((guint64)offset + size > len)
+ {
+ size = len - offset;
+ }
+ d.buf = buf;
+ d.size = size;
+ d.offset = offset;
+ ret = GNUNET_ECRS_file_download_partial(ectx, cfg, de->de_fi.uri,
"/dev/null",
+ offset, size, anonymity, GNUNET_YES, dpcb, &d, tt, NULL);
+ if(ret != GNUNET_OK)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_ERROR,
+ "%s: failed to download file\n", __FUNCTION__);
+ size = -ENODATA;
+ }
+out_sema_up:
+ GNUNET_semaphore_up(de->de_sema);
+out:
+ gn_dirent_put(de);
+ return size;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/readdir.c (from rev 20388,
gnunet-fuse/readdir.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/readdir.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/readdir.c 2012-03-09 08:38:54 UTC (rev
20389)
@@ -0,0 +1,113 @@
+/*
+ * readdir.c - FUSE readdir function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#define _LARGEFILE64_SOURCE
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <fuse.h>
+#include <GNUnet/gnunet_ecrs_lib.h>
+#include "gnfs.h"
+
+struct readdir_callback_data
+{
+ fuse_fill_dir_t filler;
+ void *buf;
+ const char *prefix;
+};
+
+static int readdir_callback(struct dirent *de, void *data)
+{
+ struct readdir_callback_data *d = data;
+
+ (void)de;
+
+ if(d->prefix != NULL)
+ {
+ char *buf = GNUNET_malloc(strlen(d->prefix) +
strlen(de->de_basename)
+ + 1);
+
+ sprintf(buf, "%s%s", d->prefix, de->de_basename);
+ d->filler(d->buf, buf, NULL, 0);
+ GNUNET_free(buf);
+ }
+ else
+ {
+ d->filler(d->buf, de->de_basename, NULL, 0);
+ }
+ return GNUNET_OK;
+}
+
+int gn_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
+ off_t offset, struct fuse_file_info *fi)
+{
+ struct dirent *de;
+ int ret = 0;
+ struct readdir_callback_data d;
+
+ (void)offset;
+ (void)fi;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "readdir for '%s'\n",
+ path);
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "readdir: file not found\n");
+ return -ENOENT;
+ }
+ if(de->de_type != DE_DIR)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "readdir: not a directory\n");
+ gn_dirent_put(de);
+ ret = -ENOENT;
+ goto out;
+ }
+ filler(buf, ".", NULL, 0);
+ filler(buf, "..", NULL, 0);
+ if(uri_files)
+ {
+ filler(buf, URI_FILE, NULL, 0);
+ d.filler = filler;
+ d.buf = buf;
+ d.prefix = ".uri.";
+ ret = gn_directory_foreach(de, readdir_callback, &d);
+ if(ret == -1)
+ {
+ ret = -ENOENT;
+ goto out;
+ }
+ }
+ d.filler = filler;
+ d.buf = buf;
+ d.prefix = NULL;
+ ret = gn_directory_foreach(de, readdir_callback, &d);
+ if(ret == -1)
+ ret = -ENOENT;
+out:
+ gn_dirent_put(de);
+ return ret;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/release.c (from rev 20388,
gnunet-fuse/release.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/release.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/release.c 2012-03-09 08:38:54 UTC (rev
20389)
@@ -0,0 +1,63 @@
+/*
+ * release.c - FUSE release function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_release(const char *path, struct fuse_file_info *fi)
+{
+ struct dirent *de;
+ int dirty = GN_UNLOCK_CLEAN;
+
+ (void)fi;
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Don't do anything for special files */
+ if(gn_exists_special_file(path))
+ return 0;
+
+ /* If it doesn't exist we don't care */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ return 0;
+ if(de->de_type != DE_FILE)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: not a file\n", __FUNCTION__);
+ gn_dirent_put(de);
+ return 0;
+ }
+
+ /* Lock our path */
+ if(gn_lock_path(de) == -1)
+ return 0;
+
+ /* Un-dirty ourselfs */
+ if(gn_file_upload_locked(de) == 0)
+ {
+ /* Now we must mark every containing directory dirty */
+ dirty = GN_UNLOCK_ANCESTORS_DIRTY;
+ }
+
+ gn_unlock_path(de, dirty);
+ gn_dirent_put(de);
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/rename.c (from rev 20388,
gnunet-fuse/rename.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/rename.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/rename.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,135 @@
+/*
+ * rename.c - FUSE rename function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+static gboolean rename_callback(struct dirent *de, void *data)
+{
+ int *empty = data;
+
+ (void)de;
+ *empty = 0;
+ return 1;
+}
+
+int gn_rename(const char *from, const char *to)
+{
+ struct dirent *from_de, *to_de, *from_parent_de, *to_parent_de;
+ char *from_parent, *from_file, *to_parent, *to_file;
+ int ret = 0, empty = 1;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: '%s' to '%s'\n",
+ __FUNCTION__, from, to);
+
+ /* Check for special file */
+ if(gn_exists_special_file(from) || gn_exists_special_file(to))
+ return -EACCES;
+
+ /* Make sure 'from' exists */
+ from_de = gn_dirent_find(from);
+ if(from_de == NULL)
+ return -ENOENT;
+
+ /* We need to check some things before we remove 'from' */
+ to_de = gn_dirent_find(to);
+ if(to_de != NULL)
+ {
+ if(from_de->de_type == DE_FILE && to_de->de_type == DE_DIR)
+ {
+ ret = -EISDIR;
+ goto out;
+ }
+ if(from_de->de_type == DE_DIR && to_de->de_type == DE_FILE)
+ {
+ ret = -ENOTDIR;
+ goto out;
+ }
+ if(to_de->de_type == DE_DIR)
+ {
+ gn_directory_foreach(to_de, rename_callback, &empty);
+ if(!empty)
+ {
+ ret = -ENOTEMPTY;
+ goto out;
+ }
+ }
+ }
+
+ /* Now we can remove the 'from' */
+ from_parent = gn_dirname(from, &from_file);
+ from_parent_de = gn_dirent_find(from_parent);
+ GNUNET_free(from_parent);
+ if(from_parent_de == NULL)
+ {
+ ret = -ENOENT;
+ goto out;
+ }
+ gn_directory_remove(from_parent_de, from_de);
+ gn_dirent_put(from_parent_de);
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: removed '%s'\n",
+ __FUNCTION__, from);
+
+ /* Modify our path */
+ gn_dirent_path_set(from_de, to);
+
+ /* Replace the 'to' */
+ to_parent = gn_dirname(to, &to_file);
+ to_parent_de = gn_dirent_find(to_parent);
+ GNUNET_free(to_parent);
+ if(to_parent_de == NULL)
+ {
+ ret = -EIO;
+ goto out;
+ }
+
+ /* We should have some kind of directory_remove_insert for atomicity */
+ if(to_de != NULL)
+ {
+ if(gn_directory_remove(to_parent_de, to_de) == -1)
+ {
+ gn_dirent_put(to_parent_de);
+ ret = -EIO;
+ goto out;
+ }
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: removed '%s'\n", __FUNCTION__, to);
+ }
+ if(gn_directory_insert(to_parent_de, from_de) == -1)
+ {
+ gn_dirent_put(to_parent_de);
+ ret = -EIO;
+ goto out;
+ }
+ gn_dirent_put(to_parent_de);
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: inserted '%s'\n", __FUNCTION__, to);
+
+out:
+ if(to_de != NULL)
+ gn_dirent_put(to_de);
+ if(from_de != NULL)
+ gn_dirent_put(from_de);
+ return ret;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/rmdir.c (from rev 20388, gnunet-fuse/rmdir.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/rmdir.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/rmdir.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,78 @@
+/*
+ * rmdir.c - FUSE rmdir function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+static gboolean rmdir_callback(struct dirent *de, void *data)
+{
+ int *empty = data;
+
+ (void)de;
+ *empty = 0;
+ return 1;
+}
+
+int gn_rmdir(const char *path)
+{
+ struct dirent *de, *dechild;
+ char *parent, *file;
+ int ret, empty = 1;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -ENOTDIR;
+
+ /* Check for existing file */
+ dechild = gn_dirent_find(path);
+ if(dechild == NULL)
+ return -ENOENT;
+
+ /* Can't rmdir a non-empty directory */
+ gn_directory_foreach(dechild, rmdir_callback, &empty);
+ if(!empty)
+ {
+ gn_dirent_put(dechild);
+ return -ENOTEMPTY;
+ }
+
+ /* Remove directory */
+ parent = gn_dirname(path, &file);
+ de = gn_dirent_find(parent);
+ GNUNET_free(parent);
+ if(de == NULL)
+ {
+ gn_dirent_put(dechild);
+ return -ENOENT;
+ }
+ ret = gn_directory_remove(de, dechild);
+ gn_dirent_put(dechild);
+ gn_dirent_put(de);
+ if(ret == -1)
+ return -EIO;
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/special_file.c (from rev 20388,
gnunet-fuse/special_file.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/special_file.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/special_file.c 2012-03-09 08:38:54 UTC (rev
20389)
@@ -0,0 +1,159 @@
+/*
+ * special_file.c - special file support (like .uri)
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <GNUnet/gnunet_util_string.h>
+#include <GNUnet/gnunet_ecrs_lib.h>
+#include "gnfs.h"
+
+char *gn_dirname(const char *path, char **file)
+{
+ char *parent, *slash;
+
+ parent = GNUNET_strdup(path);
+ slash = strrchr(parent, G_DIR_SEPARATOR);
+ if(slash != NULL)
+ {
+ slash[0] = '\0';
+ slash++;
+ }
+ if(file != NULL)
+ *file = slash;
+ return parent;
+}
+
+/* Checks to see if path is the path to a special file */
+int gn_exists_special_file(const char *path)
+{
+ struct dirent *de;
+ char *file, *parent;
+ int ret = 0;
+
+ parent = gn_dirname(path, &file);
+
+ /* Check for special file name */
+ if(strcmp(file, URI_FILE) == 0)
+ {
+ ret = 1;
+ }
+ else if(strncmp(file, URI_FILE ".", URI_LEN + 1) == 0)
+ {
+ char *actual_file = GNUNET_malloc(strlen(path));
+
+ /* Return URI of the file named after the .uri. */
+ sprintf(actual_file, "%s" G_DIR_SEPARATOR_S "%s", parent,
+ &file[URI_LEN + 1]);
+ de = gn_dirent_find(actual_file);
+ GNUNET_free(actual_file);
+ if(de == NULL)
+ goto out;
+ gn_dirent_put(de);
+ ret = 1;
+ }
+out:
+ GNUNET_free(parent);
+ return ret;
+}
+
+/*
+ * Returns a malloc'd string for a special file, and in the case of .uri files
+ * will sync it if it's dirty
+ */
+char *gn_get_special_file(const char *path)
+{
+ struct dirent *de;
+ char *buf = NULL, *file, *parent;
+
+ parent = gn_dirname(path, &file);
+
+ /* Check for special file name */
+ if(strcmp(file, URI_FILE) == 0)
+ {
+ /* Return URI of the 'current' directory */
+ de = gn_dirent_find(parent);
+ if(de == NULL)
+ goto out;
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) ==
GNUNET_SYSERR)
+ {
+ gn_dirent_put(de);
+ goto out;
+ }
+ if(de->de_dirty)
+ {
+ if(gn_directory_upload_locked(de) == -1)
+ {
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ goto out;
+ }
+ }
+ buf = GNUNET_ECRS_uri_to_string(de->de_fi.uri);
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ buf = GNUNET_realloc(buf, strlen(buf) + 2);
+ strcat(buf, "\n");
+ }
+ else if(strncmp(file, URI_FILE ".", URI_LEN + 1) == 0)
+ {
+ char *actual_file = GNUNET_malloc(strlen(path));
+
+ /* Return URI of the file named after the .uri. */
+ sprintf(actual_file, "%s" G_DIR_SEPARATOR_S "%s", parent,
+ &file[URI_LEN + 1]);
+ de = gn_dirent_find(actual_file);
+ GNUNET_free(actual_file);
+ if(de == NULL)
+ goto out;
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) ==
GNUNET_SYSERR)
+ {
+ gn_dirent_put(de);
+ goto out;
+ }
+ if(de->de_dirty)
+ {
+ if(de->de_type == DE_DIR)
+ {
+ if(gn_directory_upload_locked(de) == -1)
+ {
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ goto out;
+ }
+ }
+ else
+ {
+ if(de->de_fi.uri == NULL)
+ {
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ goto out;
+ }
+ }
+ }
+ buf = GNUNET_ECRS_uri_to_string(de->de_fi.uri);
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ buf = GNUNET_realloc(buf, strlen(buf) + 2);
+ strcat(buf, "\n");
+ }
+out:
+ GNUNET_free(parent);
+ return buf;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/truncate.c (from rev 20388,
gnunet-fuse/truncate.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/truncate.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/truncate.c 2012-03-09 08:38:54 UTC (rev
20389)
@@ -0,0 +1,90 @@
+/*
+ * truncate.c - FUSE truncate function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_truncate(const char *path, off_t size)
+{
+ struct dirent *de;
+ int ret = 0, dirty = GN_UNLOCK_CLEAN;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: called for '%s' %lld bytes\n", __FUNCTION__, path, size);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -EACCES;
+
+ /* Lookup dirent for path */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: file not found\n", __FUNCTION__);
+ return -ENOENT;
+ }
+ if(de->de_type != DE_FILE)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: not a file\n", __FUNCTION__);
+ ret = -EISDIR;
+ goto out;
+ }
+
+ /* Lock our path */
+ if(gn_lock_path(de) == -1)
+ {
+ ret = -EIO;
+ goto out;
+ }
+ if(!de->de_cached)
+ {
+ if(gn_file_download_locked(de) == -1)
+ {
+ ret = -EIO;
+ goto out_unlock;
+ }
+ }
+
+ /* Perform truncate */
+ ret = ftruncate(de->de_fd, size);
+ if(ret == -1)
+ {
+ ret = -errno;
+ goto out_unlock;
+ }
+
+ /* Mark us dirty */
+ de->de_dirty = 1;
+
+ /* Then un-mark us dirty */
+ if(gn_file_upload_locked(de) == 0)
+ {
+ dirty = GN_UNLOCK_ANCESTORS_DIRTY;
+ }
+out_unlock:
+ gn_unlock_path(de, GN_UNLOCK_ANCESTORS_DIRTY);
+out:
+ gn_dirent_put(de);
+ return ret;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/unlink.c (from rev 20388,
gnunet-fuse/unlink.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/unlink.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/unlink.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,68 @@
+/*
+ * unlink.c - FUSE unlink function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_unlink(const char *path)
+{
+ struct dirent *de, *dechild;
+ char *parent, *file;
+ int ret;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -EPERM;
+
+ /* Check for existing file */
+ dechild = gn_dirent_find(path);
+ if(dechild == NULL)
+ return -ENOENT;
+
+ /* Can't unlink a directory */
+ if(dechild->de_type != DE_FILE)
+ {
+ gn_dirent_put(dechild);
+ return -EPERM;
+ }
+
+ /* Remove file from parent dir */
+ parent = gn_dirname(path, &file);
+ de = gn_dirent_find(parent);
+ GNUNET_free(parent);
+ if(de == NULL)
+ {
+ gn_dirent_put(dechild);
+ return -ENOENT;
+ }
+ ret = gn_directory_remove(de, dechild);
+ gn_dirent_put(dechild);
+ gn_dirent_put(de);
+ if(ret == -1)
+ return -EIO;
+ return 0;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/utimens.c (from rev 20388,
gnunet-fuse/utimens.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/utimens.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/utimens.c 2012-03-09 08:38:54 UTC (rev
20389)
@@ -0,0 +1,72 @@
+/*
+ * utimens.c - FUSE utimens function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <string.h>
+#include <errno.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_utimens(const char *path, const struct timespec ts[2])
+{
+ struct dirent *de;
+ struct timeval tv[2];
+ int ret = 0;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check to see if this is a special file */
+ if(gn_exists_special_file(path))
+ return -EACCES;
+
+ /* Get file or dir */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ return -ENOENT;
+
+ /* If it's a cached file just call utime */
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
+ {
+ gn_dirent_put(de);
+ return -EIO;
+ }
+ if(de->de_cached && de->de_type == DE_FILE)
+ {
+ TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
+ ret = utimes(path, tv);
+ if(ret == -1)
+ {
+ ret = -errno;
+ GNUNET_GE_LOG_STRERROR(ectx, GNUNET_GE_BULK |
GNUNET_GE_USER | GNUNET_GE_ERROR,
+ "utimes");
+ goto out;
+ }
+ goto out;
+ }
+
+ /* For now we do nothing otherwise */
+out:
+ GNUNET_semaphore_up(de->de_sema);
+ gn_dirent_put(de);
+ return ret;
+}
Copied: gnunet-fuse/gnunet-fuse-v8/write.c (from rev 20388, gnunet-fuse/write.c)
===================================================================
--- gnunet-fuse/gnunet-fuse-v8/write.c (rev 0)
+++ gnunet-fuse/gnunet-fuse-v8/write.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -0,0 +1,88 @@
+/*
+ * write.c - FUSE write function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#define _XOPEN_SOURCE 500
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_write(const char *path, const char *buf, size_t size, off_t offset,
+ struct fuse_file_info *fi)
+{
+ struct dirent *de;
+ ssize_t slen;
+
+ (void)fi;
+
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: called for '%s' %d bytes\n", __FUNCTION__, path, size);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -EACCES;
+
+ /* Lookup dirent for path */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: file not found\n", __FUNCTION__);
+ return -ENOENT;
+ }
+ if(de->de_type != DE_FILE)
+ {
+ GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
+ "%s: not a file\n", __FUNCTION__);
+ size = -ENOENT;
+ goto out;
+ }
+
+ /* We must be cached */
+ if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
+ {
+ size = -EIO;
+ goto out;
+ }
+ if(!de->de_cached)
+ {
+ if(gn_file_download_locked(de) == -1)
+ {
+ size = -EIO;
+ goto out_unlock;
+ }
+ }
+
+ /* Perform write on temp file */
+ slen = pwrite(de->de_fd, buf, size, offset);
+ if(slen == -1)
+ size = -errno;
+ else
+ size = slen;
+
+ /* Mark us dirty */
+ de->de_dirty = 1;
+out_unlock:
+ GNUNET_semaphore_up(de->de_sema);
+out:
+ gn_dirent_put(de);
+ return size;
+}
Deleted: gnunet-fuse/main.c
===================================================================
--- gnunet-fuse/main.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/main.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,232 +0,0 @@
-/*
- * main.c - program start
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <glib.h>
-#include <fuse.h>
-#include <GNUnet/gnunet_directories.h>
-#include <GNUnet/gnunet_util.h>
-#include <GNUnet/gnunet_ecrs_lib.h>
-#include "gnfs.h"
-#include "gettext.h"
-
-struct GNUNET_GC_Configuration *cfg;
-struct GNUNET_GE_Context *ectx;
-static char *cfgFilename = GNUNET_DEFAULT_CLIENT_CONFIG_FILE;
-static char *cfgLogfile = "/tmp/gnunet_fuse.log";
-
-/* Flag to indicate that we are shutting down */
-int closing = 0;
-
-/* Level of anonymity for downloading and uploading files */
-unsigned int anonymity = 1;
-
-/* Priority for uploaded files */
-unsigned int priority = 1000;
-
-/* Flag for including .uri files in readdir() */
-int uri_files = 0;
-
-/* argv and argc to pass to fuse, filled in by main and getopt_configure_argv
*/
-char **fuse_argv;
-int fuse_argc;
-
-/* Root directory entry, currently used by the dirent cache when asked for / */
-int root_fd;
-struct dirent *root_de;
-
-int getopt_configure_argv(GNUNET_CommandLineProcessorContext *ctx, void *scls,
- const char *cmdLineOption, const char *value)
-{
- (void)ctx;
- (void)scls;
- (void)cmdLineOption;
-
- fuse_argv[fuse_argc] = (char *)value;
- fuse_argc++;
- fuse_argv[fuse_argc] = NULL;
- return GNUNET_OK;
-}
-
-static struct fuse_operations fops =
-{
- .getattr = gn_getattr,
- .mknod = gn_mknod,
- .mkdir = gn_mkdir,
- .unlink = gn_unlink,
- .rmdir = gn_rmdir,
- .rename = gn_rename,
- .truncate = gn_truncate,
- .open = gn_open,
- .read = gn_read,
- .write = gn_write,
- .release = gn_release,
- .readdir = gn_readdir,
- .utimens = gn_utimens,
-};
-
-static struct GNUNET_CommandLineOption gn_options[] =
-{
- GNUNET_COMMAND_LINE_OPTION_HELP("GNUnet filesystem"),
- GNUNET_COMMAND_LINE_OPTION_CFG_FILE(&cfgFilename), /* -c */
- GNUNET_COMMAND_LINE_OPTION_LOGGING, /* -L */
- { 'l', "logfile", "FILE", "set logfile name", 1,
- &GNUNET_getopt_configure_set_string, &cfgLogfile },
- { 'a', "anonymity", "LEVEL",
- "set the desired LEVEL of sender-anonymity", 1,
- &GNUNET_getopt_configure_set_uint, &anonymity },
- { 'p', "priority", "LEVEL",
- "set the desired LEVEL of priority", 1,
- &GNUNET_getopt_configure_set_uint, &priority },
- { 'u', "uri-files", NULL, "Make .uri files visible", 0,
- &GNUNET_getopt_configure_set_one, &uri_files },
- { 'x', "Xfuse", NULL, "Escape fuse option", 1,
- &getopt_configure_argv, NULL },
- GNUNET_COMMAND_LINE_OPTION_END,
-};
-
-int main(int argc, char **argv)
-{
- int i, ret;
- struct GNUNET_ECRS_URI *uri;
- char *buf;
-
- /* Initialize fuse options */
- fuse_argc = 1;
- fuse_argv = GNUNET_malloc(sizeof(char *) * argc);
- fuse_argv[0] = argv[0];
- fuse_argv[1] = NULL;
-
- /* Parse gnunet options */
- i = GNUNET_init(argc, argv,
- "gnunet-fuse [OPTIONS] <URI FILE> <MOUNT-POINT>",
- &cfgFilename, gn_options, &ectx, &cfg);
- if(i == -1)
- {
- ret = -1;
- goto quit;
- }
-
- /* Set up log file */
- GNUNET_disk_directory_create_for_file(ectx, cfgLogfile);
- ectx = GNUNET_GE_create_context_logfile(ectx, GNUNET_GE_ALL,
cfgLogfile, NULL, GNUNET_YES, 0);
- GNUNET_GE_setDefaultContext(ectx);
-
- /* There should be exactly two extra arguments */
- if(i + 2 != argc)
- {
- printf("You must specify a URI to mount and mountpoint\n");
- ret = -1;
- goto quit;
- }
-
- /* Set URI as our root directory entry */
- gn_dirent_cache_init();
- if(GNUNET_disk_file_test(ectx, argv[i]) == GNUNET_YES)
- {
- unsigned long long len;
- char *uribuf;
-
- root_fd = GNUNET_disk_file_open(ectx, argv[i], O_RDWR | O_SYNC);
- if(root_fd == -1)
- {
- printf("Unable to open URI file: %s\n", argv[i]);
- ret = -1;
- goto quit;
- }
- if(GNUNET_disk_file_size(ectx, argv[i], &len, GNUNET_YES) ==
GNUNET_SYSERR)
- {
- printf("Unable to determine URI file size\n");
- ret = -1;
- goto out_close_root;
- }
- uribuf = GNUNET_malloc(len + 1);
- read(root_fd, uribuf, len);
- uribuf[len] = '\0';
- uri = GNUNET_ECRS_string_to_uri(ectx, uribuf);
- GNUNET_free(uribuf);
- if(uri == NULL)
- {
- printf("URI cannot be parsed\n");
- ret = -1;
- goto out_close_root;
- }
- if(!GNUNET_ECRS_uri_test_chk(uri))
- {
- struct GNUNET_ECRS_URI *new_uri;
-
- new_uri = GNUNET_ECRS_uri_get_content_uri_from_loc(uri);
- if(new_uri == NULL)
- {
- printf("URI cannot be mounted\n");
- ret = -1;
- goto out_close_root;
- }
- GNUNET_ECRS_uri_destroy(uri);
- uri = new_uri;
- }
- root_de = gn_dirent_new(G_DIR_SEPARATOR_S, uri, NULL, DE_DIR);
- GNUNET_ECRS_uri_destroy(uri);
- }
- else
- {
- /* In the case where the file does not exist, let's mount an
- * empty directory and create the file to store its URI */
- root_fd = GNUNET_disk_file_open(ectx, argv[i], O_RDWR | O_SYNC
- | O_CREAT, 0666);
- if(root_fd == -1)
- {
- printf("Unable to create URI file: %s\n", argv[i]);
- ret = -1;
- goto quit;
- }
- root_de = gn_dirent_new(G_DIR_SEPARATOR_S, NULL, NULL, DE_DIR);
- }
-
- /* Add mount point as the last fuse option */
- fuse_argv = GNUNET_realloc(fuse_argv, sizeof(char *) * (fuse_argc + 2));
- fuse_argv[fuse_argc] = argv[i + 1];
- fuse_argc++;
- fuse_argv[fuse_argc] = NULL;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER | GNUNET_GE_DEBUG,
"calling fuse_main\n");
- ret = fuse_main(fuse_argc, fuse_argv, &fops, NULL);
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER | GNUNET_GE_DEBUG,
"fuse_main returned\n");
-
- /* Save root uri */
- closing = 1;
- buf = gn_get_special_file(G_DIR_SEPARATOR_S URI_FILE);
- if(buf != NULL)
- {
- ftruncate(root_fd, 0);
- lseek(root_fd, SEEK_SET, 0);
- write(root_fd, buf, strlen(buf));
- GNUNET_free(buf);
- }
-out_close_root:
- GNUNET_disk_file_close(ectx, argv[i], root_fd);
-quit:
- GNUNET_free(fuse_argv);
- GNUNET_fini(ectx, cfg);
- return ret;
-}
Deleted: gnunet-fuse/mkdir.c
===================================================================
--- gnunet-fuse/mkdir.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/mkdir.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,71 +0,0 @@
-/*
- * mkdir.c - FUSE mkdir function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_mkdir(const char *path, mode_t mode)
-{
- struct dirent *de, *newde;
- struct GNUNET_MetaData *meta;
- char *parent, *file;
- int ret;
-
- (void)mode;
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* Check for special file */
- if(gn_exists_special_file(path))
- return -EEXIST;
-
- /* Check for existing file */
- de = gn_dirent_find(path);
- if(de != NULL)
- {
- gn_dirent_put(de);
- return -EEXIST;
- }
-
- /* Create new directory */
- parent = gn_dirname(path, &file);
- de = gn_dirent_find(parent);
- if(de == NULL)
- {
- GNUNET_free(parent);
- return -ENOENT;
- }
- meta = GNUNET_meta_data_create();
- GNUNET_meta_data_insert(meta, EXTRACTOR_FILENAME, file);
- GNUNET_meta_data_insert(meta, EXTRACTOR_MIMETYPE,
GNUNET_DIRECTORY_MIME);
- newde = gn_dirent_new(path, NULL, meta, DE_DIR);
- GNUNET_meta_data_destroy(meta);
- ret = gn_directory_insert(de, newde);
- gn_dirent_put(de);
- gn_dirent_put(newde);
- GNUNET_free(parent);
- if(ret == -1)
- return -EIO;
- return 0;
-}
Deleted: gnunet-fuse/mknod.c
===================================================================
--- gnunet-fuse/mknod.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/mknod.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,77 +0,0 @@
-/*
- * mknod.c - FUSE mknod function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_mknod(const char *path, mode_t mode, dev_t rdev)
-{
- struct dirent *de, *newde;
- struct GNUNET_ECRS_URI *uri;
- struct GNUNET_MetaData *meta;
- char *parent, *file;
- int ret;
-
- (void)rdev;
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* We only support regular files */
- if(!S_ISREG(mode))
- return -ENOTSUP;
-
- /* Check for special file */
- if(gn_exists_special_file(path))
- return -EEXIST;
-
- /* Check for existing file */
- de = gn_dirent_find(path);
- if(de != NULL)
- {
- gn_dirent_put(de);
- return -EEXIST;
- }
-
- /* Create new file */
- parent = gn_dirname(path, &file);
- de = gn_dirent_find(parent);
- if(de == NULL)
- {
- GNUNET_free(parent);
- return -ENOENT;
- }
- uri = GNUNET_ECRS_string_to_uri(ectx, GN_EMPTY_FILE_URI);
- meta = GNUNET_meta_data_create();
- GNUNET_meta_data_insert(meta, EXTRACTOR_FILENAME, file);
- GNUNET_free(parent);
- newde = gn_dirent_new(path, uri, meta, DE_FILE);
- GNUNET_meta_data_destroy(meta);
- GNUNET_ECRS_uri_destroy(uri);
- ret = gn_directory_insert(de, newde);
- gn_dirent_put(de);
- gn_dirent_put(newde);
- if(ret == -1)
- return -EIO;
- return 0;
-}
Deleted: gnunet-fuse/open.c
===================================================================
--- gnunet-fuse/open.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/open.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,60 +0,0 @@
-/*
- * open.c - FUSE open function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_open(const char *path, struct fuse_file_info *fi)
-{
- struct dirent *de;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* Check for special file */
- if(gn_exists_special_file(path))
- {
- if(fi->flags & O_WRONLY)
- return -EACCES;
- if((fi->flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
- return -EEXIST;
- return 0;
- }
-
- /* Check for existing file */
- de = gn_dirent_find(path);
- if(de == NULL)
- return -ENOENT;
- if(de->de_type != DE_FILE)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: not a file\n", __FUNCTION__);
- gn_dirent_put(de);
- return -ENOENT;
- }
- gn_dirent_put(de);
- if((fi->flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
- return -EEXIST;
- return 0;
-}
Deleted: gnunet-fuse/read.c
===================================================================
--- gnunet-fuse/read.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/read.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,168 +0,0 @@
-/*
- * read.c - FUSE read function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-struct read_data
-{
- char *buf;
- guint size;
- guint64 offset;
-};
-
-static void dpcb(unsigned long long totalBytes,
- unsigned long long completedBytes, GNUNET_CronTime eta,
- unsigned long long lastBlockOffset, const char *lastBlock,
- unsigned int lastBlockSize, void *cls)
-{
- struct read_data *d = cls;
- guint64 block_end = lastBlockOffset + lastBlockSize;
- guint64 buf_end = d->offset + d->size;
-
- (void)totalBytes;
- (void)completedBytes;
- (void)eta;
-
- /* Check if this block is entirely before the buffer */
- if(block_end < d->offset)
- return;
-
- /* Check if this block is entirely after the buffer */
- if(lastBlockOffset > buf_end)
- return;
-
- /* Chop off residue at beginning of block */
- if(lastBlockOffset < d->offset)
- {
- lastBlock += d->offset - lastBlockOffset;
- lastBlockSize -= d->offset - lastBlockOffset;
- lastBlockOffset = d->offset;
- }
- /* Chop off residue at end of block */
- if(block_end > buf_end)
- {
- lastBlockSize -= block_end - buf_end;
- }
- memcpy(d->buf + (lastBlockOffset - d->offset), lastBlock,
- lastBlockSize);
-}
-
-static int tt(void *cls)
-{
- (void)cls;
- return fuse_interrupted() ? GNUNET_SYSERR : GNUNET_OK;
-}
-
-int gn_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
-{
- struct dirent *de;
- struct read_data d;
- char *special;
- int ret;
- ssize_t slen;
- guint64 len;
-
- (void)fi;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: called for '%s' %u bytes %lld offset\n", __FUNCTION__,
- path, size, offset);
-
- /* Check for special file */
- special = gn_get_special_file(path);
- if(special != NULL)
- {
- slen = strlen(special);
- if(offset >= slen)
- {
- GNUNET_free(special);
- return 0;
- }
- if( ((ssize_t) (offset + size)) > slen)
- {
- size = slen - offset;
- }
- memcpy(buf, special + offset, size);
- GNUNET_free(special);
- return size;
- }
-
- /* Lookup dirent for path */
- de = gn_dirent_find(path);
- if(de == NULL)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: file not found\n", __FUNCTION__);
- return -ENOENT;
- }
- if(de->de_type != DE_FILE)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: not a file\n", __FUNCTION__);
- size = -ENOENT;
- goto out;
- }
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
- {
- size = -EIO;
- goto out;
- }
- if(de->de_cached)
- {
- slen = pread(de->de_fd, buf, size, offset);
- if(slen == -1)
- size = -errno;
- else
- size = slen;
- goto out_sema_up;
- }
- len = GNUNET_ECRS_uri_get_file_size(de->de_fi.uri);
- if((guint64)offset >= len)
- {
- size = 0;
- goto out_sema_up;
- }
- if((guint64)offset + size > len)
- {
- size = len - offset;
- }
- d.buf = buf;
- d.size = size;
- d.offset = offset;
- ret = GNUNET_ECRS_file_download_partial(ectx, cfg, de->de_fi.uri,
"/dev/null",
- offset, size, anonymity, GNUNET_YES, dpcb, &d, tt, NULL);
- if(ret != GNUNET_OK)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_USER |
GNUNET_GE_ERROR,
- "%s: failed to download file\n", __FUNCTION__);
- size = -ENODATA;
- }
-out_sema_up:
- GNUNET_semaphore_up(de->de_sema);
-out:
- gn_dirent_put(de);
- return size;
-}
Deleted: gnunet-fuse/readdir.c
===================================================================
--- gnunet-fuse/readdir.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/readdir.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,113 +0,0 @@
-/*
- * readdir.c - FUSE readdir function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#define _LARGEFILE64_SOURCE
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <glib.h>
-#include <fuse.h>
-#include <GNUnet/gnunet_ecrs_lib.h>
-#include "gnfs.h"
-
-struct readdir_callback_data
-{
- fuse_fill_dir_t filler;
- void *buf;
- const char *prefix;
-};
-
-static int readdir_callback(struct dirent *de, void *data)
-{
- struct readdir_callback_data *d = data;
-
- (void)de;
-
- if(d->prefix != NULL)
- {
- char *buf = GNUNET_malloc(strlen(d->prefix) +
strlen(de->de_basename)
- + 1);
-
- sprintf(buf, "%s%s", d->prefix, de->de_basename);
- d->filler(d->buf, buf, NULL, 0);
- GNUNET_free(buf);
- }
- else
- {
- d->filler(d->buf, de->de_basename, NULL, 0);
- }
- return GNUNET_OK;
-}
-
-int gn_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi)
-{
- struct dirent *de;
- int ret = 0;
- struct readdir_callback_data d;
-
- (void)offset;
- (void)fi;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "readdir for '%s'\n",
- path);
- de = gn_dirent_find(path);
- if(de == NULL)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "readdir: file not found\n");
- return -ENOENT;
- }
- if(de->de_type != DE_DIR)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "readdir: not a directory\n");
- gn_dirent_put(de);
- ret = -ENOENT;
- goto out;
- }
- filler(buf, ".", NULL, 0);
- filler(buf, "..", NULL, 0);
- if(uri_files)
- {
- filler(buf, URI_FILE, NULL, 0);
- d.filler = filler;
- d.buf = buf;
- d.prefix = ".uri.";
- ret = gn_directory_foreach(de, readdir_callback, &d);
- if(ret == -1)
- {
- ret = -ENOENT;
- goto out;
- }
- }
- d.filler = filler;
- d.buf = buf;
- d.prefix = NULL;
- ret = gn_directory_foreach(de, readdir_callback, &d);
- if(ret == -1)
- ret = -ENOENT;
-out:
- gn_dirent_put(de);
- return ret;
-}
Deleted: gnunet-fuse/release.c
===================================================================
--- gnunet-fuse/release.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/release.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,63 +0,0 @@
-/*
- * release.c - FUSE release function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_release(const char *path, struct fuse_file_info *fi)
-{
- struct dirent *de;
- int dirty = GN_UNLOCK_CLEAN;
-
- (void)fi;
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* Don't do anything for special files */
- if(gn_exists_special_file(path))
- return 0;
-
- /* If it doesn't exist we don't care */
- de = gn_dirent_find(path);
- if(de == NULL)
- return 0;
- if(de->de_type != DE_FILE)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: not a file\n", __FUNCTION__);
- gn_dirent_put(de);
- return 0;
- }
-
- /* Lock our path */
- if(gn_lock_path(de) == -1)
- return 0;
-
- /* Un-dirty ourselfs */
- if(gn_file_upload_locked(de) == 0)
- {
- /* Now we must mark every containing directory dirty */
- dirty = GN_UNLOCK_ANCESTORS_DIRTY;
- }
-
- gn_unlock_path(de, dirty);
- gn_dirent_put(de);
- return 0;
-}
Deleted: gnunet-fuse/rename.c
===================================================================
--- gnunet-fuse/rename.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/rename.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,135 +0,0 @@
-/*
- * rename.c - FUSE rename function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-static gboolean rename_callback(struct dirent *de, void *data)
-{
- int *empty = data;
-
- (void)de;
- *empty = 0;
- return 1;
-}
-
-int gn_rename(const char *from, const char *to)
-{
- struct dirent *from_de, *to_de, *from_parent_de, *to_parent_de;
- char *from_parent, *from_file, *to_parent, *to_file;
- int ret = 0, empty = 1;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: '%s' to '%s'\n",
- __FUNCTION__, from, to);
-
- /* Check for special file */
- if(gn_exists_special_file(from) || gn_exists_special_file(to))
- return -EACCES;
-
- /* Make sure 'from' exists */
- from_de = gn_dirent_find(from);
- if(from_de == NULL)
- return -ENOENT;
-
- /* We need to check some things before we remove 'from' */
- to_de = gn_dirent_find(to);
- if(to_de != NULL)
- {
- if(from_de->de_type == DE_FILE && to_de->de_type == DE_DIR)
- {
- ret = -EISDIR;
- goto out;
- }
- if(from_de->de_type == DE_DIR && to_de->de_type == DE_FILE)
- {
- ret = -ENOTDIR;
- goto out;
- }
- if(to_de->de_type == DE_DIR)
- {
- gn_directory_foreach(to_de, rename_callback, &empty);
- if(!empty)
- {
- ret = -ENOTEMPTY;
- goto out;
- }
- }
- }
-
- /* Now we can remove the 'from' */
- from_parent = gn_dirname(from, &from_file);
- from_parent_de = gn_dirent_find(from_parent);
- GNUNET_free(from_parent);
- if(from_parent_de == NULL)
- {
- ret = -ENOENT;
- goto out;
- }
- gn_directory_remove(from_parent_de, from_de);
- gn_dirent_put(from_parent_de);
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: removed '%s'\n",
- __FUNCTION__, from);
-
- /* Modify our path */
- gn_dirent_path_set(from_de, to);
-
- /* Replace the 'to' */
- to_parent = gn_dirname(to, &to_file);
- to_parent_de = gn_dirent_find(to_parent);
- GNUNET_free(to_parent);
- if(to_parent_de == NULL)
- {
- ret = -EIO;
- goto out;
- }
-
- /* We should have some kind of directory_remove_insert for atomicity */
- if(to_de != NULL)
- {
- if(gn_directory_remove(to_parent_de, to_de) == -1)
- {
- gn_dirent_put(to_parent_de);
- ret = -EIO;
- goto out;
- }
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: removed '%s'\n", __FUNCTION__, to);
- }
- if(gn_directory_insert(to_parent_de, from_de) == -1)
- {
- gn_dirent_put(to_parent_de);
- ret = -EIO;
- goto out;
- }
- gn_dirent_put(to_parent_de);
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: inserted '%s'\n", __FUNCTION__, to);
-
-out:
- if(to_de != NULL)
- gn_dirent_put(to_de);
- if(from_de != NULL)
- gn_dirent_put(from_de);
- return ret;
-}
Deleted: gnunet-fuse/rmdir.c
===================================================================
--- gnunet-fuse/rmdir.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/rmdir.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,78 +0,0 @@
-/*
- * rmdir.c - FUSE rmdir function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-static gboolean rmdir_callback(struct dirent *de, void *data)
-{
- int *empty = data;
-
- (void)de;
- *empty = 0;
- return 1;
-}
-
-int gn_rmdir(const char *path)
-{
- struct dirent *de, *dechild;
- char *parent, *file;
- int ret, empty = 1;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* Check for special file */
- if(gn_exists_special_file(path))
- return -ENOTDIR;
-
- /* Check for existing file */
- dechild = gn_dirent_find(path);
- if(dechild == NULL)
- return -ENOENT;
-
- /* Can't rmdir a non-empty directory */
- gn_directory_foreach(dechild, rmdir_callback, &empty);
- if(!empty)
- {
- gn_dirent_put(dechild);
- return -ENOTEMPTY;
- }
-
- /* Remove directory */
- parent = gn_dirname(path, &file);
- de = gn_dirent_find(parent);
- GNUNET_free(parent);
- if(de == NULL)
- {
- gn_dirent_put(dechild);
- return -ENOENT;
- }
- ret = gn_directory_remove(de, dechild);
- gn_dirent_put(dechild);
- gn_dirent_put(de);
- if(ret == -1)
- return -EIO;
- return 0;
-}
Deleted: gnunet-fuse/special_file.c
===================================================================
--- gnunet-fuse/special_file.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/special_file.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,159 +0,0 @@
-/*
- * special_file.c - special file support (like .uri)
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <string.h>
-#include <GNUnet/gnunet_util_string.h>
-#include <GNUnet/gnunet_ecrs_lib.h>
-#include "gnfs.h"
-
-char *gn_dirname(const char *path, char **file)
-{
- char *parent, *slash;
-
- parent = GNUNET_strdup(path);
- slash = strrchr(parent, G_DIR_SEPARATOR);
- if(slash != NULL)
- {
- slash[0] = '\0';
- slash++;
- }
- if(file != NULL)
- *file = slash;
- return parent;
-}
-
-/* Checks to see if path is the path to a special file */
-int gn_exists_special_file(const char *path)
-{
- struct dirent *de;
- char *file, *parent;
- int ret = 0;
-
- parent = gn_dirname(path, &file);
-
- /* Check for special file name */
- if(strcmp(file, URI_FILE) == 0)
- {
- ret = 1;
- }
- else if(strncmp(file, URI_FILE ".", URI_LEN + 1) == 0)
- {
- char *actual_file = GNUNET_malloc(strlen(path));
-
- /* Return URI of the file named after the .uri. */
- sprintf(actual_file, "%s" G_DIR_SEPARATOR_S "%s", parent,
- &file[URI_LEN + 1]);
- de = gn_dirent_find(actual_file);
- GNUNET_free(actual_file);
- if(de == NULL)
- goto out;
- gn_dirent_put(de);
- ret = 1;
- }
-out:
- GNUNET_free(parent);
- return ret;
-}
-
-/*
- * Returns a malloc'd string for a special file, and in the case of .uri files
- * will sync it if it's dirty
- */
-char *gn_get_special_file(const char *path)
-{
- struct dirent *de;
- char *buf = NULL, *file, *parent;
-
- parent = gn_dirname(path, &file);
-
- /* Check for special file name */
- if(strcmp(file, URI_FILE) == 0)
- {
- /* Return URI of the 'current' directory */
- de = gn_dirent_find(parent);
- if(de == NULL)
- goto out;
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) ==
GNUNET_SYSERR)
- {
- gn_dirent_put(de);
- goto out;
- }
- if(de->de_dirty)
- {
- if(gn_directory_upload_locked(de) == -1)
- {
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- goto out;
- }
- }
- buf = GNUNET_ECRS_uri_to_string(de->de_fi.uri);
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- buf = GNUNET_realloc(buf, strlen(buf) + 2);
- strcat(buf, "\n");
- }
- else if(strncmp(file, URI_FILE ".", URI_LEN + 1) == 0)
- {
- char *actual_file = GNUNET_malloc(strlen(path));
-
- /* Return URI of the file named after the .uri. */
- sprintf(actual_file, "%s" G_DIR_SEPARATOR_S "%s", parent,
- &file[URI_LEN + 1]);
- de = gn_dirent_find(actual_file);
- GNUNET_free(actual_file);
- if(de == NULL)
- goto out;
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) ==
GNUNET_SYSERR)
- {
- gn_dirent_put(de);
- goto out;
- }
- if(de->de_dirty)
- {
- if(de->de_type == DE_DIR)
- {
- if(gn_directory_upload_locked(de) == -1)
- {
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- goto out;
- }
- }
- else
- {
- if(de->de_fi.uri == NULL)
- {
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- goto out;
- }
- }
- }
- buf = GNUNET_ECRS_uri_to_string(de->de_fi.uri);
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- buf = GNUNET_realloc(buf, strlen(buf) + 2);
- strcat(buf, "\n");
- }
-out:
- GNUNET_free(parent);
- return buf;
-}
Deleted: gnunet-fuse/truncate.c
===================================================================
--- gnunet-fuse/truncate.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/truncate.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,90 +0,0 @@
-/*
- * truncate.c - FUSE truncate function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <errno.h>
-#include <unistd.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_truncate(const char *path, off_t size)
-{
- struct dirent *de;
- int ret = 0, dirty = GN_UNLOCK_CLEAN;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: called for '%s' %lld bytes\n", __FUNCTION__, path, size);
-
- /* Check for special file */
- if(gn_exists_special_file(path))
- return -EACCES;
-
- /* Lookup dirent for path */
- de = gn_dirent_find(path);
- if(de == NULL)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: file not found\n", __FUNCTION__);
- return -ENOENT;
- }
- if(de->de_type != DE_FILE)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: not a file\n", __FUNCTION__);
- ret = -EISDIR;
- goto out;
- }
-
- /* Lock our path */
- if(gn_lock_path(de) == -1)
- {
- ret = -EIO;
- goto out;
- }
- if(!de->de_cached)
- {
- if(gn_file_download_locked(de) == -1)
- {
- ret = -EIO;
- goto out_unlock;
- }
- }
-
- /* Perform truncate */
- ret = ftruncate(de->de_fd, size);
- if(ret == -1)
- {
- ret = -errno;
- goto out_unlock;
- }
-
- /* Mark us dirty */
- de->de_dirty = 1;
-
- /* Then un-mark us dirty */
- if(gn_file_upload_locked(de) == 0)
- {
- dirty = GN_UNLOCK_ANCESTORS_DIRTY;
- }
-out_unlock:
- gn_unlock_path(de, GN_UNLOCK_ANCESTORS_DIRTY);
-out:
- gn_dirent_put(de);
- return ret;
-}
Deleted: gnunet-fuse/unlink.c
===================================================================
--- gnunet-fuse/unlink.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/unlink.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,68 +0,0 @@
-/*
- * unlink.c - FUSE unlink function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_unlink(const char *path)
-{
- struct dirent *de, *dechild;
- char *parent, *file;
- int ret;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* Check for special file */
- if(gn_exists_special_file(path))
- return -EPERM;
-
- /* Check for existing file */
- dechild = gn_dirent_find(path);
- if(dechild == NULL)
- return -ENOENT;
-
- /* Can't unlink a directory */
- if(dechild->de_type != DE_FILE)
- {
- gn_dirent_put(dechild);
- return -EPERM;
- }
-
- /* Remove file from parent dir */
- parent = gn_dirname(path, &file);
- de = gn_dirent_find(parent);
- GNUNET_free(parent);
- if(de == NULL)
- {
- gn_dirent_put(dechild);
- return -ENOENT;
- }
- ret = gn_directory_remove(de, dechild);
- gn_dirent_put(dechild);
- gn_dirent_put(de);
- if(ret == -1)
- return -EIO;
- return 0;
-}
Deleted: gnunet-fuse/utimens.c
===================================================================
--- gnunet-fuse/utimens.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/utimens.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,72 +0,0 @@
-/*
- * utimens.c - FUSE utimens function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#define _GNU_SOURCE
-#include <sys/time.h>
-#include <string.h>
-#include <errno.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_utimens(const char *path, const struct timespec ts[2])
-{
- struct dirent *de;
- struct timeval tv[2];
- int ret = 0;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG, "%s: for '%s'\n",
- __FUNCTION__, path);
-
- /* Check to see if this is a special file */
- if(gn_exists_special_file(path))
- return -EACCES;
-
- /* Get file or dir */
- de = gn_dirent_find(path);
- if(de == NULL)
- return -ENOENT;
-
- /* If it's a cached file just call utime */
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
- {
- gn_dirent_put(de);
- return -EIO;
- }
- if(de->de_cached && de->de_type == DE_FILE)
- {
- TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
- TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
- ret = utimes(path, tv);
- if(ret == -1)
- {
- ret = -errno;
- GNUNET_GE_LOG_STRERROR(ectx, GNUNET_GE_BULK |
GNUNET_GE_USER | GNUNET_GE_ERROR,
- "utimes");
- goto out;
- }
- goto out;
- }
-
- /* For now we do nothing otherwise */
-out:
- GNUNET_semaphore_up(de->de_sema);
- gn_dirent_put(de);
- return ret;
-}
Deleted: gnunet-fuse/write.c
===================================================================
--- gnunet-fuse/write.c 2012-03-08 23:45:33 UTC (rev 20388)
+++ gnunet-fuse/write.c 2012-03-09 08:38:54 UTC (rev 20389)
@@ -1,88 +0,0 @@
-/*
- * write.c - FUSE write function
- *
- * This file is part of gnunet-fuse.
- * Copyright (C) 2007 David Barksdale
- *
- * gnunet-fuse is free software; you can redistribute it and/or
- * modify if under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * 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
- */
-
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fuse.h>
-#include "gnfs.h"
-
-int gn_write(const char *path, const char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
-{
- struct dirent *de;
- ssize_t slen;
-
- (void)fi;
-
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: called for '%s' %d bytes\n", __FUNCTION__, path, size);
-
- /* Check for special file */
- if(gn_exists_special_file(path))
- return -EACCES;
-
- /* Lookup dirent for path */
- de = gn_dirent_find(path);
- if(de == NULL)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: file not found\n", __FUNCTION__);
- return -ENOENT;
- }
- if(de->de_type != DE_FILE)
- {
- GNUNET_GE_LOG(ectx, GNUNET_GE_BULK | GNUNET_GE_DEVELOPER |
GNUNET_GE_DEBUG,
- "%s: not a file\n", __FUNCTION__);
- size = -ENOENT;
- goto out;
- }
-
- /* We must be cached */
- if(GNUNET_semaphore_down(de->de_sema, GNUNET_YES) == GNUNET_SYSERR)
- {
- size = -EIO;
- goto out;
- }
- if(!de->de_cached)
- {
- if(gn_file_download_locked(de) == -1)
- {
- size = -EIO;
- goto out_unlock;
- }
- }
-
- /* Perform write on temp file */
- slen = pwrite(de->de_fd, buf, size, offset);
- if(slen == -1)
- size = -errno;
- else
- size = slen;
-
- /* Mark us dirty */
- de->de_dirty = 1;
-out_unlock:
- GNUNET_semaphore_up(de->de_sema);
-out:
- gn_dirent_put(de);
- return size;
-}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r20389 - in gnunet-fuse: . gnunet-fuse-v8,
gnunet <=