blob: deb2894e2b78d2e676b55833be69468aa0362b83 [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
101static void
102join(buffer, stuff)
103 char *buffer;
104 char *stuff;
105{
106 int n, k;
107 if (is_sep(stuff[0]))
108 n = 0;
109 else {
110 n = strlen(buffer);
111 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
112 buffer[n++] = SEP;
113 }
114 k = strlen(stuff);
115 if (n + k > MAXPATHLEN)
116 k = MAXPATHLEN - n;
117 strncpy(buffer+n, stuff, k);
118 buffer[n+k] = '\0';
119}
120
121
122static int
123search_for_prefix(argv0_path, landmark)
124 char *argv0_path;
125 char *landmark;
126{
127 int n;
128
129 /* Search from argv0_path, until root is found */
130 strcpy(prefix, argv0_path);
131 do {
132 n = strlen(prefix);
133 join(prefix, landmark);
Guido van Rossumeea14491997-08-13 21:30:44 +0000134 if (exists(prefix)) {
135 prefix[n] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000136 return 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000137 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000138 prefix[n] = '\0';
139 reduce(prefix);
140 } while (prefix[0]);
141 return 0;
142}
143
Guido van Rossumeea14491997-08-13 21:30:44 +0000144#ifdef MS_WIN32
Guido van Rossum271f9771997-09-29 23:39:31 +0000145#include "malloc.h" // for alloca - see comments below!
146extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
147
Guido van Rossumeea14491997-08-13 21:30:44 +0000148
149/* Load a PYTHONPATH value from the registry.
150 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
151
152 Returns NULL, or a pointer that should be freed.
153*/
154
155static char *
156getpythonregpath(HKEY keyBase, BOOL bWin32s)
157{
158 HKEY newKey = 0;
159 DWORD nameSize = 0;
160 DWORD dataSize = 0;
161 DWORD numEntries = 0;
162 LONG rc;
163 char *retval = NULL;
164 char *dataBuf;
Guido van Rossum271f9771997-09-29 23:39:31 +0000165 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
166 const char keySuffix[] = "\\PythonPath";
167 int versionLen;
168 char *keyBuf;
169
170 // Tried to use sysget("winver") but here is too early :-(
171 versionLen = strlen(PyWin_DLLVersionString);
172 // alloca == no free required, but memory only local to fn.
173 // also no heap fragmentation! Am I being silly?
174 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
175 // lots of constants here for the compiler to optimize away :-)
176 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
177 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
178 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
179
Guido van Rossumeea14491997-08-13 21:30:44 +0000180 rc=RegOpenKey(keyBase,
Guido van Rossum271f9771997-09-29 23:39:31 +0000181 keyBuf,
Guido van Rossumeea14491997-08-13 21:30:44 +0000182 &newKey);
183 if (rc==ERROR_SUCCESS) {
184 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
185 &numEntries, &nameSize, &dataSize, NULL, NULL);
186 }
187 if (bWin32s && numEntries==0 && dataSize==0) {
188 /* must hardcode for Win32s */
189 numEntries = 1;
190 dataSize = 511;
191 }
192 if (numEntries) {
193 /* Loop over all subkeys. */
194 /* Win32s doesnt know how many subkeys, so we do
195 it twice */
196 char keyBuf[MAX_PATH+1];
197 int index = 0;
198 int off = 0;
199 for(index=0;;index++) {
200 long reqdSize = 0;
201 DWORD rc = RegEnumKey(newKey,
202 index, keyBuf, MAX_PATH+1);
203 if (rc) break;
204 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
205 if (rc) break;
206 if (bWin32s && reqdSize==0) reqdSize = 512;
207 dataSize += reqdSize + 1; /* 1 for the ";" */
208 }
209 dataBuf = malloc(dataSize+1);
210 if (dataBuf==NULL)
211 return NULL; /* pretty serious? Raise error? */
212 /* Now loop over, grabbing the paths.
213 Subkeys before main library */
214 for(index=0;;index++) {
215 int adjust;
216 long reqdSize = dataSize;
217 DWORD rc = RegEnumKey(newKey,
218 index, keyBuf,MAX_PATH+1);
219 if (rc) break;
220 rc = RegQueryValue(newKey,
221 keyBuf, dataBuf+off, &reqdSize);
222 if (rc) break;
223 if (reqdSize>1) {
224 /* If Nothing, or only '\0' copied. */
225 adjust = strlen(dataBuf+off);
226 dataSize -= adjust;
227 off += adjust;
228 dataBuf[off++] = ';';
229 dataBuf[off] = '\0';
230 dataSize--;
231 }
232 }
233 /* Additionally, win32s doesnt work as expected, so
234 the specific strlen() is required for 3.1. */
235 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
236 if (rc==ERROR_SUCCESS) {
237 if (strlen(dataBuf)==0)
238 free(dataBuf);
239 else
240 retval = dataBuf; /* caller will free */
241 }
242 else
243 free(dataBuf);
244 }
245
246 if (newKey)
247 RegCloseKey(newKey);
248 return retval;
249}
250#endif /* MS_WIN32 */
251
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000252static void
253get_progpath()
254{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000255 extern char *Py_GetProgramName();
256 char *path = getenv("PATH");
257 char *prog = Py_GetProgramName();
258
Guido van Rossumeea14491997-08-13 21:30:44 +0000259#ifdef MS_WIN32
260 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
261 return;
262#endif
263 if (prog == NULL || *prog == '\0')
264 prog = "python";
265
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000266 /* If there is no slash in the argv0 path, then we have to
267 * assume python is on the user's $PATH, since there's no
268 * other way to find a directory to start the search from. If
269 * $PATH isn't exported, you lose.
270 */
271#ifdef ALTSEP
272 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
273#else
274 if (strchr(prog, SEP))
275#endif
276 strcpy(progpath, prog);
277 else if (path) {
278 while (1) {
279 char *delim = strchr(path, DELIM);
280
281 if (delim) {
282 int len = delim - path;
283 strncpy(progpath, path, len);
284 *(progpath + len) = '\0';
285 }
286 else
287 strcpy(progpath, path);
288
289 join(progpath, prog);
290 if (exists(progpath))
291 break;
292
293 if (!delim) {
294 progpath[0] = '\0';
295 break;
296 }
297 path = delim + 1;
298 }
299 }
300 else
301 progpath[0] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000302}
303
304static void
305calculate_path()
306{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000307 char argv0_path[MAXPATHLEN+1];
308 char *buf;
309 int bufsz;
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000310 char *pythonhome = Py_GetPythonHome();
Guido van Rossumeea14491997-08-13 21:30:44 +0000311 char *envpath = getenv("PYTHONPATH");
312#ifdef MS_WIN32
313 char *machinepath, *userpath;
314
315 /* Are we running under Windows 3.1(1) Win32s? */
316 if (PyWin_IsWin32s()) {
317 /* Only CLASSES_ROOT is supported */
318 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
319 userpath = NULL;
320 } else {
321 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
322 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
323 }
324#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000325
326 get_progpath();
327 strcpy(argv0_path, progpath);
328 reduce(argv0_path);
Guido van Rossumeea14491997-08-13 21:30:44 +0000329 if (pythonhome == NULL || *pythonhome == '\0') {
330 if (search_for_prefix(argv0_path, LANDMARK))
331 pythonhome = prefix;
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000332 else {
333 /* Couldnt find a source version - lets see if a compiled version exists. */
334 char LANDMARK_Look[MAX_PATH+1];
335 strcpy(LANDMARK_Look, LANDMARK);
336 /* Turn it into ".pyc" or ".pyc" depending on the current mode. */
337 strcat(LANDMARK_Look, Py_OptimizeFlag ? "o": "c");
338 /* And search again */
339 if (search_for_prefix(argv0_path, LANDMARK_Look))
340 pythonhome = prefix;
341 else
342 /* Give up in disgust - just use the default! */
343 pythonhome = NULL;
344 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000345 }
346 else
347 strcpy(prefix, pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000348
Guido van Rossumeea14491997-08-13 21:30:44 +0000349 if (envpath && *envpath == '\0')
350 envpath = NULL;
351
352 /* We need to construct a path from the following parts:
353 (1) the PYTHONPATH environment variable, if set;
354 (2) for Win32, the machinepath and userpath, if set;
Guido van Rossum67ab6721998-08-08 19:58:59 +0000355 The following only if neither machinepath nor userpath is set:
Guido van Rossumeea14491997-08-13 21:30:44 +0000356 (3) the PYTHONPATH config macro, with the leading "."
357 of each component replaced with pythonhome, if set;
358 (4) the directory containing the executable (argv0_path).
359 The length calculation calculates #3 first.
360 */
361
362 /* Calculate size of return buffer */
363 if (pythonhome != NULL) {
364 char *p;
365 bufsz = 1;
366 for (p = PYTHONPATH; *p; p++) {
367 if (*p == DELIM)
368 bufsz++; /* number of DELIM plus one */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000369 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000370 bufsz *= strlen(pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000371 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000372 else
373 bufsz = 0;
Guido van Rossum691d2ad1997-12-11 02:32:43 +0000374 bufsz += strlen(PYTHONPATH) + 1;
Guido van Rossum8f1b6511997-08-13 19:55:43 +0000375 bufsz += strlen(argv0_path) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000376#ifdef MS_WIN32
Guido van Rossum67ab6721998-08-08 19:58:59 +0000377 if (userpath || machinepath)
378 bufsz = 0; /* Reset! */
Guido van Rossumeea14491997-08-13 21:30:44 +0000379 if (userpath)
380 bufsz += strlen(userpath) + 1;
Guido van Rossum67ab6721998-08-08 19:58:59 +0000381 if (machinepath)
382 bufsz += strlen(machinepath) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000383#endif
Guido van Rossum67ab6721998-08-08 19:58:59 +0000384 if (envpath != NULL)
385 bufsz += strlen(envpath) + 1;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000386
387 module_search_path = buf = malloc(bufsz);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000388 if (buf == NULL) {
389 /* We can't exit, so print a warning and limp along */
Guido van Rossumeea14491997-08-13 21:30:44 +0000390 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
391 if (envpath) {
392 fprintf(stderr, "Using default static $PYTHONPATH.\n");
393 module_search_path = envpath;
394 }
395 else {
396 fprintf(stderr, "Using environment $PYTHONPATH.\n");
397 module_search_path = PYTHONPATH;
398 }
Guido van Rossum42a97441998-02-19 21:00:45 +0000399#ifdef MS_WIN32
400 if (machinepath)
401 free(machinepath);
402 if (userpath)
403 free(userpath);
404#endif /* MS_WIN32 */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000405 return;
406 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000407
408 if (envpath) {
409 strcpy(buf, envpath);
410 buf = strchr(buf, '\0');
411 *buf++ = DELIM;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000412 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000413#ifdef MS_WIN32
Guido van Rossum67ab6721998-08-08 19:58:59 +0000414 if (userpath) {
415 strcpy(buf, userpath);
416 buf = strchr(buf, '\0');
417 *buf++ = DELIM;
418 free(userpath);
419 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000420 if (machinepath) {
421 strcpy(buf, machinepath);
422 buf = strchr(buf, '\0');
423 *buf++ = DELIM;
Guido van Rossum42a97441998-02-19 21:00:45 +0000424 free(machinepath);
Guido van Rossumeea14491997-08-13 21:30:44 +0000425 }
Guido van Rossum67ab6721998-08-08 19:58:59 +0000426 if (userpath || machinepath) {
427 buf[-1] = '\0';
428 return;
Guido van Rossumeea14491997-08-13 21:30:44 +0000429 }
430#endif
431 if (pythonhome == NULL) {
432 strcpy(buf, PYTHONPATH);
433 buf = strchr(buf, '\0');
434 }
435 else {
436 char *p = PYTHONPATH;
437 char *q;
438 int n;
439 for (;;) {
440 q = strchr(p, DELIM);
441 if (q == NULL)
442 n = strlen(p);
443 else
444 n = q-p;
445 if (p[0] == '.' && is_sep(p[1])) {
446 strcpy(buf, pythonhome);
447 buf = strchr(buf, '\0');
448 p++;
449 n--;
450 }
451 strncpy(buf, p, n);
452 buf += n;
453 if (q == NULL)
454 break;
455 *buf++ = DELIM;
456 p = q+1;
457 }
458 }
459 if (argv0_path) {
460 *buf++ = DELIM;
461 strcpy(buf, argv0_path);
462 buf = strchr(buf, '\0');
463 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000464 *buf = '\0';
465}
466
467
468/* External interface */
469
470char *
471Py_GetPath()
472{
473 if (!module_search_path)
474 calculate_path();
475 return module_search_path;
476}
477
478char *
479Py_GetPrefix()
480{
Guido van Rossumeea14491997-08-13 21:30:44 +0000481 if (!module_search_path)
482 calculate_path();
483 return prefix;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000484}
485
486char *
487Py_GetExecPrefix()
488{
Guido van Rossumeea14491997-08-13 21:30:44 +0000489 return Py_GetPrefix();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000490}
491
492char *
Guido van Rossumeea14491997-08-13 21:30:44 +0000493Py_GetProgramFullPath()
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000494{
495 if (!module_search_path)
496 calculate_path();
497 return progpath;
498}
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000499