quickmod/FuseMounter/fuseinterface.h

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