From f1ff4c3e11f67adde1aa8ef3a13546aab46a80e6 Mon Sep 17 00:00:00 2001 From: ayounes Date: Fri, 29 Nov 2019 10:42:07 -0500 Subject: [PATCH] archiver: add libarchive Change-Id: I2ff7d879de55e18bedcbddce74f743ffe8755ca6 --- CMakeLists.txt | 69 ++++----- compat/msvc/package.json | 3 +- configure.ac | 1 + contrib/src/libarchive/SHA512SUMS | 1 + contrib/src/libarchive/package.json | 17 +++ contrib/src/libarchive/rules.mak | 38 +++++ contrib/src/main.mak | 4 +- src/Makefile.am | 1 + src/archiver.cpp | 212 +++++++++++++++++++++++++++- src/archiver.h | 38 ++++- 10 files changed, 344 insertions(+), 40 deletions(-) create mode 100644 contrib/src/libarchive/SHA512SUMS create mode 100644 contrib/src/libarchive/package.json create mode 100644 contrib/src/libarchive/rules.mak diff --git a/CMakeLists.txt b/CMakeLists.txt index ef6cd2674..c5659effb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,7 @@ if(MSVC) "${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc;" "${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/include;" "${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/msgpack-c/include;" + "${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/libarchive/libarchive;" "${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/jsoncpp/include;" "${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/yaml-cpp/include;" "${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib/include;" @@ -165,6 +166,7 @@ if(MSVC) "_WIN32_WINNT=0x0A00;" "ASIO_STANDALONE;" "STATIC_GETOPT;" + "LIBARCHIVE_STATIC;" "OPENDHT_PROXY_CLIENT;" "OPENDHT_PROXY_SERVER;" "OPENDHT_PUSH_NOTIFICATIONS;" @@ -226,40 +228,41 @@ if(MSVC) # Dependencies ################################################################################ - set(libAdditionalDependencies "${CMAKE_STATIC_LINKER_FLAGS} /LTCG ws2_32.lib - advapi32.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avcodec.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avdevice.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avfilter.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avformat.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avutil.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swresample.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swscale.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libgnutls.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/lib_json.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libopendht.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/secp256k1.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/yaml-cpp/msvc/Release/libyaml-cppmd.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/portaudio.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libupnp.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/natpmp/msvc/Release/natpmp.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-core-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-simple-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua2-lib-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua-lib-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-ua-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjmedia/lib/pjmedia-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib-util/lib/pjlib-util-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib/lib/pjlib-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjnath/lib/pjnath-x86_64-x64-vc15-Release.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/fmt/msvc/Release/fmt.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/http_parser/x64/Release/http-parser.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/asio/asio/msvc/x64/Release/asio.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/libeay32.lib - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/ssleay32.lib + set(libAdditionalDependencies "${CMAKE_STATIC_LINKER_FLAGS} /LTCG ws2_32.lib + advapi32.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avcodec.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avdevice.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avfilter.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avformat.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avutil.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swresample.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swscale.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libgnutls.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/lib_json.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libopendht.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/secp256k1.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/yaml-cpp/msvc/Release/libyaml-cppmd.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/portaudio.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libupnp.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/natpmp/msvc/Release/natpmp.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/libarchive/msvc/libarchive/Release/archive_static.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-core-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-simple-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua2-lib-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua-lib-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-ua-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjmedia/lib/pjmedia-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib-util/lib/pjlib-util-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib/lib/pjlib-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjnath/lib/pjnath-x86_64-x64-vc15-Release.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/fmt/msvc/Release/fmt.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/http_parser/x64/Release/http-parser.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/asio/asio/msvc/x64/Release/asio.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/libeay32.lib + ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/ssleay32.lib ${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/speexdsp/lib/libspeexdsp.lib - /ignore:4006 + /ignore:4006 " ) diff --git a/compat/msvc/package.json b/compat/msvc/package.json index 0aea6554e..59b084a14 100644 --- a/compat/msvc/package.json +++ b/compat/msvc/package.json @@ -10,7 +10,8 @@ "secp256k1", "speexdsp", "upnp", - "yaml-cpp" + "yaml-cpp", + "libarchive" ], "configuration": "ReleaseLib_win32", "project_paths": ["ring-daemon.vcxproj"] diff --git a/configure.ac b/configure.ac index 5eb5f87c5..10287bc0f 100644 --- a/configure.ac +++ b/configure.ac @@ -302,6 +302,7 @@ PKG_CHECK_MODULES(PJPROJECT, libpjproject,, AC_MSG_ERROR([Missing pjproject file PKG_CHECK_MODULES([YAMLCPP], [yaml-cpp >= 0.5.1],, AC_MSG_ERROR([yaml-cpp not found])) PKG_CHECK_MODULES([JSONCPP], [jsoncpp >= 1.6.5],, AC_MSG_ERROR([jsoncpp not found])) +PKG_CHECK_MODULES([ARCHIVE], [libarchive >= 3.0],, AC_MSG_ERROR([libarchive not found])) if test "${HAVE_ANDROID}" = "1"; then dnl Check for OpenSL diff --git a/contrib/src/libarchive/SHA512SUMS b/contrib/src/libarchive/SHA512SUMS new file mode 100644 index 000000000..1d2549912 --- /dev/null +++ b/contrib/src/libarchive/SHA512SUMS @@ -0,0 +1 @@ +2f9e2a551a6bcab56fb1a030b5d656df7299a3d151465aa02f0420d344d2fada49dee4755b3abff9095f62519e14dc9af8afa1695ecc6d5fdb4f0b28e6ede852 libarchive-3.4.0.tar.gz diff --git a/contrib/src/libarchive/package.json b/contrib/src/libarchive/package.json new file mode 100644 index 000000000..1dd9ab194 --- /dev/null +++ b/contrib/src/libarchive/package.json @@ -0,0 +1,17 @@ +{ + "name": "libarchive", + "version": "a53d711261f4d5bf2104d9c3616a8602a45ba196", + "url": "https://github.com/libarchive/libarchive/archive/__VERSION__.tar.gz", + "deps": [], + "patches": [], + "win_patches": [], + "project_paths": ["msvc/libarchive/archive_static.vcxproj"], + "with_env" : "", + "custom_scripts": { + "pre_build": [ + "mkdir msvc & cd msvc & cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=lib -DENABLE_TEST=OFF -DENABLE_TAR=OFF -DENABLE_CPIO=OFF -DENABLE_CAT=OFF -DENABLE_LIBXML2=OFF -G %CMAKE_GENERATOR%" + ], + "build": [], + "post_build": [] + } +} \ No newline at end of file diff --git a/contrib/src/libarchive/rules.mak b/contrib/src/libarchive/rules.mak new file mode 100644 index 000000000..68033dd64 --- /dev/null +++ b/contrib/src/libarchive/rules.mak @@ -0,0 +1,38 @@ +# LIBARCHIVE +LIBARCHIVE_VERSION := 3.4.0 +LIBARCHIVE_URL := https://github.com/libarchive/libarchive/releases/download/v$(LIBARCHIVE_VERSION)/libarchive-$(LIBARCHIVE_VERSION).tar.gz + +PKGS += libarchive +ifeq ($(call need_pkg,"libarchive >= 3.4.0"),) +PKGS_FOUND += libarchive +endif + +LIBARCHIVE_CMAKECONF := \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DENABLE_TEST=OFF \ + -DENABLE_TAR=OFF \ + -DENABLE_CPIO=OFF \ + -DENABLE_CAT=OFF \ + -DENABLE_LIBXML2=OFF + +$(TARBALLS)/libarchive-$(LIBARCHIVE_VERSION).tar.gz: + $(call download,$(LIBARCHIVE_URL)) + +.sum-libarchive: libarchive-$(LIBARCHIVE_VERSION).tar.gz + +libarchive: libarchive-$(LIBARCHIVE_VERSION).tar.gz + $(UNPACK) + $(MOVE) + +.libarchive: libarchive toolchain.cmake .sum-libarchive + cd $< && mkdir -p buildlib +ifdef HAVE_ANDROID + cd $< && cp -R contrib/android/include/* $(PREFIX)/include +endif + cd $< && cd buildlib && $(HOSTVARS) $(CMAKE) .. $(LIBARCHIVE_CMAKECONF) + cd $< && cd buildlib && $(MAKE) install +ifdef HAVE_LINUX + cd $< && cd $(PREFIX)/lib && rm libarchive.so* +endif + touch $@ diff --git a/contrib/src/main.mak b/contrib/src/main.mak index 74974b233..28cce1f39 100644 --- a/contrib/src/main.mak +++ b/contrib/src/main.mak @@ -503,8 +503,8 @@ endif echo "set(CMAKE_CXX_COMPILER $(CXX))" >> $@ echo "set(CMAKE_FIND_ROOT_PATH $(PREFIX))" >> $@ echo "set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)" >> $@ - echo "set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)" >> $@ - echo "set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" >> $@ + echo "set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)" >> $@ + echo "set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)" >> $@ echo "set(CMAKE_BUILD_TYPE Release)" >> $@ # Default pattern rules diff --git a/src/Makefile.am b/src/Makefile.am index 6b9c5b6ff..f9f7e3995 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -57,6 +57,7 @@ libring_la_LDFLAGS = \ @GNUTLS_LIBS@ \ @OPENDHT_LIBS@ \ @SECP256K1_LIBS@ \ + @ARCHIVE_LIBS@ \ @ZLIB_LIBS@ \ @LIBSSL_LIBS@ \ @LIBCRYPTO_LIBS@ \ diff --git a/src/archiver.cpp b/src/archiver.cpp index d45ffae1e..e8d9772fc 100644 --- a/src/archiver.cpp +++ b/src/archiver.cpp @@ -32,6 +32,11 @@ #include #include +extern "C" { +#include +#include +} + #include #include @@ -87,8 +92,8 @@ accountToJsonValue(const std::map& details) { int exportAccounts(const std::vector& accountIDs, - const std::string& filepath, - const std::string& password) + const std::string& filepath, + const std::string& password) { if (filepath.empty() || !accountIDs.size()) { JAMI_ERR("Missing arguments"); @@ -304,4 +309,207 @@ openGzip(const std::string& path, const char *mode) #endif } +// LIBARCHIVE DEFINITIONS +//========================== +using ArchivePtr = std::unique_ptr; +using ArchiveEntryPtr = std::unique_ptr; + +struct DataBlock { + const void *buff; + size_t size; + int64_t offset; +}; + +long readDataBlock(const ArchivePtr &a, DataBlock &b) +{ + return archive_read_data_block(a.get(), &b.buff, &b.size, &b.offset); +} + +long writeDataBlock(const ArchivePtr &a, DataBlock &b) +{ + return archive_write_data_block(a.get(), b.buff, b.size, b.offset); +} + + +ArchivePtr createArchiveReader() { + ArchivePtr archivePtr{archive_read_new(), [](archive * a) { + archive_read_close(a); + archive_read_free(a); + }}; + return archivePtr; +} + +static ArchivePtr createArchiveDiskWriter() { + return {archive_write_disk_new(), [](archive * a) { + archive_write_close(a); + archive_write_free(a); + }}; +} + +//========================== + +std::vector listArchiveContent(const std::string &archivePath) +{ + std::vector fileNames; + ArchivePtr archiveReader = createArchiveReader(); + struct archive_entry* entry; + int r; + + // Set reader formats(archive) and filters(compression) + archive_read_support_filter_all(archiveReader.get()); + archive_read_support_format_all(archiveReader.get()); + + // Try to read the archive + if ((r = archive_read_open_filename(archiveReader.get(), archivePath.c_str(), 10240))) { + throw std::runtime_error(archive_error_string(archiveReader.get())); + } + + while (archive_read_next_header(archiveReader.get(), &entry) == ARCHIVE_OK) { + std::string fileEntry = archive_entry_pathname(entry) ? archive_entry_pathname(entry) : "Undefined"; + fileNames.push_back(fileEntry); + } + + return fileNames; +} + +void uncompressArchive(const std::string &archivePath, const std::string &dir, const FileMatchPair& f) +{ + int r; + + ArchivePtr archiveReader = createArchiveReader(); + ArchivePtr archiveDiskWriter = createArchiveDiskWriter(); + struct archive_entry* entry; + + int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_NO_HFS_COMPRESSION; + + // Set reader formats(archive) and filters(compression) + archive_read_support_filter_all(archiveReader.get()); + archive_read_support_format_all(archiveReader.get()); + + // Set written files flags and standard lookup(uid/gid) + archive_write_disk_set_options(archiveDiskWriter.get(), flags); + archive_write_disk_set_standard_lookup(archiveDiskWriter.get()); + + // Try to read the archive + if ((r = archive_read_open_filename(archiveReader.get(), archivePath.c_str(), 10240))) { + throw std::runtime_error("Open Archive: " + archivePath + "\t" + + archive_error_string(archiveReader.get())); + } + + while(true) { + // Read headers until End of File + r = archive_read_next_header(archiveReader.get(), &entry); + if( r == ARCHIVE_EOF) { + break; + } + + std::string fileEntry = archive_entry_pathname(entry) ? archive_entry_pathname(entry) : "Undefined"; + + if (r != ARCHIVE_OK) { + throw std::runtime_error("Read file pathname: " + fileEntry + "\t" + + archive_error_string(archiveReader.get())); + } + + // File is ok, copy its header to the ext writer + const auto& fileMatchPair = f(fileEntry); + if(fileMatchPair.first) { + std::string entryDestinationPath = dir + DIR_SEPARATOR_CH + fileMatchPair.second; + archive_entry_set_pathname(entry, entryDestinationPath.c_str()); + r = archive_write_header(archiveDiskWriter.get(), entry); + if (r != ARCHIVE_OK) { + // Rollback if failed at a write operation + fileutils::removeAll(dir); + throw std::runtime_error("Write file header: " + fileEntry + "\t" + + archive_error_string(archiveDiskWriter.get())); + } else { + // Here both the reader and the writer have moved past the headers + // Copying the data content + DataBlock db; + + while(true) { + r = readDataBlock(archiveReader,db); + if (r == ARCHIVE_EOF) { + break; + } + + if (r != ARCHIVE_OK) { + throw std::runtime_error("Read file data: " + fileEntry + "\t" + + archive_error_string(archiveReader.get())); + } + + r = writeDataBlock(archiveDiskWriter, db); + + if (r != ARCHIVE_OK) { + // Rollback if failed at a write operation + fileutils::removeAll(dir); + throw std::runtime_error("Write file data: " + fileEntry + "\t" + + archive_error_string(archiveDiskWriter.get())); + } + } + } + } + } +} + +std::vector readFileFromArchive(const std::string &archivePath, + const std::string &fileRelativePathName) +{ + long r; + ArchivePtr archiveReader = createArchiveReader(); + struct archive_entry* entry; + + // Set reader formats(archive) and filters(compression) + archive_read_support_filter_all(archiveReader.get()); + archive_read_support_format_all(archiveReader.get()); + + // Try to read the archive + if ((r = archive_read_open_filename(archiveReader.get(), archivePath.c_str(), 10240))) { + throw std::runtime_error("Open Archive: " + archivePath + "\t" + + archive_error_string(archiveReader.get())); + } + + while(true) { + // Read headers until End of File + r = archive_read_next_header(archiveReader.get(), &entry); + if( r == ARCHIVE_EOF) { + break; + } + + std::string fileEntry = archive_entry_pathname(entry) ? archive_entry_pathname(entry) : ""; + + if (r != ARCHIVE_OK) { + throw std::runtime_error("Read file pathname: " + fileEntry + "\t" + + archive_error_string(archiveReader.get())); + } + + // File is ok and the reader has moved past the header + if(fileEntry == fileRelativePathName){ + // Copying the data content + DataBlock db; + std::vector fileContent; + + while(true) { + r = readDataBlock(archiveReader,db); + if (r == ARCHIVE_EOF) { + return fileContent; + } + + if (r != ARCHIVE_OK) { + throw std::runtime_error("Read file data: " + fileEntry + "\t" + + archive_error_string(archiveReader.get())); + } + + if (fileContent.size() < static_cast(db.offset)) { + fileContent.resize(db.offset); + } + + auto dat = static_cast(db.buff); + // push the buffer data in the string stream + fileContent.insert(fileContent.end(), dat, dat+db.size); + } + } + } + throw std::runtime_error("File " + fileRelativePathName + " not found in the archive"); +} + }} // namespace jami::archiver diff --git a/src/archiver.h b/src/archiver.h index 1b03df4f7..b06ca7917 100644 --- a/src/archiver.h +++ b/src/archiver.h @@ -25,6 +25,7 @@ #include #include #include +#include typedef struct gzFile_s *gzFile; @@ -35,6 +36,8 @@ namespace jami { */ namespace archiver { +using FileMatchPair = std::function(const std::string&)>; + /** * Create a protected archive containing a list of accounts * @param accountIDs The accounts to exports @@ -43,8 +46,8 @@ namespace archiver { * @returns 0 for OK, error code otherwise */ int exportAccounts(const std::vector& accountIDs, - const std::string& filepath, - const std::string& password); + const std::string& filepath, + const std::string& password); /** * Read a protected archive and add accounts found in it @@ -81,6 +84,37 @@ std::vector decompressGzip(const std::string& path); */ gzFile openGzip(const std::string& path, const char *mode); +/** + * @brief listArchiveContent + * @param archivePath + * @return list of relative file path names + */ +std::vector listArchiveContent(const std::string& archivePath); + +/** + * @brief uncompressArchive Uncompresses an archive and puts the different files + * in dir folder according to a FileMatchPair f + * @param path + * @param dir + * @param f takes a file name relative path inside the archive like mysubfolder/myfile + * and returns a pair (bool, new file name relative path) + * Where the bool indicates if we should uncompress this file + * and the new file name relative path puts the file in the directory dir under a different + * relative path name like mynewsubfolder/myfile + * @return void + */ +void uncompressArchive(const std::string& path, const std::string &dir, const FileMatchPair& f); + +/** + * @brief readFileFromArchive read a file from an archive without uncompressing + * the whole archive + * @param path archive path + * @param fileRelativePathName file path relative path name in the archive + * E.g: data/myfile.txt inside the archive + * @return fileContent std::vector that contains the file content + */ +std::vector readFileFromArchive(const std::string &path, + const std::string &fileRelativePathName); } } // namespace jami