blob: 607f2a192a56a327d16d317f187132081fa9e3f3 [file] [log] [blame]
Guido van Rossum50d4cc21997-11-22 21:59:45 +00001
2/* Return the initial module search path. */
3/* Used by DOS, OS/2, Windows 3.1. Works on NT too. */
4
5#include "Python.h"
6#include "osdefs.h"
7
8#ifdef MS_WIN32
9#include <windows.h>
Thomas Woutersa5345942000-07-22 23:59:33 +000010extern BOOL PyWin_IsWin32s(void);
Guido van Rossum50d4cc21997-11-22 21:59:45 +000011#endif
12
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <string.h>
16
17#if HAVE_UNISTD_H
18#include <unistd.h>
19#endif /* HAVE_UNISTD_H */
20
21/* Search in some common locations for the associated Python libraries.
22 *
Guido van Rossuma34c3131997-12-05 22:07:14 +000023 * Two directories must be found, the platform independent directory
24 * (prefix), containing the common .py and .pyc files, and the platform
25 * dependent directory (exec_prefix), containing the shared library
26 * modules. Note that prefix and exec_prefix can be the same directory,
27 * but for some installations, they are different.
Guido van Rossum50d4cc21997-11-22 21:59:45 +000028 *
29 * Py_GetPath() tries to return a sensible Python module search path.
30 *
31 * First, we look to see if the executable is in a subdirectory of
32 * the Python build directory. We calculate the full path of the
33 * directory containing the executable as progpath. We work backwards
34 * along progpath and look for $dir/Modules/Setup.in, a distinctive
35 * landmark. If found, we use $dir/Lib as $root. The returned
36 * Python path is the compiled #define PYTHONPATH with all the initial
37 * "./lib" replaced by $root.
38 *
39 * Otherwise, if there is a PYTHONPATH environment variable, we return that.
40 *
Jeremy Hylton847a9962000-05-26 21:49:07 +000041 * Otherwise we try to find $progpath/lib/os.py, and if found, then
Guido van Rossum50d4cc21997-11-22 21:59:45 +000042 * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
43 * with all "./lib" replaced by $root (as above).
44 *
45 */
46
47#ifndef LANDMARK
Jeremy Hylton847a9962000-05-26 21:49:07 +000048#define LANDMARK "lib\\os.py"
Guido van Rossum50d4cc21997-11-22 21:59:45 +000049#endif
50
51static char prefix[MAXPATHLEN+1];
Guido van Rossuma34c3131997-12-05 22:07:14 +000052static char exec_prefix[MAXPATHLEN+1];
Guido van Rossum50d4cc21997-11-22 21:59:45 +000053static char progpath[MAXPATHLEN+1];
54static char *module_search_path = NULL;
55
56
57static int
Thomas Wouters78890102000-07-22 19:25:51 +000058is_sep(char ch) /* determine if "ch" is a separator character */
Guido van Rossum50d4cc21997-11-22 21:59:45 +000059{
60#ifdef ALTSEP
61 return ch == SEP || ch == ALTSEP;
62#else
63 return ch == SEP;
64#endif
65}
66
67
68static void
Thomas Wouters78890102000-07-22 19:25:51 +000069reduce(char *dir)
Guido van Rossum50d4cc21997-11-22 21:59:45 +000070{
71 int i = strlen(dir);
72 while (i > 0 && !is_sep(dir[i]))
73 --i;
74 dir[i] = '\0';
75}
76
77
78static int
Thomas Wouters78890102000-07-22 19:25:51 +000079exists(char *filename)
Guido van Rossum50d4cc21997-11-22 21:59:45 +000080{
81 struct stat buf;
82 return stat(filename, &buf) == 0;
83}
84
85
Andrew MacIntyred0278ec2004-12-12 08:28:11 +000086/* Add a path component, by appending stuff to buffer.
87 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
88 NUL-terminated string with no more than MAXPATHLEN characters (not counting
89 the trailing NUL). It's a fatal error if it contains a string longer than
90 that (callers must be careful!). If these requirements are met, it's
91 guaranteed that buffer will still be a NUL-terminated string with no more
92 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
93 stuff as fits will be appended.
94*/
Guido van Rossum50d4cc21997-11-22 21:59:45 +000095static void
Thomas Wouters78890102000-07-22 19:25:51 +000096join(char *buffer, char *stuff)
Guido van Rossum50d4cc21997-11-22 21:59:45 +000097{
98 int n, k;
99 if (is_sep(stuff[0]))
100 n = 0;
101 else {
102 n = strlen(buffer);
103 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
104 buffer[n++] = SEP;
105 }
Andrew MacIntyred0278ec2004-12-12 08:28:11 +0000106 if (n > MAXPATHLEN)
107 Py_FatalError("buffer overflow in getpathp.c's joinpath()");
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000108 k = strlen(stuff);
109 if (n + k > MAXPATHLEN)
110 k = MAXPATHLEN - n;
111 strncpy(buffer+n, stuff, k);
112 buffer[n+k] = '\0';
113}
114
115
116static int
Thomas Wouters78890102000-07-22 19:25:51 +0000117search_for_prefix(char *argv0_path, char *landmark)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000118{
119 int n;
120
121 /* Search from argv0_path, until root is found */
122 strcpy(prefix, argv0_path);
123 do {
124 n = strlen(prefix);
125 join(prefix, landmark);
126 if (exists(prefix)) {
127 prefix[n] = '\0';
128 return 1;
129 }
130 prefix[n] = '\0';
131 reduce(prefix);
132 } while (prefix[0]);
133 return 0;
134}
135
136#ifdef MS_WIN32
137#include "malloc.h" // for alloca - see comments below!
138extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
139
140
141/* Load a PYTHONPATH value from the registry.
142 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
143
144 Returns NULL, or a pointer that should be freed.
145*/
146
147static char *
148getpythonregpath(HKEY keyBase, BOOL bWin32s)
149{
150 HKEY newKey = 0;
151 DWORD nameSize = 0;
152 DWORD dataSize = 0;
153 DWORD numEntries = 0;
154 LONG rc;
155 char *retval = NULL;
156 char *dataBuf;
157 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
158 const char keySuffix[] = "\\PythonPath";
159 int versionLen;
160 char *keyBuf;
161
162 // Tried to use sysget("winver") but here is too early :-(
163 versionLen = strlen(PyWin_DLLVersionString);
164 // alloca == no free required, but memory only local to fn.
165 // also no heap fragmentation! Am I being silly?
166 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
167 // lots of constants here for the compiler to optimize away :-)
168 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
169 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
170 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
171
172 rc=RegOpenKey(keyBase,
173 keyBuf,
174 &newKey);
175 if (rc==ERROR_SUCCESS) {
176 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
177 &numEntries, &nameSize, &dataSize, NULL, NULL);
178 }
179 if (bWin32s && numEntries==0 && dataSize==0) {
180 /* must hardcode for Win32s */
181 numEntries = 1;
182 dataSize = 511;
183 }
184 if (numEntries) {
185 /* Loop over all subkeys. */
186 /* Win32s doesnt know how many subkeys, so we do
187 it twice */
188 char keyBuf[MAX_PATH+1];
189 int index = 0;
190 int off = 0;
191 for(index=0;;index++) {
192 long reqdSize = 0;
193 DWORD rc = RegEnumKey(newKey,
194 index, keyBuf, MAX_PATH+1);
195 if (rc) break;
196 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
197 if (rc) break;
198 if (bWin32s && reqdSize==0) reqdSize = 512;
199 dataSize += reqdSize + 1; /* 1 for the ";" */
200 }
201 dataBuf = malloc(dataSize+1);
202 if (dataBuf==NULL)
203 return NULL; /* pretty serious? Raise error? */
204 /* Now loop over, grabbing the paths.
205 Subkeys before main library */
206 for(index=0;;index++) {
207 int adjust;
208 long reqdSize = dataSize;
209 DWORD rc = RegEnumKey(newKey,
210 index, keyBuf,MAX_PATH+1);
211 if (rc) break;
212 rc = RegQueryValue(newKey,
213 keyBuf, dataBuf+off, &reqdSize);
214 if (rc) break;
215 if (reqdSize>1) {
216 /* If Nothing, or only '\0' copied. */
217 adjust = strlen(dataBuf+off);
218 dataSize -= adjust;
219 off += adjust;
220 dataBuf[off++] = ';';
221 dataBuf[off] = '\0';
222 dataSize--;
223 }
224 }
225 /* Additionally, win32s doesnt work as expected, so
226 the specific strlen() is required for 3.1. */
227 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
228 if (rc==ERROR_SUCCESS) {
229 if (strlen(dataBuf)==0)
230 free(dataBuf);
231 else
232 retval = dataBuf; /* caller will free */
233 }
234 else
235 free(dataBuf);
236 }
237
238 if (newKey)
239 RegCloseKey(newKey);
240 return retval;
241}
242#endif /* MS_WIN32 */
243
244static void
Thomas Wouters78890102000-07-22 19:25:51 +0000245get_progpath(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000246{
Thomas Woutersa5345942000-07-22 23:59:33 +0000247 extern char *Py_GetProgramName(void);
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000248 char *path = getenv("PATH");
249 char *prog = Py_GetProgramName();
250
251#ifdef MS_WIN32
252 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
253 return;
254#endif
255 if (prog == NULL || *prog == '\0')
256 prog = "python";
257
258 /* If there is no slash in the argv0 path, then we have to
259 * assume python is on the user's $PATH, since there's no
260 * other way to find a directory to start the search from. If
261 * $PATH isn't exported, you lose.
262 */
263#ifdef ALTSEP
264 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
265#else
266 if (strchr(prog, SEP))
267#endif
268 strcpy(progpath, prog);
269 else if (path) {
270 while (1) {
271 char *delim = strchr(path, DELIM);
272
273 if (delim) {
274 int len = delim - path;
275 strncpy(progpath, path, len);
276 *(progpath + len) = '\0';
277 }
278 else
279 strcpy(progpath, path);
280
281 join(progpath, prog);
282 if (exists(progpath))
283 break;
284
285 if (!delim) {
286 progpath[0] = '\0';
287 break;
288 }
289 path = delim + 1;
290 }
291 }
292 else
293 progpath[0] = '\0';
294}
295
296static void
Thomas Wouters78890102000-07-22 19:25:51 +0000297calculate_path(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000298{
299 char argv0_path[MAXPATHLEN+1];
300 char *buf;
301 int bufsz;
Guido van Rossum28700c41998-07-27 13:49:04 +0000302 char *pythonhome = Py_GetPythonHome();
Neil Schemenauer7d4bb9f2001-07-23 16:30:27 +0000303 char *envpath = Py_GETENV("PYTHONPATH");
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000304#ifdef MS_WIN32
305 char *machinepath, *userpath;
306
307 /* Are we running under Windows 3.1(1) Win32s? */
308 if (PyWin_IsWin32s()) {
309 /* Only CLASSES_ROOT is supported */
310 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
311 userpath = NULL;
312 } else {
313 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
314 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
315 }
316#endif
317
318 get_progpath();
319 strcpy(argv0_path, progpath);
320 reduce(argv0_path);
321 if (pythonhome == NULL || *pythonhome == '\0') {
322 if (search_for_prefix(argv0_path, LANDMARK))
323 pythonhome = prefix;
324 else
325 pythonhome = NULL;
326 }
Guido van Rossuma34c3131997-12-05 22:07:14 +0000327 else {
328 char *delim;
329
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000330 strcpy(prefix, pythonhome);
331
Guido van Rossuma34c3131997-12-05 22:07:14 +0000332 /* Extract Any Optional Trailing EXEC_PREFIX */
333 /* e.g. PYTHONHOME=<prefix>:<exec_prefix> */
334 delim = strchr(prefix, DELIM);
335 if (delim) {
336 *delim = '\0';
337 strcpy(exec_prefix, delim+1);
338 } else
339 strcpy(exec_prefix, EXEC_PREFIX);
340 }
341
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000342 if (envpath && *envpath == '\0')
343 envpath = NULL;
344
345 /* We need to construct a path from the following parts:
346 (1) the PYTHONPATH environment variable, if set;
347 (2) for Win32, the machinepath and userpath, if set;
348 (3) the PYTHONPATH config macro, with the leading "."
349 of each component replaced with pythonhome, if set;
350 (4) the directory containing the executable (argv0_path).
351 The length calculation calculates #3 first.
352 */
353
354 /* Calculate size of return buffer */
355 if (pythonhome != NULL) {
356 char *p;
357 bufsz = 1;
358 for (p = PYTHONPATH; *p; p++) {
359 if (*p == DELIM)
360 bufsz++; /* number of DELIM plus one */
361 }
362 bufsz *= strlen(pythonhome);
363 }
364 else
365 bufsz = 0;
Guido van Rossumd0ec7611997-12-11 15:21:33 +0000366 bufsz += strlen(PYTHONPATH) + 1;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000367 if (envpath != NULL)
368 bufsz += strlen(envpath) + 1;
369 bufsz += strlen(argv0_path) + 1;
370#ifdef MS_WIN32
371 if (machinepath)
372 bufsz += strlen(machinepath) + 1;
373 if (userpath)
374 bufsz += strlen(userpath) + 1;
375#endif
376
377 module_search_path = buf = malloc(bufsz);
378 if (buf == NULL) {
379 /* We can't exit, so print a warning and limp along */
380 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
381 if (envpath) {
382 fprintf(stderr, "Using default static $PYTHONPATH.\n");
383 module_search_path = envpath;
384 }
385 else {
386 fprintf(stderr, "Using environment $PYTHONPATH.\n");
387 module_search_path = PYTHONPATH;
388 }
389 return;
390 }
391
392 if (envpath) {
393 strcpy(buf, envpath);
394 buf = strchr(buf, '\0');
395 *buf++ = DELIM;
396 }
397#ifdef MS_WIN32
398 if (machinepath) {
399 strcpy(buf, machinepath);
400 buf = strchr(buf, '\0');
401 *buf++ = DELIM;
402 }
403 if (userpath) {
404 strcpy(buf, userpath);
405 buf = strchr(buf, '\0');
406 *buf++ = DELIM;
407 }
408#endif
409 if (pythonhome == NULL) {
410 strcpy(buf, PYTHONPATH);
411 buf = strchr(buf, '\0');
412 }
413 else {
414 char *p = PYTHONPATH;
415 char *q;
416 int n;
417 for (;;) {
418 q = strchr(p, DELIM);
419 if (q == NULL)
420 n = strlen(p);
421 else
422 n = q-p;
423 if (p[0] == '.' && is_sep(p[1])) {
424 strcpy(buf, pythonhome);
425 buf = strchr(buf, '\0');
426 p++;
427 n--;
428 }
429 strncpy(buf, p, n);
430 buf += n;
431 if (q == NULL)
432 break;
433 *buf++ = DELIM;
434 p = q+1;
435 }
436 }
437 if (argv0_path) {
438 *buf++ = DELIM;
439 strcpy(buf, argv0_path);
440 buf = strchr(buf, '\0');
441 }
442 *buf = '\0';
443}
444
445
446/* External interface */
447
448char *
Thomas Wouters78890102000-07-22 19:25:51 +0000449Py_GetPath(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000450{
451 if (!module_search_path)
452 calculate_path();
453
454 return module_search_path;
455}
456
457char *
Thomas Wouters78890102000-07-22 19:25:51 +0000458Py_GetPrefix(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000459{
460 if (!module_search_path)
461 calculate_path();
462
463 return prefix;
464}
465
466char *
Thomas Wouters78890102000-07-22 19:25:51 +0000467Py_GetExecPrefix(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000468{
Guido van Rossuma34c3131997-12-05 22:07:14 +0000469 if (!module_search_path)
470 calculate_path();
471
472 return exec_prefix;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000473}
474
475char *
Thomas Wouters78890102000-07-22 19:25:51 +0000476Py_GetProgramFullPath(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000477{
478 if (!module_search_path)
479 calculate_path();
480
481 return progpath;
482}