quickmod/FuseMounter/fusesandbox.cpp

201 lines
6 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();
QDir ddir(m_resource);
ddir.mkpath( parts.join(QDir::separator()) );
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) )
{
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);
}