]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/common/path_init.c
5d729f2498edf2fe8cdc6b5b03f25d6f0a618409
[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         #ifndef Q_UNIX
72         return NULL;
73         #else
74         char            *home;
75         uid_t id;
76         struct passwd   *pwd;
77
78
79         /* get the home environment variable */
80         home = getenv( "HOME" );
81         if ( home == NULL ) {
82                 /* do some more digging */
83                 id = getuid();
84                 setpwent();
85                 while ( ( pwd = getpwent() ) != NULL )
86                 {
87                         if ( pwd->pw_uid == id ) {
88                                 home = pwd->pw_dir;
89                                 break;
90                         }
91                 }
92                 endpwent();
93         }
94
95         /* return it */
96         return home;
97         #endif
98 }
99
100
101
102 /*
103    PathLokiInitPaths()
104    initializes some paths on linux/os x
105  */
106
107 void LokiInitPaths( char *argv0 ){
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
125         /* do some path divining */
126         strcpy( temp, argv0 );
127         if ( strrchr( temp, '/' ) ) {
128                 argv0 = strrchr( argv0, '/' ) + 1;
129         }
130         else
131         {
132                 /* get path environment variable */
133                 path = getenv( "PATH" );
134
135                 /* minor setup */
136                 last[ 0 ] = path[ 0 ];
137                 last[ 1 ] = '\0';
138                 found = false;
139
140                 /* go through each : segment of path */
141                 while ( last[ 0 ] != '\0' && found == false )
142                 {
143                         /* null out temp */
144                         temp[ 0 ] = '\0';
145
146                         /* find next chunk */
147                         last = strchr( path, ':' );
148                         if ( last == NULL ) {
149                                 last = path + strlen( path );
150                         }
151
152                         /* found home dir candidate */
153                         if ( *path == '~' ) {
154                                 strcpy( temp, home );
155                                 path++;
156                         }
157
158                         /* concatenate */
159                         if ( last > ( path + 1 ) ) {
160                                 strncat( temp, path, ( last - path ) );
161                                 strcat( temp, "/" );
162                         }
163                         strcat( temp, "./" );
164                         strcat( temp, argv0 );
165
166                         /* verify the path */
167                         if ( access( temp, X_OK ) == 0 ) {
168                                 found++;
169                         }
170                         path = last + 1;
171                 }
172         }
173
174         /* flake */
175         if ( realpath( temp, installPath ) ) {
176                 /* q3map is in "tools/" */
177                 *( strrchr( installPath, '/' ) ) = '\0';
178                 *( strrchr( installPath, '/' ) + 1 ) = '\0';
179         }
180
181         /* set home path */
182         homePath = home;
183         #endif
184 }
185
186
187
188 /*
189    CleanPath() - ydnar
190    cleans a dos path \ -> /
191  */
192
193 void CleanPath( char *path ){
194         while ( *path )
195         {
196                 if ( *path == '\\' ) {
197                         *path = '/';
198                 }
199                 path++;
200         }
201 }
202
203 /*
204    AddBasePath() - ydnar
205    adds a base path to the list
206  */
207
208 void AddBasePath( char *path ){
209         /* dummy check */
210         if ( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS ) {
211                 return;
212         }
213
214         /* add it to the list */
215         basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
216         strcpy( basePaths[ numBasePaths ], path );
217         CleanPath( basePaths[ numBasePaths ] );
218         numBasePaths++;
219 }
220
221
222
223 /*
224    AddHomeBasePath() - ydnar
225    adds a base path to the beginning of the list, prefixed by ~/
226  */
227
228 void AddHomeBasePath( char *path ){
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
239         /* make a hole */
240         for ( i = 0; i < ( MAX_BASE_PATHS - 1 ); i++ )
241                 basePaths[ i + 1 ] = basePaths[ i ];
242
243         /* concatenate home dir and path */
244         sprintf( temp, "%s/%s", homePath, path );
245
246         /* add it to the list */
247         basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
248         strcpy( basePaths[ 0 ], temp );
249         CleanPath( basePaths[ 0 ] );
250         numBasePaths++;
251         #endif
252 }
253
254
255
256 /*
257    AddGamePath() - ydnar
258    adds a game path to the list
259  */
260
261 void AddGamePath( char *path ){
262         /* dummy check */
263         if ( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS ) {
264                 return;
265         }
266
267         /* add it to the list */
268         gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
269         strcpy( gamePaths[ numGamePaths ], path );
270         CleanPath( gamePaths[ numGamePaths ] );
271         numGamePaths++;
272 }
273
274
275
276
277 /*
278    InitPaths() - ydnar
279    cleaned up some of the path initialization code from bsp.c
280    will remove any arguments it uses
281  */
282
283 void InitPaths( int *argc, char **argv ){
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
310                 /* -fs_basepath */
311                 if ( strcmp( argv[ i ], "-fs_basepath" ) == 0 ) {
312                         if ( ++i >= *argc ) {
313                                 Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
314                         }
315                         argv[ i - 1 ] = NULL;
316                         AddBasePath( argv[ i ] );
317                         argv[ i ] = NULL;
318                 }
319
320         }
321
322         /* remove processed arguments */
323         for ( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
324         {
325                 for ( j; j < *argc && argv[ j ] == NULL; j++ ) ;
326                 argv[ i ] = argv[ j ];
327                 if ( argv[ i ] != NULL ) {
328                         k++;
329                 }
330         }
331         *argc = k;
332
333         /* add standard game path */
334         AddGamePath( gamePath );
335
336         /* if there is no base path set, figure it out */
337         if ( numBasePaths == 0 ) {
338                 /* this is another crappy replacement for SetQdirFromPath() */
339                 len2 = strlen( game_magic );
340                 for ( i = 0; i < *argc && numBasePaths == 0; i++ )
341                 {
342                         /* extract the arg */
343                         strcpy( temp, argv[ i ] );
344                         CleanPath( temp );
345                         len = strlen( temp );
346                         Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game_magic, temp, i );
347
348                         /* this is slow, but only done once */
349                         for ( j = 0; j < ( len - len2 ); j++ )
350                         {
351                                 /* check for the game's magic word */
352                                 if ( Q_strncasecmp( &temp[ j ], game_magic, len2 ) == 0 ) {
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
369                 /* check again */
370                 if ( numBasePaths == 0 ) {
371                         Error( "Failed to find a valid base path." );
372                 }
373         }
374
375         /* this only affects unix */
376         AddHomeBasePath( homeBasePath );
377
378         /* initialize vfs paths */
379         if ( numBasePaths > MAX_BASE_PATHS ) {
380                 numBasePaths = MAX_BASE_PATHS;
381         }
382         if ( numGamePaths > MAX_GAME_PATHS ) {
383                 numGamePaths = MAX_GAME_PATHS;
384         }
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 }