From 75a59761f93a704e4948e032c255c2b60a1d5430 Mon Sep 17 00:00:00 2001 From: Andrew Grechkin Date: Sun, 31 May 2020 09:50:12 +0200 Subject: [PATCH] Release v0.9.3 * Support for Rar external codec is fixed --- CMakeLists.txt | 2 +- README.md | 4 ++-- src/7zip/Archive.cpp | 2 ++ src/7zip/ArchiveExtractor.cpp | 12 ++++++++++++ src/7zip/WriteStream.cpp | 26 +++++++++++++++++++++++++- src/fuse3.cpp | 5 ++++- src/include/logger.hpp | 8 ++++++++ src/library.cpp | 2 +- src/main.cpp | 16 ++++++++++++---- 9 files changed, 67 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84c9389..e5059a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 3.12 FATAL_ERROR) project (fuse3-p7zip - VERSION 0.9.2 + VERSION 0.9.3 DESCRIPTION "fuse3 file system that uses the p7zip library to mount archives" LANGUAGES CXX ) diff --git a/README.md b/README.md index bda66af..7eab840 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,8 @@ mount any archive supported by 7zip as a filesysterm mountpoint and have read on * FUSE3_P7ZIP_FORMATS - When opening file application tries formats in alphabetical order. Sometimes it's desired to open file with format - later in the list. This environment variable allows to override formats order. + When opening a file application tries formats in alphabetical order. Sometimes it's desired to open a file with + format later in the list. This environment variable allows to override formats order. for example (try open .iso file with Iso or Udf formats first and only fallback on APM and GPT formats) ``` diff --git a/src/7zip/Archive.cpp b/src/7zip/Archive.cpp index 0b10703..81a70d1 100644 --- a/src/7zip/Archive.cpp +++ b/src/7zip/Archive.cpp @@ -43,9 +43,11 @@ namespace sevenzip { void ImplArchive::init_props() { CheckCom(_arc->GetNumberOfItems(&_size), "GetNumberOfItems"); + LogDebug("GetNumberOfItems: %d", _size); auto num_props = UInt32(); CheckCom(_arc->GetNumberOfArchiveProperties(&num_props), "GetNumberOfArchiveProperties"); + LogDebug("GetNumberOfArchiveProperties: %d", num_props); } ULONG WINAPI ImplArchive::AddRef() diff --git a/src/7zip/ArchiveExtractor.cpp b/src/7zip/ArchiveExtractor.cpp index 79ef3f6..dc4be45 100644 --- a/src/7zip/ArchiveExtractor.cpp +++ b/src/7zip/ArchiveExtractor.cpp @@ -1,5 +1,6 @@ #include "7zip-impl.hpp" #include "exception.hpp" +#include "logger.hpp" namespace sevenzip { ULONG WINAPI ImplArchiveExtractor::AddRef() @@ -17,12 +18,15 @@ namespace sevenzip { HRESULT ret = S_OK; if (object && (riid == IID_IArchiveExtractCallback)) { + LogDebug("%s: IID_IArchiveExtractCallback", __PRETTY_FUNCTION__); *object = static_cast(this); AddRef(); } else if (object && (riid == IID_ICryptoGetTextPassword)) { + LogDebug("%s: IID_ICryptoGetTextPassword", __PRETTY_FUNCTION__); *object = static_cast(this); AddRef(); } else { + LogDebug("%s: UnknownImp", __PRETTY_FUNCTION__); ret = UnknownImp::QueryInterface(riid, object); } return ret; @@ -39,6 +43,7 @@ namespace sevenzip { HRESULT WINAPI ImplArchiveExtractor::SetTotal(UInt64 size) { + LogDebug("%s: %d", __PRETTY_FUNCTION__, size); total = size; HRESULT ret = callback.notify_progress(0, total) == true ? S_OK : S_FALSE; @@ -47,6 +52,7 @@ namespace sevenzip { HRESULT WINAPI ImplArchiveExtractor::SetCompleted(const UInt64* completeValue) { + LogDebug("%s: %p", __PRETTY_FUNCTION__, completeValue); HRESULT ret = S_OK; if (completeValue) ret = callback.notify_progress(*completeValue, total) == true ? S_OK : S_FALSE; @@ -56,6 +62,7 @@ namespace sevenzip { HRESULT WINAPI ImplArchiveExtractor::GetStream(UInt32 index, ISequentialOutStream** outStream, Int32 askExtractMode) { + LogDebug("%s: %d %d %p", __PRETTY_FUNCTION__, index, askExtractMode, file.get()); *outStream = nullptr; //m_curr.reset(new CurrItem(askExtractMode, m_dest, arc.at(index))); @@ -93,6 +100,7 @@ namespace sevenzip { HRESULT WINAPI ImplArchiveExtractor::PrepareOperation(Int32 askExtractMode) { + LogDebug("%s: %d", __PRETTY_FUNCTION__, askExtractMode); switch (askExtractMode) { case NArchive::NExtract::NAskMode::kExtract: break; case NArchive::NExtract::NAskMode::kTest: break; @@ -103,6 +111,7 @@ namespace sevenzip { HRESULT WINAPI ImplArchiveExtractor::SetOperationResult(Int32 operationResult) { + LogDebug("%s: %d", __PRETTY_FUNCTION__, operationResult); if (operationResult != NArchive::NExtract::NOperationResult::kOK) { // failed_files.push_back(FailedFile(m_curr->item.path(), operationResult)); } else { @@ -119,6 +128,7 @@ namespace sevenzip { HRESULT WINAPI ImplArchiveExtractor::CryptoGetTextPassword(BSTR* pass) { + LogDebug("%s: %p", __PRETTY_FUNCTION__, pass); //ustring ret = callback.request_password(); //com::BStr(ret).detach(*pass); return S_OK; @@ -131,8 +141,10 @@ namespace sevenzip { const UInt32 indices[] = {index}; file.reset(new FileWriteStream); file->AddRef(); + LogDebug("Extract: %d", index); CheckCom(arc->Extract(indices, 1, test, static_cast(this)), "Extract"); file->seek(0, IFile::Whence::set); + LogDebug("Extract finished: %d", index); return std::unique_ptr(file.release()); } diff --git a/src/7zip/WriteStream.cpp b/src/7zip/WriteStream.cpp index 4dfb4f0..25948b1 100644 --- a/src/7zip/WriteStream.cpp +++ b/src/7zip/WriteStream.cpp @@ -1,5 +1,6 @@ #include "7zip-impl.hpp" #include "exception.hpp" +#include "logger.hpp" namespace sevenzip { class FileWriteStream::FileHandle: public std::FILE { @@ -7,42 +8,53 @@ namespace sevenzip { HRESULT check_error(FileWriteStream::FileHandle* file) { - if (std::ferror(file)) return 1; + if (std::ferror(file)) { + LogDebug("FileWriteStream error occured"); + return 1; + } return S_OK; } FileWriteStream::~FileWriteStream() noexcept { + LogTrace(); std::fclose(_file); } FileWriteStream::FileWriteStream() : _file(static_cast(std::tmpfile())) { + LogTrace(); CheckErrno(_file, "tmpfile: "); } ULONG WINAPI FileWriteStream::AddRef() { + LogTrace(); return UnknownImp::AddRef(); } ULONG WINAPI FileWriteStream::Release() { + LogTrace(); return UnknownImp::Release(); } HRESULT WINAPI FileWriteStream::QueryInterface(REFIID riid, void** object) { + LogTrace(); HRESULT ret = S_OK; if (object && (riid == IID_IOutStream)) { + LogDebug("FileWriteStream::QueryInterface IID_IOutStream"); *object = static_cast(this); AddRef(); } else if (object && (riid == IID_ISequentialOutStream)) { + LogDebug("FileWriteStream::QueryInterface IID_ISequentialOutStream"); *object = static_cast(this); AddRef(); } else { + LogDebug("FileWriteStream::QueryInterface UnknownImp"); ret = UnknownImp::QueryInterface(riid, object); } return ret; @@ -50,42 +62,54 @@ namespace sevenzip { HRESULT WINAPI FileWriteStream::Write(const void* data, UInt32 size, UInt32* processedSize) { + LogTrace(); DWORD written = std::fwrite(data, 1, size, _file); if (processedSize) *processedSize = written; + LogDebug("Write: %d, %d", size, written); return check_error(_file); } HRESULT WINAPI FileWriteStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64* newPosition) { + LogTrace(); std::fseek(_file, offset, seekOrigin); auto pos = std::ftell(_file); if (newPosition) *newPosition = pos; + LogDebug("Seek: %d, %d, %d", offset, seekOrigin, pos); return check_error(_file); } HRESULT WINAPI FileWriteStream::SetSize(UInt64 newSize) { + LogTrace(); auto pos = std::ftell(_file); ftruncate(_file->_fileno, newSize); std::fseek(_file, pos, SEEK_SET); + LogDebug("SetSize: %d", newSize); return check_error(_file); } uint64_t FileWriteStream::read(void* data, uint64_t size) { + LogTrace(); auto read = std::fread(data, 1, size, _file); + LogDebug("read: %ld", size); return read; } uint64_t FileWriteStream::write(const void* data, uint64_t size) { + LogTrace(); auto written = std::fwrite(data, 1, size, _file); + LogDebug("write: %ld", size); return written; } uint64_t FileWriteStream::seek(uint64_t pos, Whence whence) { + LogTrace(); std::fseek(_file, pos, whence); + LogDebug("seek: %ld", pos); return std::ftell(_file); } } // namespace sevenzip diff --git a/src/fuse3.cpp b/src/fuse3.cpp index b661d11..001638d 100644 --- a/src/fuse3.cpp +++ b/src/fuse3.cpp @@ -136,6 +136,7 @@ int Fuse::Operations::cb_getattr(const char* path, struct stat* stbuf, fuse_file int Fuse::Operations::cb_open(const char* path, fuse_file_info* fi) { + LogDebug("fuse3 open: %s", path); Cache* cache = static_cast(fuse_get_context()->private_data); auto el = cache->tree.find(path); if (el == cache->tree.end()) return -ENOENT; @@ -148,6 +149,7 @@ int Fuse::Operations::cb_open(const char* path, fuse_file_info* fi) auto tmpfile = el->second.first.extract().release(); fi->fh = reinterpret_cast(tmpfile); + LogDebug("fuse3 open fh: %p", fi->fh); return 0; } @@ -161,6 +163,7 @@ int Fuse::Operations::cb_release(const char*, struct fuse_file_info* fi) int Fuse::Operations::cb_read(const char* path, char* buf, size_t size, off_t offset, struct fuse_file_info* fi) { + LogDebug("fuse3 read: %s", path); auto file = reinterpret_cast(fi->fh); file->seek(offset, sevenzip::IFile::Whence::set); return file->read(buf, size); @@ -226,7 +229,7 @@ ssize_t Fuse::execute(sevenzip::IArchive* arc) file_stat.st_mode |= S_IFREG; } //log().printf("path: '%s'\n", path.c_str()); - cache.tree.emplace(path, std::make_pair(it, file_stat)); + cache.tree.insert_or_assign(path, std::make_pair(it, file_stat)); for (auto p = path.parent_path(); !p.empty() && p != root; p = p.parent_path()) { if (cache.tree.contains(p)) break; //log().printf("sub: '%s'\n", p.c_str()); diff --git a/src/include/logger.hpp b/src/include/logger.hpp index ef7d193..a5f05e8 100644 --- a/src/include/logger.hpp +++ b/src/include/logger.hpp @@ -3,6 +3,14 @@ #include +#ifdef NDEBUG +# define LogTrace() +# define LogDebug(format, ...) +#else +# define LogTrace() log().printf("%s:%d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__) +# define LogDebug(format, ...) log().printf(format, ##__VA_ARGS__) +#endif + class Log { public: void printf(const char* format, ...) noexcept; diff --git a/src/library.cpp b/src/library.cpp index fbc081d..676860b 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -28,7 +28,7 @@ namespace library { ImplDynamic::ImplDynamic(const Path& path, flags_type flags) : _path(path) - , _flags(flags | RTLD_NOW) + , _flags(flags | RTLD_NOW | RTLD_GLOBAL) , _hnd(dlopen(path.c_str(), _flags)) { CheckPointer(_hnd, ThrowLibraryError, "dlopen"); diff --git a/src/main.cpp b/src/main.cpp index ec23474..dd96c30 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,24 @@ #include "7zip.hpp" +#include "library.hpp" #include "fuse3.hpp" #include "logger.hpp" // TODO -// rar not working -// verbose version +// verbose --version int main(int argc, char** argv, char** env) try { auto override_library = std::getenv("FUSE3_P7ZIP_LIBRARY"); - auto lib_path = override_library ? override_library : "/usr/lib/p7zip/7z.so"; - auto lib = sevenzip::open(lib_path); + auto lib_path = sevenzip::Path(override_library ? override_library : "/usr/lib/p7zip/7z.so"); + + // preload Rar codecs (this also can be done with LD_PRELOAD) + library::Dynamic rar_codec; + auto rar_path = lib_path.parent_path() / "Codecs" / "Rar.so"; + if (std::filesystem::exists(rar_path)) { + library::open(rar_path).swap(rar_codec); + } + + auto lib = sevenzip::open(lib_path); Fuse loop(argc, argv); log().printf("open archive: %s", loop.path().c_str());