diff --git a/src/fileutils.cpp b/src/fileutils.cpp index 43eaef1faa722ed0de325aef9cba210475fd786d..46e81f66320e9239260c6d3a97d3013b6732d5c0 100644 --- a/src/fileutils.cpp +++ b/src/fileutils.cpp @@ -375,11 +375,12 @@ createHardlink(const std::string& linkFile, const std::string& target) return true; } -void +bool createFileLink(const std::string& linkFile, const std::string& target, bool hard) { if (not hard or not createHardlink(linkFile, target)) - createSymlink(linkFile, target); + return createSymlink(linkFile, target); + return true; } std::string_view @@ -459,6 +460,19 @@ loadTextFile(const std::string& path, const std::string& default_dir) return buffer; } +bool +copy(const std::string& src, const std::string& dest) +{ +#if !USE_STD_FILESYSTEM + std::ifstream srcStream(src, std::ios::binary); + std::ofstream destStream(dest, std::ios::binary); + destStream << srcStream.rdbuf(); + return srcStream && destStream; +#else + return std::filesystem::copy_file(src, dest); +#endif +} + void saveFile(const std::string& path, const uint8_t* data, size_t data_size, mode_t UNUSED mode) { diff --git a/src/fileutils.h b/src/fileutils.h index b681e1681991b616e9a29028c19d6fefcfd5db7b..e038abf33ac5ab164f32cdbbe49b718664d9418c 100644 --- a/src/fileutils.h +++ b/src/fileutils.h @@ -85,7 +85,7 @@ bool hasHardLink(const std::string& path); std::chrono::system_clock::time_point writeTime(const std::string& path); -void createFileLink(const std::string& src, const std::string& dest, bool hard = false); +bool createFileLink(const std::string& src, const std::string& dest, bool hard = false); std::string_view getFileExtension(std::string_view filename); @@ -103,6 +103,8 @@ std::vector<std::string> readDirectory(const std::string& dir); std::vector<uint8_t> loadFile(const std::string& path, const std::string& default_dir = {}); std::string loadTextFile(const std::string& path, const std::string& default_dir = {}); +bool copy(const std::string& src, const std::string& dest); + void saveFile(const std::string& path, const uint8_t* data, size_t data_size, mode_t mode = 0644); inline void saveFile(const std::string& path, const std::vector<uint8_t>& data, mode_t mode = 0644) diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp index 558de35703f3747daaad7b423c59d6f4a35a6b2f..351f41d74b52e9c296c99101cf8bfa76a9e21d59 100644 --- a/src/jamidht/jamiaccount.cpp +++ b/src/jamidht/jamiaccount.cpp @@ -4095,8 +4095,14 @@ JamiAccount::sendFile(const std::string& conversationId, auto extension = fileutils::getFileExtension(path); if (!extension.empty()) filelinkPath += "." + extension; - if (path != filelinkPath && !fileutils::isSymLink(filelinkPath)) - fileutils::createFileLink(filelinkPath, path, true); + if (path != filelinkPath && !fileutils::isSymLink(filelinkPath)) { + if (!fileutils::createFileLink(filelinkPath, path, true)) { + JAMI_WARNING("Cannot create symlink for file transfer {} - {}. Copy file", filelinkPath, path); + if (!fileutils::copy(path, filelinkPath)) { + JAMI_ERROR("Cannot copy file for file transfer {} - {}", filelinkPath, path); + } + } + } }); } }); diff --git a/test/unitTest/fileutils/testFileutils.cpp b/test/unitTest/fileutils/testFileutils.cpp index 7dae663116e89d9b9283ab15c41289de54a45fa8..1291cfa9c96e2148cefbf1b7b36c57d69898b060 100644 --- a/test/unitTest/fileutils/testFileutils.cpp +++ b/test/unitTest/fileutils/testFileutils.cpp @@ -48,6 +48,7 @@ private: void testIsDirectoryWritable(); void testGetCleanPath(); void testFullPath(); + void testCopy(); CPPUNIT_TEST_SUITE(FileutilsTest); CPPUNIT_TEST(testCheckDir); @@ -57,6 +58,7 @@ private: CPPUNIT_TEST(testIsDirectoryWritable); CPPUNIT_TEST(testGetCleanPath); CPPUNIT_TEST(testFullPath); + CPPUNIT_TEST(testCopy); CPPUNIT_TEST_SUITE_END(); static constexpr auto tmpFileName = "temp_file"; @@ -178,6 +180,16 @@ FileutilsTest::testFullPath() CPPUNIT_ASSERT(getFullPath(NON_EXISTANT_PATH_BASE, "test").compare(NON_EXISTANT_PATH) == 0); } +void +FileutilsTest::testCopy() +{ + CPPUNIT_ASSERT(isFile(EXISTANT_FILE)); + CPPUNIT_ASSERT(!isFile(NON_EXISTANT_PATH_BASE)); + CPPUNIT_ASSERT(copy(EXISTANT_FILE, NON_EXISTANT_PATH_BASE)); + CPPUNIT_ASSERT(isFile(NON_EXISTANT_PATH_BASE)); + CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0); +} + }}} // namespace jami::test::fileutils RING_TEST_RUNNER(jami::fileutils::test::FileutilsTest::name());