1+ use serde:: Serialize ;
12use std:: {
2- env:: consts:: EXE_EXTENSION ,
33 fs,
44 path:: { Path , PathBuf } ,
55} ;
66
7- use serde:: Serialize ;
8-
97/// Windows EXE suffix for unix systems where EXE_SUFFIX is empty, used for wine support
108pub const WINDOWS_EXE_EXTENSION : & str = "exe" ;
119
10+ // This is used to exclude certain file types from being detected as executables. This will match any part of the file extension!
11+ // For example, "file.so.lol" will be excluded because it contains "so"
12+ pub const EXCLUDED_EXE_FILE_EXTENSIONS : [ & str ; 2 ] = [ "ndll" , "so" ] ;
13+
1214/// Allows engine detectors to find out what type of executable they found, used for wine support
1315#[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize ) ]
1416pub enum ExecutableType {
@@ -32,6 +34,63 @@ pub fn get_paths_in_folder(folder_path: &Path) -> Vec<PathBuf> {
3234 vec ! [ ]
3335}
3436
37+ fn get_executable_type ( path : & Path ) -> Option < ExecutableType > {
38+ if path. is_dir ( ) {
39+ return None ;
40+ }
41+
42+ #[ cfg( target_family = "unix" ) ]
43+ {
44+ // First check if it's an ELF binary (with exclusions)
45+ let valid_elf = loop {
46+ if let Some ( ext) = path. extension ( ) {
47+ if let Some ( ext_str) = ext. to_str ( ) {
48+ if EXCLUDED_EXE_FILE_EXTENSIONS . contains ( & ext_str) {
49+ log:: info!(
50+ "Excluded file extension found: {} ({}), skipping ELF check" ,
51+ ext_str,
52+ path. display( )
53+ ) ;
54+ break false ;
55+ }
56+ }
57+ }
58+ break true ;
59+ } ;
60+
61+ if valid_elf {
62+ if let Ok ( mut file) = fs:: File :: open ( path) {
63+ use std:: io:: Read ;
64+ let mut magic_buf = [ 0u8 ; 4 ] ;
65+ if file. read_exact ( & mut magic_buf) . is_ok ( ) && & magic_buf == b"\x7F ELF" {
66+ log:: info!( "ELF executable found: {}" , path. display( ) ) ;
67+ return Some ( ExecutableType :: Platform ) ;
68+ }
69+ }
70+ }
71+
72+ // if not an ELF, check if it has a windows exe suffix for wine support
73+ if let Some ( ext) = path. extension ( ) {
74+ if ext == WINDOWS_EXE_EXTENSION {
75+ log:: info!( "Windows executable found: {}" , path. display( ) ) ;
76+ return Some ( ExecutableType :: WindowsOnUnix ) ;
77+ }
78+ }
79+ }
80+
81+ #[ cfg( target_family = "windows" ) ]
82+ {
83+ if let Some ( ext) = path. extension ( ) {
84+ if ext == "exe" {
85+ log:: info!( "Windows executable found: {}" , path. display( ) ) ;
86+ return Some ( ExecutableType :: Platform ) ;
87+ }
88+ }
89+ }
90+
91+ None
92+ }
93+
3594pub fn get_folders_in_folder ( folder_path : & Path ) -> Vec < String > {
3695 let folders = get_paths_in_folder ( folder_path) ;
3796 let mut found_folders = vec ! [ ] ;
@@ -53,20 +112,8 @@ pub fn check_for_specific_executable(folder_path: &Path, name: String) -> Option
53112 for file in paths {
54113 if let Some ( file_stem) = file. file_stem ( ) {
55114 if !file. is_dir ( ) && * file_stem == * name {
56- if let Some ( ext) = file. extension ( ) {
57- let is_platform_executable = * ext == * EXE_EXTENSION ;
58-
59- if is_platform_executable {
60- return Some ( ExecutableType :: Platform ) ;
61- } else {
62- // A check for .exe on unix systems, since some users use Wine to run the engines
63- #[ cfg( target_family = "unix" ) ]
64- {
65- if * ext == * WINDOWS_EXE_EXTENSION {
66- return Some ( ExecutableType :: WindowsOnUnix ) ;
67- }
68- }
69- }
115+ if let Some ( executable_type) = get_executable_type ( file. as_path ( ) ) {
116+ return Some ( executable_type) ;
70117 }
71118 }
72119 }
@@ -81,22 +128,8 @@ pub fn check_for_any_executable(folder_path: &Path) -> Option<(ExecutableType, P
81128 let mut found_executables: Vec < ( ExecutableType , PathBuf ) > = vec ! [ ] ;
82129
83130 for file in paths {
84- if let Some ( ext) = file. extension ( ) {
85- if !file. is_dir ( ) {
86- let is_platform_executable = * ext == * EXE_EXTENSION ;
87-
88- if is_platform_executable {
89- found_executables. push ( ( ExecutableType :: Platform , file) ) ;
90- } else {
91- // A check for .exe on unix systems, since some users use Wine to run the engines
92- #[ cfg( target_family = "unix" ) ]
93- {
94- if * ext == * WINDOWS_EXE_EXTENSION {
95- found_executables. push ( ( ExecutableType :: WindowsOnUnix , file) ) ;
96- }
97- }
98- }
99- }
131+ if let Some ( executable_type) = get_executable_type ( file. as_path ( ) ) {
132+ found_executables. push ( ( executable_type, file) ) ;
100133 }
101134 }
102135
0 commit comments