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.
203 lines
6.1 KiB
C++
203 lines
6.1 KiB
C++
#include <QDir>
|
|
#include <QFileInfo>
|
|
|
|
#include <fcntl.h> /* Definition of AT_* constants */
|
|
#include <sys/stat.h>
|
|
|
|
#include "fuseinterface.h"
|
|
#include "fusesandbox.h"
|
|
|
|
FuseAccessorSandbox::FuseAccessorSandbox(FuseInterface *parent, const QString &resource)
|
|
: FuseAccessorProxy(parent, resource, FuseAccessorBase::FH_SANDBOX)
|
|
{
|
|
//m_resource = m_resource + QDir::separator() + QString::number(parent->getProfileId());
|
|
}
|
|
|
|
FuseAccessorSandbox::~FuseAccessorSandbox()
|
|
{
|
|
}
|
|
|
|
FuseFHBase *FuseAccessorSandbox::open(const QString &path, QIODeviceBase::OpenMode mode)
|
|
{
|
|
QString qpath = m_resource + QDir::separator() + resolvePath( m_resource, path );
|
|
|
|
QFileInfo fi(qpath);
|
|
if( !fi.exists() ) {
|
|
if( mode & QIODeviceBase::ReadOnly ) {
|
|
//qDebug() << "FuseAccessorSandbox::open:" << path << mode << "- Nah. You get null.";
|
|
return NULL;
|
|
}
|
|
|
|
QStringList parts = qpath.split( QDir::separator() );
|
|
QString dname = parts.takeLast();
|
|
if( dname.isEmpty() )
|
|
dname = parts.takeLast();
|
|
|
|
QDir dir( m_resource );
|
|
dir.mkpath( parts.join(QDir::separator()) );
|
|
}
|
|
|
|
FuseFHSandbox *f = new FuseFHSandbox(this, path, qpath);
|
|
if( !f->open(mode) )
|
|
{
|
|
qDebug() << "FuseAccessorSandbox::open:" << path << mode << "- Open failed. You get null:" << qpath;
|
|
f->deleteLater();
|
|
return NULL;
|
|
}
|
|
|
|
//m_open_handles.insert( path, f );
|
|
return f;
|
|
}
|
|
|
|
int FuseAccessorSandbox::truncate(const QString &path, off_t offset)
|
|
{
|
|
QString qpath = m_resource + QDir::separator() + resolvePath( m_resource, path );
|
|
qDebug() << "FuseAccessorSandbox::truncate:" << path << "@" << offset;
|
|
return QFile::resize(qpath, offset) ? 0 : 1;
|
|
}
|
|
/*
|
|
int FuseAccessorSandbox::rename(const QString &path, const QString &newname)
|
|
{
|
|
return 1;
|
|
}
|
|
*/
|
|
int FuseAccessorSandbox::rmdir(const QString &path)
|
|
{
|
|
QString qpath = m_resource + QDir::separator() + resolvePath( m_resource, path );
|
|
QStringList parts = qpath.split( QDir::separator(), Qt::SkipEmptyParts );
|
|
QString dname = parts.takeLast();
|
|
if( dname.isEmpty() )
|
|
dname = parts.takeLast();
|
|
|
|
QString parentDir = QDir::separator() + parts.join(QDir::separator());
|
|
QDir dir( parentDir );
|
|
|
|
//qDebug() << "rmdir:" << dname << "from" << parentDir;
|
|
return dir.rmdir(dname) ? 0 : 1;
|
|
}
|
|
|
|
int FuseAccessorSandbox::unlink(const QString &path)
|
|
{
|
|
QString qpath = m_resource + QDir::separator() + resolvePath( m_resource, path );
|
|
QStringList parts = qpath.split( QDir::separator() );
|
|
QString fname = parts.takeLast();
|
|
if( fname.isEmpty() )
|
|
fname = parts.takeLast();
|
|
|
|
QDir dir( parts.join(QDir::separator()) );
|
|
|
|
qDebug() << "FuseAccessorSandbox::unlink:" << path;
|
|
return dir.remove(fname) ? 0 : 1;
|
|
}
|
|
|
|
int FuseAccessorSandbox::mkdir(const QString &path, QFileDevice::Permissions mode)
|
|
{
|
|
Q_UNUSED(mode)
|
|
|
|
QString qpath = resolvePath(m_resource, path);
|
|
QDir dir( m_resource );
|
|
|
|
qDebug() << "FuseAccessorSandbox::mkdir:" << path << mode << "=>" << m_resource << qpath;
|
|
if( !dir.mkpath(qpath) )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
int FuseAccessorSandbox::create(const QString &path, QFileDevice::Permissions mode)
|
|
{
|
|
Q_UNUSED(mode)
|
|
|
|
QString qpath = m_resource + QDir::separator() + resolvePath( m_resource, path );
|
|
|
|
QStringList parts = qpath.split( QDir::separator() );
|
|
QString dname = parts.takeLast();
|
|
if( dname.isEmpty() )
|
|
dname = parts.takeLast();
|
|
|
|
QDir dir( m_resource );
|
|
dir.mkpath( parts.join(QDir::separator()) );
|
|
|
|
mode_t smode = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO;
|
|
//smode += m_parent->utilQPermsToMode(mode);
|
|
|
|
// TODO: Maybe just open it right here?
|
|
qDebug() << "FuseAccessorSandbox::create:" << path << mode;
|
|
int fd = ::creat(qpath.toStdString().c_str(), smode);
|
|
if( fd > 0 )
|
|
close(fd);
|
|
return fd > 0 ? 0 : 1;
|
|
}
|
|
|
|
FuseFHBase *FuseAccessorSandbox::makeWritableFromSource(const QString &source, const QString &origpath, const QString &dest, QIODeviceBase::OpenMode mode)
|
|
{
|
|
QString qdest = m_resource + QDir::separator() + resolvePath(m_resource, dest);
|
|
|
|
QFileInfo qsf(source);
|
|
if( !qsf.exists() ) {
|
|
qWarning() << "FuseAccessorSandbox::makeWritableFromSource: Couldn't access file at" << source;
|
|
return NULL;
|
|
}
|
|
|
|
//QStringList parts = dest.toLower().split(QDir::separator(), Qt::SkipEmptyParts);
|
|
//QString dfname = parts.takeLast();
|
|
//ddir.mkpath( parts.join(QDir::separator()) );
|
|
|
|
QDir ddir(m_resource);
|
|
QFile::copy(source, qdest);
|
|
|
|
qDebug() << "FuseAccessorSandbox::makeWritableFromSource: cp" << source << qdest;
|
|
FuseFHSandbox *ent = new FuseFHSandbox(this, origpath, qdest);
|
|
if( !ent->open(mode) )
|
|
{
|
|
ent->deleteLater();
|
|
return NULL;
|
|
}
|
|
|
|
return ent;
|
|
}
|
|
|
|
FuseFHBase *FuseAccessorSandbox::makeWritableFromData(const QByteArray &source, const QString &origpath, const QString &dest, QIODeviceBase::OpenMode mode)
|
|
{
|
|
QString qdest = m_resource + QDir::separator() + resolvePath(m_resource, dest);
|
|
|
|
QStringList parts = dest.toLower().split(QDir::separator(), Qt::SkipEmptyParts);
|
|
QString dfname = parts.takeLast();
|
|
QDir ddir(m_resource);
|
|
ddir.mkpath( parts.join(QDir::separator()) );
|
|
|
|
qDebug() << "FuseAccessorSandbox::makeWritableFromData:" << qdest << mode;
|
|
QFile f(qdest);
|
|
if( !f.open(QIODeviceBase::WriteOnly) ) {
|
|
qDebug() << "FuseAccessorSandbox::makeWritableFromData: open failed.";
|
|
return NULL;
|
|
}
|
|
f.write(source);
|
|
f.close();
|
|
|
|
FuseFHSandbox *ent = new FuseFHSandbox(this, origpath, qdest);
|
|
if( !ent->open(mode) )
|
|
{
|
|
qDebug() << "FuseAccessorSandbox::makeWritableFromData: FuseFHSandbox open failed";
|
|
ent->deleteLater();
|
|
return NULL;
|
|
}
|
|
|
|
return ent;
|
|
}
|
|
|
|
FuseFHSandbox::FuseFHSandbox(FuseAccessorSandbox *parent, const QString &path, const QString &newpath)
|
|
: FuseFHProxy(parent, path, newpath)
|
|
{
|
|
}
|
|
|
|
FuseFHSandbox::~FuseFHSandbox()
|
|
{
|
|
}
|
|
|
|
int FuseFHSandbox::write(const QByteArray &data, off_t offset, fuse_file_info *fi)
|
|
{
|
|
Q_UNUSED(fi)
|
|
|
|
m_file.seek(offset);
|
|
return m_file.write(data);
|
|
}
|