129 lines
4.8 KiB
C++
129 lines
4.8 KiB
C++
#ifndef FUSEINTERFACE_H
|
|
#define FUSEINTERFACE_H
|
|
|
|
#include <QCache>
|
|
#include <QDateTime>
|
|
#include <QDir>
|
|
#include <QFileSystemWatcher>
|
|
#include <QMutex>
|
|
#include <QObject>
|
|
#include <QSharedPointer>
|
|
#include <QSocketNotifier>
|
|
#include <QSqlDatabase>
|
|
|
|
extern "C" {
|
|
#define FUSE_USE_VERSION 31
|
|
|
|
#include <fuse3/fuse.h>
|
|
#include <fuse3/fuse_lowlevel.h>
|
|
#include <fcntl.h>
|
|
#include <stdarg.h>
|
|
#include <unarr.h>
|
|
#include <unistd.h>
|
|
}
|
|
|
|
//#include "database.h"
|
|
|
|
struct VFSStatEntry {
|
|
QString path;
|
|
time_t lastAccess;
|
|
quint32 openCount;
|
|
quint32 refCount;
|
|
};
|
|
|
|
class FuseAccessorBase;
|
|
class FuseFHBase;
|
|
class FuseInterface : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
int m_fuse_id;
|
|
struct fuse *m_fuse;
|
|
struct fuse_session *m_fuse_session;
|
|
QSocketNotifier *m_notifier;
|
|
QMutex m_mutex;
|
|
|
|
QSqlDatabase &m_database;
|
|
int m_profileId;
|
|
QString m_gameDataDir;
|
|
QString m_sandboxDir;
|
|
QString m_mountpoint;
|
|
|
|
QList< FuseAccessorBase * > m_accessors;
|
|
QList< FuseFHBase * > m_open_handles;
|
|
|
|
QMap< QString, QStringList > m_dircache;
|
|
QMap<QString, struct stat *> m_cache_stat;
|
|
QMap<QString, FuseAccessorBase *> m_cache_accessor;
|
|
QCache< QString, QSharedPointer<QByteArray> > m_cache_data;
|
|
QFileSystemWatcher m_watcher;
|
|
QHash< QString, VFSStatEntry > m_stats;
|
|
|
|
public:
|
|
explicit FuseInterface(QSqlDatabase &database, int profileId, const QString &gameDataDir, const QString &sandboxDir, const QString &mountpoint, QObject *parent=nullptr);
|
|
~FuseInterface();
|
|
|
|
Q_INVOKABLE bool mount();
|
|
Q_INVOKABLE int pump();
|
|
Q_INVOKABLE void unmount();
|
|
|
|
Q_INVOKABLE void clear();
|
|
Q_INVOKABLE void prepend(FuseAccessorBase *accessor);
|
|
Q_INVOKABLE void append(FuseAccessorBase *accessor);
|
|
Q_INVOKABLE void remove(FuseAccessorBase *accessor);
|
|
|
|
QSqlDatabase &getDatabase() { return m_database; }
|
|
int getProfileId() { return m_profileId; }
|
|
|
|
//int utilQPermsToMode(QFileDevice::Permissions perms);
|
|
FuseFHBase *makeWritableFromSource(const QString &source, const QString &origsource, const QString &dest, QIODeviceBase::OpenMode mode);
|
|
FuseFHBase *makeWritableFromData(const QByteArray &source, const QString &origsource, const QString &dest, QIODeviceBase::OpenMode mode);
|
|
|
|
void cacheInsert(const QString &path, QByteArray &data);
|
|
QSharedPointer<QByteArray> cacheGrab(const QString &path);
|
|
|
|
protected:
|
|
void init();
|
|
|
|
// FUSE stuff:
|
|
int getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi);
|
|
int create(const char *path, mode_t mode, struct fuse_file_info *fi);
|
|
int mkdir(const char *path, mode_t mode);
|
|
int unlink(const char *path);
|
|
int rmdir(const char *path);
|
|
int rename(const char *path, const char *newname, unsigned int flags);
|
|
int truncate(const char *path, off_t offset, struct fuse_file_info *fi);
|
|
int readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags);
|
|
int write(const char *path, const char *buf, size_t bufsz, off_t offset, struct fuse_file_info *fi);
|
|
int open(const char *path, struct fuse_file_info *fi);
|
|
int release(const char *path, struct fuse_file_info *fi);
|
|
int read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi);
|
|
off_t lseek(const char *path, off_t off, int whence, struct fuse_file_info *fi);
|
|
|
|
// FUSE hooks:
|
|
static int f_getattr(const char *path, struct stat *stbuf,
|
|
struct fuse_file_info *fi);
|
|
static int f_create(const char *path, mode_t mode, struct fuse_file_info *fi);
|
|
static int f_mkdir(const char *path, mode_t mode);
|
|
static int f_unlink(const char *path);
|
|
static int f_rmdir(const char *path);
|
|
static int f_rename(const char *path, const char *newname, unsigned int flags);
|
|
static int f_truncate(const char *path, off_t offset, struct fuse_file_info *fi);
|
|
static int f_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
|
off_t offset, struct fuse_file_info *fi,
|
|
enum fuse_readdir_flags flags);
|
|
static int f_write(const char *path, const char *buf, size_t bufsz, off_t offset,
|
|
struct fuse_file_info *fi);
|
|
static int f_open(const char *path, struct fuse_file_info *fi);
|
|
static int f_release(const char *path, struct fuse_file_info *fi);
|
|
static int f_read(const char *path, char *buf, size_t size, off_t offset,
|
|
struct fuse_file_info *fi);
|
|
static off_t f_lseek(const char *path, off_t off, int whence, struct fuse_file_info *fi);
|
|
|
|
signals:
|
|
void entryUpdated(const QString &path, const QString &facility, quint32 count, quint8 refcount);
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(FuseInterface *)
|
|
|
|
#endif // FUSEINTERFACE_H
|