2828#ifdef WIN32
2929 // Linux gcc 4.4.5 memory corruption on destruction of g_StatEvents (Reason unknown)
3030 #include " SharedUtil.hpp"
31+ #else
32+ bool SString::Contains ( const SString& strOther ) const
33+ {
34+ return find ( strOther ) != std::string::npos;
35+ }
36+ SString SharedUtil::GetSystemCurrentDirectory ( void )
37+ {
38+ char szBuffer[ MAX_PATH ];
39+ getcwd ( szBuffer, MAX_PATH - 1 );
40+ return szBuffer;
41+ }
42+ void HandleLinuxLibs ( const SString& strLaunchDirectory, int argc, char * argv [] );
3143#endif
3244
3345using namespace std ;
3446
3547#ifdef WIN32
3648 #ifdef MTA_DEBUG
3749 #define LIB_CORE SERVER_BIN_PATH " core_d.dll"
50+ #define LIB_NET SERVER_BIN_PATH " net_d.dll"
3851 #else
3952 #define LIB_CORE SERVER_BIN_PATH " core.dll"
53+ #define LIB_NET SERVER_BIN_PATH " net.dll"
4054 #endif
4155#else
4256 #ifdef MTA_DEBUG
4357 #define LIB_CORE " ./" SERVER_BIN_PATH " core_d.so"
58+ #define LIB_NET " ./" SERVER_BIN_PATH " net_d.so"
4459 #else
4560 #define LIB_CORE " ./" SERVER_BIN_PATH " core.so"
61+ #define LIB_NET " ./" SERVER_BIN_PATH " net.so"
62+ #endif
63+ #ifdef ANY_x86
64+ #define LINUX_LIBS_PATH " x86/linux-libs"
65+ #else
66+ #define LINUX_LIBS_PATH " x64/linux-libs"
4667 #endif
4768#endif
4869
@@ -51,25 +72,31 @@ int main ( int argc, char* argv [] )
5172 // Work out the launched directory and filename
5273 int iLength = strlen ( argv[0 ] );
5374 char *szLaunchDirectory = static_cast < char * > ( alloca ( iLength + 1 ) );
54- char *szLaunchFile = NULL ;
5575
5676 strncpy ( szLaunchDirectory, argv[0 ], iLength + 1 );
5777
5878 for ( int i = 0 ; i < iLength ; i++ )
5979 if ( szLaunchDirectory[i] == ' \\ ' )
6080 szLaunchDirectory[i] = ' /' ;
6181
82+ SString strLaunchFile, strLaunchDirectory;
6283 if ( char * cpPos = strrchr ( szLaunchDirectory, ' /' ) )
6384 {
6485 *cpPos = 0 ;
65- szLaunchFile = cpPos + 1 ;
86+ strLaunchFile = cpPos + 1 ;
87+ strLaunchDirectory = szLaunchDirectory;
88+ }
89+ else
90+ {
91+ strLaunchFile = szLaunchDirectory;
92+ strLaunchDirectory = " " ;
6693 }
6794
6895 if ( argc > 1 )
6996 {
7097 if ( strcmp ( argv[1 ], " /?" ) == 0 || strcmp ( argv[1 ], " --help" ) == 0 || strcmp ( argv[1 ], " -h" ) == 0 )
7198 {
72- printf ( " Usage: %s [OPTION]\n\n " , szLaunchFile ? szLaunchFile : " mtaserver " );
99+ printf ( " Usage: %s [OPTION]\n\n " , *strLaunchFile );
73100 printf ( " -v Shows the program version\n " );
74101 printf ( " -s Run server in silent mode\n " );
75102#ifndef WIN32
@@ -80,6 +107,8 @@ int main ( int argc, char* argv [] )
80107 printf ( " -n Disable the usage of ncurses (For screenlog)\n " );
81108#ifndef WIN32
82109 printf ( " -x Disable simplified crash reports (To allow core dumps)\n " );
110+ printf ( " -p Always add linux-libs directory to library search path\n " );
111+ printf ( " -q Never add linux-libs directory to library search path\n " );
83112#endif
84113 printf ( " -D [PATH] Use as base directory\n " );
85114 printf ( " --config [FILE] Alternate mtaserver.conf file\n " );
@@ -102,6 +131,8 @@ int main ( int argc, char* argv [] )
102131 cin.get ();
103132 return 1 ;
104133 }
134+ #else
135+ HandleLinuxLibs ( strLaunchDirectory, argc, argv );
105136#endif
106137
107138 // If we are unable to access the core module, try changing to the directory of the launched file
@@ -114,7 +145,7 @@ int main ( int argc, char* argv [] )
114145 PathRemoveFileSpecW ( szBuffer );
115146 SetCurrentDirectoryW ( szBuffer );
116147 #else
117- chdir ( szLaunchDirectory );
148+ chdir ( strLaunchDirectory );
118149 #endif
119150 }
120151 else
@@ -151,3 +182,73 @@ int main ( int argc, char* argv [] )
151182 cin.get ();
152183 return 1 ;
153184}
185+
186+
187+ #ifndef WIN32
188+ //
189+ // Add linux-libs to library search path if either:
190+ // 1. Options don't forbid it (-q)
191+ // 2. Options force it (-p)
192+ // 3. net.so is not loadable
193+ //
194+ void HandleLinuxLibs ( const SString& strLaunchDirectory, int argc, char * argv [] )
195+ {
196+ // Check linux-libs options
197+ bool bUseLinuxLibs = false ;
198+ bool bForbidLinuxLibs = false ;
199+ for ( int i = 1 ; i < argc ; i++ )
200+ {
201+ bUseLinuxLibs |= ( strcmp ( argv[i], " -p" ) == 0 );
202+ bForbidLinuxLibs |= ( strcmp ( argv[i], " -q" ) == 0 );
203+ }
204+
205+ // Is linux-libs forbidden by options?
206+ if ( bForbidLinuxLibs )
207+ return ;
208+
209+ // Calculate absolute path to MTA directory
210+ SString strSavedDir = GetSystemCurrentDirectory ();
211+ chdir ( strLaunchDirectory );
212+ SString strAbsLaunchDirectory = GetSystemCurrentDirectory ();
213+ chdir ( strSavedDir );
214+
215+ if ( !bUseLinuxLibs )
216+ {
217+ // linux-libs not forced by options - Check if net module might need it
218+ void * hModule = dlopen ( strAbsLaunchDirectory + " /" LIB_NET, RTLD_NOW );
219+ if ( hModule )
220+ dlclose ( hModule );
221+ else
222+ bUseLinuxLibs = true ;
223+ }
224+
225+ if ( bUseLinuxLibs )
226+ {
227+ SString strLdLibraryPath = getenv ( " LD_LIBRARY_PATH" );
228+ SString strLinuxLibsPath = strAbsLaunchDirectory + " /" LINUX_LIBS_PATH;
229+
230+ // Check that linux-libs is not already in library path
231+ if ( !strLdLibraryPath.Contains ( strLinuxLibsPath ) )
232+ {
233+ // Add linux-libs to search path
234+ if ( !strLdLibraryPath.empty () )
235+ strLdLibraryPath += " ;" ;
236+ strLdLibraryPath += strLinuxLibsPath;
237+ putenv ( (char *)*( SStringX ( " LD_LIBRARY_PATH=" ) + strLdLibraryPath ) );
238+
239+ // Add -q to ensure linux-libs don't get added again
240+ char ** pArgArray = new char *[argc + 2 ];
241+ for ( int i = 0 ; i <= argc ; i++ )
242+ {
243+ pArgArray[i] = argv[i];
244+ }
245+ char newArg[] = " -q" ;
246+ pArgArray[argc] = newArg;
247+ pArgArray[argc + 1 ] = nullptr ;
248+
249+ // Go for launch #2
250+ execv ( argv[0 ], pArgArray );
251+ }
252+ }
253+ }
254+ #endif
0 commit comments