]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/common/path_init.c
ok
[xonotic/netradiant.git] / tools / quake2 / common / path_init.c
1 /* -------------------------------------------------------------------------------
2
3 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
4 For a list of contributors, see the accompanying CONTRIBUTORS file.
5
6 This file is part of GtkRadiant.
7
8 GtkRadiant is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 GtkRadiant is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GtkRadiant; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
22 Nurail: Swiped from Q3Map2
23
24 */
25
26
27
28 /* marker */
29 #define PATH_INIT_C
30
31 #if defined( __linux__ ) || defined( __APPLE__ )
32         #define Q_UNIX
33 #endif
34
35 #ifdef Q_UNIX
36         #include <unistd.h>
37         #include <pwd.h>
38         #include <limits.h>
39 #endif
40
41
42 /* dependencies */
43 #include "cmdlib.h"
44 #include "inout.h"
45
46
47
48 /* path support */
49 #define MAX_BASE_PATHS  10
50 #define MAX_GAME_PATHS  10
51
52 char                                    *homePath;
53 char                                    installPath[ MAX_OS_PATH ];
54
55 int                                             numBasePaths;
56 char                                    *basePaths[ MAX_BASE_PATHS ];
57 int                                             numGamePaths;
58 char                                    *gamePaths[ MAX_GAME_PATHS ];
59
60 /*
61 some of this code is based off the original q3map port from loki
62 and finds various paths. moved here from bsp.c for clarity.
63 */
64
65 /*
66 PathLokiGetHomeDir()
67 gets the user's home dir (for ~/.q3a)
68 */
69
70 char *LokiGetHomeDir( void )
71 {
72         #ifndef Q_UNIX
73                 return NULL;
74         #else
75                 char                    *home;
76                 uid_t                   id;
77                 struct passwd   *pwd;
78                 
79                 
80                 /* get the home environment variable */
81                 home = getenv( "HOME" );
82                 if( home == NULL )
83                 {
84                         /* do some more digging */
85                         id = getuid();
86                         setpwent();
87                         while( (pwd = getpwent()) != NULL )
88                         {
89                                 if( pwd->pw_uid == id )
90                                 {
91                                         home = pwd->pw_dir;
92                                         break;
93                                 }
94                         }
95                         endpwent();
96                 }
97                 
98                 /* return it */
99                 return home;
100         #endif
101 }
102
103
104
105 /*
106 PathLokiInitPaths()
107 initializes some paths on linux/os x
108 */
109
110 void LokiInitPaths( char *argv0 )
111 {
112         #ifndef Q_UNIX
113                 /* this is kinda crap, but hey */
114                 strcpy( installPath, "../" );
115         #else
116                 char            temp[ MAX_OS_PATH ];
117                 char            *home;
118                 char            *path;
119                 char            *last;
120                 qboolean        found;
121                 
122                 
123                 /* get home dir */
124                 home = LokiGetHomeDir();
125                 if( home == NULL )
126                         home = ".";
127                 
128                 /* do some path divining */
129                 strcpy( temp, argv0 );
130                 if( strrchr( temp, '/' ) )
131                         argv0 = strrchr( argv0, '/' ) + 1;
132                 else
133                 {
134                         /* get path environment variable */
135                         path = getenv( "PATH" );
136                         
137                         /* minor setup */
138                         last[ 0 ] = path[ 0 ];
139                         last[ 1 ] = '\0';
140                         found = false;
141                         
142                         /* go through each : segment of path */
143                         while( last[ 0 ] != '\0' && found == false )
144                         {
145                                 /* null out temp */
146                                 temp[ 0 ] = '\0';
147                                 
148                                 /* find next chunk */
149                                 last = strchr( path, ':' );
150                                 if( last == NULL )
151                                         last = path + strlen( path );
152                                 
153                                 /* found home dir candidate */
154                                 if( *path == '~' )
155                                 {
156                                         strcpy( temp, home );
157                                         path++;
158                                 }
159                                 
160                                 /* concatenate */
161                                 if( last > (path + 1) )
162                                 {
163                                         strncat( temp, path, (last - path) );
164                                         strcat( temp, "/" );
165                                 }
166                                 strcat( temp, "./" );
167                                 strcat( temp, argv0 );
168                                 
169                                 /* verify the path */
170                                 if( access( temp, X_OK ) == 0 )
171                                         found++;
172                                 path = last + 1;
173                         }
174                 }
175                 
176                 /* flake */
177                 if( realpath( temp, installPath ) )
178                 {
179                         /* q3map is in "tools/" */
180                         *(strrchr( installPath, '/' )) = '\0';
181                         *(strrchr( installPath, '/' ) + 1) = '\0';
182                 }
183                 
184                 /* set home path */
185                 homePath = home;
186         #endif
187 }
188
189
190
191 /*
192 CleanPath() - ydnar
193 cleans a dos path \ -> /
194 */
195
196 void CleanPath( char *path )
197 {
198         while( *path )
199         {
200                 if( *path == '\\' )
201                         *path = '/';
202                 path++;
203         }
204 }
205
206 /*
207 AddBasePath() - ydnar
208 adds a base path to the list
209 */
210
211 void AddBasePath( char *path )
212 {
213         /* dummy check */
214         if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
215                 return;
216         
217         /* add it to the list */
218         basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
219         strcpy( basePaths[ numBasePaths ], path );
220         CleanPath( basePaths[ numBasePaths ] );
221         numBasePaths++;
222 }
223
224
225
226 /*
227 AddHomeBasePath() - ydnar
228 adds a base path to the beginning of the list, prefixed by ~/
229 */
230
231 void AddHomeBasePath( char *path )
232 {
233         #ifdef Q_UNIX
234                 int             i;
235                 char    temp[ MAX_OS_PATH ];
236
237
238                 /* dummy check */
239                 if( path == NULL || path[ 0 ] == '\0' )
240                         return;
241
242                 /* make a hole */
243                 for( i = 0; i < (MAX_BASE_PATHS - 1); i++ )
244                         basePaths[ i + 1 ] = basePaths[ i ];
245                 
246                 /* concatenate home dir and path */
247                 sprintf( temp, "%s/%s", homePath, path );
248                 
249                 /* add it to the list */
250                 basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
251                 strcpy( basePaths[ 0 ], temp );
252                 CleanPath( basePaths[ 0 ] );
253                 numBasePaths++;
254         #endif
255 }
256
257
258
259 /*
260 AddGamePath() - ydnar
261 adds a game path to the list
262 */
263
264 void AddGamePath( char *path )
265 {
266         /* dummy check */
267         if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
268                 return;
269         
270         /* add it to the list */
271         gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
272         strcpy( gamePaths[ numGamePaths ], path );
273         CleanPath( gamePaths[ numGamePaths ] );
274         numGamePaths++;
275 }
276
277
278
279
280 /*
281 InitPaths() - ydnar
282 cleaned up some of the path initialization code from bsp.c
283 will remove any arguments it uses
284 */
285
286 void InitPaths( int *argc, char **argv )
287 {
288         int             i, j, k, len, len2;
289         char    temp[ MAX_OS_PATH ];
290   char gamePath[MAX_OS_PATH], homeBasePath[MAX_OS_PATH], game_magic[10];
291
292   strcpy(gamePath, "baseq2");
293   strcpy(game_magic, "quake");
294   strcpy(homeBasePath, ".quake2");
295         
296         /* note it */
297         Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
298         
299         /* get the install path for backup */
300         LokiInitPaths( argv[ 0 ] );
301
302         /* set game to default (q3a) */
303         numBasePaths = 0;
304         numGamePaths = 0;
305
306         /* parse through the arguments and extract those relevant to paths */
307         for( i = 0; i < *argc; i++ )
308         {
309                 /* check for null */
310                 if( argv[ i ] == NULL )
311                         continue;
312
313                 /* -fs_basepath */
314                 if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
315                 {
316                         if( ++i >= *argc )
317                                 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
318                         argv[ i - 1 ] = NULL;
319                         AddBasePath( argv[ i ] );
320                         argv[ i ] = NULL;
321                 }
322
323         }
324
325         /* remove processed arguments */
326         for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
327         {
328                 for( j; j < *argc && argv[ j ] == NULL; j++ );
329                 argv[ i ] = argv[ j ];
330                 if( argv[ i ] != NULL )
331                         k++;
332         }
333         *argc = k;
334
335         /* add standard game path */
336   AddGamePath( gamePath );
337
338         /* if there is no base path set, figure it out */
339         if( numBasePaths == 0 )
340         {
341                 /* this is another crappy replacement for SetQdirFromPath() */
342     len2 = strlen( game_magic );
343                 for( i = 0; i < *argc && numBasePaths == 0; i++ )
344                 {
345                         /* extract the arg */
346                         strcpy( temp, argv[ i ] );
347                         CleanPath( temp );
348                         len = strlen( temp );
349                         Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game_magic, temp, i );
350
351                         /* this is slow, but only done once */
352                         for( j = 0; j < (len - len2); j++ )
353                         {
354                                 /* check for the game's magic word */
355                                 if( Q_strncasecmp( &temp[ j ], game_magic, len2 ) == 0 )
356                                 {
357                                         /* now find the next slash and nuke everything after it */
358                                         while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
359                                         temp[ j ] = '\0';
360
361                                         /* add this as a base path */
362                                         AddBasePath( temp );
363                                         break;
364                                 }
365                         }
366                 }
367
368                 /* add install path */
369                 if( numBasePaths == 0 )
370                         AddBasePath( installPath );
371
372                 /* check again */
373                 if( numBasePaths == 0 )
374                         Error( "Failed to find a valid base path." );
375         }
376
377         /* this only affects unix */
378         AddHomeBasePath( homeBasePath );
379
380         /* initialize vfs paths */
381         if( numBasePaths > MAX_BASE_PATHS )
382                 numBasePaths = MAX_BASE_PATHS;
383         if( numGamePaths > MAX_GAME_PATHS )
384                 numGamePaths = MAX_GAME_PATHS;
385         
386         /* walk the list of game paths */
387         //for( j = 0; j < numGamePaths; j++ )
388         //{
389                 /* walk the list of base paths */
390         //      for( i = 0; i < numBasePaths; i++ )
391         //      {
392                         /* create a full path and initialize it */
393         //              sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
394         //              vfsInitDirectory( temp );
395         //      }
396         //}
397         
398         /* done */
399         Sys_Printf( "\n" );
400 }
401
402
403
404