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