1
2 /* Return the initial module search path. */
3 /* Used by DOS, OS/2, Windows 3.1. Works on NT too. */
4
5 #include "Python.h"
6 #include "osdefs.h"
7
8 #ifdef MS_WIN32
9 #include <windows.h>
10 extern BOOL PyWin_IsWin32s(void);
11 #endif
12
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <string.h>
16
17 #if HAVE_UNISTD_H
18 #include <unistd.h>
19 #endif /* HAVE_UNISTD_H */
20
21 /* Search in some common locations for the associated Python libraries.
22 *
23 * Two directories must be found, the platform independent directory
24 * (prefix), containing the common .py and .pyc files, and the platform
25 * dependent directory (exec_prefix), containing the shared library
26 * modules. Note that prefix and exec_prefix can be the same directory,
27 * but for some installations, they are different.
28 *
29 * Py_GetPath() tries to return a sensible Python module search path.
30 *
31 * First, we look to see if the executable is in a subdirectory of
32 * the Python build directory. We calculate the full path of the
33 * directory containing the executable as progpath. We work backwards
34 * along progpath and look for $dir/Modules/Setup.in, a distinctive
35 * landmark. If found, we use $dir/Lib as $root. The returned
36 * Python path is the compiled #define PYTHONPATH with all the initial
37 * "./lib" replaced by $root.
38 *
39 * Otherwise, if there is a PYTHONPATH environment variable, we return that.
40 *
41 * Otherwise we try to find $progpath/lib/os.py, and if found, then
42 * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
43 * with all "./lib" replaced by $root (as above).
44 *
45 */
46
47 #ifndef LANDMARK
48 #define LANDMARK "lib\\os.py"
49 #endif
50
51 static char prefix[MAXPATHLEN+1];
52 static char exec_prefix[MAXPATHLEN+1];
53 static char progpath[MAXPATHLEN+1];
54 static char *module_search_path = NULL;
55
56
57 static int
is_sep(char ch)58 is_sep(char ch) /* determine if "ch" is a separator character */
59 {
60 #ifdef ALTSEP
61 return ch == SEP || ch == ALTSEP;
62 #else
63 return ch == SEP;
64 #endif
65 }
66
67
68 static void
reduce(char * dir)69 reduce(char *dir)
70 {
71 int i = strlen(dir);
72 while (i > 0 && !is_sep(dir[i]))
73 --i;
74 dir[i] = '\0';
75 }
76
77
78 static int
exists(char * filename)79 exists(char *filename)
80 {
81 struct stat buf;
82 return stat(filename, &buf) == 0;
83 }
84
85
86 /* Add a path component, by appending stuff to buffer.
87 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
88 NUL-terminated string with no more than MAXPATHLEN characters (not counting
89 the trailing NUL). It's a fatal error if it contains a string longer than
90 that (callers must be careful!). If these requirements are met, it's
91 guaranteed that buffer will still be a NUL-terminated string with no more
92 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
93 stuff as fits will be appended.
94 */
95 static void
join(char * buffer,char * stuff)96 join(char *buffer, char *stuff)
97 {
98 int n, k;
99 if (is_sep(stuff[0]))
100 n = 0;
101 else {
102 n = strlen(buffer);
103 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
104 buffer[n++] = SEP;
105 }
106 if (n > MAXPATHLEN)
107 Py_FatalError("buffer overflow in getpathp.c's joinpath()");
108 k = strlen(stuff);
109 if (n + k > MAXPATHLEN)
110 k = MAXPATHLEN - n;
111 strncpy(buffer+n, stuff, k);
112 buffer[n+k] = '\0';
113 }
114
115
116 static int
search_for_prefix(char * argv0_path,char * landmark)117 search_for_prefix(char *argv0_path, char *landmark)
118 {
119 int n;
120
121 /* Search from argv0_path, until root is found */
122 strcpy(prefix, argv0_path);
123 do {
124 n = strlen(prefix);
125 join(prefix, landmark);
126 if (exists(prefix)) {
127 prefix[n] = '\0';
128 return 1;
129 }
130 prefix[n] = '\0';
131 reduce(prefix);
132 } while (prefix[0]);
133 return 0;
134 }
135
136 #ifdef MS_WIN32
137 #include "malloc.h" // for alloca - see comments below!
138 extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
139
140
141 /* Load a PYTHONPATH value from the registry.
142 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
143
144 Returns NULL, or a pointer that should be freed.
145 */
146
147 static char *
getpythonregpath(HKEY keyBase,BOOL bWin32s)148 getpythonregpath(HKEY keyBase, BOOL bWin32s)
149 {
150 HKEY newKey = 0;
151 DWORD nameSize = 0;
152 DWORD dataSize = 0;
153 DWORD numEntries = 0;
154 LONG rc;
155 char *retval = NULL;
156 char *dataBuf;
157 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
158 const char keySuffix[] = "\\PythonPath";
159 int versionLen;
160 char *keyBuf;
161
162 // Tried to use sysget("winver") but here is too early :-(
163 versionLen = strlen(PyWin_DLLVersionString);
164 // alloca == no free required, but memory only local to fn.
165 // also no heap fragmentation! Am I being silly?
166 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
167 // lots of constants here for the compiler to optimize away :-)
168 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
169 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
170 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
171
172 rc=RegOpenKey(keyBase,
173 keyBuf,
174 &newKey);
175 if (rc==ERROR_SUCCESS) {
176 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
177 &numEntries, &nameSize, &dataSize, NULL, NULL);
178 }
179 if (bWin32s && numEntries==0 && dataSize==0) {
180 /* must hardcode for Win32s */
181 numEntries = 1;
182 dataSize = 511;
183 }
184 if (numEntries) {
185 /* Loop over all subkeys. */
186 /* Win32s doesnt know how many subkeys, so we do
187 it twice */
188 char keyBuf[MAX_PATH+1];
189 int index = 0;
190 int off = 0;
191 for(index=0;;index++) {
192 long reqdSize = 0;
193 DWORD rc = RegEnumKey(newKey,
194 index, keyBuf, MAX_PATH+1);
195 if (rc) break;
196 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
197 if (rc) break;
198 if (bWin32s && reqdSize==0) reqdSize = 512;
199 dataSize += reqdSize + 1; /* 1 for the ";" */
200 }
201 dataBuf = malloc(dataSize+1);
202 if (dataBuf==NULL)
203 return NULL; /* pretty serious? Raise error? */
204 /* Now loop over, grabbing the paths.
205 Subkeys before main library */
206 for(index=0;;index++) {
207 int adjust;
208 long reqdSize = dataSize;
209 DWORD rc = RegEnumKey(newKey,
210 index, keyBuf,MAX_PATH+1);
211 if (rc) break;
212 rc = RegQueryValue(newKey,
213 keyBuf, dataBuf+off, &reqdSize);
214 if (rc) break;
215 if (reqdSize>1) {
216 /* If Nothing, or only '\0' copied. */
217 adjust = strlen(dataBuf+off);
218 dataSize -= adjust;
219 off += adjust;
220 dataBuf[off++] = ';';
221 dataBuf[off] = '\0';
222 dataSize--;
223 }
224 }
225 /* Additionally, win32s doesnt work as expected, so
226 the specific strlen() is required for 3.1. */
227 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
228 if (rc==ERROR_SUCCESS) {
229 if (strlen(dataBuf)==0)
230 free(dataBuf);
231 else
232 retval = dataBuf; /* caller will free */
233 }
234 else
235 free(dataBuf);
236 }
237
238 if (newKey)
239 RegCloseKey(newKey);
240 return retval;
241 }
242 #endif /* MS_WIN32 */
243
244 static void
get_progpath(void)245 get_progpath(void)
246 {
247 extern char *Py_GetProgramName(void);
248 char *path = getenv("PATH");
249 char *prog = Py_GetProgramName();
250
251 #ifdef MS_WIN32
252 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
253 return;
254 #endif
255 if (prog == NULL || *prog == '\0')
256 prog = "python";
257
258 /* If there is no slash in the argv0 path, then we have to
259 * assume python is on the user's $PATH, since there's no
260 * other way to find a directory to start the search from. If
261 * $PATH isn't exported, you lose.
262 */
263 #ifdef ALTSEP
264 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
265 #else
266 if (strchr(prog, SEP))
267 #endif
268 strcpy(progpath, prog);
269 else if (path) {
270 while (1) {
271 char *delim = strchr(path, DELIM);
272
273 if (delim) {
274 int len = delim - path;
275 strncpy(progpath, path, len);
276 *(progpath + len) = '\0';
277 }
278 else
279 strcpy(progpath, path);
280
281 join(progpath, prog);
282 if (exists(progpath))
283 break;
284
285 if (!delim) {
286 progpath[0] = '\0';
287 break;
288 }
289 path = delim + 1;
290 }
291 }
292 else
293 progpath[0] = '\0';
294 }
295
296 static void
calculate_path(void)297 calculate_path(void)
298 {
299 char argv0_path[MAXPATHLEN+1];
300 char *buf;
301 int bufsz;
302 char *pythonhome = Py_GetPythonHome();
303 char *envpath = Py_GETENV("PYTHONPATH");
304 #ifdef MS_WIN32
305 char *machinepath, *userpath;
306
307 /* Are we running under Windows 3.1(1) Win32s? */
308 if (PyWin_IsWin32s()) {
309 /* Only CLASSES_ROOT is supported */
310 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
311 userpath = NULL;
312 } else {
313 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
314 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
315 }
316 #endif
317
318 get_progpath();
319 strcpy(argv0_path, progpath);
320 reduce(argv0_path);
321 if (pythonhome == NULL || *pythonhome == '\0') {
322 if (search_for_prefix(argv0_path, LANDMARK))
323 pythonhome = prefix;
324 else
325 pythonhome = NULL;
326 }
327 else {
328 char *delim;
329
330 strcpy(prefix, pythonhome);
331
332 /* Extract Any Optional Trailing EXEC_PREFIX */
333 /* e.g. PYTHONHOME=<prefix>:<exec_prefix> */
334 delim = strchr(prefix, DELIM);
335 if (delim) {
336 *delim = '\0';
337 strcpy(exec_prefix, delim+1);
338 } else
339 strcpy(exec_prefix, EXEC_PREFIX);
340 }
341
342 if (envpath && *envpath == '\0')
343 envpath = NULL;
344
345 /* We need to construct a path from the following parts:
346 (1) the PYTHONPATH environment variable, if set;
347 (2) for Win32, the machinepath and userpath, if set;
348 (3) the PYTHONPATH config macro, with the leading "."
349 of each component replaced with pythonhome, if set;
350 (4) the directory containing the executable (argv0_path).
351 The length calculation calculates #3 first.
352 */
353
354 /* Calculate size of return buffer */
355 if (pythonhome != NULL) {
356 char *p;
357 bufsz = 1;
358 for (p = PYTHONPATH; *p; p++) {
359 if (*p == DELIM)
360 bufsz++; /* number of DELIM plus one */
361 }
362 bufsz *= strlen(pythonhome);
363 }
364 else
365 bufsz = 0;
366 bufsz += strlen(PYTHONPATH) + 1;
367 if (envpath != NULL)
368 bufsz += strlen(envpath) + 1;
369 bufsz += strlen(argv0_path) + 1;
370 #ifdef MS_WIN32
371 if (machinepath)
372 bufsz += strlen(machinepath) + 1;
373 if (userpath)
374 bufsz += strlen(userpath) + 1;
375 #endif
376
377 module_search_path = buf = malloc(bufsz);
378 if (buf == NULL) {
379 /* We can't exit, so print a warning and limp along */
380 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
381 if (envpath) {
382 fprintf(stderr, "Using default static $PYTHONPATH.\n");
383 module_search_path = envpath;
384 }
385 else {
386 fprintf(stderr, "Using environment $PYTHONPATH.\n");
387 module_search_path = PYTHONPATH;
388 }
389 return;
390 }
391
392 if (envpath) {
393 strcpy(buf, envpath);
394 buf = strchr(buf, '\0');
395 *buf++ = DELIM;
396 }
397 #ifdef MS_WIN32
398 if (machinepath) {
399 strcpy(buf, machinepath);
400 buf = strchr(buf, '\0');
401 *buf++ = DELIM;
402 }
403 if (userpath) {
404 strcpy(buf, userpath);
405 buf = strchr(buf, '\0');
406 *buf++ = DELIM;
407 }
408 #endif
409 if (pythonhome == NULL) {
410 strcpy(buf, PYTHONPATH);
411 buf = strchr(buf, '\0');
412 }
413 else {
414 char *p = PYTHONPATH;
415 char *q;
416 int n;
417 for (;;) {
418 q = strchr(p, DELIM);
419 if (q == NULL)
420 n = strlen(p);
421 else
422 n = q-p;
423 if (p[0] == '.' && is_sep(p[1])) {
424 strcpy(buf, pythonhome);
425 buf = strchr(buf, '\0');
426 p++;
427 n--;
428 }
429 strncpy(buf, p, n);
430 buf += n;
431 if (q == NULL)
432 break;
433 *buf++ = DELIM;
434 p = q+1;
435 }
436 }
437 if (argv0_path) {
438 *buf++ = DELIM;
439 strcpy(buf, argv0_path);
440 buf = strchr(buf, '\0');
441 }
442 *buf = '\0';
443 }
444
445
446 /* External interface */
447
448 char *
Py_GetPath(void)449 Py_GetPath(void)
450 {
451 if (!module_search_path)
452 calculate_path();
453
454 return module_search_path;
455 }
456
457 char *
Py_GetPrefix(void)458 Py_GetPrefix(void)
459 {
460 if (!module_search_path)
461 calculate_path();
462
463 return prefix;
464 }
465
466 char *
Py_GetExecPrefix(void)467 Py_GetExecPrefix(void)
468 {
469 if (!module_search_path)
470 calculate_path();
471
472 return exec_prefix;
473 }
474
475 char *
Py_GetProgramFullPath(void)476 Py_GetProgramFullPath(void)
477 {
478 if (!module_search_path)
479 calculate_path();
480
481 return progpath;
482 }
483