1515#include < errno.h>
1616#include < sstream>
1717#include < algorithm>
18- #include < memory>
1918
2019#ifdef _WIN32
2120#include < io.h>
2221#include < direct.h>
2322#include < windows.h>
2423#include < winbase.h> /* needed for memory mapping of file functions */
25- #include < shlwapi.h>
26-
27- struct dir_handle_deleter {
28- typedef HANDLE pointer;
29-
30- void operator ()(HANDLE dirp) {
31- if (dirp != INVALID_HANDLE_VALUE) {
32- FindClose (dirp);
33- }
34- }
35- };
36- typedef std::unique_ptr<HANDLE, dir_handle_deleter> unique_dir_handle_ptr;
3724#endif
3825
3926#ifdef SCP_UNIX
@@ -43,14 +30,6 @@ typedef std::unique_ptr<HANDLE, dir_handle_deleter> unique_dir_handle_ptr;
4330#include < fnmatch.h>
4431#include < sys/stat.h>
4532#include < unistd.h>
46- #include < libgen.h>
47-
48- struct dir_deleter {
49- void operator ()(DIR* dirp) {
50- closedir (dirp);
51- }
52- };
53- typedef std::unique_ptr<DIR, dir_deleter> unique_dir_ptr;
5433#endif
5534
5635#include " cfile/cfile.h"
@@ -59,7 +38,6 @@ typedef std::unique_ptr<DIR, dir_deleter> unique_dir_ptr;
5938#include " globalincs/pstypes.h"
6039#include " localization/localize.h"
6140#include " osapi/osapi.h"
62- #include " parse/parselo.h"
6341
6442#define CF_ROOTTYPE_PATH 0
6543#define CF_ROOTTYPE_PACK 1
@@ -574,62 +552,6 @@ void cf_search_root_path(int root_index)
574552 }
575553
576554#if defined _WIN32
577- {
578- // Check if the case matches the case as specified in Pathtypes
579- // Since Windows paths are case insensitive this wouldn't cause issues here but other
580- // platforms would fail to find data paths in this case so we show a nice error if we detect that here
581-
582- // Ignore the root since the case of that is allowed to differ (it's handled in the mod handling)
583- if (i != CF_TYPE_ROOT) {
584- // We use FindFirstFileNameW for this, it should hopefully work...
585- // First, convert our path from ASCII/UTF-8 to wchar_t
586- std::string search_string = search_path;
587- // Remove any trailing directory separators
588- if (search_string[search_string.size () - 1 ] == ' \\ ' ) {
589- search_string = search_string.substr (0 , search_string.size () - 1 );
590- }
591-
592- char parent_name[MAX_PATH];
593- memset (parent_name, 0 , sizeof (parent_name));
594- strcpy_s (parent_name, search_string.c_str ());
595-
596- CHAR file_name[MAX_PATH];
597- memset (file_name, 0 , sizeof (file_name));
598- strcpy_s (file_name, search_string.c_str ());
599-
600- PathStripPathA (file_name);
601- if (PathRemoveFileSpecA (parent_name)) {
602- strcat_s (parent_name, " \\ *" );
603-
604- WIN32_FIND_DATAA find_data;
605- auto handle = unique_dir_handle_ptr (FindFirstFileA (parent_name, &find_data));
606- if (handle.get () != INVALID_HANDLE_VALUE) {
607- do {
608- if (stricmp (find_data.cFileName , file_name)) {
609- // Not the same name, not even if we check case-insensitive
610- continue ;
611- }
612-
613- // Same name, might have case differences
614- if (!strcmp (find_data.cFileName , file_name)) {
615- // Case matches, everything is alright.
616- continue ;
617- }
618-
619- // We need to do some formatting on the parent_name in order to show a nice error message
620- SCP_string parent_name_str = parent_name;
621- parent_name_str = parent_name_str.substr (0 , parent_name_str.size () - 1 ); // Remove trailing *
622- parent_name_str += find_data.cFileName ;
623-
624- // If we are still here then the case didn't match which means that we have to show the error message
625- Error (LOCATION, " Data directory '%s' for path type '%s' does not match the required case! "
626- " All data directories must exactly match the case specified by the engine or your mod "
627- " will not work on other platforms." , parent_name_str.c_str (), Pathtypes[i].path );
628- } while (FindNextFileA (handle.get (), &find_data) != 0 );
629- }
630- }
631- }
632- }
633555 strcat_s ( search_path, " *.*" );
634556
635557 intptr_t find_handle;
@@ -666,65 +588,21 @@ void cf_search_root_path(int root_index)
666588 _findclose ( find_handle );
667589 }
668590#elif defined SCP_UNIX
669- auto dirp = unique_dir_ptr (opendir (search_path));
670- if (!dirp)
671- {
672- // If the directory does not exist then check if it might exist with a different case. If that's the case
673- // we bail out with an error so inform the user that this is not valid.
674-
675- // On Unix we can have a different case for the search paths so we also need to account for that
676- // We do that by looking at the parent of search_path and enumerating all directories and then check if any of
677- // them are a case-insensitive match
678- char dirname_copy[CF_MAX_PATHNAME_LENGTH];
679- memcpy (dirname_copy, search_path, sizeof (search_path));
680- // According to the documentation of directory_name and basename, the return value does not need to be freed
681- auto directory_name = dirname (dirname_copy);
682-
683- char basename_copy[CF_MAX_PATHNAME_LENGTH];
684- memcpy (basename_copy, search_path, sizeof (search_path));
685- // According to the documentation of dirname and basename, the return value does not need to be freed
686- auto search_name = basename (basename_copy);
687-
688- auto parentDirP = unique_dir_ptr (opendir (directory_name));
689- if (parentDirP) {
690- struct dirent *dir = nullptr ;
691- while ((dir = readdir (parentDirP.get ())) != nullptr ) {
692-
693- if (stricmp (search_name, dir->d_name )) {
694- continue ;
695- }
696-
697- SCP_string fn;
698- sprintf (fn, " %s/%s" , directory_name, dir->d_name );
699-
700- struct stat buf;
701- if (stat (fn.c_str (), &buf) == -1 ) {
702- continue ;
703- }
591+ DIR *dirp;
592+ struct dirent *dir;
704593
705- if (S_ISDIR (buf.st_mode )) {
706- // Found a case insensitive match
707- // If the name is not exactly the same as the one we are currently searching then it's an error
708- if (strcmp (search_name, dir->d_name )) {
709- Error (LOCATION, " Data directory '%s' for path type '%s' does not match the required case! "
710- " All data directories must exactly match the case specified by the engine or your mod "
711- " will not work on other platforms." , fn.c_str (), Pathtypes[i].path );
712- }
713- break ;
714- }
715- }
716- }
717- } else {
718- struct dirent *dir = nullptr ;
719- while ((dir = readdir (dirp.get ())) != NULL )
594+ dirp = opendir (search_path);
595+ if ( dirp ) {
596+ while ((dir = readdir (dirp)) != NULL )
720597 {
721598 if (!fnmatch (" *.*" , dir->d_name , 0 ))
722599 {
723- SCP_string fn;
724- sprintf (fn, " %s%s" , search_path, dir->d_name );
600+ char fn[MAX_PATH];
601+ snprintf (fn, MAX_PATH-1 , " %s%s" , search_path, dir->d_name );
602+ fn[MAX_PATH-1 ] = 0 ;
725603
726604 struct stat buf;
727- if (stat (fn. c_str () , &buf) == -1 ) {
605+ if (stat (fn, &buf) == -1 ) {
728606 continue ;
729607 }
730608
@@ -754,6 +632,7 @@ void cf_search_root_path(int root_index)
754632 }
755633 }
756634 }
635+ closedir (dirp);
757636 }
758637#endif
759638 }
0 commit comments