blob: 7c4d1218294025eec0e7a451bcf11f7f437a7c26 [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
Guido van Rossume02e48b2000-03-29 01:49:47 +0000140gotlandmark(landmark)
141 char *landmark;
142{
143 int n, ok;
144
145 n = strlen(prefix);
146 join(prefix, landmark);
147 ok = ismodule(prefix);
148 prefix[n] = '\0';
149 return ok;
150}
151
152
153static int
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000154search_for_prefix(argv0_path, landmark)
155 char *argv0_path;
156 char *landmark;
157{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000158
Guido van Rossume02e48b2000-03-29 01:49:47 +0000159 /* Search from argv0_path, until landmark is found */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000160 strcpy(prefix, argv0_path);
161 do {
Guido van Rossume02e48b2000-03-29 01:49:47 +0000162 if (gotlandmark(landmark))
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000163 return 1;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000164 reduce(prefix);
165 } while (prefix[0]);
166 return 0;
167}
168
Guido van Rossumeea14491997-08-13 21:30:44 +0000169#ifdef MS_WIN32
Guido van Rossum43ff1141998-08-08 23:40:40 +0000170
171#ifndef BUILD_LANDMARK
172#define BUILD_LANDMARK "PC\\getpathp.c"
173#endif
174
Guido van Rossum271f9771997-09-29 23:39:31 +0000175#include "malloc.h" // for alloca - see comments below!
176extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
177
Guido van Rossumeea14491997-08-13 21:30:44 +0000178
179/* Load a PYTHONPATH value from the registry.
180 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
181
182 Returns NULL, or a pointer that should be freed.
183*/
184
185static char *
Guido van Rossume02e48b2000-03-29 01:49:47 +0000186getpythonregpath(HKEY keyBase)
Guido van Rossumeea14491997-08-13 21:30:44 +0000187{
188 HKEY newKey = 0;
189 DWORD nameSize = 0;
190 DWORD dataSize = 0;
191 DWORD numEntries = 0;
192 LONG rc;
193 char *retval = NULL;
194 char *dataBuf;
Guido van Rossum271f9771997-09-29 23:39:31 +0000195 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
196 const char keySuffix[] = "\\PythonPath";
197 int versionLen;
198 char *keyBuf;
199
200 // Tried to use sysget("winver") but here is too early :-(
201 versionLen = strlen(PyWin_DLLVersionString);
202 // alloca == no free required, but memory only local to fn.
203 // also no heap fragmentation! Am I being silly?
204 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
205 // lots of constants here for the compiler to optimize away :-)
206 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
207 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
208 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
209
Guido van Rossumeea14491997-08-13 21:30:44 +0000210 rc=RegOpenKey(keyBase,
Guido van Rossum271f9771997-09-29 23:39:31 +0000211 keyBuf,
Guido van Rossumeea14491997-08-13 21:30:44 +0000212 &newKey);
213 if (rc==ERROR_SUCCESS) {
214 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
215 &numEntries, &nameSize, &dataSize, NULL, NULL);
216 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000217 if (numEntries) {
218 /* Loop over all subkeys. */
219 /* Win32s doesnt know how many subkeys, so we do
220 it twice */
221 char keyBuf[MAX_PATH+1];
222 int index = 0;
223 int off = 0;
224 for(index=0;;index++) {
225 long reqdSize = 0;
226 DWORD rc = RegEnumKey(newKey,
227 index, keyBuf, MAX_PATH+1);
228 if (rc) break;
229 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
230 if (rc) break;
Guido van Rossumeea14491997-08-13 21:30:44 +0000231 dataSize += reqdSize + 1; /* 1 for the ";" */
232 }
233 dataBuf = malloc(dataSize+1);
234 if (dataBuf==NULL)
235 return NULL; /* pretty serious? Raise error? */
236 /* Now loop over, grabbing the paths.
237 Subkeys before main library */
238 for(index=0;;index++) {
239 int adjust;
240 long reqdSize = dataSize;
241 DWORD rc = RegEnumKey(newKey,
242 index, keyBuf,MAX_PATH+1);
243 if (rc) break;
244 rc = RegQueryValue(newKey,
245 keyBuf, dataBuf+off, &reqdSize);
246 if (rc) break;
247 if (reqdSize>1) {
248 /* If Nothing, or only '\0' copied. */
249 adjust = strlen(dataBuf+off);
250 dataSize -= adjust;
251 off += adjust;
252 dataBuf[off++] = ';';
253 dataBuf[off] = '\0';
254 dataSize--;
255 }
256 }
257 /* Additionally, win32s doesnt work as expected, so
258 the specific strlen() is required for 3.1. */
259 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
260 if (rc==ERROR_SUCCESS) {
261 if (strlen(dataBuf)==0)
262 free(dataBuf);
263 else
264 retval = dataBuf; /* caller will free */
265 }
266 else
267 free(dataBuf);
268 }
269
270 if (newKey)
271 RegCloseKey(newKey);
272 return retval;
273}
274#endif /* MS_WIN32 */
275
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000276static void
277get_progpath()
278{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000279 extern char *Py_GetProgramName();
280 char *path = getenv("PATH");
281 char *prog = Py_GetProgramName();
282
Guido van Rossumeea14491997-08-13 21:30:44 +0000283#ifdef MS_WIN32
284 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
285 return;
286#endif
287 if (prog == NULL || *prog == '\0')
288 prog = "python";
289
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000290 /* If there is no slash in the argv0 path, then we have to
291 * assume python is on the user's $PATH, since there's no
292 * other way to find a directory to start the search from. If
293 * $PATH isn't exported, you lose.
294 */
295#ifdef ALTSEP
296 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
297#else
298 if (strchr(prog, SEP))
299#endif
300 strcpy(progpath, prog);
301 else if (path) {
302 while (1) {
303 char *delim = strchr(path, DELIM);
304
305 if (delim) {
306 int len = delim - path;
307 strncpy(progpath, path, len);
308 *(progpath + len) = '\0';
309 }
310 else
311 strcpy(progpath, path);
312
313 join(progpath, prog);
314 if (exists(progpath))
315 break;
316
317 if (!delim) {
318 progpath[0] = '\0';
319 break;
320 }
321 path = delim + 1;
322 }
323 }
324 else
325 progpath[0] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000326}
327
328static void
329calculate_path()
330{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000331 char argv0_path[MAXPATHLEN+1];
332 char *buf;
333 int bufsz;
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000334 char *pythonhome = Py_GetPythonHome();
Guido van Rossumeea14491997-08-13 21:30:44 +0000335 char *envpath = getenv("PYTHONPATH");
Guido van Rossumeea14491997-08-13 21:30:44 +0000336
Guido van Rossum43ff1141998-08-08 23:40:40 +0000337#ifdef MS_WIN32
Guido van Rossume02e48b2000-03-29 01:49:47 +0000338 int skiphome = 0;
Guido van Rossum43ff1141998-08-08 23:40:40 +0000339 char *machinepath = NULL;
340 char *userpath = NULL;
Guido van Rossumeea14491997-08-13 21:30:44 +0000341#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000342
343 get_progpath();
344 strcpy(argv0_path, progpath);
345 reduce(argv0_path);
Guido van Rossumeea14491997-08-13 21:30:44 +0000346 if (pythonhome == NULL || *pythonhome == '\0') {
347 if (search_for_prefix(argv0_path, LANDMARK))
348 pythonhome = prefix;
Guido van Rossum43ff1141998-08-08 23:40:40 +0000349 else
350 pythonhome = NULL;
Guido van Rossumeea14491997-08-13 21:30:44 +0000351 }
352 else
353 strcpy(prefix, pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000354
Guido van Rossumeea14491997-08-13 21:30:44 +0000355 if (envpath && *envpath == '\0')
356 envpath = NULL;
357
Guido van Rossume02e48b2000-03-29 01:49:47 +0000358
Guido van Rossum43ff1141998-08-08 23:40:40 +0000359#ifdef MS_WIN32
Guido van Rossume02e48b2000-03-29 01:49:47 +0000360 if (!gotlandmark(BUILD_LANDMARK)) {
361 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE);
362 userpath = getpythonregpath(HKEY_CURRENT_USER);
Guido van Rossum43ff1141998-08-08 23:40:40 +0000363 }
364#endif
365
366 /* We need to construct a path from the following parts.
Guido van Rossumeea14491997-08-13 21:30:44 +0000367 (1) the PYTHONPATH environment variable, if set;
368 (2) for Win32, the machinepath and userpath, if set;
369 (3) the PYTHONPATH config macro, with the leading "."
370 of each component replaced with pythonhome, if set;
371 (4) the directory containing the executable (argv0_path).
372 The length calculation calculates #3 first.
Guido van Rossum43ff1141998-08-08 23:40:40 +0000373 Extra rules:
374 - If PYTHONHOME is set (in any way) item (2) is ignored.
375 - If registry values are used, (3) and (4) are ignored.
Guido van Rossumeea14491997-08-13 21:30:44 +0000376 */
377
378 /* Calculate size of return buffer */
379 if (pythonhome != NULL) {
380 char *p;
381 bufsz = 1;
382 for (p = PYTHONPATH; *p; p++) {
383 if (*p == DELIM)
384 bufsz++; /* number of DELIM plus one */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000385 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000386 bufsz *= strlen(pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000387 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000388 else
389 bufsz = 0;
Guido van Rossum691d2ad1997-12-11 02:32:43 +0000390 bufsz += strlen(PYTHONPATH) + 1;
Guido van Rossum8f1b6511997-08-13 19:55:43 +0000391 bufsz += strlen(argv0_path) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000392#ifdef MS_WIN32
Guido van Rossumeea14491997-08-13 21:30:44 +0000393 if (userpath)
394 bufsz += strlen(userpath) + 1;
Guido van Rossum67ab6721998-08-08 19:58:59 +0000395 if (machinepath)
396 bufsz += strlen(machinepath) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000397#endif
Guido van Rossum67ab6721998-08-08 19:58:59 +0000398 if (envpath != NULL)
399 bufsz += strlen(envpath) + 1;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000400
401 module_search_path = buf = malloc(bufsz);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000402 if (buf == NULL) {
403 /* We can't exit, so print a warning and limp along */
Guido van Rossumeea14491997-08-13 21:30:44 +0000404 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
405 if (envpath) {
Guido van Rossume02e48b2000-03-29 01:49:47 +0000406 fprintf(stderr, "Using environment $PYTHONPATH.\n");
Guido van Rossumeea14491997-08-13 21:30:44 +0000407 module_search_path = envpath;
408 }
409 else {
Guido van Rossume02e48b2000-03-29 01:49:47 +0000410 fprintf(stderr, "Using default static path.\n");
Guido van Rossumeea14491997-08-13 21:30:44 +0000411 module_search_path = PYTHONPATH;
412 }
Guido van Rossum42a97441998-02-19 21:00:45 +0000413#ifdef MS_WIN32
414 if (machinepath)
415 free(machinepath);
416 if (userpath)
417 free(userpath);
418#endif /* MS_WIN32 */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000419 return;
420 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000421
422 if (envpath) {
423 strcpy(buf, envpath);
424 buf = strchr(buf, '\0');
425 *buf++ = DELIM;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000426 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000427#ifdef MS_WIN32
Guido van Rossum67ab6721998-08-08 19:58:59 +0000428 if (userpath) {
429 strcpy(buf, userpath);
430 buf = strchr(buf, '\0');
431 *buf++ = DELIM;
432 free(userpath);
Guido van Rossume02e48b2000-03-29 01:49:47 +0000433 skiphome = 1;
Guido van Rossum67ab6721998-08-08 19:58:59 +0000434 }
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 Rossume02e48b2000-03-29 01:49:47 +0000440 skiphome = 1;
441 }
442 if (skiphome) {
443 *buf = 0;
444 return;
Guido van Rossumeea14491997-08-13 21:30:44 +0000445 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000446#endif
447 if (pythonhome == NULL) {
448 strcpy(buf, PYTHONPATH);
449 buf = strchr(buf, '\0');
450 }
451 else {
452 char *p = PYTHONPATH;
453 char *q;
454 int n;
455 for (;;) {
456 q = strchr(p, DELIM);
457 if (q == NULL)
458 n = strlen(p);
459 else
460 n = q-p;
461 if (p[0] == '.' && is_sep(p[1])) {
462 strcpy(buf, pythonhome);
463 buf = strchr(buf, '\0');
464 p++;
465 n--;
466 }
467 strncpy(buf, p, n);
468 buf += n;
469 if (q == NULL)
470 break;
471 *buf++ = DELIM;
472 p = q+1;
473 }
474 }
475 if (argv0_path) {
476 *buf++ = DELIM;
477 strcpy(buf, argv0_path);
478 buf = strchr(buf, '\0');
479 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000480 *buf = '\0';
481}
482
483
484/* External interface */
485
486char *
487Py_GetPath()
488{
489 if (!module_search_path)
490 calculate_path();
491 return module_search_path;
492}
493
494char *
495Py_GetPrefix()
496{
Guido van Rossumeea14491997-08-13 21:30:44 +0000497 if (!module_search_path)
498 calculate_path();
499 return prefix;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000500}
501
502char *
503Py_GetExecPrefix()
504{
Guido van Rossumeea14491997-08-13 21:30:44 +0000505 return Py_GetPrefix();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000506}
507
508char *
Guido van Rossumeea14491997-08-13 21:30:44 +0000509Py_GetProgramFullPath()
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000510{
511 if (!module_search_path)
512 calculate_path();
513 return progpath;
514}
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000515