28
28
#ifdef WIN32
29
29
// Linux gcc 4.4.5 memory corruption on destruction of g_StatEvents (Reason unknown)
30
30
#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 [] );
31
43
#endif
32
44
33
45
using namespace std ;
34
46
35
47
#ifdef WIN32
36
48
#ifdef MTA_DEBUG
37
49
#define LIB_CORE SERVER_BIN_PATH " core_d.dll"
50
+ #define LIB_NET SERVER_BIN_PATH " net_d.dll"
38
51
#else
39
52
#define LIB_CORE SERVER_BIN_PATH " core.dll"
53
+ #define LIB_NET SERVER_BIN_PATH " net.dll"
40
54
#endif
41
55
#else
42
56
#ifdef MTA_DEBUG
43
57
#define LIB_CORE " ./" SERVER_BIN_PATH " core_d.so"
58
+ #define LIB_NET " ./" SERVER_BIN_PATH " net_d.so"
44
59
#else
45
60
#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"
46
67
#endif
47
68
#endif
48
69
@@ -51,25 +72,31 @@ int main ( int argc, char* argv [] )
51
72
// Work out the launched directory and filename
52
73
int iLength = strlen ( argv[0 ] );
53
74
char *szLaunchDirectory = static_cast < char * > ( alloca ( iLength + 1 ) );
54
- char *szLaunchFile = NULL ;
55
75
56
76
strncpy ( szLaunchDirectory, argv[0 ], iLength + 1 );
57
77
58
78
for ( int i = 0 ; i < iLength ; i++ )
59
79
if ( szLaunchDirectory[i] == ' \\ ' )
60
80
szLaunchDirectory[i] = ' /' ;
61
81
82
+ SString strLaunchFile, strLaunchDirectory;
62
83
if ( char * cpPos = strrchr ( szLaunchDirectory, ' /' ) )
63
84
{
64
85
*cpPos = 0 ;
65
- szLaunchFile = cpPos + 1 ;
86
+ strLaunchFile = cpPos + 1 ;
87
+ strLaunchDirectory = szLaunchDirectory;
88
+ }
89
+ else
90
+ {
91
+ strLaunchFile = szLaunchDirectory;
92
+ strLaunchDirectory = " " ;
66
93
}
67
94
68
95
if ( argc > 1 )
69
96
{
70
97
if ( strcmp ( argv[1 ], " /?" ) == 0 || strcmp ( argv[1 ], " --help" ) == 0 || strcmp ( argv[1 ], " -h" ) == 0 )
71
98
{
72
- printf ( " Usage: %s [OPTION]\n\n " , szLaunchFile ? szLaunchFile : " mtaserver " );
99
+ printf ( " Usage: %s [OPTION]\n\n " , *strLaunchFile );
73
100
printf ( " -v Shows the program version\n " );
74
101
printf ( " -s Run server in silent mode\n " );
75
102
#ifndef WIN32
@@ -80,6 +107,8 @@ int main ( int argc, char* argv [] )
80
107
printf ( " -n Disable the usage of ncurses (For screenlog)\n " );
81
108
#ifndef WIN32
82
109
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 " );
83
112
#endif
84
113
printf ( " -D [PATH] Use as base directory\n " );
85
114
printf ( " --config [FILE] Alternate mtaserver.conf file\n " );
@@ -102,6 +131,8 @@ int main ( int argc, char* argv [] )
102
131
cin.get ();
103
132
return 1 ;
104
133
}
134
+ #else
135
+ HandleLinuxLibs ( strLaunchDirectory, argc, argv );
105
136
#endif
106
137
107
138
// 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 [] )
114
145
PathRemoveFileSpecW ( szBuffer );
115
146
SetCurrentDirectoryW ( szBuffer );
116
147
#else
117
- chdir ( szLaunchDirectory );
148
+ chdir ( strLaunchDirectory );
118
149
#endif
119
150
}
120
151
else
@@ -151,3 +182,73 @@ int main ( int argc, char* argv [] )
151
182
cin.get ();
152
183
return 1 ;
153
184
}
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