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