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