blob: 1a50dd9571bb870b470fda7703002b3bc4c9aaa9 [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. */
33/* Used by DOS, OS/2, Windows 3.1. Works on NT too. */
34
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 *
53 * This version always returns "" for both prefix and exec_prefix.
54 *
55 * Py_GetPath() tries to return a sensible Python module search path.
56 *
57 * First, we look to see if the executable is in a subdirectory of
58 * the Python build directory. We calculate the full path of the
59 * directory containing the executable as progpath. We work backwards
60 * along progpath and look for $dir/Modules/Setup.in, a distinctive
61 * landmark. If found, we use $dir/Lib as $root. The returned
62 * Python path is the compiled #define PYTHONPATH with all the initial
63 * "./lib" replaced by $root.
64 *
65 * Otherwise, if there is a PYTHONPATH environment variable, we return that.
66 *
67 * Otherwise we try to find $progpath/lib/string.py, and if found, then
68 * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
69 * with all "./lib" replaced by $root (as above).
70 *
71 */
72
73#ifndef LANDMARK
Guido van Rossumeea14491997-08-13 21:30:44 +000074#define LANDMARK "lib\\string.py"
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000075#endif
76
77static char prefix[MAXPATHLEN+1];
78static char progpath[MAXPATHLEN+1];
79static char *module_search_path = NULL;
80
Guido van Rossumeea14491997-08-13 21:30:44 +000081
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000082static int
83is_sep(ch) /* determine if "ch" is a separator character */
84 char ch;
85{
86#ifdef ALTSEP
87 return ch == SEP || ch == ALTSEP;
88#else
89 return ch == SEP;
90#endif
91}
92
Guido van Rossumeea14491997-08-13 21:30:44 +000093
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000094static void
95reduce(dir)
96 char *dir;
97{
98 int i = strlen(dir);
99 while (i > 0 && !is_sep(dir[i]))
100 --i;
101 dir[i] = '\0';
102}
103
104
105static int
106exists(filename)
107 char *filename;
108{
109 struct stat buf;
110 return stat(filename, &buf) == 0;
111}
112
113
114static void
115join(buffer, stuff)
116 char *buffer;
117 char *stuff;
118{
119 int n, k;
120 if (is_sep(stuff[0]))
121 n = 0;
122 else {
123 n = strlen(buffer);
124 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
125 buffer[n++] = SEP;
126 }
127 k = strlen(stuff);
128 if (n + k > MAXPATHLEN)
129 k = MAXPATHLEN - n;
130 strncpy(buffer+n, stuff, k);
131 buffer[n+k] = '\0';
132}
133
134
135static int
136search_for_prefix(argv0_path, landmark)
137 char *argv0_path;
138 char *landmark;
139{
140 int n;
141
142 /* Search from argv0_path, until root is found */
143 strcpy(prefix, argv0_path);
144 do {
145 n = strlen(prefix);
146 join(prefix, landmark);
Guido van Rossumeea14491997-08-13 21:30:44 +0000147 if (exists(prefix)) {
148 prefix[n] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000149 return 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000150 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000151 prefix[n] = '\0';
152 reduce(prefix);
153 } while (prefix[0]);
154 return 0;
155}
156
Guido van Rossumeea14491997-08-13 21:30:44 +0000157#ifdef MS_WIN32
158
159/* Load a PYTHONPATH value from the registry.
160 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
161
162 Returns NULL, or a pointer that should be freed.
163*/
164
165static char *
166getpythonregpath(HKEY keyBase, BOOL bWin32s)
167{
168 HKEY newKey = 0;
169 DWORD nameSize = 0;
170 DWORD dataSize = 0;
171 DWORD numEntries = 0;
172 LONG rc;
173 char *retval = NULL;
174 char *dataBuf;
175 rc=RegOpenKey(keyBase,
176 "Software\\Python\\PythonCore\\"
177 MS_DLL_ID "\\PythonPath",
178 &newKey);
179 if (rc==ERROR_SUCCESS) {
180 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
181 &numEntries, &nameSize, &dataSize, NULL, NULL);
182 }
183 if (bWin32s && numEntries==0 && dataSize==0) {
184 /* must hardcode for Win32s */
185 numEntries = 1;
186 dataSize = 511;
187 }
188 if (numEntries) {
189 /* Loop over all subkeys. */
190 /* Win32s doesnt know how many subkeys, so we do
191 it twice */
192 char keyBuf[MAX_PATH+1];
193 int index = 0;
194 int off = 0;
195 for(index=0;;index++) {
196 long reqdSize = 0;
197 DWORD rc = RegEnumKey(newKey,
198 index, keyBuf, MAX_PATH+1);
199 if (rc) break;
200 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
201 if (rc) break;
202 if (bWin32s && reqdSize==0) reqdSize = 512;
203 dataSize += reqdSize + 1; /* 1 for the ";" */
204 }
205 dataBuf = malloc(dataSize+1);
206 if (dataBuf==NULL)
207 return NULL; /* pretty serious? Raise error? */
208 /* Now loop over, grabbing the paths.
209 Subkeys before main library */
210 for(index=0;;index++) {
211 int adjust;
212 long reqdSize = dataSize;
213 DWORD rc = RegEnumKey(newKey,
214 index, keyBuf,MAX_PATH+1);
215 if (rc) break;
216 rc = RegQueryValue(newKey,
217 keyBuf, dataBuf+off, &reqdSize);
218 if (rc) break;
219 if (reqdSize>1) {
220 /* If Nothing, or only '\0' copied. */
221 adjust = strlen(dataBuf+off);
222 dataSize -= adjust;
223 off += adjust;
224 dataBuf[off++] = ';';
225 dataBuf[off] = '\0';
226 dataSize--;
227 }
228 }
229 /* Additionally, win32s doesnt work as expected, so
230 the specific strlen() is required for 3.1. */
231 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
232 if (rc==ERROR_SUCCESS) {
233 if (strlen(dataBuf)==0)
234 free(dataBuf);
235 else
236 retval = dataBuf; /* caller will free */
237 }
238 else
239 free(dataBuf);
240 }
241
242 if (newKey)
243 RegCloseKey(newKey);
244 return retval;
245}
246#endif /* MS_WIN32 */
247
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000248static void
249get_progpath()
250{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000251 extern char *Py_GetProgramName();
252 char *path = getenv("PATH");
253 char *prog = Py_GetProgramName();
254
Guido van Rossumeea14491997-08-13 21:30:44 +0000255#ifdef MS_WIN32
256 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
257 return;
258#endif
259 if (prog == NULL || *prog == '\0')
260 prog = "python";
261
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000262 /* If there is no slash in the argv0 path, then we have to
263 * assume python is on the user's $PATH, since there's no
264 * other way to find a directory to start the search from. If
265 * $PATH isn't exported, you lose.
266 */
267#ifdef ALTSEP
268 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
269#else
270 if (strchr(prog, SEP))
271#endif
272 strcpy(progpath, prog);
273 else if (path) {
274 while (1) {
275 char *delim = strchr(path, DELIM);
276
277 if (delim) {
278 int len = delim - path;
279 strncpy(progpath, path, len);
280 *(progpath + len) = '\0';
281 }
282 else
283 strcpy(progpath, path);
284
285 join(progpath, prog);
286 if (exists(progpath))
287 break;
288
289 if (!delim) {
290 progpath[0] = '\0';
291 break;
292 }
293 path = delim + 1;
294 }
295 }
296 else
297 progpath[0] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000298}
299
300static void
301calculate_path()
302{
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000303 char argv0_path[MAXPATHLEN+1];
304 char *buf;
305 int bufsz;
Guido van Rossumeea14491997-08-13 21:30:44 +0000306 char *pythonhome = getenv("PYTHONHOME");
307 char *envpath = getenv("PYTHONPATH");
308#ifdef MS_WIN32
309 char *machinepath, *userpath;
310
311 /* Are we running under Windows 3.1(1) Win32s? */
312 if (PyWin_IsWin32s()) {
313 /* Only CLASSES_ROOT is supported */
314 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
315 userpath = NULL;
316 } else {
317 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
318 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
319 }
320#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000321
322 get_progpath();
323 strcpy(argv0_path, progpath);
324 reduce(argv0_path);
Guido van Rossumeea14491997-08-13 21:30:44 +0000325 if (pythonhome == NULL || *pythonhome == '\0') {
326 if (search_for_prefix(argv0_path, LANDMARK))
327 pythonhome = prefix;
328 else
329 pythonhome = NULL;
330 }
331 else
332 strcpy(prefix, pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000333
Guido van Rossumeea14491997-08-13 21:30:44 +0000334 if (envpath && *envpath == '\0')
335 envpath = NULL;
336
337 /* We need to construct a path from the following parts:
338 (1) the PYTHONPATH environment variable, if set;
339 (2) for Win32, the machinepath and userpath, if set;
340 (3) the PYTHONPATH config macro, with the leading "."
341 of each component replaced with pythonhome, if set;
342 (4) the directory containing the executable (argv0_path).
343 The length calculation calculates #3 first.
344 */
345
346 /* Calculate size of return buffer */
347 if (pythonhome != NULL) {
348 char *p;
349 bufsz = 1;
350 for (p = PYTHONPATH; *p; p++) {
351 if (*p == DELIM)
352 bufsz++; /* number of DELIM plus one */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000353 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000354 bufsz *= strlen(pythonhome);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000355 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000356 else
357 bufsz = 0;
358 bufsz += strlen(PYTHONPATH);
359 if (envpath != NULL)
360 bufsz += strlen(envpath) + 1;
Guido van Rossum8f1b6511997-08-13 19:55:43 +0000361 bufsz += strlen(argv0_path) + 1;
Guido van Rossumeea14491997-08-13 21:30:44 +0000362#ifdef MS_WIN32
363 if (machinepath)
364 bufsz += strlen(machinepath) + 1;
365 if (userpath)
366 bufsz += strlen(userpath) + 1;
367#endif
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000368
369 module_search_path = buf = malloc(bufsz);
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000370 if (buf == NULL) {
371 /* We can't exit, so print a warning and limp along */
Guido van Rossumeea14491997-08-13 21:30:44 +0000372 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
373 if (envpath) {
374 fprintf(stderr, "Using default static $PYTHONPATH.\n");
375 module_search_path = envpath;
376 }
377 else {
378 fprintf(stderr, "Using environment $PYTHONPATH.\n");
379 module_search_path = PYTHONPATH;
380 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000381 return;
382 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000383
384 if (envpath) {
385 strcpy(buf, envpath);
386 buf = strchr(buf, '\0');
387 *buf++ = DELIM;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000388 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000389#ifdef MS_WIN32
390 if (machinepath) {
391 strcpy(buf, machinepath);
392 buf = strchr(buf, '\0');
393 *buf++ = DELIM;
394 }
395 if (userpath) {
396 strcpy(buf, userpath);
397 buf = strchr(buf, '\0');
398 *buf++ = DELIM;
399 }
400#endif
401 if (pythonhome == NULL) {
402 strcpy(buf, PYTHONPATH);
403 buf = strchr(buf, '\0');
404 }
405 else {
406 char *p = PYTHONPATH;
407 char *q;
408 int n;
409 for (;;) {
410 q = strchr(p, DELIM);
411 if (q == NULL)
412 n = strlen(p);
413 else
414 n = q-p;
415 if (p[0] == '.' && is_sep(p[1])) {
416 strcpy(buf, pythonhome);
417 buf = strchr(buf, '\0');
418 p++;
419 n--;
420 }
421 strncpy(buf, p, n);
422 buf += n;
423 if (q == NULL)
424 break;
425 *buf++ = DELIM;
426 p = q+1;
427 }
428 }
429 if (argv0_path) {
430 *buf++ = DELIM;
431 strcpy(buf, argv0_path);
432 buf = strchr(buf, '\0');
433 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000434 *buf = '\0';
435}
436
437
438/* External interface */
439
440char *
441Py_GetPath()
442{
443 if (!module_search_path)
444 calculate_path();
445 return module_search_path;
446}
447
448char *
449Py_GetPrefix()
450{
Guido van Rossumeea14491997-08-13 21:30:44 +0000451 if (!module_search_path)
452 calculate_path();
453 return prefix;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000454}
455
456char *
457Py_GetExecPrefix()
458{
Guido van Rossumeea14491997-08-13 21:30:44 +0000459 return Py_GetPrefix();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000460}
461
462char *
Guido van Rossumeea14491997-08-13 21:30:44 +0000463Py_GetProgramFullPath()
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000464{
465 if (!module_search_path)
466 calculate_path();
467 return progpath;
468}