diff options
author | B. Stack <bgstack15@gmail.com> | 2021-12-06 13:37:35 +0000 |
---|---|---|
committer | B. Stack <bgstack15@gmail.com> | 2021-12-06 13:37:35 +0000 |
commit | f142f32c8d2b53f305cb72cb5953e3394d6a6243 (patch) | |
tree | 2999df8f80b28d0f7f60a84b7f75d613e280bba1 /zen | |
parent | Merge branch 'b11.14' into 'master' (diff) | |
parent | add upstream 11.15 (diff) | |
download | FreeFileSync-f142f32c8d2b53f305cb72cb5953e3394d6a6243.tar.gz FreeFileSync-f142f32c8d2b53f305cb72cb5953e3394d6a6243.tar.bz2 FreeFileSync-f142f32c8d2b53f305cb72cb5953e3394d6a6243.zip |
Merge branch 'b11.15' into 'master'11.15
add upstream 11.15
See merge request opensource-tracking/FreeFileSync!39
Diffstat (limited to 'zen')
-rw-r--r-- | zen/file_access.cpp | 65 | ||||
-rw-r--r-- | zen/file_access.h | 9 | ||||
-rw-r--r-- | zen/file_path.cpp | 79 | ||||
-rw-r--r-- | zen/file_path.h | 27 | ||||
-rw-r--r-- | zen/http.cpp | 1 | ||||
-rw-r--r-- | zen/resolve_path.cpp | 3 | ||||
-rw-r--r-- | zen/symlink_target.h | 15 | ||||
-rw-r--r-- | zen/zstring.h | 4 |
8 files changed, 121 insertions, 82 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp index db4f2505..6940b22f 100644 --- a/zen/file_access.cpp +++ b/zen/file_access.cpp @@ -29,71 +29,8 @@ using namespace zen; -std::optional<PathComponents> zen::parsePathComponents(const Zstring& itemPath) -{ - auto doParse = [&](int sepCountVolumeRoot, bool rootWithSep) -> std::optional<PathComponents> - { - const Zstring itemPathFmt = appendSeparator(itemPath); //simplify analysis of root without separator, e.g. \\server-name\share - int sepCount = 0; - for (auto it = itemPathFmt.begin(); it != itemPathFmt.end(); ++it) - if (*it == FILE_NAME_SEPARATOR) - if (++sepCount == sepCountVolumeRoot) - { - Zstring rootPath(itemPathFmt.begin(), rootWithSep ? it + 1 : it); - - Zstring relPath(it + 1, itemPathFmt.end()); - trim(relPath, true, true, [](Zchar c) { return c == FILE_NAME_SEPARATOR; }); - - return PathComponents({rootPath, relPath}); - } - return {}; - }; - - std::optional<PathComponents> pc; //"/media/zenju/" and "/Volumes/" should not fail to parse - - if (!pc && startsWith(itemPath, "/mnt/")) //e.g. /mnt/DEVICE_NAME - pc = doParse(3 /*sepCountVolumeRoot*/, false /*rootWithSep*/); - - if (!pc && startsWith(itemPath, "/media/")) //Ubuntu: e.g. /media/zenju/DEVICE_NAME - if (const char* username = ::getenv("USER")) - if (startsWith(itemPath, std::string("/media/") + username + "/")) - pc = doParse(4 /*sepCountVolumeRoot*/, false /*rootWithSep*/); - - if (!pc && startsWith(itemPath, "/run/media/")) //CentOS, Suse: e.g. /run/media/zenju/DEVICE_NAME - if (const char* username = ::getenv("USER")) - if (startsWith(itemPath, std::string("/run/media/") + username + "/")) - pc = doParse(5 /*sepCountVolumeRoot*/, false /*rootWithSep*/); - - if (!pc && startsWith(itemPath, "/run/user/")) //Ubuntu, e.g.: /run/user/1000/gvfs/smb-share:server=192.168.62.145,share=folder - { - Zstring tmp(itemPath.begin() + strLength("/run/user/"), itemPath.end()); - tmp = beforeFirst(tmp, "/gvfs/", IfNotFoundReturn::none); - if (!tmp.empty() && std::all_of(tmp.begin(), tmp.end(), [](char c) { return isDigit(c); })) - /**/pc = doParse(6 /*sepCountVolumeRoot*/, false /*rootWithSep*/); - } - - - if (!pc && startsWith(itemPath, "/")) - pc = doParse(1 /*sepCountVolumeRoot*/, true /*rootWithSep*/); - - return pc; -} - - -std::optional<Zstring> zen::getParentFolderPath(const Zstring& itemPath) +namespace { - if (const std::optional<PathComponents> comp = parsePathComponents(itemPath)) - { - if (comp->relPath.empty()) - return std::nullopt; - - const Zstring parentRelPath = beforeLast(comp->relPath, FILE_NAME_SEPARATOR, IfNotFoundReturn::none); - if (parentRelPath.empty()) - return comp->rootPath; - return appendSeparator(comp->rootPath) + parentRelPath; - } - assert(false); - return std::nullopt; } diff --git a/zen/file_access.h b/zen/file_access.h index f3ea6c00..691a8df9 100644 --- a/zen/file_access.h +++ b/zen/file_access.h @@ -17,15 +17,6 @@ namespace zen { //note: certain functions require COM initialization! (vista_file_op.h) -struct PathComponents -{ - Zstring rootPath; //itemPath = rootPath + (FILE_NAME_SEPARATOR?) + relPath - Zstring relPath; // -}; -std::optional<PathComponents> parsePathComponents(const Zstring& itemPath); //no value on failure - -std::optional<Zstring> getParentFolderPath(const Zstring& itemPath); - //POSITIVE existence checks; if false: 1. item not existing 2. different type 3.device access error or similar bool fileAvailable(const Zstring& filePath); //noexcept bool dirAvailable (const Zstring& dirPath ); // diff --git a/zen/file_path.cpp b/zen/file_path.cpp new file mode 100644 index 00000000..d846e804 --- /dev/null +++ b/zen/file_path.cpp @@ -0,0 +1,79 @@ +// ***************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 * +// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * +// ***************************************************************************** + +#include "file_path.h" + +using namespace zen; + + +std::optional<PathComponents> zen::parsePathComponents(const Zstring& itemPath) +{ + auto doParse = [&](int sepCountVolumeRoot, bool rootWithSep) -> std::optional<PathComponents> + { + const Zstring itemPathFmt = appendSeparator(itemPath); //simplify analysis of root without separator, e.g. \\server-name\share + int sepCount = 0; + for (auto it = itemPathFmt.begin(); it != itemPathFmt.end(); ++it) + if (*it == FILE_NAME_SEPARATOR) + if (++sepCount == sepCountVolumeRoot) + { + Zstring rootPath(itemPathFmt.begin(), rootWithSep ? it + 1 : it); + + Zstring relPath(it + 1, itemPathFmt.end()); + trim(relPath, true, true, [](Zchar c) { return c == FILE_NAME_SEPARATOR; }); + + return PathComponents({rootPath, relPath}); + } + return {}; + }; + + std::optional<PathComponents> pc; //"/media/zenju/" and "/Volumes/" should not fail to parse + + if (!pc && startsWith(itemPath, "/mnt/")) //e.g. /mnt/DEVICE_NAME + pc = doParse(3 /*sepCountVolumeRoot*/, false /*rootWithSep*/); + + if (!pc && startsWith(itemPath, "/media/")) //Ubuntu: e.g. /media/zenju/DEVICE_NAME + if (const char* username = ::getenv("USER")) + if (startsWith(itemPath, std::string("/media/") + username + "/")) + pc = doParse(4 /*sepCountVolumeRoot*/, false /*rootWithSep*/); + + if (!pc && startsWith(itemPath, "/run/media/")) //CentOS, Suse: e.g. /run/media/zenju/DEVICE_NAME + if (const char* username = ::getenv("USER")) + if (startsWith(itemPath, std::string("/run/media/") + username + "/")) + pc = doParse(5 /*sepCountVolumeRoot*/, false /*rootWithSep*/); + + if (!pc && startsWith(itemPath, "/run/user/")) //Ubuntu, e.g.: /run/user/1000/gvfs/smb-share:server=192.168.62.145,share=folder + { + Zstring tmp(itemPath.begin() + strLength("/run/user/"), itemPath.end()); + tmp = beforeFirst(tmp, "/gvfs/", IfNotFoundReturn::none); + if (!tmp.empty() && std::all_of(tmp.begin(), tmp.end(), [](char c) { return isDigit(c); })) + /**/pc = doParse(6 /*sepCountVolumeRoot*/, false /*rootWithSep*/); + } + + + if (!pc && startsWith(itemPath, "/")) + pc = doParse(1 /*sepCountVolumeRoot*/, true /*rootWithSep*/); + + return pc; +} + + +std::optional<Zstring> zen::getParentFolderPath(const Zstring& itemPath) +{ + if (const std::optional<PathComponents> comp = parsePathComponents(itemPath)) + { + if (comp->relPath.empty()) + return std::nullopt; + + const Zstring parentRelPath = beforeLast(comp->relPath, FILE_NAME_SEPARATOR, IfNotFoundReturn::none); + if (parentRelPath.empty()) + return comp->rootPath; + return appendSeparator(comp->rootPath) + parentRelPath; + } + assert(false); + return std::nullopt; +} + + diff --git a/zen/file_path.h b/zen/file_path.h new file mode 100644 index 00000000..e328fa8e --- /dev/null +++ b/zen/file_path.h @@ -0,0 +1,27 @@ +// ***************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 * +// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * +// ***************************************************************************** + +#ifndef FILE_PATH_H_3984678473567247567 +#define FILE_PATH_H_3984678473567247567 + +#include "zstring.h" + + +namespace zen +{ +struct PathComponents +{ + Zstring rootPath; //itemPath = rootPath + (FILE_NAME_SEPARATOR?) + relPath + Zstring relPath; // +}; +std::optional<PathComponents> parsePathComponents(const Zstring& itemPath); //no value on failure + +std::optional<Zstring> getParentFolderPath(const Zstring& itemPath); + + +} + +#endif //FILE_PATH_H_3984678473567247567 diff --git a/zen/http.cpp b/zen/http.cpp index f8fb24a3..05ed81d1 100644 --- a/zen/http.cpp +++ b/zen/http.cpp @@ -5,7 +5,6 @@ // ***************************************************************************** #include "http.h" - #include "socket.h" #include "open_ssl.h" diff --git a/zen/resolve_path.cpp b/zen/resolve_path.cpp index 4eab76ee..0a45646e 100644 --- a/zen/resolve_path.cpp +++ b/zen/resolve_path.cpp @@ -8,6 +8,7 @@ #include "time.h" #include "thread.h" #include "file_access.h" +#include "file_path.h" #include <stdlib.h> //getenv() #include <unistd.h> //getcwd() @@ -44,7 +45,7 @@ Zstring resolveRelativePath(const Zstring& relativePath) assert(runningOnMainThread()); /* MSDN: "Multithreaded applications and shared library code should not use the GetFullPathName function and should avoid using relative path names. The current directory state written by the - SetCurrentDirectory function is stored as a global variable in each process, + SetCurrentDirectory function is stored as a global variable in each process, therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads, [...]" => Just plain wrong, there is no data corruption. What MSDN really means: GetFullPathName() is *perfectly* thread-safe, but depends diff --git a/zen/symlink_target.h b/zen/symlink_target.h index 32b1211d..60353292 100644 --- a/zen/symlink_target.h +++ b/zen/symlink_target.h @@ -9,6 +9,7 @@ #include "scope_guard.h" #include "file_error.h" +#include "file_path.h" #include <unistd.h> #include <stdlib.h> //realpath @@ -58,11 +59,15 @@ zen::SymlinkRawContent getSymlinkRawContent_impl(const Zstring& linkPath) //thro Zstring getResolvedSymlinkPath_impl(const Zstring& linkPath) //throw FileError { using namespace zen; - char* targetPath = ::realpath(linkPath.c_str(), nullptr); - if (!targetPath) - THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot determine final path for %x."), L"%x", fmtPath(linkPath)), "realpath"); - ZEN_ON_SCOPE_EXIT(::free(targetPath)); - return targetPath; + try + { + char* targetPath = ::realpath(linkPath.c_str(), nullptr); + if (!targetPath) + THROW_LAST_SYS_ERROR("realpath"); + ZEN_ON_SCOPE_EXIT(::free(targetPath)); + return targetPath; + } + catch (const SysError& e) { throw FileError(replaceCpy(_("Cannot determine final path for %x."), L"%x", fmtPath(linkPath)), e.toString()); } } } diff --git a/zen/zstring.h b/zen/zstring.h index de90c324..1afebe58 100644 --- a/zen/zstring.h +++ b/zen/zstring.h @@ -136,9 +136,9 @@ Zstring getFileExtension(const Zstring& filePath) //common unicode characters -const wchar_t EM_DASH = L'\u2014'; const wchar_t EN_DASH = L'\u2013'; -const wchar_t* const SPACED_DASH = L" \u2013 "; //using 'EN DASH' +const wchar_t EM_DASH = L'\u2014'; +const wchar_t* const SPACED_DASH = L" \u2014 "; //using 'EM DASH' const wchar_t LTR_MARK = L'\u200E'; //UTF-8: E2 80 8E const wchar_t* const ELLIPSIS = L"\u2026"; //"..." const wchar_t MULT_SIGN = L'\u00D7'; //fancy "x" |