Decided to leave the VFS tab for now. Filtering likely doesn't work, except Show Only Open. Sorting works. Rewrites to replace dynamicRoles done for Mods and Plugins tables. Database.qml now reads "moddir", though installing extracted is still unimplemented so far. Launch still doesn't work. Ignore the "file -> test extract". It's a test for file extraction.
139 lines
5.3 KiB
C++
139 lines
5.3 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;
|
|
qint8 type;
|
|
};
|
|
|
|
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;
|
|
|
|
QStringList m_deleted;
|
|
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;
|
|
|
|
QMap< qint64, FuseFHBase * > m_cow_redirects;
|
|
|
|
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 *getFH(struct fuse_file_info *fi);
|
|
FuseFHBase *makeWritableFromSource(struct fuse_file_info *fi, const QString &source, const QString &origsource, const QString &dest, QIODeviceBase::OpenMode mode);
|
|
FuseFHBase *makeWritableFromData(struct fuse_file_info *fi, const QByteArray &source, const QString &origsource, const QString &dest, QIODeviceBase::OpenMode mode);
|
|
|
|
void cacheInsert(FuseAccessorBase *fab, const QString &path, const QByteArray &data);
|
|
//QByteArray cacheGrab(const QString &path);
|
|
QSharedPointer<QByteArray> cacheGrab(const QString &path);
|
|
void cacheInvalidate(const QString &path);
|
|
|
|
bool markDeleted(const QString &path, bool isdeleted=true);
|
|
void readDeleted();
|
|
|
|
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, qint8 type, const QString &facility, quint32 count, quint8 refcount);
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(FuseInterface *)
|
|
|
|
#endif // FUSEINTERFACE_H
|