mirror of
https://github.com/abraunegg/onedrive
synced 2026-03-14 14:35:46 +01:00
Update PR
* Update PR
This commit is contained in:
parent
9b941961e4
commit
433b1971e7
4 changed files with 825 additions and 1 deletions
|
|
@ -88,7 +88,10 @@ SOURCES = \
|
|||
src/xattr.d \
|
||||
src/intune.d \
|
||||
src/socketio.d \
|
||||
src/curlWebsockets.d
|
||||
src/curlWebsockets.d \
|
||||
src/c/fuse/common.d \
|
||||
src/c/fuse/fuse.d \
|
||||
src/fused/fuse.d
|
||||
|
||||
ifeq ($(NOTIFICATIONS),yes)
|
||||
SOURCES += src/notifications/notify.d src/notifications/dnotify.d
|
||||
|
|
|
|||
115
src/c/fuse/common.d
Normal file
115
src/c/fuse/common.d
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the Boost-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
module c.fuse.common;
|
||||
|
||||
import std.stdint;
|
||||
|
||||
extern (System) {
|
||||
static assert(fuse_conn_info.sizeof == 128);
|
||||
struct fuse_conn_info
|
||||
{
|
||||
/**
|
||||
* Major version of the protocol (read-only)
|
||||
*/
|
||||
uint proto_major;
|
||||
|
||||
/**
|
||||
* Minor version of the protocol (read-only)
|
||||
*/
|
||||
uint proto_minor;
|
||||
|
||||
/**
|
||||
* Is asynchronous read supported (read-write)
|
||||
*/
|
||||
uint async_read;
|
||||
|
||||
/**
|
||||
* Maximum size of the write buffer
|
||||
*/
|
||||
uint max_write;
|
||||
|
||||
/**
|
||||
* Maximum readahead
|
||||
*/
|
||||
uint max_readahead;
|
||||
|
||||
/**
|
||||
* Capability flags, that the kernel supports
|
||||
*/
|
||||
uint capable;
|
||||
|
||||
/**
|
||||
* Capability flags, that the filesystem wants to enable
|
||||
*/
|
||||
uint want;
|
||||
|
||||
/**
|
||||
* Maximum number of backgrounded requests
|
||||
*/
|
||||
uint max_background;
|
||||
|
||||
/**
|
||||
* Kernel congestion threshold parameter
|
||||
*/
|
||||
uint congestion_threshold;
|
||||
|
||||
/**
|
||||
* For future use.
|
||||
*/
|
||||
uint[23] reserved;
|
||||
}
|
||||
|
||||
static assert(fuse_file_info.sizeof == 64);
|
||||
struct fuse_file_info
|
||||
{
|
||||
/** Open flags. Available in open() and release() */
|
||||
int flags;
|
||||
|
||||
/** Old file handle, don't use */
|
||||
ulong fh_old;
|
||||
|
||||
/** In case of a write operation indicates if this was caused by a
|
||||
writepage */
|
||||
int writepage;
|
||||
|
||||
/** Can be filled in by open, to use direct I/O on this file.
|
||||
Introduced in version 2.4 */
|
||||
uint direct_io = 1;
|
||||
|
||||
/** Can be filled in by open, to indicate, that cached file data
|
||||
need not be invalidated. Introduced in version 2.4 */
|
||||
uint keep_cache = 1;
|
||||
|
||||
/** Indicates a flush operation. Set in flush operation, also
|
||||
maybe set in highlevel lock operation and lowlevel release
|
||||
operation. Introduced in version 2.6 */
|
||||
uint flush = 1;
|
||||
|
||||
/** Can be filled in by open, to indicate that the file is not
|
||||
seekable. Introduced in version 2.8 */
|
||||
uint nonseekable = 1;
|
||||
|
||||
/* Indicates that flock locks for this file should be
|
||||
released. If set, lock_owner shall contain a valid value.
|
||||
May only be set in ->release(). Introduced in version
|
||||
2.9 */
|
||||
uint flock_release = 1;
|
||||
|
||||
/** Padding. Do not use*/
|
||||
uint padding = 27;
|
||||
|
||||
/** File handle. May be filled in by filesystem in open().
|
||||
Available in all other file operations */
|
||||
uint64_t fh;
|
||||
|
||||
/** Lock owner id. Available in locking operations and flush */
|
||||
uint64_t lock_owner;
|
||||
}
|
||||
}
|
||||
104
src/c/fuse/fuse.d
Normal file
104
src/c/fuse/fuse.d
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* From: https://code.google.com/p/dutils/
|
||||
*
|
||||
* Licensed under the Apache License 2.0. See
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
module c.fuse.fuse;
|
||||
public import c.fuse.common;
|
||||
|
||||
import std.stdint;
|
||||
import core.sys.posix.sys.statvfs;
|
||||
import core.sys.posix.fcntl;
|
||||
import core.sys.posix.time;
|
||||
import core.sys.posix.utime;
|
||||
|
||||
extern (System)
|
||||
{
|
||||
struct fuse;
|
||||
|
||||
struct fuse_pollhandle;
|
||||
struct fuse_conn_info; /* temporary anonymous struct */
|
||||
struct fuse_dirhandle;
|
||||
|
||||
alias fuse_dirh_t = fuse_dirhandle*;
|
||||
alias flock _flock;
|
||||
alias fuse_fill_dir_t =
|
||||
int function(void *buf, char *name, stat_t *stbuf, off_t off);
|
||||
alias fuse_dirfil_t =
|
||||
int function(fuse_dirh_t, const char *name, int type, ino_t ino);
|
||||
|
||||
struct fuse_operations
|
||||
{
|
||||
int function(const char*, stat_t*) getattr;
|
||||
int function(const char*, char *, size_t) readlink;
|
||||
int function(const char*, fuse_dirh_t, fuse_dirfil_t) getdir;
|
||||
int function(const char*, mode_t, dev_t) mknod;
|
||||
int function(const char*, mode_t) mkdir;
|
||||
int function(const char*) unlink;
|
||||
int function(const char*) rmdir;
|
||||
int function(const char*, char*) symlink;
|
||||
int function(const char*, const char*) rename;
|
||||
int function(const char*, char*) link;
|
||||
int function(const char*, mode_t) chmod;
|
||||
int function(const char*, uid_t, gid_t) chown;
|
||||
int function(const char*, off_t) truncate;
|
||||
int function(const char*, utimbuf *) utime;
|
||||
int function(const char*, fuse_file_info *) open;
|
||||
int function(const char*, char*, size_t, off_t, fuse_file_info*) read;
|
||||
int function(const char*, char*, size_t, off_t, fuse_file_info*) write;
|
||||
int function(const char*, statvfs_t*) statfs;
|
||||
int function(const char*, fuse_file_info*) flush;
|
||||
int function(const char*, fuse_file_info*) release;
|
||||
int function(const char*, int, fuse_file_info*) fsync;
|
||||
int function(const char*, char*, char*, size_t, int) setxattr;
|
||||
int function(const char*, char*, char*, size_t) getxattr;
|
||||
int function(const char*, char*, size_t) listxattr;
|
||||
int function(const char*, char*) removexattr;
|
||||
int function(const char*, fuse_file_info*) opendir;
|
||||
int function(const char*, void*, fuse_fill_dir_t, off_t,
|
||||
fuse_file_info*) readdir;
|
||||
int function(const char*, fuse_file_info*) releasedir;
|
||||
int function(const char*, int, fuse_file_info*) fsyncdir;
|
||||
void* function(fuse_conn_info* conn) init;
|
||||
void function(void*) destroy;
|
||||
int function(const char*, int) access;
|
||||
int function(const char*, mode_t, fuse_file_info*) create;
|
||||
int function(const char*, off_t, fuse_file_info*) ftruncate;
|
||||
int function(const char*, stat_t*, fuse_file_info*) fgetattr;
|
||||
int function(const char*, fuse_file_info*, int cmd, _flock*) lock;
|
||||
int function(const char*, const timespec) utimens;
|
||||
int function(const char*, size_t, uint64_t*) bmap;
|
||||
uint flag_nullpath_ok = 1;
|
||||
uint flag_reserved = 31;
|
||||
int function(const char*, int, void*, fuse_file_info*, uint, void*)
|
||||
ioctl;
|
||||
int function(const char*, fuse_file_info*, fuse_pollhandle*, uint*)
|
||||
poll;
|
||||
}
|
||||
|
||||
struct fuse_context
|
||||
{
|
||||
/** Pointer to the fuse object */
|
||||
fuse* _fuse;
|
||||
|
||||
uid_t uid; // User ID of the calling process
|
||||
gid_t gid; // Group ID of the calling process
|
||||
pid_t pid; // Thread ID of the calling process
|
||||
|
||||
void* private_data; // Private filesystem data
|
||||
|
||||
mode_t umask; // Umask of the calling process (introduced in version 2.8)
|
||||
}
|
||||
|
||||
fuse_context* fuse_get_context();
|
||||
int fuse_main_real(int argc, char** argv, fuse_operations* op,
|
||||
size_t op_size, void* user_data);
|
||||
}
|
||||
|
||||
|
||||
/* mappping of the fuse_main macro in fuse.h */
|
||||
int fuse_main(int argc, char** argv, fuse_operations* op, void* user_data)
|
||||
{
|
||||
return fuse_main_real(argc, argv, op, fuse_operations.sizeof, user_data);
|
||||
}
|
||||
602
src/fused/fuse.d
Normal file
602
src/fused/fuse.d
Normal file
|
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the Boost-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
module fused.fuse;
|
||||
|
||||
/* reexport stat_t */
|
||||
public import core.sys.posix.fcntl;
|
||||
public import core.sys.posix.utime;
|
||||
|
||||
import std.algorithm;
|
||||
import std.array;
|
||||
import std.conv;
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
import std.process;
|
||||
import errno = core.stdc.errno;
|
||||
import core.stdc.string;
|
||||
import core.sys.posix.signal;
|
||||
|
||||
import c.fuse.fuse;
|
||||
|
||||
import core.thread : thread_attachThis, thread_detachThis;
|
||||
import core.sys.posix.pthread;
|
||||
|
||||
/**
|
||||
* libfuse is handling the thread creation and we cannot hook into it. However
|
||||
* we need to make the GC aware of the threads. So for any call to a handler
|
||||
* we check if the current thread is attached and attach it if necessary.
|
||||
*/
|
||||
private int threadAttached = false;
|
||||
private pthread_cleanup cleanup;
|
||||
|
||||
extern(C) void detach(void* ptr) nothrow
|
||||
{
|
||||
import std.exception;
|
||||
collectException(thread_detachThis());
|
||||
}
|
||||
|
||||
private void attach()
|
||||
{
|
||||
if (!threadAttached)
|
||||
{
|
||||
thread_attachThis();
|
||||
cleanup.push(&detach, cast(void*) null);
|
||||
threadAttached = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A template to wrap C function calls and support exceptions to indicate
|
||||
* errors.
|
||||
*
|
||||
* The templates passes the Operations object to the lambda as the first
|
||||
* arguemnt.
|
||||
*/
|
||||
private auto call(alias fn)()
|
||||
{
|
||||
attach();
|
||||
auto t = cast(Operations*) fuse_get_context().private_data;
|
||||
try
|
||||
{
|
||||
return fn(*t);
|
||||
}
|
||||
catch (FuseException fe)
|
||||
{
|
||||
/* errno is used to indicate an error to libfuse */
|
||||
errno.errno = fe.errno;
|
||||
return -fe.errno;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
(*t).exception(e);
|
||||
return -errno.EIO;
|
||||
}
|
||||
}
|
||||
|
||||
/* C calling convention compatible function to hand into libfuse which wrap
|
||||
* the call to our Operations object.
|
||||
*
|
||||
* Note that we convert our * char pointer to an array using the
|
||||
* ptr[0..len] syntax.
|
||||
*/
|
||||
extern(System)
|
||||
{
|
||||
private int dfuse_access(const char* path, int mode)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
if(t.access(path[0..path.strlen], mode))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_getattr(const char* path, stat_t* st)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.getattr(path[0..path.strlen], *st);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_readdir(const char* path, void* buf,
|
||||
fuse_fill_dir_t filler, off_t offset, fuse_file_info* fi)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
foreach(file; t.readdir(path[0..path.strlen]))
|
||||
{
|
||||
filler(buf, cast(char*) toStringz(file), null, 0);
|
||||
}
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_readlink(const char* path, char* buf, size_t size)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
auto length = t.readlink(path[0..path.strlen],
|
||||
(cast(ubyte*)buf)[0..size]);
|
||||
/* Null-terminate the string and copy it over to the buffer. */
|
||||
assert(length <= size);
|
||||
buf[length] = '\0';
|
||||
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_open(const char* path, fuse_file_info* fi)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.open(path[0..path.strlen]);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_release(const char* path, fuse_file_info* fi)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.release(path[0..path.strlen]);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_read(const char* path, char* buf, size_t size,
|
||||
off_t offset, fuse_file_info* fi)
|
||||
{
|
||||
/* Ensure at compile time that off_t and size_t fit into an ulong. */
|
||||
static assert(ulong.max >= size_t.max);
|
||||
static assert(ulong.max >= off_t.max);
|
||||
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
auto bbuf = cast(ubyte*) buf;
|
||||
return cast(int) t.read(path[0..path.strlen], bbuf[0..size],
|
||||
to!ulong(offset));
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_write(const char* path, char* data, size_t size,
|
||||
off_t offset, fuse_file_info* fi)
|
||||
{
|
||||
static assert(ulong.max >= size_t.max);
|
||||
static assert(ulong.max >= off_t.max);
|
||||
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
auto bdata = cast(ubyte*) data;
|
||||
return t.write(path[0..path.strlen], bdata[0..size],
|
||||
to!ulong(offset));
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_truncate(const char* path, off_t length)
|
||||
{
|
||||
static assert(ulong.max >= off_t.max);
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.truncate(path[0..path.strlen], to!ulong(length));
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_mknod(const char* path, mode_t mod, dev_t dev)
|
||||
{
|
||||
static assert(ulong.max >= dev_t.max);
|
||||
static assert(uint.max >= mode_t.max);
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.mknod(path[0..path.strlen], mod, dev);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_unlink(const char* path)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.unlink(path[0..path.strlen]);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_mkdir(const char * path, mode_t mode)
|
||||
{
|
||||
static assert(uint.max >= mode_t.max);
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.mkdir(path[0..path.strlen], mode.to!uint);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
private int dfuse_rmdir(const char * path)
|
||||
{
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.rmdir(path[0..path.strlen]);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_rename(const char* orig, const char* dest) {
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.rename(orig[0..orig.strlen], dest[0..dest.strlen]);
|
||||
return 0;
|
||||
})();
|
||||
}
|
||||
|
||||
private int dfuse_chmod(const char* path, mode_t mode) {
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.chmod(path[0 .. path.strlen], mode);
|
||||
return 0;
|
||||
}
|
||||
)();
|
||||
}
|
||||
|
||||
private int dfuse_utime(const char* path, utimbuf* time) {
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.utime(path[0 .. path.strlen], time);
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private int dfuse_symlink(const char* target, char* link) {
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.symlink(target[0 .. target.strlen], link[0 .. link.strlen]);
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private int dfuse_chown(const char* path, uid_t uid, gid_t gid) {
|
||||
return call!(
|
||||
(Operations t)
|
||||
{
|
||||
t.chown(path[0 .. path.strlen], uid, gid);
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void* dfuse_init(fuse_conn_info* conn)
|
||||
{
|
||||
attach();
|
||||
auto t = cast(Operations*) fuse_get_context().private_data;
|
||||
(*t).initialize();
|
||||
return t;
|
||||
}
|
||||
|
||||
private void dfuse_destroy(void* data)
|
||||
{
|
||||
/* this is an ugly hack at the moment. We need to somehow detach all
|
||||
threads from the runtime because after fuse_main finishes the pthreads
|
||||
are joined. We circumvent that problem by just exiting while our
|
||||
threads still run. */
|
||||
import core.stdc.stdlib : exit;
|
||||
exit(0);
|
||||
}
|
||||
} /* extern(C) */
|
||||
|
||||
export class FuseException : Exception
|
||||
{
|
||||
public int errno;
|
||||
this(int errno, string file = __FILE__, size_t line = __LINE__,
|
||||
Throwable next = null)
|
||||
{
|
||||
super("Fuse Exception", file, line, next);
|
||||
this.errno = errno;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An object oriented wrapper around fuse_operations.
|
||||
*/
|
||||
export class Operations
|
||||
{
|
||||
/**
|
||||
* Runs on filesystem creation
|
||||
*/
|
||||
void initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to get a stat(2) structure for a path.
|
||||
*/
|
||||
void getattr(const(char)[] path, ref stat_t stat)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read path into the provided buffer beginning at offset.
|
||||
*
|
||||
* Params:
|
||||
* path = The path to the file to read.
|
||||
* buf = The buffer to read the data into.
|
||||
* offset = An offset to start reading at.
|
||||
* Returns: The amount of bytes read.
|
||||
*/
|
||||
ulong read(const(char)[] path, ubyte[] buf, ulong offset)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given data to the file.
|
||||
*
|
||||
* Params:
|
||||
* path = The path to the file to write.
|
||||
* buf = A read-only buffer containing the data to write.
|
||||
* offset = An offset to start writing at.
|
||||
* Returns: The amount of bytes written.
|
||||
*/
|
||||
int write(const(char)[] path, in ubyte[] data, ulong offset)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate a file to the given length.
|
||||
* Params:
|
||||
* path = The path to the file to trunate.
|
||||
* length = Truncate file to this given length.
|
||||
*/
|
||||
void truncate(const(char)[] path, ulong length)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of files and directory names in the given folder. Note
|
||||
* that you have to return . and ..
|
||||
*
|
||||
* Params:
|
||||
* path = The path to the directory.
|
||||
* Returns: An array of filenames.
|
||||
*/
|
||||
string[] readdir(const(char)[] path)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the link identified by path into the given buffer.
|
||||
*
|
||||
* Params:
|
||||
* path = The path to the directory.
|
||||
*/
|
||||
size_t readlink(const(char)[] path, ubyte[] buf)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user has access to the given path.
|
||||
*
|
||||
* Params:
|
||||
* path = The path to check.
|
||||
* mode = An flag indicating what to check for. See access(2) for
|
||||
* supported modes.
|
||||
* Returns: True on success otherwise false.
|
||||
*/
|
||||
bool access(const(char)[] path, int mode)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the mode of a path.
|
||||
*
|
||||
* Params:
|
||||
* path = The path to check.
|
||||
* mode = The mode to set.
|
||||
*/
|
||||
void chmod(const(char)[] path, mode_t mode)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets access and modification time.
|
||||
*
|
||||
* Params:
|
||||
* path = The patch to modify.
|
||||
* time = The time to set.
|
||||
*/
|
||||
void utime(const(char)[] path, utimbuf* time)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a symlink.
|
||||
*
|
||||
* Params:
|
||||
* path = The path to create.
|
||||
* target = The target of the link.
|
||||
*/
|
||||
void symlink(const(char)[] target, const(char)[] path)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes ownership of a file.
|
||||
*
|
||||
* Params:
|
||||
* path = Path to the file.
|
||||
* uid = New user ID.
|
||||
* gid = New group ID.
|
||||
*/
|
||||
void chown(const(char)[] path, uid_t uid, gid_t gid)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void mknod(const(char)[] path, int mod, ulong dev)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void unlink(const(char)[] path)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void mkdir(const(char)[] path, uint mode)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void rmdir(const(char)[] path)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void rename(const(char)[] orig, const(char)[] dest)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void open(const(char)[] path)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void release(const(char)[] path)
|
||||
{
|
||||
throw new FuseException(errno.EOPNOTSUPP);
|
||||
}
|
||||
|
||||
void exception(Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around fuse_main()
|
||||
*/
|
||||
export class Fuse
|
||||
{
|
||||
private:
|
||||
bool foreground;
|
||||
bool threaded;
|
||||
string fsname;
|
||||
int pid;
|
||||
|
||||
public:
|
||||
this(string fsname)
|
||||
{
|
||||
this(fsname, false, true);
|
||||
}
|
||||
|
||||
this(string fsname, bool foreground, bool threaded)
|
||||
{
|
||||
this.fsname = fsname;
|
||||
this.foreground = foreground;
|
||||
this.threaded = threaded;
|
||||
}
|
||||
|
||||
void mount(Operations ops, const string mountpoint, string[] mountopts)
|
||||
{
|
||||
string [] args = [this.fsname];
|
||||
|
||||
args ~= mountpoint;
|
||||
|
||||
if(mountopts.length > 0)
|
||||
{
|
||||
args ~= format("-o%s", mountopts.join(","));
|
||||
}
|
||||
|
||||
if(this.foreground)
|
||||
{
|
||||
args ~= "-f";
|
||||
}
|
||||
|
||||
if(!this.threaded)
|
||||
{
|
||||
args ~= "-s";
|
||||
}
|
||||
|
||||
debug writefln("fuse arguments s=(%s)", args);
|
||||
|
||||
fuse_operations fops;
|
||||
|
||||
fops.init = &dfuse_init;
|
||||
fops.access = &dfuse_access;
|
||||
fops.getattr = &dfuse_getattr;
|
||||
fops.readdir = &dfuse_readdir;
|
||||
fops.open = &dfuse_open;
|
||||
fops.release = &dfuse_release;
|
||||
fops.read = &dfuse_read;
|
||||
fops.write = &dfuse_write;
|
||||
fops.truncate = &dfuse_truncate;
|
||||
fops.readlink = &dfuse_readlink;
|
||||
fops.destroy = &dfuse_destroy;
|
||||
fops.mknod = &dfuse_mknod;
|
||||
fops.unlink = &dfuse_unlink;
|
||||
fops.mkdir = &dfuse_mkdir;
|
||||
fops.rmdir = &dfuse_rmdir;
|
||||
fops.rename = &dfuse_rename;
|
||||
fops.chmod = &dfuse_chmod;
|
||||
fops.utime = &dfuse_utime;
|
||||
fops.symlink = &dfuse_symlink;
|
||||
fops.chown = &dfuse_chown;
|
||||
|
||||
/* Create c-style arguments from a string[] array. */
|
||||
auto cargs = array(map!(a => toStringz(a))(args));
|
||||
int length = cast(int) cargs.length;
|
||||
static if(length.max < cargs.length.max)
|
||||
{
|
||||
/* This is an unsafe cast that we need to do for C compat.
|
||||
Enforce unlike assert will be checked in opt-builds as well. */
|
||||
import std.exception : enforce;
|
||||
enforce(length >= 0);
|
||||
enforce(length == cargs.length);
|
||||
}
|
||||
|
||||
this.pid = thisProcessID();
|
||||
fuse_main(length, cast(char**) cargs.ptr, &fops, &ops);
|
||||
}
|
||||
|
||||
void exit()
|
||||
{
|
||||
kill(this.pid, SIGINT);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue