Use the user that started jmtpfs for the uid and gid of the files.
Return total for all storage devices for statfs of the root directory.
This commit is contained in:
parent
71283756a1
commit
385417b93c
@ -56,6 +56,22 @@ MtpLibLock lock;
|
||||
return std::unique_ptr<MtpDevice>(new MtpDevice(m_devs[index]));
|
||||
}
|
||||
|
||||
std::unique_ptr<MtpDevice> ConnectedMtpDevices::GetDevice(uint32_t busLocation, uint8_t devnum)
|
||||
{
|
||||
MtpLibLock lock;
|
||||
|
||||
for(int i = 0; i<NumDevices(); i++)
|
||||
{
|
||||
ConnectedDeviceInfo devInfo = GetDeviceInfo(i);
|
||||
if ((devInfo.bus_location == busLocation) &&
|
||||
(devInfo.devnum == devnum))
|
||||
{
|
||||
return GetDevice(i);;
|
||||
}
|
||||
}
|
||||
throw MtpDeviceNotFound("Requested MTP device not found");
|
||||
}
|
||||
|
||||
LIBMTP_raw_device_t& ConnectedMtpDevices::GetRawDeviceEntry(int index)
|
||||
{
|
||||
return m_devs[index];
|
||||
|
@ -43,6 +43,8 @@ public:
|
||||
|
||||
int NumDevices();
|
||||
std::unique_ptr<MtpDevice> GetDevice(int index);
|
||||
std::unique_ptr<MtpDevice> GetDevice(uint32_t busLocation, uint8_t devnum);
|
||||
|
||||
ConnectedDeviceInfo GetDeviceInfo(int index);
|
||||
LIBMTP_raw_device_t& GetRawDeviceEntry(int index);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
bin_PROGRAMS=jmtpfs
|
||||
jmtpfs_SOURCES=jmtpfs.cpp MtpDevice.cpp ConnectedMtpDevices.cpp Mutex.cpp MtpFilesystemPath.cpp \
|
||||
MtpMetadataCache.cpp MtpNode.cpp MtpRoot.cpp MtpLibLock.cpp MtpStorage.cpp \
|
||||
MtpFolder.cpp MtpFile.cpp TemporaryFile.cpp MtpLocalFileCopy.cpp
|
||||
MtpFolder.cpp MtpFile.cpp TemporaryFile.cpp MtpLocalFileCopy.cpp \
|
||||
MtpFuseContext.cpp
|
||||
jmtpfs_CPPFLAGS = $(MTP_CFLAGS) $(FUSE_CFLAGS)
|
||||
jmtpfs_LDADD = $(MTP_LIBS) $(FUSE_LIBS)
|
||||
|
@ -54,7 +54,8 @@ am_jmtpfs_OBJECTS = jmtpfs-jmtpfs.$(OBJEXT) jmtpfs-MtpDevice.$(OBJEXT) \
|
||||
jmtpfs-MtpRoot.$(OBJEXT) jmtpfs-MtpLibLock.$(OBJEXT) \
|
||||
jmtpfs-MtpStorage.$(OBJEXT) jmtpfs-MtpFolder.$(OBJEXT) \
|
||||
jmtpfs-MtpFile.$(OBJEXT) jmtpfs-TemporaryFile.$(OBJEXT) \
|
||||
jmtpfs-MtpLocalFileCopy.$(OBJEXT)
|
||||
jmtpfs-MtpLocalFileCopy.$(OBJEXT) \
|
||||
jmtpfs-MtpFuseContext.$(OBJEXT)
|
||||
jmtpfs_OBJECTS = $(am_jmtpfs_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
jmtpfs_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||
@ -183,7 +184,8 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
jmtpfs_SOURCES = jmtpfs.cpp MtpDevice.cpp ConnectedMtpDevices.cpp Mutex.cpp MtpFilesystemPath.cpp \
|
||||
MtpMetadataCache.cpp MtpNode.cpp MtpRoot.cpp MtpLibLock.cpp MtpStorage.cpp \
|
||||
MtpFolder.cpp MtpFile.cpp TemporaryFile.cpp MtpLocalFileCopy.cpp
|
||||
MtpFolder.cpp MtpFile.cpp TemporaryFile.cpp MtpLocalFileCopy.cpp \
|
||||
MtpFuseContext.cpp
|
||||
|
||||
jmtpfs_CPPFLAGS = $(MTP_CFLAGS) $(FUSE_CFLAGS)
|
||||
jmtpfs_LDADD = $(MTP_LIBS) $(FUSE_LIBS)
|
||||
@ -273,6 +275,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmtpfs-MtpFile.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmtpfs-MtpFilesystemPath.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmtpfs-MtpFolder.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmtpfs-MtpFuseContext.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmtpfs-MtpLibLock.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmtpfs-MtpLocalFileCopy.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmtpfs-MtpMetadataCache.Po@am__quote@
|
||||
@ -493,6 +496,20 @@ jmtpfs-MtpLocalFileCopy.obj: MtpLocalFileCopy.cpp
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(jmtpfs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o jmtpfs-MtpLocalFileCopy.obj `if test -f 'MtpLocalFileCopy.cpp'; then $(CYGPATH_W) 'MtpLocalFileCopy.cpp'; else $(CYGPATH_W) '$(srcdir)/MtpLocalFileCopy.cpp'; fi`
|
||||
|
||||
jmtpfs-MtpFuseContext.o: MtpFuseContext.cpp
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(jmtpfs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT jmtpfs-MtpFuseContext.o -MD -MP -MF $(DEPDIR)/jmtpfs-MtpFuseContext.Tpo -c -o jmtpfs-MtpFuseContext.o `test -f 'MtpFuseContext.cpp' || echo '$(srcdir)/'`MtpFuseContext.cpp
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/jmtpfs-MtpFuseContext.Tpo $(DEPDIR)/jmtpfs-MtpFuseContext.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MtpFuseContext.cpp' object='jmtpfs-MtpFuseContext.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(jmtpfs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o jmtpfs-MtpFuseContext.o `test -f 'MtpFuseContext.cpp' || echo '$(srcdir)/'`MtpFuseContext.cpp
|
||||
|
||||
jmtpfs-MtpFuseContext.obj: MtpFuseContext.cpp
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(jmtpfs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT jmtpfs-MtpFuseContext.obj -MD -MP -MF $(DEPDIR)/jmtpfs-MtpFuseContext.Tpo -c -o jmtpfs-MtpFuseContext.obj `if test -f 'MtpFuseContext.cpp'; then $(CYGPATH_W) 'MtpFuseContext.cpp'; else $(CYGPATH_W) '$(srcdir)/MtpFuseContext.cpp'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/jmtpfs-MtpFuseContext.Tpo $(DEPDIR)/jmtpfs-MtpFuseContext.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MtpFuseContext.cpp' object='jmtpfs-MtpFuseContext.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(jmtpfs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o jmtpfs-MtpFuseContext.obj `if test -f 'MtpFuseContext.cpp'; then $(CYGPATH_W) 'MtpFuseContext.cpp'; else $(CYGPATH_W) '$(srcdir)/MtpFuseContext.cpp'; fi`
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
|
@ -60,6 +60,12 @@ public:
|
||||
MtpDeviceDisconnected(const std::string& message) : MtpError(message, LIBMTP_ERROR_NO_DEVICE_ATTACHED) {}
|
||||
};
|
||||
|
||||
class MtpDeviceNotFound : public MtpError
|
||||
{
|
||||
public:
|
||||
MtpDeviceNotFound(const std::string& message) : MtpError(message, LIBMTP_ERROR_GENERAL) {}
|
||||
};
|
||||
|
||||
class MtpStorageNotFound : public MtpError
|
||||
{
|
||||
public:
|
||||
|
47
src/MtpFuseContext.cpp
Normal file
47
src/MtpFuseContext.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MtpFuseContext.cpp
|
||||
*
|
||||
* Author: Jason Ferrara
|
||||
*
|
||||
* This software is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02111-1301, USA.
|
||||
* licensing@fsf.org
|
||||
*/
|
||||
#include "MtpFuseContext.h"
|
||||
#include "MtpRoot.h"
|
||||
|
||||
MtpFuseContext::MtpFuseContext(std::unique_ptr<MtpDevice> device, uid_t uid, gid_t gid) :
|
||||
m_device(std::move(device)), m_uid(uid), m_gid(gid)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<MtpNode> MtpFuseContext::getNode(const FilesystemPath& path)
|
||||
{
|
||||
std::unique_ptr<MtpNode> root(new MtpRoot(*m_device, m_cache));
|
||||
if (path.Head()=="/")
|
||||
return root;
|
||||
else
|
||||
return root->getNode(path.Body());
|
||||
}
|
||||
|
||||
uid_t MtpFuseContext::uid() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
gid_t MtpFuseContext::gid() const
|
||||
{
|
||||
return m_gid;
|
||||
}
|
49
src/MtpFuseContext.h
Normal file
49
src/MtpFuseContext.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MtpFuseContext.h
|
||||
*
|
||||
* Author: Jason Ferrara
|
||||
*
|
||||
* This software is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02111-1301, USA.
|
||||
* licensing@fsf.org
|
||||
*/
|
||||
|
||||
#ifndef MTPFUSECONTEXT_H_
|
||||
#define MTPFUSECONTEXT_H_
|
||||
|
||||
#include "MtpDevice.h"
|
||||
#include "MtpMetadataCache.h"
|
||||
#include "MtpNode.h"
|
||||
#include <memory>
|
||||
#include <sys/types.h>
|
||||
|
||||
class MtpFuseContext
|
||||
{
|
||||
public:
|
||||
MtpFuseContext(std::unique_ptr<MtpDevice> device, uid_t uid, gid_t gid);
|
||||
|
||||
std::unique_ptr<MtpNode> getNode(const FilesystemPath& path);
|
||||
|
||||
uid_t uid() const;
|
||||
gid_t gid() const;
|
||||
|
||||
protected:
|
||||
uid_t m_uid;
|
||||
gid_t m_gid;
|
||||
std::unique_ptr<MtpDevice> m_device;
|
||||
MtpMetadataCache m_cache;
|
||||
};
|
||||
|
||||
|
||||
#endif /* MTPFUSECONTEXT_H_ */
|
@ -122,3 +122,21 @@ MtpStorageInfo MtpNode::GetStorageInfo()
|
||||
MtpNodeMetadata md = m_cache.getItem(m_id, *this);
|
||||
return m_device.GetStorageInfo(md.self.storageId);
|
||||
}
|
||||
|
||||
void MtpNode::statfs(struct statvfs *stat)
|
||||
{
|
||||
|
||||
MtpStorageInfo storageInfo = GetStorageInfo();
|
||||
|
||||
stat->f_bsize = 512; // We have to pick some block size, so why not 512?
|
||||
stat->f_blocks = storageInfo.maxCapacity / stat->f_bsize;
|
||||
stat->f_bfree = storageInfo.freeSpaceInBytes / stat->f_bsize;
|
||||
stat->f_bavail = stat->f_bfree;
|
||||
stat->f_namemax = 233;
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<MtpNode> MtpNode::Clone()
|
||||
{
|
||||
throw NotImplemented("Clone");
|
||||
}
|
||||
|
@ -66,6 +66,10 @@ public:
|
||||
virtual uint32_t FolderId();
|
||||
virtual uint32_t StorageId();
|
||||
|
||||
virtual std::unique_ptr<MtpNode> Clone();
|
||||
|
||||
virtual void statfs(struct statvfs *stat);
|
||||
|
||||
protected:
|
||||
uint32_t GetParentNodeId();
|
||||
|
||||
|
@ -94,3 +94,24 @@ MtpStorageInfo MtpRoot::GetStorageInfo()
|
||||
{
|
||||
return MtpStorageInfo(0,"",0,0);
|
||||
}
|
||||
|
||||
void MtpRoot::statfs(struct statvfs *stat)
|
||||
{
|
||||
size_t totalSize = 0;
|
||||
size_t totalFree = 0;
|
||||
|
||||
std::vector<std::string> storages = readDirectory();
|
||||
for(std::vector<std::string>::iterator s = storages.begin(); s != storages.end(); s++)
|
||||
{
|
||||
MtpStorageInfo info = getNode(FilesystemPath(s->c_str()))->GetStorageInfo();
|
||||
totalSize += info.maxCapacity;
|
||||
totalFree += info.freeSpaceInBytes;
|
||||
}
|
||||
|
||||
stat->f_bsize = 512; // We have to pick some block size, so why not 512?
|
||||
stat->f_blocks = totalSize / stat->f_bsize;
|
||||
stat->f_bfree = totalFree / stat->f_bsize;
|
||||
stat->f_bavail = stat->f_bfree;
|
||||
stat->f_namemax = 233;
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,8 @@ public:
|
||||
MtpNodeMetadata getMetadata();
|
||||
|
||||
MtpStorageInfo GetStorageInfo();
|
||||
|
||||
void statfs(struct statvfs *stat);
|
||||
};
|
||||
|
||||
|
||||
|
@ -27,7 +27,10 @@ MtpStorage::MtpStorage(MtpDevice& device, MtpMetadataCache& cache, uint32_t id)
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<MtpNode> MtpStorage::Clone()
|
||||
{
|
||||
return std::unique_ptr<MtpNode>(new MtpStorage(m_device, m_cache, m_id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -32,6 +32,8 @@ public:
|
||||
void Remove();
|
||||
|
||||
void Rename(MtpNode& newParent, const std::string& newName);
|
||||
|
||||
std::unique_ptr<MtpNode> Clone();
|
||||
};
|
||||
|
||||
|
||||
|
157
src/jmtpfs.cpp
157
src/jmtpfs.cpp
@ -23,8 +23,9 @@
|
||||
#include "mtpFilesystemErrors.h"
|
||||
#include "Mutex.h"
|
||||
#include "FuseHeader.h"
|
||||
#include "MtpFuseContext.h"
|
||||
#include "MtpRoot.h"
|
||||
|
||||
#include <MtpRoot.h>
|
||||
#include <iostream>
|
||||
#include <cstddef>
|
||||
#include <errno.h>
|
||||
@ -47,7 +48,8 @@ RecursiveMutex globalLock;
|
||||
#define FUSE_ERROR_BLOCK_START \
|
||||
try \
|
||||
{ \
|
||||
LockMutex lock(globalLock);
|
||||
LockMutex lock(globalLock); \
|
||||
MtpFuseContext* context((MtpFuseContext*)(fuse_get_context()->private_data)); \
|
||||
|
||||
#define FUSE_ERROR_BLOCK_END \
|
||||
} \
|
||||
@ -69,28 +71,15 @@ RecursiveMutex globalLock;
|
||||
}
|
||||
|
||||
|
||||
MtpDevice* currentDevice;
|
||||
MtpMetadataCache* metadataCache;
|
||||
|
||||
std::unique_ptr<MtpNode> getNode(const FilesystemPath& path)
|
||||
{
|
||||
if (path.Head() != "/")
|
||||
throw FileNotFound(path.str());
|
||||
std::unique_ptr<MtpNode> root(new MtpRoot(*currentDevice, *metadataCache));
|
||||
FilesystemPath childPath = path.Body();
|
||||
if (childPath.Empty())
|
||||
return root;
|
||||
else
|
||||
return root->getNode(childPath);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int jmtpfs_getattr(const char* pathStr, struct stat* info)
|
||||
{
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path)->getattr(*info);
|
||||
context->getNode(path)->getattr(*info);
|
||||
info->st_uid = context->uid();
|
||||
info->st_gid = context->gid();
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -103,7 +92,7 @@ extern "C" int jmtpfs_readdir(const char* pathStr, void* buf, fuse_fill_dir_t fi
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
std::unique_ptr<MtpNode> n = getNode(path);
|
||||
std::unique_ptr<MtpNode> n = context->getNode(path);
|
||||
std::vector<std::string> contents = n->readdir();
|
||||
for(std::vector<std::string>::iterator i = contents.begin(); i != contents.end(); i++)
|
||||
{
|
||||
@ -121,7 +110,7 @@ extern "C" int jmtpfs_open(const char *pathStr, struct fuse_file_info *)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path)->Open();
|
||||
context->getNode(path)->Open();
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -132,7 +121,7 @@ extern "C" int jmtpfs_release(const char *pathStr, struct fuse_file_info *)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path)->Close();
|
||||
context->getNode(path)->Close();
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -143,7 +132,7 @@ extern "C" int jmtpfs_read(const char *pathStr, char *buf, size_t size, off_t o
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
return getNode(path)->Read(buf,size,offset);
|
||||
return context->getNode(path)->Read(buf,size,offset);
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
}
|
||||
@ -153,7 +142,7 @@ extern "C" int jmtpfs_mkdir(const char* pathStr, mode_t mode)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path.AllButTail())->mkdir(path.Tail());
|
||||
context->getNode(path.AllButTail())->mkdir(path.Tail());
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -164,7 +153,7 @@ extern "C" int jmtpfs_rmdir(const char* pathStr)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path)->Remove();
|
||||
context->getNode(path)->Remove();
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -176,9 +165,9 @@ extern "C" int jmtpfs_create(const char* pathStr, mode_t mode, struct fuse_file_
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
std::unique_ptr<MtpNode> n = getNode(path.AllButTail());
|
||||
std::unique_ptr<MtpNode> n = context->getNode(path.AllButTail());
|
||||
n->CreateFile(path.Tail());
|
||||
n = getNode(path);
|
||||
n = context->getNode(path);
|
||||
n->Open();
|
||||
return 0;
|
||||
|
||||
@ -190,7 +179,7 @@ extern "C" int jmtpfs_write(const char *pathStr, const char *data, size_t size,
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
return getNode(path)->Write(data, size, offset);
|
||||
return context->getNode(path)->Write(data, size, offset);
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
}
|
||||
@ -200,7 +189,7 @@ extern "C" int jmtpfs_truncate(const char *pathStr, off_t length)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path)->Truncate(length);
|
||||
context->getNode(path)->Truncate(length);
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -211,7 +200,7 @@ extern "C" int jmtpfs_unlink(const char *pathStr)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path)->Remove();
|
||||
context->getNode(path)->Remove();
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -222,7 +211,7 @@ extern "C" int jmtpfs_flush(const char *pathStr, struct fuse_file_info *)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
getNode(path)->Close();
|
||||
context->getNode(path)->Close();
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -234,9 +223,9 @@ extern "C" int jmtpfs_rename(const char *pathStr, const char *newPathStr)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
std::unique_ptr<MtpNode> n = getNode(path);
|
||||
std::unique_ptr<MtpNode> n = context->getNode(path);
|
||||
FilesystemPath newPath(newPathStr);
|
||||
std::unique_ptr<MtpNode> newParent = getNode(newPath.AllButTail());
|
||||
std::unique_ptr<MtpNode> newParent = context->getNode(newPath.AllButTail());
|
||||
n->Rename(*newParent, newPath.Tail());
|
||||
|
||||
return 0;
|
||||
@ -249,20 +238,8 @@ extern "C" int jmtpfs_statfs(const char *pathStr, struct statvfs *stat)
|
||||
FUSE_ERROR_BLOCK_START
|
||||
|
||||
FilesystemPath path(pathStr);
|
||||
std::unique_ptr<MtpNode> n = getNode(path);
|
||||
MtpStorageInfo storageInfo = n->GetStorageInfo();
|
||||
|
||||
if (storageInfo.maxCapacity > 0)
|
||||
{
|
||||
stat->f_bsize = 512; // We have to pick some block size, so why not 512?
|
||||
stat->f_blocks = storageInfo.maxCapacity / stat->f_bsize;
|
||||
stat->f_bfree = storageInfo.freeSpaceInBytes / stat->f_bsize;
|
||||
stat->f_bavail = stat->f_bfree;
|
||||
stat->f_namemax = 233;
|
||||
}
|
||||
else
|
||||
stat->f_flag = ST_RDONLY;
|
||||
|
||||
std::unique_ptr<MtpNode> n = context->getNode(path);
|
||||
n->statfs(stat);
|
||||
return 0;
|
||||
|
||||
FUSE_ERROR_BLOCK_END
|
||||
@ -272,16 +249,20 @@ extern "C" int jmtpfs_statfs(const char *pathStr, struct statvfs *stat)
|
||||
struct jmtpfs_options
|
||||
{
|
||||
jmtpfs_options() : listDevices(0), displayHelp(0),
|
||||
showVersion(0), device(0) {}
|
||||
showVersion(0), device(0), listStorage(0) {}
|
||||
|
||||
int listDevices;
|
||||
int displayHelp;
|
||||
int showVersion;
|
||||
int listStorage;
|
||||
char* device;
|
||||
};
|
||||
|
||||
static struct fuse_opt jmtpfs_opts[] = {
|
||||
{"-l", offsetof(struct jmtpfs_options, listDevices), 1},
|
||||
{"--listDevices", offsetof(struct jmtpfs_options, listDevices), 1},
|
||||
// {"-ls", offsetof(struct jmtpfs_options, listStorage), 1},
|
||||
// {"--listStorage", offsetof(struct jmtpfs_options, listStorage), 1},
|
||||
{"-h", offsetof(struct jmtpfs_options, displayHelp), 1},
|
||||
{"-device=%s", offsetof(struct jmtpfs_options, device),0},
|
||||
{"-V", offsetof(struct jmtpfs_options, showVersion),1},
|
||||
@ -296,8 +277,7 @@ static struct fuse_operations jmtpfs_oper = {
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::unique_ptr<MtpDevice> device;
|
||||
std::unique_ptr<MtpMetadataCache> cache;
|
||||
|
||||
|
||||
LIBMTP_Init();
|
||||
jmtpfs_oper.getattr = jmtpfs_getattr;
|
||||
@ -328,6 +308,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
ConnectedMtpDevices devices;
|
||||
std::vector<std::string> devListing;
|
||||
std::vector<std::vector<std::string> > storageDevices;
|
||||
for(int i=0; i < devices.NumDevices(); i++)
|
||||
{
|
||||
ConnectedDeviceInfo devInfo = devices.GetDeviceInfo(i);
|
||||
@ -337,10 +318,27 @@ int main(int argc, char *argv[])
|
||||
devText << "0x" << hex << setfill('0') << setw(4)<< devInfo.vendor_id << ", ";
|
||||
devText << devInfo.product << ", " << devInfo.vendor;
|
||||
devListing.push_back(devText.str());
|
||||
if (options.listStorage)
|
||||
{
|
||||
std::unique_ptr<MtpDevice> device = devices.GetDevice(i);
|
||||
std::vector<MtpStorageInfo> storages = device->GetStorageDevices();
|
||||
std::vector<std::string> storageList;
|
||||
for(std::vector<MtpStorageInfo>::iterator i = storages.begin(); i != storages.end(); i++)
|
||||
storageList.push_back(i->description);
|
||||
storageDevices.push_back(storageList);
|
||||
}
|
||||
}
|
||||
std::cout << "Available devices (busLocation, devNum, productId, vendorId, product, vendor):" << std::endl;
|
||||
for(std::vector<std::string>::iterator i = devListing.begin(); i != devListing.end(); i++)
|
||||
std::cout << *i << std::endl;
|
||||
for(size_t i=0; i<devListing.size(); i++)
|
||||
{
|
||||
std::cout << devListing[i] << std::endl;
|
||||
if (options.listStorage)
|
||||
{
|
||||
for(std::vector<std::string>::iterator s = storageDevices[i].begin(); s != storageDevices[i].end(); s++)
|
||||
std::cout << " " << *s << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -364,6 +362,36 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (options.listStorage)
|
||||
{
|
||||
std::unique_ptr<MtpDevice> device;
|
||||
ConnectedMtpDevices devices;
|
||||
if (devices.NumDevices()==0)
|
||||
{
|
||||
std::cerr << "No mtp devices found." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
if ((requestedBusLocation!=-1) && (requestedDevnum != -1))
|
||||
device = devices.GetDevice(0);
|
||||
else
|
||||
device = devices.GetDevice(requestedBusLocation, requestedDevnum);
|
||||
}
|
||||
catch(MtpDeviceNotFound&)
|
||||
{
|
||||
std::cerr << "Requested device not found" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "Storage devices on " << device->Get_Modelname() << ":"<< std::endl;
|
||||
std::vector<MtpStorageInfo> storages = device->GetStorageDevices();
|
||||
for(std::vector<MtpStorageInfo>::iterator i = storages.begin(); i != storages.end(); i++)
|
||||
std::cout << " " << i->description << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<MtpFuseContext> context;
|
||||
|
||||
if (options.displayHelp)
|
||||
{
|
||||
@ -375,32 +403,28 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDevice = 0;
|
||||
std::unique_ptr<MtpDevice> device;
|
||||
ConnectedMtpDevices devices;
|
||||
if (devices.NumDevices()==0)
|
||||
{
|
||||
std::cerr << "No mtp devices found." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
for(int i = 0; i<devices.NumDevices(); i++)
|
||||
try
|
||||
{
|
||||
ConnectedDeviceInfo devInfo = devices.GetDeviceInfo(i);
|
||||
if (((devInfo.bus_location == requestedBusLocation) &&
|
||||
(devInfo.devnum == requestedDevnum)) ||
|
||||
(requestedBusLocation == -1) || (requestedDevnum == -1))
|
||||
{
|
||||
device = devices.GetDevice(i);
|
||||
currentDevice = device.get();
|
||||
break;
|
||||
}
|
||||
if ((requestedBusLocation==-1) || (requestedDevnum == -1))
|
||||
device = devices.GetDevice(0);
|
||||
else
|
||||
device = devices.GetDevice(requestedBusLocation, requestedDevnum);
|
||||
}
|
||||
if (currentDevice == 0)
|
||||
catch(MtpDeviceNotFound&)
|
||||
{
|
||||
std::cerr << "Requested device not found" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
cache = std::unique_ptr<MtpMetadataCache>(new MtpMetadataCache);
|
||||
metadataCache = cache.get();
|
||||
|
||||
context = std::unique_ptr<MtpFuseContext>(new MtpFuseContext(std::move(device), getuid(), getgid()));
|
||||
|
||||
}
|
||||
|
||||
if (options.showVersion)
|
||||
@ -413,12 +437,13 @@ int main(int argc, char *argv[])
|
||||
std::cout << "Running in the background disabled because of an imcompatiblity between fork and libmtp under Max OS X" << std::endl;
|
||||
#endif
|
||||
|
||||
int result = fuse_main(args.argc, args.argv, &jmtpfs_oper, 0);
|
||||
int result = fuse_main(args.argc, args.argv, &jmtpfs_oper, context.get());
|
||||
|
||||
if (options.displayHelp)
|
||||
{
|
||||
std::cout << std::endl << "jmtpfs options:" << std::endl;
|
||||
std::cout << " -l list available mtp devices and then exit" << std::endl;
|
||||
std::cout << " -l --listDevices list available mtp devices and then exit" << std::endl;
|
||||
// std::cout << " -ls --listStorage list the storage areas on the device (or all devices if -l is also specified)" << std::endl;
|
||||
std::cout << " -device=<busnum>,<devnum> Device to mount. It not specified the first device found is used"<< std::endl;
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user