summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMeway <mewaysid92@gmail.com>2025-06-30 13:24:20 -0500
committerFedja Beader <fedja@protonmail.ch>2025-07-01 19:00:09 +0200
commitdfb709e3da28d1e895b1ef278666a61e890a0c6e (patch)
treec100513e25c77cccbee6b8d89c42613986938f19
parent2c95745f2dfe6a723ffb380e41a193c2a673ad61 (diff)
downloadverse-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.cpp27
-rw-r--r--src/fs/virtfs/fsdir.cpp101
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)