blob: 2aaa4f3d361cbd2eab5337c4a4740c05673600bc [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
167static int
168prefixisbuilddir()
169{
170 int n = strlen(prefix);
171 int ok;
172 join(prefix, BUILD_LANDMARK);
173 ok = exists(prefix);
174 prefix[n] = '\0';
175 return ok;
176}
177
Guido van Rossum271f9771997-09-29 23:39:31 +0000178#include "malloc.h" // for alloca - see comments below!
179extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
180
Guido van Rossumeea14491997-08-13 21:30:44 +0000181
182/* Load a PYTHONPATH value from the registry.
183 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
184
185 Returns NULL, or a pointer that should be freed.
186*/
187
188static char *
189getpythonregpath(HKEY keyBase, BOOL bWin32s)
190{
191 HKEY newKey = 0;
192 DWORD nameSize = 0;
193 DWORD dataSize = 0;
194 DWORD numEntries = 0;
195 LONG rc;
196 char *retval = NULL;
197 char *dataBuf;
Guido van Rossum271f9771997-09-29 23:39:31 +0000198 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
199 const char keySuffix[] = "\\PythonPath";
200 int versionLen;
201 char *keyBuf;
202
203 // Tried to use sysget("winver") but here is too early :-(
204 versionLen = strlen(PyWin_DLLVersionString);
205 // alloca == no free required, but memory only local to fn.
206 // also no heap fragmentation! Am I being silly?
207 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
208 // lots of constants here for the compiler to optimize away :-)
209 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
210 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
211 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
212
Guido van Rossumeea14491997-08-13 21:30:44 +0000213 rc=RegOpenKey(keyBase,
Guido van Rossum271f9771997-09-29 23:39:31 +0000214 keyBuf,
Guido van Rossumeea14491997-08-13 21:30:44 +0000215 &newKey);
216 if (rc==ERROR_SUCCESS) {
217 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
218 &numEntries, &nameSize, &dataSize, NULL, NULL);
219 }
220 if (bWin32s && numEntries==0 && dataSize==0) {
221 /* must hardcode for Win32s */
222 numEntries = 1;
223 dataSize = 511;
224 }
225 if (numEntries) {
226 /* Loop over all subkeys. */
227 /* Win32s doesnt know how many subkeys, so we do
228 it twice */
229 char keyBuf[MAX_PATH+1];
230 int index = 0;
231 int off = 0;
232 for(index=0;;index++) {
233 long reqdSize = 0;
234 DWORD rc = RegEnumKey(newKey,
235 index, keyBuf, MAX_PATH+1);
236 if (rc) break;
237 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
238 if (rc) break;
239 if (bWin32s && reqdSize==0) reqdSize = 512;
240 dataSize += reqdSize + 1; /* 1 for the ";" */
241 }
242 dataBuf = malloc(dataSize+1);
243 if (dataBuf==NULL)
244 return NULL; /* pretty serious? Raise error? */
245 /* Now loop over, grabbing the paths.
246 Subkeys before main library */
247 for(index=0;;index++) {
248 int adjust;
249 long reqdSize = dataSize;
250 DWORD rc = RegEnumKey(newKey,
251 index, keyBuf,MAX_PATH+1);
252 if (rc) break;
253 rc = RegQueryValue(newKey,
254 keyBuf, dataBuf+off, &reqdSize);
255 if (rc) break;
256 if (reqdSize>1) {
257 /* If Nothing, or only '\0' copied. */
258 adjust = strlen(dataBuf+off);
259 dataSize -= adjust;
260 off += adjust;
261 dataBuf[off++] = ';';
262 dataBuf[off] = '\0';
263 dataSize--;
264 }
265 }
266 /* Additionally, win32s doesnt work as expected, so
267 the specific strlen() is required for 3.1. */
268 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
269 if (rc==ERROR_SUCCESS) {
270 if (strlen(dataBuf)==0)
271 free(dataBuf);
272 else
273 retval = dataBuf; /* caller will free */
274 }
275 else
276 free(dataBuf);
277 }
278
279 if (newKey)
280 RegCloseKey(newKey);
281 return retval;
282}
283#endif /* MS_WIN32 */
284
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000285static void
286get_progpath()
287{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000288 extern char *Py_GetProgramName();
289 char *path = getenv("PATH");
290 char *prog = Py_GetProgramName();
291
Guido van Rossumeea14491997-08-13 21:30:44 +0000292#ifdef MS_WIN32
293 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
294 return;
295#endif
296 if (prog == NULL || *prog == '\0')
297 prog = "python";
298
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000299 /* If there is no slash in the argv0 path, then we have to
300 * assume python is on the user's $PATH, since there's no
301 * other way to find a directory to start the search from. If
302 * $PATH isn't exported, you lose.
303 */
304#ifdef ALTSEP
305 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
306#else
307 if (strchr(prog, SEP))
308#endif
309 strcpy(progpath, prog);
310 else if (path) {
311 while (1) {
312 char *delim = strchr(path, DELIM);
313
314 if (delim) {
315 int len = delim - path;
316 strncpy(progpath, path, len);
317 *(progpath + len) = '\0';
318 }
319 else
320 strcpy(progpath, path);
321
322 join(progpath, prog);
323 if (exists(progpath))
324 break;
325
326 if (!delim) {
327 progpath[0] = '\0';
328 break;
329 }
330 path = delim + 1;
331 }
332 }
333 else
334 progpath[0] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000335}
336
337static void
338calculate_path()
339{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000340 char argv0_path[MAXPATHLEN+1];
341 char *buf;
342 int bufsz;
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000343 char *pythonhome = Py_GetPythonHome();
Guido van Rossumeea14491997-08-13 21:30:44 +0000344 char *envpath = getenv("PYTHONPATH");
Guido van Rossumeea14491997-08-13 21:30:44 +0000345
Guido van Rossum43ff1141998-08-08 23:40:40 +0000346#ifdef MS_WIN32
347 char *machinepath = NULL;
348 char *userpath = NULL;
Guido van Rossumeea14491997-08-13 21:30:44 +0000349#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000350
351 get_progpath();
352 strcpy(argv0_path, progpath);
353 reduce(argv0_path);
Guido van Rossumeea14491997-08-13 21:30:44 +0000354 if (pythonhome == NULL || *pythonhome == '\0') {
355 if (search_for_prefix(argv0_path, LANDMARK))
356 pythonhome = prefix;
Guido van Rossum43ff1141998-08-08 23:40:40 +0000357 else
358 pythonhome = NULL;
Guido van Rossumeea14491997-08-13 21:30:44 +0000359 }
360 else
361 strcpy(prefix, pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000362
Guido van Rossumeea14491997-08-13 21:30:44 +0000363 if (envpath && *envpath == '\0')
364 envpath = NULL;
365
Guido van Rossum43ff1141998-08-08 23:40:40 +0000366#ifdef MS_WIN32
367 if (!prefixisbuilddir()) {
368 /* Are we running under Windows 3.1(1) Win32s? */
369 if (PyWin_IsWin32s()) {
370 /* Only CLASSES_ROOT is supported */
371 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
372 userpath = NULL;
373 } else {
374 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
375 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
376 }
377 }
378#endif
379
380 /* We need to construct a path from the following parts.
Guido van Rossumeea14491997-08-13 21:30:44 +0000381 (1) the PYTHONPATH environment variable, if set;
382 (2) for Win32, the machinepath and userpath, if set;
383 (3) the PYTHONPATH config macro, with the leading "."
384 of each component replaced with pythonhome, if set;
385 (4) the directory containing the executable (argv0_path).
386 The length calculation calculates #3 first.
Guido van Rossum43ff1141998-08-08 23:40:40 +0000387 Extra rules:
388 - If PYTHONHOME is set (in any way) item (2) is ignored.
389 - If registry values are used, (3) and (4) are ignored.
Guido van Rossumeea14491997-08-13 21:30:44 +0000390 */
391
392 /* Calculate size of return buffer */
393 if (pythonhome != NULL) {
394 char *p;
395 bufsz = 1;
396 for (p = PYTHONPATH; *p; p++) {
397 if (*p == DELIM)
398 bufsz++; /* number of DELIM plus one */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000399 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000400 bufsz *= strlen(pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000401 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000402 else
403 bufsz = 0;
Guido van Rossum691d2ad1997-12-11 02:32:43 +0000404 bufsz += strlen(PYTHONPATH) + 1;
Guido van Rossum8f1b6511997-08-13 19:55:43 +0000405 bufsz += strlen(argv0_path) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000406#ifdef MS_WIN32
Guido van Rossum67ab6721998-08-08 19:58:59 +0000407 if (userpath || machinepath)
408 bufsz = 0; /* Reset! */
Guido van Rossumeea14491997-08-13 21:30:44 +0000409 if (userpath)
410 bufsz += strlen(userpath) + 1;
Guido van Rossum67ab6721998-08-08 19:58:59 +0000411 if (machinepath)
412 bufsz += strlen(machinepath) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000413#endif
Guido van Rossum67ab6721998-08-08 19:58:59 +0000414 if (envpath != NULL)
415 bufsz += strlen(envpath) + 1;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000416
417 module_search_path = buf = malloc(bufsz);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000418 if (buf == NULL) {
419 /* We can't exit, so print a warning and limp along */
Guido van Rossumeea14491997-08-13 21:30:44 +0000420 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
421 if (envpath) {
422 fprintf(stderr, "Using default static $PYTHONPATH.\n");
423 module_search_path = envpath;
424 }
425 else {
426 fprintf(stderr, "Using environment $PYTHONPATH.\n");
427 module_search_path = PYTHONPATH;
428 }
Guido van Rossum42a97441998-02-19 21:00:45 +0000429#ifdef MS_WIN32
430 if (machinepath)
431 free(machinepath);
432 if (userpath)
433 free(userpath);
434#endif /* MS_WIN32 */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000435 return;
436 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000437
438 if (envpath) {
439 strcpy(buf, envpath);
440 buf = strchr(buf, '\0');
441 *buf++ = DELIM;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000442 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000443#ifdef MS_WIN32
Guido van Rossum67ab6721998-08-08 19:58:59 +0000444 if (userpath) {
445 strcpy(buf, userpath);
446 buf = strchr(buf, '\0');
447 *buf++ = DELIM;
448 free(userpath);
449 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000450 if (machinepath) {
451 strcpy(buf, machinepath);
452 buf = strchr(buf, '\0');
453 *buf++ = DELIM;
Guido van Rossum42a97441998-02-19 21:00:45 +0000454 free(machinepath);
Guido van Rossumeea14491997-08-13 21:30:44 +0000455 }
Guido van Rossum67ab6721998-08-08 19:58:59 +0000456 if (userpath || machinepath) {
457 buf[-1] = '\0';
458 return;
Guido van Rossumeea14491997-08-13 21:30:44 +0000459 }
460#endif
461 if (pythonhome == NULL) {
462 strcpy(buf, PYTHONPATH);
463 buf = strchr(buf, '\0');
464 }
465 else {
466 char *p = PYTHONPATH;
467 char *q;
468 int n;
469 for (;;) {
470 q = strchr(p, DELIM);
471 if (q == NULL)
472 n = strlen(p);
473 else
474 n = q-p;
475 if (p[0] == '.' && is_sep(p[1])) {
476 strcpy(buf, pythonhome);
477 buf = strchr(buf, '\0');
478 p++;
479 n--;
480 }
481 strncpy(buf, p, n);
482 buf += n;
483 if (q == NULL)
484 break;
485 *buf++ = DELIM;
486 p = q+1;
487 }
488 }
489 if (argv0_path) {
490 *buf++ = DELIM;
491 strcpy(buf, argv0_path);
492 buf = strchr(buf, '\0');
493 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000494 *buf = '\0';
495}
496
497
498/* External interface */
499
500char *
501Py_GetPath()
502{
503 if (!module_search_path)
504 calculate_path();
505 return module_search_path;
506}
507
508char *
509Py_GetPrefix()
510{
Guido van Rossumeea14491997-08-13 21:30:44 +0000511 if (!module_search_path)
512 calculate_path();
513 return prefix;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000514}
515
516char *
517Py_GetExecPrefix()
518{
Guido van Rossumeea14491997-08-13 21:30:44 +0000519 return Py_GetPrefix();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000520}
521
522char *
Guido van Rossumeea14491997-08-13 21:30:44 +0000523Py_GetProgramFullPath()
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000524{
525 if (!module_search_path)
526 calculate_path();
527 return progpath;
528}
Guido van Rossum8b2b3ce1998-07-27 13:48:07 +0000529