diff --git a/src/CryFuse.cpp b/src/CryFuse.cpp index 1b47094b..75e101cc 100644 --- a/src/CryFuse.cpp +++ b/src/CryFuse.cpp @@ -268,45 +268,43 @@ int CryFuse::fsync(const path &path, int datasync, fuse_file_info *fileinfo) { } } -//TODO int CryFuse::opendir(const path &path, fuse_file_info *fileinfo) { //printf("opendir(%s, _)\n", path.c_str()); - auto real_path = _device->RootDir() / path; - DIR *dp = ::opendir(real_path.c_str()); - if (dp == nullptr) { - return -errno; + try { + fileinfo->fh = _device->openDir(path); + return 0; + } catch(CryErrnoException &e) { + return -e.getErrno(); } - fileinfo->fh = (intptr_t)dp; - return 0; } -//TODO int CryFuse::readdir(const path &path, void *buf, fuse_fill_dir_t filler, off_t offset, fuse_file_info *fileinfo) { + UNUSED(path); //printf("readdir(%s, _, _, %zu, _)\n", path.c_str(), offset); UNUSED(offset); - auto real_path = _device->RootDir() / path; - - DIR *dp = (DIR*)(uintptr_t)fileinfo->fh; - struct dirent *de = ::readdir(dp); - if (de == nullptr) { - return -errno; - } - - do { - if (filler(buf, de->d_name, nullptr, 0) != 0) { - return -ENOMEM; + try { + auto entries = _device->readDir(fileinfo->fh); + for (const auto &entry : *entries) { + //TODO Also give file attributes (third param of filler) + if (filler(buf, entry.c_str(), nullptr, 0) != 0) { + return -ENOMEM; + } } - } while ((de = ::readdir(dp)) != nullptr); - - return 0; + return 0; + } catch (CryErrnoException &e) { + return -e.getErrno(); + } } -//TODO int CryFuse::releasedir(const path &path, fuse_file_info *fileinfo) { //printf("releasedir(%s, _)\n", path.c_str()); UNUSED(path); - int retstat = closedir((DIR*)(uintptr_t)fileinfo->fh); - return errcode_map(retstat); + try { + _device->closeDir(fileinfo->fh); + return 0; + } catch (CryErrnoException &e) { + return -e.getErrno(); + } } //TODO diff --git a/src/cryfs_lib/CMakeLists.txt b/src/cryfs_lib/CMakeLists.txt index 25b7e573..75da9699 100644 --- a/src/cryfs_lib/CMakeLists.txt +++ b/src/cryfs_lib/CMakeLists.txt @@ -1,3 +1,3 @@ -add_library(cryfs_lib CryDevice.cpp CryDir.cpp CryErrnoException.cpp CryFile.cpp CryNode.cpp CryOpenFile.cpp CryOpenDir.cpp CryOpenFileList.cpp IdList.cpp) +add_library(cryfs_lib CryDevice.cpp CryDir.cpp CryErrnoException.cpp CryFile.cpp CryNode.cpp CryOpenFile.cpp CryOpenDir.cpp CryOpenFileList.cpp CryOpenDirList.cpp IdList.cpp) target_link_libraries(cryfs_lib boost_filesystem) diff --git a/src/cryfs_lib/CryDevice.cpp b/src/cryfs_lib/CryDevice.cpp index aa42944d..4e5cc653 100644 --- a/src/cryfs_lib/CryDevice.cpp +++ b/src/cryfs_lib/CryDevice.cpp @@ -9,13 +9,17 @@ #include "CryErrnoException.h" #include "utils/pointer.h" +#include "CryOpenDir.h" + using namespace cryfs; using std::unique_ptr; using std::make_unique; +using std::vector; +using std::string; CryDevice::CryDevice(const bf::path &rootdir) - :_rootdir(rootdir), _open_files() { + :_rootdir(rootdir), _open_files(), _open_dirs() { } CryDevice::~CryDevice() { @@ -126,3 +130,17 @@ void CryDevice::rename(const bf::path &from, const bf::path &to) { auto node = Load(from); node->rename(to); } + +int CryDevice::openDir(const bf::path &path) { + auto dir = LoadDir(path); + return _open_dirs.open(*dir); +} + +unique_ptr> CryDevice::readDir(int descriptor) { + return _open_dirs.get(descriptor)->readdir(); +} + +void CryDevice::closeDir(int descriptor) { + _open_dirs.close(descriptor); +} + diff --git a/src/cryfs_lib/CryDevice.h b/src/cryfs_lib/CryDevice.h index 88a4a8d6..12744f91 100644 --- a/src/cryfs_lib/CryDevice.h +++ b/src/cryfs_lib/CryDevice.h @@ -8,6 +8,7 @@ #include "utils/macros.h" #include "CryOpenFileList.h" +#include "CryOpenDirList.h" namespace cryfs { class CryNode; @@ -39,6 +40,10 @@ public: void unlink(const bf::path &path); void rename(const bf::path &from, const bf::path &to); + int openDir(const bf::path &path); + std::unique_ptr> readDir(int descriptor); + void closeDir(int descriptor); + const bf::path &RootDir() const; private: std::unique_ptr Load(const bf::path &path); @@ -47,6 +52,7 @@ private: int openFile(const CryFile &file, int flags); const bf::path _rootdir; CryOpenFileList _open_files; + CryOpenDirList _open_dirs; DISALLOW_COPY_AND_ASSIGN(CryDevice); }; diff --git a/src/cryfs_lib/CryDir.cpp b/src/cryfs_lib/CryDir.cpp index b1704195..42d69dad 100644 --- a/src/cryfs_lib/CryDir.cpp +++ b/src/cryfs_lib/CryDir.cpp @@ -45,7 +45,7 @@ void CryDir::rmdir() { CHECK_RETVAL(retval); } -unique_ptr CryDir::opendir() { +unique_ptr CryDir::opendir() const { return make_unique(device(), path()); } diff --git a/src/cryfs_lib/CryDir.h b/src/cryfs_lib/CryDir.h index d4076186..4e923624 100644 --- a/src/cryfs_lib/CryDir.h +++ b/src/cryfs_lib/CryDir.h @@ -21,7 +21,7 @@ public: std::unique_ptr createDir(const std::string &name, mode_t mode); void rmdir(); - std::unique_ptr opendir(); + std::unique_ptr opendir() const; private: DISALLOW_COPY_AND_ASSIGN(CryDir); }; diff --git a/src/cryfs_lib/CryOpenDirList.cpp b/src/cryfs_lib/CryOpenDirList.cpp new file mode 100644 index 00000000..3118f971 --- /dev/null +++ b/src/cryfs_lib/CryOpenDirList.cpp @@ -0,0 +1,25 @@ +#include +#include "CryDir.h" +#include "CryOpenDir.h" + +using namespace cryfs; + +CryOpenDirList::~CryOpenDirList() { +} + +CryOpenDirList::CryOpenDirList() + :_open_dirs() { +} + +int CryOpenDirList::open(const CryDir &dir) { + return _open_dirs.add(dir.opendir()); +} + +CryOpenDir *CryOpenDirList::get(int descriptor) { + return _open_dirs.get(descriptor); +} + +void CryOpenDirList::close(int descriptor) { + //The destructor of the stored CryOpenDir closes the dir + _open_dirs.remove(descriptor); +} diff --git a/src/cryfs_lib/CryOpenDirList.h b/src/cryfs_lib/CryOpenDirList.h new file mode 100644 index 00000000..218c11b5 --- /dev/null +++ b/src/cryfs_lib/CryOpenDirList.h @@ -0,0 +1,28 @@ +#ifndef CRYFS_LIB_CRYOPENDIRLIST_H_ +#define CRYFS_LIB_CRYOPENDIRLIST_H_ + +#include "utils/macros.h" +#include "IdList.h" + +namespace cryfs { +class CryOpenDir; +class CryDir; + +class CryOpenDirList { +public: + CryOpenDirList(); + virtual ~CryOpenDirList(); + + int open(const CryDir &rhs); + CryOpenDir *get(int descriptor); + void close(int descriptor); + +private: + IdList _open_dirs; + + DISALLOW_COPY_AND_ASSIGN(CryOpenDirList); +}; + +} + +#endif /* CRYFS_LIB_CRYOPENDIRLIST_H_ */ diff --git a/src/cryfs_lib/CryOpenFileList.cpp b/src/cryfs_lib/CryOpenFileList.cpp index 37479e9a..a278daaf 100644 --- a/src/cryfs_lib/CryOpenFileList.cpp +++ b/src/cryfs_lib/CryOpenFileList.cpp @@ -20,6 +20,6 @@ CryOpenFile *CryOpenFileList::get(int descriptor) { } void CryOpenFileList::close(int descriptor) { - //The destructor of the stored CryFile::OpenFile closes the file + //The destructor of the stored CryOpenFile closes the file _open_files.remove(descriptor); } diff --git a/src/cryfs_lib/CryOpenFileList.h b/src/cryfs_lib/CryOpenFileList.h index 69ef362b..1c41d277 100644 --- a/src/cryfs_lib/CryOpenFileList.h +++ b/src/cryfs_lib/CryOpenFileList.h @@ -1,8 +1,6 @@ #ifndef CRYFS_LIB_CRYOPENFILELIST_H_ #define CRYFS_LIB_CRYOPENFILELIST_H_ -#include -#include #include "utils/macros.h" #include "IdList.h"