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