From 569c369b7fcc7c47f8c55f6c5646e266bbaea1a9 Mon Sep 17 00:00:00 2001 From: USeebi Date: Sat, 24 Sep 2016 20:54:51 +0800 Subject: [PATCH] Msys2 pkg-config Msys2 fuse library pkg-config and pacman package to be consumed by makepkg --- dokan_fuse/pkg/.PKGINFO | 14 + .../pkg/opt/include/dokan_fuse/ScopeGuard.h | 287 ++++++ .../pkg/opt/include/dokan_fuse/dokanfuse.h | 64 ++ dokan_fuse/pkg/opt/include/dokan_fuse/fuse.h | 854 ++++++++++++++++++ .../pkg/opt/include/dokan_fuse/fuse_common.h | 249 +++++ .../pkg/opt/include/dokan_fuse/fuse_opt.h | 267 ++++++ .../pkg/opt/include/dokan_fuse/fuse_sem_fix.h | 27 + .../pkg/opt/include/dokan_fuse/fuse_win.h | 221 +++++ .../pkg/opt/include/dokan_fuse/fusemain.h | 234 +++++ dokan_fuse/pkg/opt/include/dokan_fuse/utils.h | 59 ++ dokan_fuse/pkg/usr/lib/pkgconfig/fuse.pc | 10 + 11 files changed, 2286 insertions(+) create mode 100644 dokan_fuse/pkg/.PKGINFO create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/ScopeGuard.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/dokanfuse.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/fuse.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/fuse_common.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/fuse_opt.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/fuse_sem_fix.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/fuse_win.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/fusemain.h create mode 100644 dokan_fuse/pkg/opt/include/dokan_fuse/utils.h create mode 100644 dokan_fuse/pkg/usr/lib/pkgconfig/fuse.pc diff --git a/dokan_fuse/pkg/.PKGINFO b/dokan_fuse/pkg/.PKGINFO new file mode 100644 index 000000000..16d06d87b --- /dev/null +++ b/dokan_fuse/pkg/.PKGINFO @@ -0,0 +1,14 @@ +# Generated by hand +# Tue Sep 13 21:11:06 UTC 2016 +pkgname = fuse +pkgbase = dokan_fuse +pkgver = 1.0.0-4 +pkgdesc = A wrapper library that makes Dokan compatible with FUSE API +url = https://github.com/dokan-dev/dokany/wiki/FUSE +builddate = 1323390194 +packager = http://mgalgs.github.io/2011/12/08/creating-arch-linux-packages-by-hand.html +size = 8192 +arch = x86_64 +license = GPL +license = LGPL +group = libraries diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/ScopeGuard.h b/dokan_fuse/pkg/opt/include/dokan_fuse/ScopeGuard.h new file mode 100644 index 000000000..f51b20add --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/ScopeGuard.h @@ -0,0 +1,287 @@ +#ifndef SCOPEGUARD_H_ +#define SCOPEGUARD_H_ + +#include + +template +class RefHolder +{ + T& ref_; +public: + RefHolder(T& ref) : ref_(ref) {} + operator T& () const + { + return ref_; + } +private: + // Disable assignment - not implemented + RefHolder& operator=(const RefHolder&); +}; + +template +inline RefHolder ByRef(T& t) +{ + return RefHolder(t); +} + +class ScopeGuardImplBase +{ + ScopeGuardImplBase& operator =(const ScopeGuardImplBase&); +protected: + ~ScopeGuardImplBase() + { + } + ScopeGuardImplBase(const ScopeGuardImplBase& other) throw() + : dismissed_(other.dismissed_) + { + other.Dismiss(); + } + template + static void SafeExecute(J& j) throw() + { + if (!j.dismissed_) + try + { + j.Execute(); + } + catch(...) + { + assert(!"Exception while performing cleanup!"); + } + } + + mutable bool dismissed_; +public: + ScopeGuardImplBase() throw() : dismissed_(false) + { + } + void Dismiss() const throw() + { + dismissed_ = true; + } +}; + +typedef const ScopeGuardImplBase& ScopeGuard; + +template +class ScopeGuardImpl0 : public ScopeGuardImplBase +{ +public: + static ScopeGuardImpl0 MakeGuard(F fun) + { + return ScopeGuardImpl0(fun); + } + ~ScopeGuardImpl0() throw() + { + SafeExecute(*this); + } + void Execute() + { + fun_(); + } +protected: + ScopeGuardImpl0(F fun) : fun_(fun) + { + } + F fun_; +}; + +template +inline ScopeGuardImpl0 MakeGuard(F fun) +{ + return ScopeGuardImpl0::MakeGuard(fun); +} + +template +class ScopeGuardImpl1 : public ScopeGuardImplBase +{ +public: + static ScopeGuardImpl1 MakeGuard(F fun, P1 p1) + { + return ScopeGuardImpl1(fun, p1); + } + ~ScopeGuardImpl1() throw() + { + SafeExecute(*this); + } + void Execute() + { + fun_(p1_); + } +protected: + ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) + { + } + F fun_; + const P1 p1_; +}; + +template +inline ScopeGuardImpl1 MakeGuard(F fun, P1 p1) +{ + return ScopeGuardImpl1::MakeGuard(fun, p1); +} + +template +class ScopeGuardImpl2: public ScopeGuardImplBase +{ +public: + static ScopeGuardImpl2 MakeGuard(F fun, P1 p1, P2 p2) + { + return ScopeGuardImpl2(fun, p1, p2); + } + ~ScopeGuardImpl2() throw() + { + SafeExecute(*this); + } + void Execute() + { + fun_(p1_, p2_); + } +protected: + ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) + { + } + F fun_; + const P1 p1_; + const P2 p2_; +}; + +template +inline ScopeGuardImpl2 MakeGuard(F fun, P1 p1, P2 p2) +{ + return ScopeGuardImpl2::MakeGuard(fun, p1, p2); +} + +template +class ScopeGuardImpl3 : public ScopeGuardImplBase +{ +public: + static ScopeGuardImpl3 MakeGuard(F fun, P1 p1, P2 p2, P3 p3) + { + return ScopeGuardImpl3(fun, p1, p2, p3); + } + ~ScopeGuardImpl3() throw() + { + SafeExecute(*this); + } + void Execute() + { + fun_(p1_, p2_, p3_); + } +protected: + ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) + { + } + F fun_; + const P1 p1_; + const P2 p2_; + const P3 p3_; +}; + +template +inline ScopeGuardImpl3 MakeGuard(F fun, P1 p1, P2 p2, P3 p3) +{ + return ScopeGuardImpl3::MakeGuard(fun, p1, p2, p3); +} + +//************************************************************ + +template +class ObjScopeGuardImpl0 : public ScopeGuardImplBase +{ +public: + static ObjScopeGuardImpl0 MakeObjGuard(Obj& obj, MemFun memFun) + { + return ObjScopeGuardImpl0(obj, memFun); + } + ~ObjScopeGuardImpl0() throw() + { + SafeExecute(*this); + } + void Execute() + { + (obj_.*memFun_)(); + } +protected: + ObjScopeGuardImpl0(Obj& obj, MemFun memFun) + : obj_(obj), memFun_(memFun) {} + Obj& obj_; + MemFun memFun_; +}; + +template +inline ObjScopeGuardImpl0 MakeObjGuard(Obj& obj, MemFun memFun) +{ + return ObjScopeGuardImpl0::MakeObjGuard(obj, memFun); +} + +template +class ObjScopeGuardImpl1 : public ScopeGuardImplBase +{ +public: + static ObjScopeGuardImpl1 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1) + { + return ObjScopeGuardImpl1(obj, memFun, p1); + } + ~ObjScopeGuardImpl1() throw() + { + SafeExecute(*this); + } + void Execute() + { + (obj_.*memFun_)(p1_); + } +protected: + ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) + : obj_(obj), memFun_(memFun), p1_(p1) {} + Obj& obj_; + MemFun memFun_; + const P1 p1_; +}; + +template +inline ObjScopeGuardImpl1 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1) +{ + return ObjScopeGuardImpl1::MakeObjGuard(obj, memFun, p1); +} + +template +class ObjScopeGuardImpl2 : public ScopeGuardImplBase +{ +public: + static ObjScopeGuardImpl2 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) + { + return ObjScopeGuardImpl2(obj, memFun, p1, p2); + } + ~ObjScopeGuardImpl2() throw() + { + SafeExecute(*this); + } + void Execute() + { + (obj_.*memFun_)(p1_, p2_); + } +protected: + ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) + : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {} + Obj& obj_; + MemFun memFun_; + const P1 p1_; + const P2 p2_; +}; + +template +inline ObjScopeGuardImpl2 MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) +{ + return ObjScopeGuardImpl2::MakeObjGuard(obj, memFun, p1, p2); +} + +#define CONCATENATE_DIRECT(s1, s2) s1##s2 +#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2) +#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__) + +#define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard +#define ON_BLOCK_EXIT_OBJ ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard + +#endif //SCOPEGUARD_H_ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/dokanfuse.h b/dokan_fuse/pkg/opt/include/dokan_fuse/dokanfuse.h new file mode 100644 index 000000000..787788d29 --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/dokanfuse.h @@ -0,0 +1,64 @@ +#ifndef DOKANFUSE_H_ +#define DOKANFUSE_H_ + +#include + +#define FUSE_THREAD_COUNT 10 +#define DOKAN_DLL L"dokan" DOKAN_MAJOR_API_VERSION L".dll" + +struct fuse_config +{ + unsigned int umask; + unsigned int fileumask, dirumask; + const char *fsname, *volname; + int help; + int debug; + int setsignals; + unsigned int timeoutInSec; + int networkDrive; +}; + +struct fuse_session +{ + fuse_chan *ch; +}; + +struct fuse_chan +{ + fuse_chan():ResolvedDokanMain(NULL), ResolvedDokanUnmount(NULL), ResolvedDokanRemoveMountPoint(NULL), dokanDll(NULL) {} + ~fuse_chan(); + + //This method dynamically loads DOKAN functions + bool init(); + + typedef int (__stdcall *DokanMainType)(PDOKAN_OPTIONS,PDOKAN_OPERATIONS); + typedef BOOL (__stdcall *DokanUnmountType)(WCHAR DriveLetter); + typedef BOOL (__stdcall *DokanRemoveMountPointType)(LPCWSTR MountPoint); + DokanMainType ResolvedDokanMain; + DokanUnmountType ResolvedDokanUnmount; + DokanRemoveMountPointType ResolvedDokanRemoveMountPoint; + + std::string mountpoint; +private: + HMODULE dokanDll; +}; + +struct fuse +{ + bool within_loop; + std::unique_ptr ch; + fuse_session sess; + fuse_config conf; + + struct fuse_operations ops; + void *user_data; + + fuse() : within_loop(), user_data() + { + memset(&conf,0,sizeof(fuse_config)); + memset(&sess, 0, sizeof(fuse_session)); + memset(&ops, 0, sizeof(fuse_operations)); + } +}; + +#endif //DOKANFUSE_H_ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/fuse.h b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse.h new file mode 100644 index 000000000..ec0ec8bf0 --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse.h @@ -0,0 +1,854 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001-2007 Miklos Szeredi + + This program can be distributed under the terms of the GNU LGPLv2. + See the file COPYING.LIB. +*/ + +#ifndef FUSE_H_ +#define FUSE_H_ + +/* Include Windows compatibility stuff early*/ +#ifdef _WIN32 +#include "fuse_win.h" +typedef struct _FILETIME FILETIME; +#else +#define FUSE_OFF_T off_t +#define FUSE_STAT stat +#endif + +/* Add semaphore fix for Cygwin. TODO: think of a better workaround? */ +#ifdef __CYGWIN__ +#ifndef NO_CYGWIN_SEM_FIX +#include "fuse_sem_fix.h" +#endif +#endif + +/** @file + * + * This file defines the library interface of FUSE + * + * IMPORTANT: you should define FUSE_USE_VERSION before including this + * header. To use the newest API define it to 26 (recommended for any + * new application), to use the old API define it to 21 (default) 22 + * or 25, to use the even older 1.X API define it to 11. + * NOTE: Windows port always uses the latest FUSE version. + */ + +#ifndef FUSE_USE_VERSION +#define FUSE_USE_VERSION 27 +#endif + +#include "fuse_common.h" + +#include +#include +#include +#include + +#if defined(__CYGWIN__) || defined(__MINGW32__) + +#include +#endif +#if defined(__CYGWIN__) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------------------------------------- * + * Basic FUSE API * + * ----------------------------------------------------------- */ + +/** Handle for a FUSE filesystem */ +struct fuse; + +/** Structure containing a raw command */ +struct fuse_cmd; + +/** Function to add an entry in a readdir() operation + * + * @param buf the buffer passed to the readdir() operation + * @param name the file name of the directory entry + * @param stbuf file attributes, can be NULL + * @param off offset of the next entry or zero + * @return 1 if buffer is full, zero otherwise + */ +typedef int (*fuse_fill_dir_t) (void *buf, const char *name, + const struct FUSE_STAT *stbuf, FUSE_OFF_T off); + +/* Used by deprecated getdir() method */ +typedef struct fuse_dirhandle *fuse_dirh_t; +typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type, + ino_t ino); + +/** + * The file system operations: + * + * Most of these should work very similarly to the well known UNIX + * file system operations. + * + * All methods are optional, but some are essential for a useful + * filesystem (e.g. getattr). Open, flush, release, fsync, opendir, + * releasedir, fsyncdir, access, create, ftruncate, fgetattr, lock, + * init and destroy are special purpose methods, without which a full + * featured filesystem can still be implemented. + */ +struct fuse_operations { + /** Get file attributes. + * + * Similar to stat(). The 'st_dev' and 'st_blksize' fields are + * ignored. The 'st_ino' field is ignored except if the 'use_ino' + * mount option is given. + */ + int (*getattr) (const char *, struct FUSE_STAT *); + + /** Read the target of a symbolic link + * + * The buffer should be filled with a null terminated string. The + * buffer size argument includes the space for the terminating + * null character. If the linkname is too long to fit in the + * buffer, it should be truncated. The return value should be 0 + * for success. + */ + int (*readlink) (const char *, char *, size_t); + + /* Deprecated, use readdir() instead */ + int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t); + + /** Create a file node + * + * This is called for creation of all non-directory, non-symlink + * nodes. If the filesystem defines a create() method, then for + * regular files that will be called instead. + */ + int (*mknod) (const char *, mode_t, dev_t); + + /** Create a directory */ + int (*mkdir) (const char *, mode_t); + + /** Remove a file */ + int (*unlink) (const char *); + + /** Remove a directory */ + int (*rmdir) (const char *); + + /** Create a symbolic link */ + int (*symlink) (const char *, const char *); + + /** Rename a file */ + int (*rename) (const char *, const char *); + + /** Create a hard link to a file */ + int (*link) (const char *, const char *); + + /** Change the permission bits of a file */ + int (*chmod) (const char *, mode_t); + + /** Change the owner and group of a file */ + int (*chown) (const char *, uid_t, gid_t); + + /** Change the size of a file */ + int (*truncate) (const char *, FUSE_OFF_T); + + /** Change the access and/or modification times of a file + * + * Deprecated, use utimens() instead. + */ + int (*utime) (const char *, struct utimbuf *); + + /** File open operation + * + * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC) + * will be passed to open(). Open should check if the operation + * is permitted for the given flags. Optionally open may also + * return an arbitrary filehandle in the fuse_file_info structure, + * which will be passed to all file operations. + * + * Changed in version 2.2 + */ + int (*open) (const char *, struct fuse_file_info *); + + /** Read data from an open file + * + * Read should return exactly the number of bytes requested except + * on EOF or error, otherwise the rest of the data will be + * substituted with zeroes. An exception to this is when the + * 'direct_io' mount option is specified, in which case the return + * value of the read system call will reflect the return value of + * this operation. + * + * Changed in version 2.2 + */ + int (*read) (const char *, char *, size_t, FUSE_OFF_T, + struct fuse_file_info *); + + /** Write data to an open file + * + * Write should return exactly the number of bytes requested + * except on error. An exception to this is when the 'direct_io' + * mount option is specified (see read operation). + * + * Changed in version 2.2 + */ + int (*write) (const char *, const char *, size_t, FUSE_OFF_T, + struct fuse_file_info *); + + /** Get file system statistics + * + * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored + * + * Replaced 'struct statfs' parameter with 'struct statvfs' in + * version 2.5 + */ + int (*statfs) (const char *, struct statvfs *); + + /** Possibly flush cached data + * + * BIG NOTE: This is not equivalent to fsync(). It's not a + * request to sync dirty data. + * + * Flush is called on each close() of a file descriptor. So if a + * filesystem wants to return write errors in close() and the file + * has cached dirty data, this is a good place to write back data + * and return any errors. Since many applications ignore close() + * errors this is not always useful. + * + * NOTE: The flush() method may be called more than once for each + * open(). This happens if more than one file descriptor refers + * to an opened file due to dup(), dup2() or fork() calls. It is + * not possible to determine if a flush is final, so each flush + * should be treated equally. Multiple write-flush sequences are + * relatively rare, so this shouldn't be a problem. + * + * Filesystems shouldn't assume that flush will always be called + * after some writes, or that if will be called at all. + * + * Changed in version 2.2 + */ + int (*flush) (const char *, struct fuse_file_info *); + + /** Release an open file + * + * Release is called when there are no more references to an open + * file: all file descriptors are closed and all memory mappings + * are unmapped. + * + * For every open() call there will be exactly one release() call + * with the same flags and file descriptor. It is possible to + * have a file opened more than once, in which case only the last + * release will mean, that no more reads/writes will happen on the + * file. The return value of release is ignored. + * + * Changed in version 2.2 + */ + int (*release) (const char *, struct fuse_file_info *); + + /** Synchronize file contents + * + * If the datasync parameter is non-zero, then only the user data + * should be flushed, not the meta data. + * + * Changed in version 2.2 + */ + int (*fsync) (const char *, int, struct fuse_file_info *); + + /** Set extended attributes */ + int (*setxattr) (const char *, const char *, const char *, size_t, int); + + /** Get extended attributes */ + int (*getxattr) (const char *, const char *, char *, size_t); + + /** List extended attributes */ + int (*listxattr) (const char *, char *, size_t); + + /** Remove extended attributes */ + int (*removexattr) (const char *, const char *); + + /** Open directory + * + * This method should check if the open operation is permitted for + * this directory + * + * Introduced in version 2.3 + */ + int (*opendir) (const char *, struct fuse_file_info *); + + /** Read directory + * + * This supersedes the old getdir() interface. New applications + * should use this. + * + * The filesystem may choose between two modes of operation: + * + * 1) The readdir implementation ignores the offset parameter, and + * passes zero to the filler function's offset. The filler + * function will not return '1' (unless an error happens), so the + * whole directory is read in a single readdir operation. This + * works just like the old getdir() method. + * + * 2) The readdir implementation keeps track of the offsets of the + * directory entries. It uses the offset parameter and always + * passes non-zero offset to the filler function. When the buffer + * is full (or an error happens) the filler function will return + * '1'. + * + * Introduced in version 2.3 + */ + int (*readdir) (const char *, void *, fuse_fill_dir_t, FUSE_OFF_T, + struct fuse_file_info *); + + /** Release directory + * + * Introduced in version 2.3 + */ + int (*releasedir) (const char *, struct fuse_file_info *); + + /** Synchronize directory contents + * + * If the datasync parameter is non-zero, then only the user data + * should be flushed, not the meta data + * + * Introduced in version 2.3 + */ + int (*fsyncdir) (const char *, int, struct fuse_file_info *); + + /** + * Initialize filesystem + * + * The return value will passed in the private_data field of + * fuse_context to all file operations and as a parameter to the + * destroy() method. + * + * Introduced in version 2.3 + * Changed in version 2.6 + */ + void *(*init) (struct fuse_conn_info *conn); + + /** + * Clean up filesystem + * + * Called on filesystem exit. + * + * Introduced in version 2.3 + */ + void (*destroy) (void *); + + /** + * Check file access permissions + * + * This will be called for the access() system call. If the + * 'default_permissions' mount option is given, this method is not + * called. + * + * This method is not called under Linux kernel versions 2.4.x + * + * Introduced in version 2.5 + */ + int (*access) (const char *, int); + + /** + * Create and open a file + * + * If the file does not exist, first create it with the specified + * mode, and then open it. + * + * If this method is not implemented or under Linux kernel + * versions earlier than 2.6.15, the mknod() and open() methods + * will be called instead. + * + * Introduced in version 2.5 + */ + int (*create) (const char *, mode_t, struct fuse_file_info *); + + /** + * Change the size of an open file + * + * This method is called instead of the truncate() method if the + * truncation was invoked from an ftruncate() system call. + * + * If this method is not implemented or under Linux kernel + * versions earlier than 2.6.15, the truncate() method will be + * called instead. + * + * Introduced in version 2.5 + */ + int (*ftruncate) (const char *, FUSE_OFF_T, struct fuse_file_info *); + + /** + * Get attributes from an open file + * + * This method is called instead of the getattr() method if the + * file information is available. + * + * Currently this is only called after the create() method if that + * is implemented (see above). Later it may be called for + * invocations of fstat() too. + * + * Introduced in version 2.5 + */ + int (*fgetattr) (const char *, struct FUSE_STAT *, struct fuse_file_info *); + + /** + * Perform POSIX file locking operation + * + * The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW. + * + * For the meaning of fields in 'struct flock' see the man page + * for fcntl(2). The l_whence field will always be set to + * SEEK_SET. + * + * For checking lock ownership, the 'fuse_file_info->owner' + * argument must be used. + * + * For F_GETLK operation, the library will first check currently + * held locks, and if a conflicting lock is found it will return + * information without calling this method. This ensures, that + * for local locks the l_pid field is correctly filled in. The + * results may not be accurate in case of race conditions and in + * the presence of hard links, but it's unlikly that an + * application would rely on accurate GETLK results in these + * cases. If a conflicting lock is not found, this method will be + * called, and the filesystem may fill out l_pid by a meaningful + * value, or it may leave this field zero. + * + * For F_SETLK and F_SETLKW the l_pid field will be set to the pid + * of the process performing the locking operation. + * + * Note: if this method is not implemented, the kernel will still + * allow file locking to work locally. Hence it is only + * interesting for network filesystems and similar. + * + * Introduced in version 2.6 + */ + int (*lock) (const char *, struct fuse_file_info *, int cmd, + struct flock *); + + /** + * Change the access and modification times of a file with + * nanosecond resolution + * + * Introduced in version 2.6 + */ + int (*utimens) (const char *, const struct timespec tv[2]); + + /** + * Map block index within file to block index within device + * + * Note: This makes sense only for block device backed filesystems + * mounted with the 'blkdev' option + * + * Introduced in version 2.6 + */ + int (*bmap) (const char *, size_t blocksize, uint64_t *idx); + +#ifdef _WIN32 + /* these to support extented windows calls */ + uint32_t (*win_get_attributes) (const char *fn); + int (*win_set_attributes) (const char *fn, uint32_t attr); + int (*win_set_times) (const char *fn, struct fuse_file_info *, const FILETIME *create, const FILETIME *access, const FILETIME *modified); +#endif +}; + +/** Extra context that may be needed by some filesystems + * + * The uid, gid and pid fields are not filled in case of a writepage + * operation. + */ +struct fuse_context { + /** Pointer to the fuse object */ + struct fuse *fuse; + + /** User ID of the calling process */ + uid_t uid; + + /** Group ID of the calling process */ + gid_t gid; + + /** Thread ID of the calling process */ + pid_t pid; + + /** Private filesystem data */ + void *private_data; +}; + +/** + * Main function of FUSE. + * + * This is for the lazy. This is all that has to be called from the + * main() function. + * + * This function does the following: + * - parses command line options (-d -s and -h) + * - passes relevant mount options to the fuse_mount() + * - installs signal handlers for INT, HUP, TERM and PIPE + * - registers an exit handler to unmount the filesystem on program exit + * - creates a fuse handle + * - registers the operations + * - calls either the single-threaded or the multi-threaded event loop + * + * Note: this is currently implemented as a macro. + * + * @param argc the argument counter passed to the main() function + * @param argv the argument vector passed to the main() function + * @param op the file system operation + * @param user_data user data supplied in the context during the init() method + * @return 0 on success, nonzero on failure + */ +/* + int fuse_main(int argc, char *argv[], const struct fuse_operations *op, + void *user_data); +*/ +#define fuse_main(argc, argv, op, user_data) \ + fuse_main_real(argc, argv, op, sizeof(*(op)), user_data) + +/* ----------------------------------------------------------- * + * More detailed API * + * ----------------------------------------------------------- */ + +/** + * Create a new FUSE filesystem. + * + * @param ch the communication channel + * @param args argument vector + * @param op the filesystem operations + * @param op_size the size of the fuse_operations structure + * @param user_data user data supplied in the context during the init() method + * @return the created FUSE handle + */ +struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *op, size_t op_size, + void *user_data); + +/** + * Destroy the FUSE handle. + * + * The communication channel attached to the handle is also destroyed. + * + * NOTE: This function does not unmount the filesystem. If this is + * needed, call fuse_unmount() before calling this function. + * + * @param f the FUSE handle + */ +void fuse_destroy(struct fuse *f); + +/** + * FUSE event loop. + * + * Requests from the kernel are processed, and the appropriate + * operations are called. + * + * @param f the FUSE handle + * @return 0 if no error occurred, -1 otherwise + */ +int fuse_loop(struct fuse *f); + +/** + * Exit from event loop + * + * @param f the FUSE handle + */ +void fuse_exit(struct fuse *f); + +/** + * FUSE event loop with multiple threads + * + * Requests from the kernel are processed, and the appropriate + * operations are called. Request are processed in parallel by + * distributing them between multiple threads. + * + * Calling this function requires the pthreads library to be linked to + * the application. + * + * @param f the FUSE handle + * @return 0 if no error occurred, -1 otherwise + */ +int fuse_loop_mt(struct fuse *f); + +/** + * Get the current context + * + * The context is only valid for the duration of a filesystem + * operation, and thus must not be stored and used later. + * + * @return the context + */ +struct fuse_context *fuse_get_context(void); + +/** + * Check if a request has already been interrupted + * + * @param req request handle + * @return 1 if the request has been interrupted, 0 otherwise + */ +int fuse_interrupted(void); + +/** + * Obsolete, doesn't do anything + * + * @return -EINVAL + */ +int fuse_invalidate(struct fuse *f, const char *path); + +/* Deprecated, don't use */ +int fuse_is_lib_option(const char *opt); + +/** + * The real main function + * + * Do not call this directly, use fuse_main() + */ +int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, + size_t op_size, void *user_data); + +/* + * Stacking API + */ + +/** + * Fuse filesystem object + * + * This is opaque object represents a filesystem layer + */ +struct fuse_fs; + +/* + * These functions call the relevant filesystem operation, and return + * the result. + * + * If the operation is not defined, they return -ENOSYS, with the + * exception of fuse_fs_open, fuse_fs_release, fuse_fs_opendir, + * fuse_fs_releasedir and fuse_fs_statfs, which return 0. + */ + +int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct FUSE_STAT *buf); +int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct FUSE_STAT *buf, + struct fuse_file_info *fi); +int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath, + const char *newpath); +int fuse_fs_unlink(struct fuse_fs *fs, const char *path); +int fuse_fs_rmdir(struct fuse_fs *fs, const char *path); +int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, + const char *path); +int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath); +int fuse_fs_release(struct fuse_fs *fs, const char *path, + struct fuse_file_info *fi); +int fuse_fs_open(struct fuse_fs *fs, const char *path, + struct fuse_file_info *fi); +int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size, + FUSE_OFF_T off, struct fuse_file_info *fi); +int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf, + size_t size, FUSE_OFF_T off, struct fuse_file_info *fi); +int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync, + struct fuse_file_info *fi); +int fuse_fs_flush(struct fuse_fs *fs, const char *path, + struct fuse_file_info *fi); +int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf); +int fuse_fs_opendir(struct fuse_fs *fs, const char *path, + struct fuse_file_info *fi); +int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf, + fuse_fill_dir_t filler, FUSE_OFF_T off, + struct fuse_file_info *fi); +int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync, + struct fuse_file_info *fi); +int fuse_fs_releasedir(struct fuse_fs *fs, const char *path, + struct fuse_file_info *fi); +int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode, + struct fuse_file_info *fi); +int fuse_fs_lock(struct fuse_fs *fs, const char *path, + struct fuse_file_info *fi, int cmd, struct flock *lock); +int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode); +int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid); +int fuse_fs_truncate(struct fuse_fs *fs, const char *path, FUSE_OFF_T size); +int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, FUSE_OFF_T size, + struct fuse_file_info *fi); +int fuse_fs_utimens(struct fuse_fs *fs, const char *path, + const struct timespec tv[2]); +int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask); +int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf, + size_t len); +int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode, + dev_t rdev); +int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode); +int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name, + const char *value, size_t size, int flags); +int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name, + char *value, size_t size); +int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list, + size_t size); +int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, + const char *name); +int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize, + uint64_t *idx); +void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn); +void fuse_fs_destroy(struct fuse_fs *fs); + +/** + * Create a new fuse filesystem object + * + * This is usually called from the factory of a fuse module to create + * a new instance of a filesystem. + * + * @param op the filesystem operations + * @param op_size the size of the fuse_operations structure + * @param user_data user data supplied in the context during the init() method + * @return a new filesystem object + */ +struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size, + void *user_data); + +/** + * Filesystem module + * + * Filesystem modules are registered with the FUSE_REGISTER_MODULE() + * macro. + * + * If the "-omodules=modname:..." option is present, filesystem + * objects are created and pushed onto the stack with the 'factory' + * function. + */ +struct fuse_module { + /** + * Name of filesystem + */ + const char *name; + + /** + * Factory for creating filesystem objects + * + * The function may use and remove options from 'args' that belong + * to this module. + * + * For now the 'fs' vector always contains exactly one filesystem. + * This is the filesystem which will be below the newly created + * filesystem in the stack. + * + * @param args the command line arguments + * @param fs NULL terminated filesystem object vector + * @return the new filesystem object + */ + struct fuse_fs *(*factory)(struct fuse_args *args, + struct fuse_fs *fs[]); + + struct fuse_module *next; + struct fusemod_so *so; + int ctr; +}; + +/** + * Register a filesystem module + * + * This function is used by FUSE_REGISTER_MODULE and there's usually + * no need to call it directly + */ +void fuse_register_module(struct fuse_module *mod); + +/** + * Register filesystem module + * + * For the parameters, see description of the fields in 'struct + * fuse_module' + */ +#define FUSE_REGISTER_MODULE(name_, factory_) \ + static __attribute__((constructor)) void name_ ## _register(void) \ + { \ + static struct fuse_module mod = \ + { #name_, factory_, NULL, NULL, 0 }; \ + fuse_register_module(&mod); \ + } + + +/* ----------------------------------------------------------- * + * Advanced API for event handling, don't worry about this... * + * ----------------------------------------------------------- */ + +/* NOTE: the following functions are deprecated, and will be removed + from the 3.0 API. Use the lowlevel session functions instead */ + +/** Function type used to process commands */ +typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *); + +/** This is the part of fuse_main() before the event loop */ +struct fuse *fuse_setup(int argc, char *argv[], + const struct fuse_operations *op, size_t op_size, + char **mountpoint, int *multithreaded, + void *user_data); + +/** This is the part of fuse_main() after the event loop */ +void fuse_teardown(struct fuse *fuse, char *mountpoint); + +/** Read a single command. If none are read, return NULL */ +struct fuse_cmd *fuse_read_cmd(struct fuse *f); + +/** Process a single command */ +void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd); + +/** Multi threaded event loop, which calls the custom command + processor function */ +int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data); + +/** Return the exited flag, which indicates if fuse_exit() has been + called */ +int fuse_exited(struct fuse *f); + +/** This function is obsolete and implemented as a no-op */ +void fuse_set_getcontext_func(struct fuse_context *(*func)(void)); + +/** Get session from fuse object */ +struct fuse_session *fuse_get_session(struct fuse *f); + +/* ----------------------------------------------------------- * + * Compatibility stuff * + * ----------------------------------------------------------- */ + +#if FUSE_USE_VERSION < 26 +# include "fuse_compat.h" +# undef fuse_main +# if FUSE_USE_VERSION == 25 +# define fuse_main(argc, argv, op) \ + fuse_main_real_compat25(argc, argv, op, sizeof(*(op))) +# define fuse_new fuse_new_compat25 +# define fuse_setup fuse_setup_compat25 +# define fuse_teardown fuse_teardown_compat22 +# define fuse_operations fuse_operations_compat25 +# elif FUSE_USE_VERSION == 22 +# define fuse_main(argc, argv, op) \ + fuse_main_real_compat22(argc, argv, op, sizeof(*(op))) +# define fuse_new fuse_new_compat22 +# define fuse_setup fuse_setup_compat22 +# define fuse_teardown fuse_teardown_compat22 +# define fuse_operations fuse_operations_compat22 +# define fuse_file_info fuse_file_info_compat +# elif FUSE_USE_VERSION == 24 +# error Compatibility with high-level API version 24 not supported +# else +# define fuse_dirfil_t fuse_dirfil_t_compat +# define __fuse_read_cmd fuse_read_cmd +# define __fuse_process_cmd fuse_process_cmd +# define __fuse_loop_mt fuse_loop_mt_proc +# if FUSE_USE_VERSION == 21 +# define fuse_operations fuse_operations_compat2 +# define fuse_main fuse_main_compat2 +# define fuse_new fuse_new_compat2 +# define __fuse_setup fuse_setup_compat2 +# define __fuse_teardown fuse_teardown_compat22 +# define __fuse_exited fuse_exited +# define __fuse_set_getcontext_func fuse_set_getcontext_func +# else +# define fuse_statfs fuse_statfs_compat1 +# define fuse_operations fuse_operations_compat1 +# define fuse_main fuse_main_compat1 +# define fuse_new fuse_new_compat1 +# define FUSE_DEBUG FUSE_DEBUG_COMPAT1 +# endif +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* FUSE_H_ */ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_common.h b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_common.h new file mode 100644 index 000000000..9cc2a44d3 --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_common.h @@ -0,0 +1,249 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001-2007 Miklos Szeredi + + This program can be distributed under the terms of the GNU LGPLv2. + See the file COPYING.LIB. +*/ + +/** @file */ + +#if !defined(FUSE_H_) && !defined(FUSE_LOWLEVEL_H_) +#error "Never include directly; use or instead." +#endif + +#ifndef FUSE_COMMON_H_ +#define FUSE_COMMON_H_ + +#include "fuse_opt.h" +#ifndef _MSC_VER +#include +#endif + +/** Major version of FUSE library interface */ +#define FUSE_MAJOR_VERSION 2 + +/** Minor version of FUSE library interface */ +#define FUSE_MINOR_VERSION 7 + +#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) +#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) + +/* This interface uses 64 bit off_t, except on Windows where it's +possible to use 32-bit filelengths for compatibility with MSVC CRT */ +#ifndef _MSC_VER +/* This interface uses 64 bit off_t */ +#if _FILE_OFFSET_BITS != 64 +#error Please add -D_FILE_OFFSET_BITS=64 to your compile flags! +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Information about open files + * + * Changed in version 2.5 + */ +struct fuse_file_info { + /** Open flags. Available in open() and release() */ + int flags; + + /** Old file handle, don't use */ + unsigned long 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 */ + unsigned int direct_io : 1; + + /** Can be filled in by open, to indicate, that cached file data + need not be invalidated. Introduced in version 2.4 */ + unsigned int 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 */ + unsigned int flush : 1; + + /** Padding. Do not use*/ + unsigned int padding : 29; + + /** 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; +}; + +/** + * Connection information, passed to the ->init() method + * + * Some of the elements are read-write, these can be changed to + * indicate the value requested by the filesystem. The requested + * value must usually be smaller than the indicated value. + */ +struct fuse_conn_info { + /** + * Major version of the protocol (read-only) + */ + unsigned proto_major; + + /** + * Minor version of the protocol (read-only) + */ + unsigned proto_minor; + + /** + * Is asynchronous read supported (read-write) + */ + unsigned async_read; + + /** + * Maximum size of the write buffer + */ + unsigned max_write; + + /** + * Maximum readahead + */ + unsigned max_readahead; + + /** + * For future use. + */ + unsigned reserved[27]; +}; + +struct fuse_session; +struct fuse_chan; + +/** + * Create a FUSE mountpoint + * + * Returns a control file descriptor suitable for passing to + * fuse_new() + * + * @param mountpoint the mount point path + * @param args argument vector + * @return the communication channel on success, NULL on failure + */ +struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args); + +/** + * Umount a FUSE mountpoint + * + * @param mountpoint the mount point path + * @param ch the communication channel + */ +void fuse_unmount(const char *mountpoint, struct fuse_chan *ch); + +/** + * Parse common options + * + * The following options are parsed: + * + * '-f' foreground + * '-d' '-odebug' foreground, but keep the debug option + * '-s' single threaded + * '-h' '--help' help + * '-ho' help without header + * '-ofsname=..' file system name, if not present, then set to the program + * name + * + * All parameters may be NULL + * + * @param args argument vector + * @param mountpoint the returned mountpoint, should be freed after use + * @param multithreaded set to 1 unless the '-s' option is present + * @param foreground set to 1 if one of the relevant options is present + * @return 0 on success, -1 on failure + */ +int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint, + int *multithreaded, int *foreground); + +/** + * Go into the background + * + * @param foreground if true, stay in the foreground + * @return 0 on success, -1 on failure + */ +int fuse_daemonize(int foreground); + +/** + * Get the version of the library + * + * @return the version + */ +int fuse_version(void); + +/* ----------------------------------------------------------- * + * Signal handling * + * ----------------------------------------------------------- */ + +/** + * Exit session on HUP, TERM and INT signals and ignore PIPE signal + * + * Stores session in a global variable. May only be called once per + * process until fuse_remove_signal_handlers() is called. + * + * @param se the session to exit + * @return 0 on success, -1 on failure + */ +int fuse_set_signal_handlers(struct fuse_session *se); + +/** + * Restore default signal handlers + * + * Resets global session. After this fuse_set_signal_handlers() may + * be called again. + * + * @param se the same session as given in fuse_set_signal_handlers() + */ +void fuse_remove_signal_handlers(struct fuse_session *se); + +/* ----------------------------------------------------------- * + * Compatibility stuff * + * ----------------------------------------------------------- */ + +#if FUSE_USE_VERSION < 26 +# ifdef __FreeBSD__ +# if FUSE_USE_VERSION < 25 +# error On FreeBSD API version 25 or greater must be used +# endif +# endif +# include "fuse_common_compat.h" +# undef FUSE_MINOR_VERSION +# undef fuse_main +# define fuse_unmount fuse_unmount_compat22 +# if FUSE_USE_VERSION == 25 +# define FUSE_MINOR_VERSION 5 +# define fuse_mount fuse_mount_compat25 +# elif FUSE_USE_VERSION == 24 || FUSE_USE_VERSION == 22 +# define FUSE_MINOR_VERSION 4 +# define fuse_mount fuse_mount_compat22 +# elif FUSE_USE_VERSION == 21 +# define FUSE_MINOR_VERSION 1 +# define fuse_mount fuse_mount_compat22 +# elif FUSE_USE_VERSION == 11 +# warning Compatibility with API version 11 is deprecated +# undef FUSE_MAJOR_VERSION +# define FUSE_MAJOR_VERSION 1 +# define FUSE_MINOR_VERSION 1 +# define fuse_mount fuse_mount_compat1 +# else +# error Compatibility with API version other than 21, 22, 24, 25 and 11 not supported +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* FUSE_COMMON_H_ */ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_opt.h b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_opt.h new file mode 100644 index 000000000..ab62858c2 --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_opt.h @@ -0,0 +1,267 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001-2007 Miklos Szeredi + + This program can be distributed under the terms of the GNU LGPLv2. + See the file COPYING.LIB. +*/ + +#ifndef FUSE_OPT_H_ +#define FUSE_OPT_H_ + +/** @file + * + * This file defines the option parsing interface of FUSE + */ + +#ifdef _MSC_VER +#define STRDUP _strdup +#else +#define STRDUP strdup +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Option description + * + * This structure describes a single option, and and action associated + * with it, in case it matches. + * + * More than one such match may occur, in which case the action for + * each match is executed. + * + * There are three possible actions in case of a match: + * + * i) An integer (int or unsigned) variable determined by 'offset' is + * set to 'value' + * + * ii) The processing function is called, with 'value' as the key + * + * iii) An integer (any) or string (char *) variable determined by + * 'offset' is set to the value of an option parameter + * + * 'offset' should normally be either set to + * + * - 'offsetof(struct foo, member)' actions i) and iii) + * + * - -1 action ii) + * + * The 'offsetof()' macro is defined in the header. + * + * The template determines which options match, and also have an + * effect on the action. Normally the action is either i) or ii), but + * if a format is present in the template, then action iii) is + * performed. + * + * The types of templates are: + * + * 1) "-x", "-foo", "--foo", "--foo-bar", etc. These match only + * themselves. Invalid values are "--" and anything beginning + * with "-o" + * + * 2) "foo", "foo-bar", etc. These match "-ofoo", "-ofoo-bar" or + * the relevant option in a comma separated option list + * + * 3) "bar=", "--foo=", etc. These are variations of 1) and 2) + * which have a parameter + * + * 4) "bar=%s", "--foo=%lu", etc. Same matching as above but perform + * action iii). + * + * 5) "-x ", etc. Matches either "-xparam" or "-x param" as + * two separate arguments + * + * 6) "-x %s", etc. Combination of 4) and 5) + * + * If the format is "%s", memory is allocated for the string unlike + * with scanf(). + */ +struct fuse_opt { + /** Matching template and optional parameter formatting */ + const char *templ; + + /** + * Offset of variable within 'data' parameter of fuse_opt_parse() + * or -1 + */ + unsigned long offset; + + /** + * Value to set the variable to, or to be passed as 'key' to the + * processing function. Ignored if template has a format + */ + int value; +}; + +/** + * Key option. In case of a match, the processing function will be + * called with the specified key. + */ +#define FUSE_OPT_KEY(templ, key) { templ, (unsigned long)(-1), key } + +/** + * Last option. An array of 'struct fuse_opt' must end with a NULL + * template value + */ +#define FUSE_OPT_END { NULL } + +/** + * Argument list + */ +struct fuse_args { + /** Argument count */ + int argc; + + /** Argument vector. NULL terminated */ + char **argv; + + /** Is 'argv' allocated? */ + int allocated; +}; + +/** + * Initializer for 'struct fuse_args' + */ +#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 } + +/** + * Key value passed to the processing function if an option did not + * match any template + */ +#define FUSE_OPT_KEY_OPT -1 + +/** + * Key value passed to the processing function for all non-options + * + * Non-options are the arguments beginning with a charater other than + * '-' or all arguments after the special '--' option + */ +#define FUSE_OPT_KEY_NONOPT -2 + +/** + * Special key value for options to keep + * + * Argument is not passed to processing function, but behave as if the + * processing function returned 1 + */ +#define FUSE_OPT_KEY_KEEP -3 + +/** + * Special key value for options to discard + * + * Argument is not passed to processing function, but behave as if the + * processing function returned zero + */ +#define FUSE_OPT_KEY_DISCARD -4 + +/** + * Processing function + * + * This function is called if + * - option did not match any 'struct fuse_opt' + * - argument is a non-option + * - option did match and offset was set to -1 + * + * The 'arg' parameter will always contain the whole argument or + * option including the parameter if exists. A two-argument option + * ("-x foo") is always converted to single arguemnt option of the + * form "-xfoo" before this function is called. + * + * Options of the form '-ofoo' are passed to this function without the + * '-o' prefix. + * + * The return value of this function determines whether this argument + * is to be inserted into the output argument vector, or discarded. + * + * @param data is the user data passed to the fuse_opt_parse() function + * @param arg is the whole argument or option + * @param key determines why the processing function was called + * @param outargs the current output argument list + * @return -1 on error, 0 if arg is to be discarded, 1 if arg should be kept + */ +typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key, + struct fuse_args *outargs); + +/** + * Option parsing function + * + * If 'args' was returned from a previous call to fuse_opt_parse() or + * it was constructed from + * + * A NULL 'args' is equivalent to an empty argument vector + * + * A NULL 'opts' is equivalent to an 'opts' array containing a single + * end marker + * + * A NULL 'proc' is equivalent to a processing function always + * returning '1' + * + * @param args is the input and output argument list + * @param data is the user data + * @param opts is the option description array + * @param proc is the processing function + * @return -1 on error, 0 on success + */ +int fuse_opt_parse(struct fuse_args *args, void *data, + const struct fuse_opt opts[], fuse_opt_proc_t proc); + +/** + * Add an option to a comma separated option list + * + * @param opts is a pointer to an option list, may point to a NULL value + * @param opt is the option to add + * @return -1 on allocation error, 0 on success + */ +int fuse_opt_add_opt(char **opts, const char *opt); + +/** + * Add an argument to a NULL terminated argument vector + * + * @param args is the structure containing the current argument list + * @param arg is the new argument to add + * @return -1 on allocation error, 0 on success + */ +int fuse_opt_add_arg(struct fuse_args *args, const char *arg); + +/** + * Add an argument at the specified position in a NULL terminated + * argument vector + * + * Adds the argument to the N-th position. This is useful for adding + * options at the beggining of the array which must not come after the + * special '--' option. + * + * @param args is the structure containing the current argument list + * @param pos is the position at which to add the argument + * @param arg is the new argument to add + * @return -1 on allocation error, 0 on success + */ +int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg); + +/** + * Free the contents of argument list + * + * The structure itself is not freed + * + * @param args is the structure containing the argument list + */ +void fuse_opt_free_args(struct fuse_args *args); + + +/** + * Check if an option matches + * + * @param opts is the option description array + * @param opt is the option to match + * @return 1 if a match is found, 0 if not + */ +int fuse_opt_match(const struct fuse_opt opts[], const char *opt); + +#ifdef __cplusplus +} +#endif + +#endif /* FUSE_OPT_H_ */ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_sem_fix.h b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_sem_fix.h new file mode 100644 index 000000000..f73c80e07 --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_sem_fix.h @@ -0,0 +1,27 @@ +#ifndef FUSE_SEM_FIX_H_ +#define FUSE_SEM_FIX_H_ + +#ifdef __CYGWIN__ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int my_sem_init(sem_t *sem, int pshared, int initial); +int my_sem_destroy(sem_t *sem); +int my_sem_post (sem_t * sem); +int my_sem_wait (sem_t * sem); +#define sem_init my_sem_init +#define sem_destroy my_sem_destroy +#define sem_wait my_sem_wait +#define sem_post my_sem_post + +#ifdef __cplusplus +}; +#endif + + +#endif + +#endif //FUSE_SEM_FIX_H_ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_win.h b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_win.h new file mode 100644 index 000000000..d7da5bc42 --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/fuse_win.h @@ -0,0 +1,221 @@ +/* ----------------------------------------------------------- * +* Win32 helper functions * +* Compilation on MSVC requires /Zc:wchar_t compiler option * +* ----------------------------------------------------------- */ +#ifndef FUSE_WIN_H_ +#define FUSE_WIN_H_ + +#include +#include + +#ifdef _MSC_VER +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS +#endif + +/** Only use the latest version on Windows */ +#ifndef FUSE_USE_VERSION +#define FUSE_USE_VERSION 27 +#endif + +#ifndef DEFAULT_FUSE_VOLUME_NAME +#define DEFAULT_FUSE_VOLUME_NAME "DOKAN" +#endif + +#ifndef DEFAULT_FUSE_FILESYSTEM_NAME +#define DEFAULT_FUSE_FILESYSTEM_NAME "Dokan user-level file system" +#endif + +#ifdef __cplusplus +extern "C" { +#endif +int ntstatus_error_to_errno(int win_res); +int errno_to_ntstatus_error(int err); + +//This stuff is useful only on Windows in MSVC +#ifdef _MSC_VER +char** convert_args(int argc, wchar_t* argv[]); +void free_converted_args(int argc, char **argv); +#endif + +#ifdef __cplusplus +}; +#endif + +extern wchar_t* Dokan_filesystem_name; +extern wchar_t* Dokan_volume_name; + +///////////////////////////////////////////////////////////////////// +////// Type definitions for MINGW32 +///////////////////////////////////////////////////////////////////// +#if defined(__MINGW32__) && !defined(UID_GID_DEF) +typedef unsigned int gid_t; +typedef unsigned int uid_t; +#endif + +#if !defined(HAVE_STRUCT_TIMESPEC) && !defined(__CYGWIN__) && !defined(_TIMESPEC_DEFINED) && defined(_CRT_NO_TIME_T) /* win32 pthread.h time.h defines it */ +/* POSIX.1b structure for a time value. This is like a `struct timeval' but +has nanoseconds instead of microseconds. */ +#define HAVE_STRUCT_TIMESPEC 1 +#define _TIMESPEC_DEFINED +struct timespec +{ + time_t tv_sec; /* Seconds. */ + long int tv_nsec; /* Nanoseconds. */ +}; +#endif + +#if defined(__MINGW32__) +/** Use 64 bit offsets */ +#define __USE_FILE_OFFSET64 +//Block sizes +typedef unsigned __int64 fsfilcnt64_t; +typedef unsigned __int64 fsblkcnt64_t; +typedef struct timespec timestruc_t; +typedef unsigned short nlink_t; +typedef unsigned __int64 uint64_t; +typedef unsigned int blksize_t; +typedef unsigned __int64 blkcnt_t; + +/** Transplanted from */ +struct statvfs +{ + unsigned long int f_bsize; + unsigned long int f_frsize; + fsblkcnt64_t f_blocks; + fsblkcnt64_t f_bfree; + fsblkcnt64_t f_bavail; + fsfilcnt64_t f_files; + fsfilcnt64_t f_ffree; + fsfilcnt64_t f_favail; + unsigned long int f_fsid; + unsigned long int f_flag; + unsigned long int f_namemax; +}; +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +#endif + +///////////////////////////////////////////////////////////////////// +////// Type definitions for MSVC +///////////////////////////////////////////////////////////////////// +#if defined(_MSC_VER) +//UNIX compatibility +typedef struct timespec timestruc_t; +typedef unsigned int mode_t; +typedef unsigned short nlink_t; +typedef unsigned int pid_t; +typedef unsigned int gid_t; +typedef unsigned int uid_t; +typedef unsigned int blksize_t; +typedef unsigned __int64 blkcnt_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; + + +//OCTAL constants! +#define S_IFLNK 0120000 +#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) + +/** Use 64 bit offsets */ +#define __USE_FILE_OFFSET64 +//Block sizes +typedef unsigned __int64 fsfilcnt64_t; +typedef unsigned __int64 fsblkcnt64_t; + +/** Transplanted from */ +struct statvfs +{ + unsigned long int f_bsize; + unsigned long int f_frsize; + fsblkcnt64_t f_blocks; + fsblkcnt64_t f_bfree; + fsblkcnt64_t f_bavail; + fsfilcnt64_t f_files; + fsfilcnt64_t f_ffree; + fsfilcnt64_t f_favail; + unsigned long int f_fsid; + unsigned long int f_flag; + unsigned long int f_namemax; +}; + +struct flock { + short l_type; + short l_whence; + __int64 l_start; + __int64 l_len; + pid_t l_pid; +}; + +#endif + +//We have a choice between CRT-compatible 32-bit off_t definition +//and a custom 64-bit definition +#define WIDE_OFF_T 1 +#ifndef WIDE_OFF_T +#define FUSE_OFF_T off_t +#define FUSE_STAT stat + +#else +#define FUSE_OFF_T __int64 +// #define FUSE_STAT _stati64 +// use stat from cygwin instead for having more members and +// being more compatible +// stat ported from cygwin sys/stat.h +struct stat64_cygwin +{ + dev_t st_dev; + uint64_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + FUSE_OFF_T st_size; + timestruc_t st_atim; + timestruc_t st_mtim; + timestruc_t st_ctim; + blksize_t st_blksize; + blkcnt_t st_blocks; + timestruc_t st_birthtim; +}; +/* The following breaks struct stat definiton in native Windows stats.h +* So whenever referencing st_atime|st_ctime|st_mtime, replacing is needed. +*/ +/* +#define st_atime st_atim.tv_sec +#define st_ctime st_ctim.tv_sec +#define st_mtime st_mtim.tv_sec +*/ +#define FUSE_STAT stat64_cygwin +#if 0 +struct stat64 { + dev_t st_dev; + ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + dev_t st_rdev; + FUSE_OFF_T st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; +#endif +#endif + + +#define F_WRLCK 1 +#define F_UNLCK 2 +#define F_SETLK 6 + +#endif // FUSE_WIN_H_ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/fusemain.h b/dokan_fuse/pkg/opt/include/dokan_fuse/fusemain.h new file mode 100644 index 000000000..94a6f80a1 --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/fusemain.h @@ -0,0 +1,234 @@ +#ifndef FUSEMAIN_H_ +#define FUSEMAIN_H_ + +#include "../../dokan/dokan.h" +#include "fuse.h" +#include "utils.h" +#include +#include +#include +#include + +#define CHECKED(arg) if (0);else {int __res=arg; if (__res<0) return __res;} +#define MAX_READ_SIZE (65536) + +class impl_fuse_context; +struct impl_chain_link; + +class impl_file_handle; +class impl_file_lock; + +class impl_file_locks +{ +private: + typedef std::map file_locks_t; + file_locks_t file_locks; + CRITICAL_SECTION lock; +public: + impl_file_locks() { InitializeCriticalSection(&lock); } + ~impl_file_locks() { DeleteCriticalSection(&lock); }; + int get_file(const std::string &name, bool is_dir, DWORD access_mode, DWORD shared_mode, std::unique_ptr& out); + void renamed_file(const std::string &name,const std::string &new_name); + void remove_file(const std::string& name); +}; + +struct impl_chain_link +{ + impl_chain_link *prev_link_; + fuse_context call_ctx_; + impl_chain_link() : prev_link_(nullptr) { memset(&call_ctx_, 0, sizeof(call_ctx_)); } +}; + +/* + This class pushes the impl_fuse_context frame on a thread-local stack, + this allows to have reentrant FUSE filesystem (if anyone really wants + it one day...) +*/ +class impl_chain_guard +{ + impl_chain_link link; +public: + impl_chain_guard(impl_fuse_context* ctx, int caller_pid); + ~impl_chain_guard(); +}; + +class win_error +{ +public: + win_error(int _err): err(errno_to_ntstatus_error(_err)) {} + win_error(int _err, bool): err(_err) {} + operator int() { return err; } +private: + int err; +}; +/* + FUSE filesystem context +*/ +class impl_fuse_context +{ + friend class impl_chain_guard; + + struct fuse_operations ops_; + fuse_conn_info conn_info_; + void *user_data_; + bool debug_; + + unsigned int filemask_; + unsigned int dirmask_; + const char *fsname_, *volname_; + + impl_file_locks file_locks; +public: + impl_fuse_context(const struct fuse_operations *ops, void *user_data, + bool debug, unsigned int filemask, unsigned int dirmask, + const char *fsname, const char *volname); + + bool debug() const {return debug_;} + + ////////////////////////////////////Methods/////////////////////////////// + static int cast_from_longlong(LONGLONG src, FUSE_OFF_T *res); + + int do_open_dir(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo); + + int do_open_file(LPCWSTR FileName, DWORD share_mode, DWORD Flags, PDOKAN_FILE_INFO DokanFileInfo); + + int do_create_file(LPCWSTR FileName, DWORD Disposition, DWORD share_mode, DWORD Flags, + PDOKAN_FILE_INFO DokanFileInfo); + + int do_delete_directory(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + int do_delete_file(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + int convert_flags(DWORD Flags); + + int resolve_symlink(const std::string &name, std::string *res); + int check_and_resolve(std::string *name); + + struct walk_data + { + impl_fuse_context *ctx; + std::string dirname; + PDOKAN_FILE_INFO DokanFileInfo; + PFillFindData delegate; + std::vector getdir_data; //Used only in walk_directory_getdir() + }; + static int walk_directory(void *buf, const char *name, + const struct FUSE_STAT *stbuf, FUSE_OFF_T off); + static int walk_directory_getdir(fuse_dirh_t hndl, const char *name, int type,ino_t ino); + + ///////////////////////////////////Delegates////////////////////////////// + int find_files(LPCWSTR file_name, PFillFindData fill_find_data, + PDOKAN_FILE_INFO dokan_file_info); + + int open_directory(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + int cleanup(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + int create_directory(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + int delete_directory(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + win_error create_file(LPCWSTR file_name, DWORD access_mode, DWORD share_mode, + DWORD creation_disposition, DWORD flags_and_attributes, + PDOKAN_FILE_INFO dokan_file_info); + + int close_file(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + int read_file(LPCWSTR file_name, LPVOID buffer, DWORD num_bytes_to_read, + LPDWORD read_bytes, LONGLONG offset, PDOKAN_FILE_INFO dokan_file_info); + + int write_file(LPCWSTR file_name, LPCVOID buffer, + DWORD num_bytes_to_write,LPDWORD num_bytes_written, + LONGLONG offset, PDOKAN_FILE_INFO dokan_file_info); + + int flush_file_buffers(LPCWSTR file_name, + PDOKAN_FILE_INFO dokan_file_info); + + int get_file_information(LPCWSTR file_name, + LPBY_HANDLE_FILE_INFORMATION handle_file_information, + PDOKAN_FILE_INFO dokan_file_info); + + int delete_file(LPCWSTR file_name, PDOKAN_FILE_INFO dokan_file_info); + + int move_file(LPCWSTR file_name, LPCWSTR new_file_name, + BOOL replace_existing, PDOKAN_FILE_INFO dokan_file_info); + + int lock_file(LPCWSTR file_name, LONGLONG byte_offset, LONGLONG length, + PDOKAN_FILE_INFO dokan_file_info); + + int unlock_file(LPCWSTR file_name, LONGLONG byte_offset, LONGLONG length, + PDOKAN_FILE_INFO dokan_file_info); + + int set_end_of_file(LPCWSTR file_name, LONGLONG byte_offset, + PDOKAN_FILE_INFO dokan_file_info); + + int set_file_attributes(LPCWSTR file_name, DWORD file_attributes, + PDOKAN_FILE_INFO dokan_file_info); + + int helper_set_time_struct(const FILETIME* filetime, const time_t backup, + time_t *dest); + + int set_file_time(PCWSTR file_name, const FILETIME* creation_time, + const FILETIME* last_access_time, const FILETIME* last_write_time, + PDOKAN_FILE_INFO dokan_file_info); + + int get_disk_free_space(PULONGLONG free_bytes_available, + PULONGLONG number_of_bytes, PULONGLONG number_of_free_bytes, + PDOKAN_FILE_INFO dokan_file_info); + + int get_volume_information(LPWSTR volume_name_buffer,DWORD volume_name_size, + LPWSTR file_system_name_buffer, DWORD file_system_name_size, + PDOKAN_FILE_INFO dokan_file_info, LPDWORD volume_flags); + + int mounted(PDOKAN_FILE_INFO DokanFileInfo); + + int unmounted(PDOKAN_FILE_INFO DokanFileInfo); +}; + + +class impl_file_lock +{ + friend class impl_file_handle; + friend class impl_file_locks; + std::string name_; + impl_file_locks* locks; + impl_file_handle *first; + CRITICAL_SECTION lock; + + void add_file_unlocked(impl_file_handle *file); + int lock_file(impl_file_handle *file, long long start, long long len, bool mark=true); + int unlock_file(impl_file_handle *file, long long start, long long len); +public: + impl_file_lock(impl_file_locks* _locks, const std::string& name): locks(_locks), name_(name), first(NULL) { InitializeCriticalSection(&lock); } + ~impl_file_lock() { DeleteCriticalSection(&lock); }; + void remove_file(impl_file_handle *file); + const std::string& get_name() const {return name_;} +}; + + +class impl_file_handle +{ + friend class impl_file_lock; + friend class impl_file_locks; + bool is_dir_; + uint64_t fh_; + impl_file_handle *next_file; + impl_file_lock *file_lock; + DWORD shared_mode_; + typedef std::map locks_t; + locks_t locks; + impl_file_handle(bool is_dir, DWORD shared_mode); +public: + ~impl_file_handle(); + + bool is_dir() const {return is_dir_;} + int close(const struct fuse_operations *ops); + fuse_file_info make_finfo(); + const std::string& get_name() const {return file_lock->get_name();} + void set_finfo(const fuse_file_info& finfo) { fh_ = finfo.fh; }; + int check_lock(long long start, long long len) { return file_lock->lock_file(this, start, len, false); } + int lock(long long start, long long len) { return file_lock->lock_file(this, start, len); } + int unlock(long long start, long long len) { return file_lock->unlock_file(this, start, len); } +}; + +#endif // FUSEMAIN_H_ diff --git a/dokan_fuse/pkg/opt/include/dokan_fuse/utils.h b/dokan_fuse/pkg/opt/include/dokan_fuse/utils.h new file mode 100644 index 000000000..5be6d4c7a --- /dev/null +++ b/dokan_fuse/pkg/opt/include/dokan_fuse/utils.h @@ -0,0 +1,59 @@ +#ifndef UTILS_H_ +#define UTILS_H_ + +#include +#include +#include "fuse.h" + +/*#ifdef _MSC_VER +#define DLLLOCAL +#else +#define DLLLOCAL __attribute__ ((visibility("hidden"))) +#endif*/ + +void utf8_to_wchar_buf_old(const char *src, wchar_t *res, int maxlen); +void utf8_to_wchar_buf(const char *src, wchar_t *res, int maxlen); +std::string wchar_to_utf8_cstr(const wchar_t *str); + +std::string unixify(const std::string &str); +std::string extract_file_name(const std::string &str); +std::string extract_dir_name(const std::string &str); + +FILETIME unixTimeToFiletime(time_t t); +time_t filetimeToUnixTime(const FILETIME *ft); +bool is_filetime_set(const FILETIME *ft); + +template void convertStatlikeBuf(const struct FUSE_STAT *stbuf, const std::string &name, + T * find_data) +{ + if (stbuf==NULL) return; + + if ((stbuf->st_mode&S_IFDIR)==S_IFDIR) + find_data->dwFileAttributes=FILE_ATTRIBUTE_DIRECTORY; + else + find_data->dwFileAttributes=FILE_ATTRIBUTE_NORMAL; + +#ifndef WIDE_OFF_T + find_data->nFileSizeLow=stbuf->st_size; +#else + //Support 64 sizes + find_data->nFileSizeLow=(DWORD) stbuf->st_size; + find_data->nFileSizeHigh=stbuf->st_size>>32; +#endif + if (stbuf->st_ctim.tv_sec!=0) + find_data->ftCreationTime=unixTimeToFiletime(stbuf->st_ctim.tv_sec); + if (stbuf->st_atim.tv_sec!=0) + find_data->ftLastAccessTime=unixTimeToFiletime(stbuf->st_atim.tv_sec); + if (stbuf->st_mtim.tv_sec!=0) + find_data->ftLastWriteTime=unixTimeToFiletime(stbuf->st_mtim.tv_sec); + + //Partial support for read-only files - currently done for a files without write permission only + if (!(stbuf->st_mode&0222)) + find_data->dwFileAttributes|=FILE_ATTRIBUTE_READONLY; + //TODO: add full support for read-only files - try to derive it from file's owner? + std::string fname=extract_file_name(name); + if (!fname.empty() && fname.at(0)=='.') //UNIX hidden files + find_data->dwFileAttributes|=FILE_ATTRIBUTE_HIDDEN; +} + +#endif // UTILS_H_ diff --git a/dokan_fuse/pkg/usr/lib/pkgconfig/fuse.pc b/dokan_fuse/pkg/usr/lib/pkgconfig/fuse.pc new file mode 100644 index 000000000..a3ec89d70 --- /dev/null +++ b/dokan_fuse/pkg/usr/lib/pkgconfig/fuse.pc @@ -0,0 +1,10 @@ +prefix=/opt +exec_prefix=${prefix} +libdir=${exec_prefix}/bin +includedir=${prefix}/include + +Name: fuse +Description: A wrapper library that makes Dokan compatible with FUSE API +Version: 2.7 +Libs: -L${libdir} -ldokanfuse1 +Cflags: -I${includedir}/dokan_fuse