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