blob: 80865d73d900d1b08ab06ee01020b89dc8018edf [file] [log] [blame]
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32/* Return the initial module search path. */
Guido van Rossumc4995721998-08-08 20:05:31 +000033/* Used by DOS, OS/2, Windows 3.1, Windows 95/98, Windows NT. */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000034
35#include "Python.h"
36#include "osdefs.h"
37
Guido van Rossum8f1b6511997-08-13 19:55:43 +000038#ifdef MS_WIN32
39#include <windows.h>
Guido van Rossumeea14491997-08-13 21:30:44 +000040extern BOOL PyWin_IsWin32s();
Guido van Rossum8f1b6511997-08-13 19:55:43 +000041#endif
42
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000043#include <sys/types.h>
44#include <sys/stat.h>
45#include <string.h>
46
47#if HAVE_UNISTD_H
48#include <unistd.h>
49#endif /* HAVE_UNISTD_H */
50
51/* Search in some common locations for the associated Python libraries.
52 *
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000053 * Py_GetPath() tries to return a sensible Python module search path.
54 *
Guido van Rossum42a97441998-02-19 21:00:45 +000055 * The approach is an adaptation for Windows of the strategy used in
56 * ../Modules/getpath.c; it uses the Windows Registry as one of its
57 * information sources.
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000058 */
59
60#ifndef LANDMARK
Guido van Rossumeea14491997-08-13 21:30:44 +000061#define LANDMARK "lib\\string.py"
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000062#endif
63
64static char prefix[MAXPATHLEN+1];
65static char progpath[MAXPATHLEN+1];
66static char *module_search_path = NULL;
67
Guido van Rossumeea14491997-08-13 21:30:44 +000068
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000069static int
70is_sep(ch) /* determine if "ch" is a separator character */
71 char ch;
72{
73#ifdef ALTSEP
74 return ch == SEP || ch == ALTSEP;
75#else
76 return ch == SEP;
77#endif
78}
79
Guido van Rossumeea14491997-08-13 21:30:44 +000080
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000081static void
82reduce(dir)
83 char *dir;
84{
85 int i = strlen(dir);
86 while (i > 0 && !is_sep(dir[i]))
87 --i;
88 dir[i] = '\0';
89}
90
91
92static int
93exists(filename)
94 char *filename;
95{
96 struct stat buf;
97 return stat(filename, &buf) == 0;
98}
99
100
Guido van Rossum43ff1141998-08-08 23:40:40 +0000101static int
102ismodule(filename) /* Is module -- check for .pyc/.pyo too */
103 char *filename;
104{
105 if (exists(filename))
106 return 1;
107
108 /* Check for the compiled version of prefix. */
109 if (strlen(filename) < MAXPATHLEN) {
110 strcat(filename, Py_OptimizeFlag ? "o" : "c");
111 if (exists(filename))
112 return 1;
113 }
114 return 0;
115}
116
117
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000118static void
119join(buffer, stuff)
120 char *buffer;
121 char *stuff;
122{
123 int n, k;
124 if (is_sep(stuff[0]))
125 n = 0;
126 else {
127 n = strlen(buffer);
128 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
129 buffer[n++] = SEP;
130 }
131 k = strlen(stuff);
132 if (n + k > MAXPATHLEN)
133 k = MAXPATHLEN - n;
134 strncpy(buffer+n, stuff, k);
135 buffer[n+k] = '\0';
136}
137
138
139static int
140search_for_prefix(argv0_path, landmark)
141 char *argv0_path;
142 char *landmark;
143{
144 int n;
145
146 /* Search from argv0_path, until root is found */
147 strcpy(prefix, argv0_path);
148 do {
149 n = strlen(prefix);
150 join(prefix, landmark);
Guido van Rossum43ff1141998-08-08 23:40:40 +0000151 if (ismodule(prefix)) {
Guido van Rossumeea14491997-08-13 21:30:44 +0000152 prefix[n] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000153 return 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000154 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000155 prefix[n] = '\0';
156 reduce(prefix);
157 } while (prefix[0]);
158 return 0;
159}
160
Guido van Rossumeea14491997-08-13 21:30:44 +0000161#ifdef MS_WIN32
Guido van Rossum43ff1141998-08-08 23:40:40 +0000162
163#ifndef BUILD_LANDMARK
164#define BUILD_LANDMARK "PC\\getpathp.c"
165#endif
166
Guido van Rossum271f9771997-09-29 23:39:31 +0000167#include "malloc.h" // for alloca - see comments below!
168extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
169
Guido van Rossumeea14491997-08-13 21:30:44 +0000170
171/* Load a PYTHONPATH value from the registry.
172 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
173
174 Returns NULL, or a pointer that should be freed.
175*/
176
177static char *
178getpythonregpath(HKEY keyBase, BOOL bWin32s)
179{
180 HKEY newKey = 0;
181 DWORD nameSize = 0;
182 DWORD dataSize = 0;
183 DWORD numEntries = 0;
184 LONG rc;
185 char *retval = NULL;
186 char *dataBuf;
Guido van Rossum271f9771997-09-29 23:39:31 +0000187 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
188 const char keySuffix[] = "\\PythonPath";
189 int versionLen;
190 char *keyBuf;
191
192 // Tried to use sysget("winver") but here is too early :-(
193 versionLen = strlen(PyWin_DLLVersionString);
194 // alloca == no free required, but memory only local to fn.
195 // also no heap fragmentation! Am I being silly?
196 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
197 // lots of constants here for the compiler to optimize away :-)
198 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
199 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
200 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
201
Guido van Rossumeea14491997-08-13 21:30:44 +0000202 rc=RegOpenKey(keyBase,
Guido van Rossum271f9771997-09-29 23:39:31 +0000203 keyBuf,
Guido van Rossumeea14491997-08-13 21:30:44 +0000204 &newKey);
205 if (rc==ERROR_SUCCESS) {
206 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
207 &numEntries, &nameSize, &dataSize, NULL, NULL);
208 }
209 if (bWin32s && numEntries==0 && dataSize==0) {
210 /* must hardcode for Win32s */
211 numEntries = 1;
212 dataSize = 511;
213 }
214 if (numEntries) {
215 /* Loop over all subkeys. */
216 /* Win32s doesnt know how many subkeys, so we do
217 it twice */
218 char keyBuf[MAX_PATH+1];
219 int index = 0;
220 int off = 0;
221 for(index=0;;index++) {
222 long reqdSize = 0;
223 DWORD rc = RegEnumKey(newKey,
224 index, keyBuf, MAX_PATH+1);
225 if (rc) break;
226 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
227 if (rc) break;
228 if (bWin32s && reqdSize==0) reqdSize = 512;
229 dataSize += reqdSize + 1; /* 1 for the ";" */
230 }
231 dataBuf = malloc(dataSize+1);
232 if (dataBuf==NULL)
233 return NULL; /* pretty serious? Raise error? */
234 /* Now loop over, grabbing the paths.
235 Subkeys before main library */
236 for(index=0;;index++) {
237 int adjust;
238 long reqdSize = dataSize;
239 DWORD rc = RegEnumKey(newKey,
240 index, keyBuf,MAX_PATH+1);
241 if (rc) break;
242 rc = RegQueryValue(newKey,
243 keyBuf, dataBuf+off, &reqdSize);
244 if (rc) break;
245 if (reqdSize>1) {
246 /* If Nothing, or only '\0' copied. */
247 adjust = strlen(dataBuf+off);
248 dataSize -= adjust;
249 off += adjust;
250 dataBuf[off++] = ';';
251 dataBuf[off] = '\0';
252 dataSize--;
253 }
254 }
255 /* Additionally, win32s doesnt work as expected, so
256 the specific strlen() is required for 3.1. */
257 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
258 if (rc==ERROR_SUCCESS) {
259 if (strlen(dataBuf)==0)
260 free(dataBuf);
261 else
262 retval = dataBuf; /* caller will free */
263 }
264 else
265 free(dataBuf);
266 }
267
268 if (newKey)
269 RegCloseKey(newKey);
270 return retval;
271}
272#endif /* MS_WIN32 */
273
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000274static void
275get_progpath()
276{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000277 extern char *Py_GetProgramName();
278 char *path = getenv("PATH");
279 char *prog = Py_GetProgramName();
280
Guido van Rossumeea14491997-08-13 21:30:44 +0000281#ifdef MS_WIN32
282 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
283 return;
284#endif
285 if (prog == NULL || *prog == '\0')
286 prog = "python";
287
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000288 /* If there is no slash in the argv0 path, then we have to
289 * assume python is on the user's $PATH, since there's no
290 * other way to find a directory to start the search from. If
291 * $PATH isn't exported, you lose.
292 */
293#ifdef ALTSEP
294 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
295#else
296 if (strchr(prog, SEP))
297#endif
298 strcpy(progpath, prog);
299 else if (path) {
300 while (1) {
301 char *delim = strchr(path, DELIM);
302
303 if (delim) {
304 int len = delim - path;
305 strncpy(progpath, path, len);
306 *(progpath + len) = '\0';
307 }
308 else
309 strcpy(progpath, path);
310
311 join(progpath, prog);
312 if (exists(progpath))
313 break;
314
315 if (!delim) {
316 progpath[0] = '\0';
317 break;
318 }
319 path = delim + 1;
320 }
321 }
322 else
323 progpath[0] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000324}
325
326static void
327calculate_path()
328{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000329 char argv0_path[MAXPATHLEN+1];
330 char *buf;
331 int bufsz;
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000332 char *pythonhome = Py_GetPythonHome();
Guido van Rossumeea14491997-08-13 21:30:44 +0000333 char *envpath = getenv("PYTHONPATH");
Guido van Rossumeea14491997-08-13 21:30:44 +0000334
Guido van Rossum43ff1141998-08-08 23:40:40 +0000335#ifdef MS_WIN32
336 char *machinepath = NULL;
337 char *userpath = NULL;
Guido van Rossumeea14491997-08-13 21:30:44 +0000338#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000339
340 get_progpath();
341 strcpy(argv0_path, progpath);
342 reduce(argv0_path);
Guido van Rossumeea14491997-08-13 21:30:44 +0000343 if (pythonhome == NULL || *pythonhome == '\0') {
344 if (search_for_prefix(argv0_path, LANDMARK))
345 pythonhome = prefix;
Guido van Rossum43ff1141998-08-08 23:40:40 +0000346 else
347 pythonhome = NULL;
Guido van Rossumeea14491997-08-13 21:30:44 +0000348 }
349 else
350 strcpy(prefix, pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000351
Guido van Rossumeea14491997-08-13 21:30:44 +0000352 if (envpath && *envpath == '\0')
353 envpath = NULL;
354
Guido van Rossum43ff1141998-08-08 23:40:40 +0000355#ifdef MS_WIN32
Guido van Rossum24edfbb1998-08-11 20:35:56 +0000356 /* Are we running under Windows 3.1(1) Win32s? */
357 if (PyWin_IsWin32s()) {
358 /* Only CLASSES_ROOT is supported */
359 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
360 userpath = NULL;
361 } else {
362 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
363 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
Guido van Rossum43ff1141998-08-08 23:40:40 +0000364 }
365#endif
366
367 /* We need to construct a path from the following parts.
Guido van Rossumeea14491997-08-13 21:30:44 +0000368 (1) the PYTHONPATH environment variable, if set;
369 (2) for Win32, the machinepath and userpath, if set;
370 (3) the PYTHONPATH config macro, with the leading "."
371 of each component replaced with pythonhome, if set;
372 (4) the directory containing the executable (argv0_path).
373 The length calculation calculates #3 first.
Guido van Rossum43ff1141998-08-08 23:40:40 +0000374 Extra rules:
375 - If PYTHONHOME is set (in any way) item (2) is ignored.
376 - If registry values are used, (3) and (4) are ignored.
Guido van Rossumeea14491997-08-13 21:30:44 +0000377 */
378
379 /* Calculate size of return buffer */
380 if (pythonhome != NULL) {
381 char *p;
382 bufsz = 1;
383 for (p = PYTHONPATH; *p; p++) {
384 if (*p == DELIM)
385 bufsz++; /* number of DELIM plus one */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000386 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000387 bufsz *= strlen(pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000388 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000389 else
390 bufsz = 0;
Guido van Rossum691d2ad1997-12-11 02:32:43 +0000391 bufsz += strlen(PYTHONPATH) + 1;
Guido van Rossum8f1b6511997-08-13 19:55:43 +0000392 bufsz += strlen(argv0_path) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000393#ifdef MS_WIN32
Guido van Rossumeea14491997-08-13 21:30:44 +0000394 if (userpath)
395 bufsz += strlen(userpath) + 1;
Guido van Rossum67ab6721998-08-08 19:58:59 +0000396 if (machinepath)
397 bufsz += strlen(machinepath) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000398#endif
Guido van Rossum67ab6721998-08-08 19:58:59 +0000399 if (envpath != NULL)
400 bufsz += strlen(envpath) + 1;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000401
402 module_search_path = buf = malloc(bufsz);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000403 if (buf == NULL) {
404 /* We can't exit, so print a warning and limp along */
Guido van Rossumeea14491997-08-13 21:30:44 +0000405 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
406 if (envpath) {
407 fprintf(stderr, "Using default static $PYTHONPATH.\n");
408 module_search_path = envpath;
409 }
410 else {
411 fprintf(stderr, "Using environment $PYTHONPATH.\n");
412 module_search_path = PYTHONPATH;
413 }
Guido van Rossum42a97441998-02-19 21:00:45 +0000414#ifdef MS_WIN32
415 if (machinepath)
416 free(machinepath);
417 if (userpath)
418 free(userpath);
419#endif /* MS_WIN32 */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000420 return;
421 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000422
423 if (envpath) {
424 strcpy(buf, envpath);
425 buf = strchr(buf, '\0');
426 *buf++ = DELIM;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000427 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000428#ifdef MS_WIN32
Guido van Rossum67ab6721998-08-08 19:58:59 +0000429 if (userpath) {
430 strcpy(buf, userpath);
431 buf = strchr(buf, '\0');
432 *buf++ = DELIM;
433 free(userpath);
434 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000435 if (machinepath) {
436 strcpy(buf, machinepath);
437 buf = strchr(buf, '\0');
438 *buf++ = DELIM;
Guido van Rossum42a97441998-02-19 21:00:45 +0000439 free(machinepath);
Guido van Rossumeea14491997-08-13 21:30:44 +0000440 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000441#endif
442 if (pythonhome == NULL) {
443 strcpy(buf, PYTHONPATH);
444 buf = strchr(buf, '\0');
445 }
446 else {
447 char *p = PYTHONPATH;
448 char *q;
449 int n;
450 for (;;) {
451 q = strchr(p, DELIM);
452 if (q == NULL)
453 n = strlen(p);
454 else
455 n = q-p;
456 if (p[0] == '.' && is_sep(p[1])) {
457 strcpy(buf, pythonhome);
458 buf = strchr(buf, '\0');
459 p++;
460 n--;
461 }
462 strncpy(buf, p, n);
463 buf += n;
464 if (q == NULL)
465 break;
466 *buf++ = DELIM;
467 p = q+1;
468 }
469 }
470 if (argv0_path) {
471 *buf++ = DELIM;
472 strcpy(buf, argv0_path);
473 buf = strchr(buf, '\0');
474 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000475 *buf = '\0';
476}
477
478
479/* External interface */
480
481char *
482Py_GetPath()
483{
484 if (!module_search_path)
485 calculate_path();
486 return module_search_path;
487}
488
489char *
490Py_GetPrefix()
491{
Guido van Rossumeea14491997-08-13 21:30:44 +0000492 if (!module_search_path)
493 calculate_path();
494 return prefix;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000495}
496
497char *
498Py_GetExecPrefix()
499{
Guido van Rossumeea14491997-08-13 21:30:44 +0000500 return Py_GetPrefix();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000501}
502
503char *
Guido van Rossumeea14491997-08-13 21:30:44 +0000504Py_GetProgramFullPath()
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000505{
506 if (!module_search_path)
507 calculate_path();
508 return progpath;
509}
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000510