summaryrefslogtreecommitdiff
path: root/zen/file_access.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zen/file_access.cpp')
-rw-r--r--zen/file_access.cpp43
1 files changed, 24 insertions, 19 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp
index 9a49cd55..8f021843 100644
--- a/zen/file_access.cpp
+++ b/zen/file_access.cpp
@@ -101,10 +101,10 @@ ItemType zen::getItemType(const Zstring& itemPath) //throw FileError
THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtPath(itemPath)), "lstat");
if (S_ISLNK(itemInfo.st_mode))
- return ItemType::SYMLINK;
+ return ItemType::symlink;
if (S_ISDIR(itemInfo.st_mode))
- return ItemType::FOLDER;
- return ItemType::FILE; //S_ISREG || S_ISCHR || S_ISBLK || S_ISFIFO || S_ISSOCK
+ return ItemType::folder;
+ return ItemType::file; //S_ISREG || S_ISCHR || S_ISBLK || S_ISFIFO || S_ISSOCK
}
@@ -128,13 +128,13 @@ std::optional<ItemType> zen::itemStillExists(const Zstring& itemPath) //throw Fi
const std::optional<ItemType> parentType = itemStillExists(*parentPath); //throw FileError
- if (parentType && *parentType != ItemType::FILE /*obscure, but possible (and not an error)*/)
+ if (parentType && *parentType != ItemType::file /*obscure, but possible (and not an error)*/)
try
{
traverseFolder(*parentPath,
- [&](const FileInfo& fi) { if (fi.itemName == itemName) throw ItemType::FILE; },
- [&](const FolderInfo& fi) { if (fi.itemName == itemName) throw ItemType::FOLDER; },
- [&](const SymlinkInfo& si) { if (si.itemName == itemName) throw ItemType::SYMLINK; },
+ [&](const FileInfo& fi) { if (fi.itemName == itemName) throw ItemType::file; },
+ [&](const FolderInfo& fi) { if (fi.itemName == itemName) throw ItemType::folder; },
+ [&](const SymlinkInfo& si) { if (si.itemName == itemName) throw ItemType::symlink; },
[](const std::wstring& errorMsg) { throw FileError(errorMsg); });
}
catch (const ItemType&) //finding the item after getItemType() previously failed is exceptional
@@ -171,13 +171,13 @@ namespace
}
-uint64_t zen::getFreeDiskSpace(const Zstring& path) //throw FileError, returns 0 if not available
+int64_t zen::getFreeDiskSpace(const Zstring& path) //throw FileError, returns < 0 if not available
{
struct ::statfs info = {};
if (::statfs(path.c_str(), &info) != 0)
THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot determine free disk space for %x."), L"%x", fmtPath(path)), "statfs");
-
- return static_cast<uint64_t>(info.f_bsize) * info.f_bavail;
+
+ return static_cast<int64_t>(info.f_bsize) * info.f_bavail;
}
@@ -237,7 +237,7 @@ void zen::removeDirectoryPlain(const Zstring& dirPath) //throw FileError
{
ErrorCode ec = getLastError(); //copy before making other system calls!
bool symlinkExists = false;
- try { symlinkExists = getItemType(dirPath) == ItemType::SYMLINK; } /*throw FileError*/ catch (FileError&) {} //previous exception is more relevant
+ try { symlinkExists = getItemType(dirPath) == ItemType::symlink; } /*throw FileError*/ catch (FileError&) {} //previous exception is more relevant
if (symlinkExists)
{
@@ -288,7 +288,7 @@ void removeDirectoryImpl(const Zstring& folderPath) //throw FileError
void zen::removeDirectoryPlainRecursion(const Zstring& dirPath) //throw FileError
{
- if (getItemType(dirPath) == ItemType::SYMLINK) //throw FileError
+ if (getItemType(dirPath) == ItemType::symlink) //throw FileError
removeSymlinkPlain(dirPath); //throw FileError
else
removeDirectoryImpl(dirPath); //throw FileError
@@ -503,7 +503,7 @@ void zen::copyItemPermissions(const Zstring& sourcePath, const Zstring& targetPa
if (::lchown(targetPath.c_str(), fileInfo.st_uid, fileInfo.st_gid) != 0) // may require admin rights!
THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot write permissions of %x."), L"%x", fmtPath(targetPath)), "lchown");
- const bool isSymlinkTarget = getItemType(targetPath) == ItemType::SYMLINK; //throw FileError
+ const bool isSymlinkTarget = getItemType(targetPath) == ItemType::symlink; //throw FileError
if (!isSymlinkTarget && //setting access permissions doesn't make sense for symlinks on Linux: there is no lchmod()
::chmod(targetPath.c_str(), fileInfo.st_mode) != 0)
THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot write permissions of %x."), L"%x", fmtPath(targetPath)), "chmod");
@@ -516,10 +516,15 @@ void zen::createDirectory(const Zstring& dirPath) //throw FileError, ErrorTarget
{
auto getErrorMsg = [&] { return replaceCpy(_("Cannot create directory %x."), L"%x", fmtPath(dirPath)); };
- //deliberately don't support creating irregular folders like "...." https://social.technet.microsoft.com/Forums/windows/en-US/ffee2322-bb6b-4fdf-86f9-8f93cf1fa6cb/
- if (endsWith(dirPath, Zstr(' ')) ||
- endsWith(dirPath, Zstr('.')))
- throw FileError(getErrorMsg(), replaceCpy<std::wstring>(L"Invalid trailing character \"%x\".", L"%x", utfTo<std::wstring>(dirPath.end()[-1])));
+ //don't allow creating irregular folders like "...." https://social.technet.microsoft.com/Forums/windows/en-US/ffee2322-bb6b-4fdf-86f9-8f93cf1fa6cb/
+ const Zstring dirName = afterLast(dirPath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_ALL);
+ if (std::all_of(dirName.begin(), dirName.end(), [](Zchar c) { return c == Zstr('.'); }))
+ /**/throw FileError(getErrorMsg(), replaceCpy<std::wstring>(L"Invalid folder name %x.", L"%x", fmtPath(dirName)));
+
+ //not critical, but will visually confuse user sooner or later:
+ if (startsWith(dirName, Zstr(' ')) ||
+ endsWith (dirName, Zstr(' ')))
+ throw FileError(getErrorMsg(), replaceCpy<std::wstring>(L"Folder name %x starts/ends with space character.", L"%x", fmtPath(dirName)));
const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; //0777, default for newly created directories
@@ -545,7 +550,7 @@ void zen::createDirectoryIfMissingRecursion(const Zstring& dirPath) //throw File
try //generally we expect that path already exists (see: ffs_paths.cpp) => check first
{
- if (getItemType(dirPath) != ItemType::FILE) //throw FileError
+ if (getItemType(dirPath) != ItemType::file) //throw FileError
return;
}
catch (FileError&) {} //not yet existing or access error? let's find out...
@@ -560,7 +565,7 @@ void zen::createDirectoryIfMissingRecursion(const Zstring& dirPath) //throw File
{
try
{
- if (getItemType(dirPath) != ItemType::FILE) //throw FileError
+ if (getItemType(dirPath) != ItemType::file) //throw FileError
return; //already existing => possible, if createDirectoryIfMissingRecursion() is run in parallel
}
catch (FileError&) {} //not yet existing or access error
bgstack15