diff options
author | Meway <mewaysid92@gmail.com> | 2025-06-30 13:24:20 -0500 |
---|---|---|
committer | Fedja Beader <fedja@protonmail.ch> | 2025-07-01 19:00:09 +0200 |
commit | dfb709e3da28d1e895b1ef278666a61e890a0c6e (patch) | |
tree | c100513e25c77cccbee6b8d89c42613986938f19 | |
parent | 2c95745f2dfe6a723ffb380e41a193c2a673ad61 (diff) | |
download | verse-dfb709e3da28d1e895b1ef278666a61e890a0c6e.tar.gz verse-dfb709e3da28d1e895b1ef278666a61e890a0c6e.tar.bz2 verse-dfb709e3da28d1e895b1ef278666a61e890a0c6e.tar.xz verse-dfb709e3da28d1e895b1ef278666a61e890a0c6e.zip |
Just some changes to compile on windows - symlink handling
1) Maybe bug fix for symlink handling on non-windows: it was checking
directory on each iteration of the loop. Is it supposed to check
directory or each file?
2) Symlink handling on Windows:
Meway said something of the sort: "symlinks do exist, but only admin can
make them" but I can no longer find the exact comment.
-rw-r--r-- | src/fs/files.cpp | 27 | ||||
-rw-r--r-- | src/fs/virtfs/fsdir.cpp | 101 |
2 files changed, 108 insertions, 20 deletions
diff --git a/src/fs/files.cpp b/src/fs/files.cpp index 59fd31f11..c7da4c8b2 100644 --- a/src/fs/files.cpp +++ b/src/fs/files.cpp @@ -18,6 +18,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifdef _WIN32 + #include <windows.h> // for FILEHDEFAULT, FILEOPEN, FILEOPEN_FLAG_READ, + // FILEOPEN_FLAG_WRITE, FILEOPEN_FLAG_APPEND +#else // _WIN32 + #define _POSIX_C_SOURCE 200809L + #include <unistd.h> // for lstat() + #include <sys/stat.h> // for S_ISLNK +#endif #include "fs/files.h" @@ -303,17 +311,32 @@ void Files::enumFiles(StringVect &files, const std::string file = next_file->d_name; if (file == "." || file == "..") continue; + #ifndef _WIN32 if (skipSymlinks == true) { struct stat statbuf; - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) + const std::string fullPath = path + file; + if (lstat(fullPath.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode)) + { + continue; + } + } +#else // _WIN32 + if (skipSymlinks) + { + const std::string fullPath = path + file; + DWORD attrs = GetFileAttributesA(fullPath.c_str()); + if (attrs != INVALID_FILE_ATTRIBUTES && + (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) { + // This is a symlink or junction, skip it continue; } } #endif // _WIN32 + files.push_back(file); } closedir(dir); diff --git a/src/fs/virtfs/fsdir.cpp b/src/fs/virtfs/fsdir.cpp index c623638ca..bf0679050 100644 --- a/src/fs/virtfs/fsdir.cpp +++ b/src/fs/virtfs/fsdir.cpp @@ -18,6 +18,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifdef _WIN32 + #include <windows.h> // for FILEHDEFAULT, FILEOPEN, FILEOPEN_FLAG_READ, + // FILEOPEN_FLAG_WRITE, FILEOPEN_FLAG_APPEND +#else // _WIN32 + #define _POSIX_C_SOURCE 200809L + #include <unistd.h> // for lstat() + #include <sys/stat.h> // for S_ISLNK +#endif #include "fs/virtfs/fsdir.h" @@ -204,17 +212,31 @@ namespace FsDir const std::string file = next_file->d_name; if (file == "." || file == "..") continue; + #ifndef _WIN32 if (mPermitLinks == false) { struct stat statbuf; - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) + const std::string fullPath = path + file; + if (lstat(fullPath.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode)) + { + continue; + } + } +#else // _WIN32 + if (mPermitLinks == false) + { + const std::string fullPath = path + file; + DWORD attrs = GetFileAttributesA(fullPath.c_str()); + if (attrs != INVALID_FILE_ATTRIBUTES && + (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) { + // It's a symlink or junction, skip it continue; } } -#endif // _WIN32 +#endif // !_WIN32 bool found(false); FOR_EACH (StringVectCIter, itn, names) @@ -261,11 +283,20 @@ namespace FsDir return false; struct stat statbuf; - return lstat(name.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0; -#else + return lstat(name.c_str(), &statbuf) == 0 + && S_ISLNK(statbuf.st_mode) != 0; + return false; -#endif // _WIN32 +#else // !_WIN32 + if (mPermitLinks == false) + return false; + + DWORD attrs = GetFileAttributesA(name.c_str()); + if (attrs == INVALID_FILE_ATTRIBUTES) + return false; + + return (attrs & FILE_ATTRIBUTE_REPARSE_POINT) != 0; +#endif // !_WIN32 } void freeList(List *restrict const handle) @@ -549,18 +580,30 @@ namespace FsDir const std::string file = next_file->d_name; if (file == "." || file == "..") continue; + + const std::string filePath = pathJoin(path, file); #ifndef _WIN32 if (mPermitLinks == false) { - if (lstat(path.c_str(), &statbuf) == 0 && + // replace `file` with actual filename variable in context + if (lstat(filePath.c_str(), &statbuf) == 0 && S_ISLNK(statbuf.st_mode) != 0) { continue; } } -#endif // _WIN32 +#else // _WIN32 + if (mPermitLinks == false) + { + DWORD attrs = GetFileAttributesA(filePath.c_str()); + if (attrs != INVALID_FILE_ATTRIBUTES && + (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) + { + continue; + } + } +#endif // !_WIN32 - const std::string filePath = pathJoin(path, file); if (stat(filePath.c_str(), &statbuf) == 0) { if (S_ISDIR(statbuf.st_mode) != 0) @@ -599,18 +642,29 @@ namespace FsDir const std::string file = next_file->d_name; if (file == "." || file == "..") continue; + + const std::string filePath = pathJoin(path, file); #ifndef _WIN32 if (mPermitLinks == false) { - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) + if (lstat(filePath.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode)) + { + continue; + } + } +#else + if (mPermitLinks == false) + { + DWORD attrs = GetFileAttributesA(filePath.c_str()); + if (attrs != INVALID_FILE_ATTRIBUTES && + (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) { continue; } } -#endif // _WIN32 +#endif // !_WIN32 - const std::string filePath = pathJoin(path, file); if (stat(filePath.c_str(), &statbuf) == 0) { if (S_ISDIR(statbuf.st_mode) != 0) @@ -649,18 +703,29 @@ namespace FsDir const std::string file = next_file->d_name; if (file == "." || file == "..") continue; + + const std::string filePath = pathJoin(path, file); #ifndef _WIN32 if (mPermitLinks == false) { - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) + if (lstat(filePath.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode)) { continue; } } -#endif // _WIN32 +#else + if (mPermitLinks == false) + { + DWORD attrs = GetFileAttributesA(filePath.c_str()); + if (attrs != INVALID_FILE_ATTRIBUTES && + (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) + { + continue; + } + } +#endif // !WIN32 - const std::string filePath = pathJoin(path, file); if (stat(filePath.c_str(), &statbuf) == 0) { if (S_ISDIR(statbuf.st_mode) == 0) |