1 /* Return the initial module search path. */
2 
3 #include "Python.h"
4 #include "osdefs.h"
5 
6 #include <sys/types.h>
7 #include <string.h>
8 
9 #ifdef __APPLE__
10 #include <mach-o/dyld.h>
11 #endif
12 
13 /* Search in some common locations for the associated Python libraries.
14  *
15  * Two directories must be found, the platform independent directory
16  * (prefix), containing the common .py and .pyc files, and the platform
17  * dependent directory (exec_prefix), containing the shared library
18  * modules.  Note that prefix and exec_prefix can be the same directory,
19  * but for some installations, they are different.
20  *
21  * Py_GetPath() carries out separate searches for prefix and exec_prefix.
22  * Each search tries a number of different locations until a ``landmark''
23  * file or directory is found.  If no prefix or exec_prefix is found, a
24  * warning message is issued and the preprocessor defined PREFIX and
25  * EXEC_PREFIX are used (even though they will not work); python carries on
26  * as best as is possible, but most imports will fail.
27  *
28  * Before any searches are done, the location of the executable is
29  * determined.  If argv[0] has one or more slashes in it, it is used
30  * unchanged.  Otherwise, it must have been invoked from the shell's path,
31  * so we search $PATH for the named executable and use that.  If the
32  * executable was not found on $PATH (or there was no $PATH environment
33  * variable), the original argv[0] string is used.
34  *
35  * Next, the executable location is examined to see if it is a symbolic
36  * link.  If so, the link is chased (correctly interpreting a relative
37  * pathname if one is found) and the directory of the link target is used.
38  *
39  * Finally, argv0_path is set to the directory containing the executable
40  * (i.e. the last component is stripped).
41  *
42  * With argv0_path in hand, we perform a number of steps.  The same steps
43  * are performed for prefix and for exec_prefix, but with a different
44  * landmark.
45  *
46  * Step 1. Are we running python out of the build directory?  This is
47  * checked by looking for a different kind of landmark relative to
48  * argv0_path.  For prefix, the landmark's path is derived from the VPATH
49  * preprocessor variable (taking into account that its value is almost, but
50  * not quite, what we need).  For exec_prefix, the landmark is
51  * Modules/Setup.  If the landmark is found, we're done.
52  *
53  * For the remaining steps, the prefix landmark will always be
54  * lib/python$VERSION/os.py and the exec_prefix will always be
55  * lib/python$VERSION/lib-dynload, where $VERSION is Python's version
56  * number as supplied by the Makefile.  Note that this means that no more
57  * build directory checking is performed; if the first step did not find
58  * the landmarks, the assumption is that python is running from an
59  * installed setup.
60  *
61  * Step 2. See if the $PYTHONHOME environment variable points to the
62  * installed location of the Python libraries.  If $PYTHONHOME is set, then
63  * it points to prefix and exec_prefix.  $PYTHONHOME can be a single
64  * directory, which is used for both, or the prefix and exec_prefix
65  * directories separated by a colon.
66  *
67  * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
68  * backtracking up the path until it is exhausted.  This is the most common
69  * step to succeed.  Note that if prefix and exec_prefix are different,
70  * exec_prefix is more likely to be found; however if exec_prefix is a
71  * subdirectory of prefix, both will be found.
72  *
73  * Step 4. Search the directories pointed to by the preprocessor variables
74  * PREFIX and EXEC_PREFIX.  These are supplied by the Makefile but can be
75  * passed in as options to the configure script.
76  *
77  * That's it!
78  *
79  * Well, almost.  Once we have determined prefix and exec_prefix, the
80  * preprocessor variable PYTHONPATH is used to construct a path.  Each
81  * relative path on PYTHONPATH is prefixed with prefix.  Then the directory
82  * containing the shared library modules is appended.  The environment
83  * variable $PYTHONPATH is inserted in front of it all.  Finally, the
84  * prefix and exec_prefix globals are tweaked so they reflect the values
85  * expected by other code, by stripping the "lib/python$VERSION/..." stuff
86  * off.  If either points to the build directory, the globals are reset to
87  * the corresponding preprocessor variables (so sys.prefix will reflect the
88  * installation location, even though sys.path points into the build
89  * directory).  This seems to make more sense given that currently the only
90  * known use of sys.prefix and sys.exec_prefix is for the ILU installation
91  * process to find the installed Python tree.
92  */
93 
94 #ifdef __cplusplus
95  extern "C" {
96 #endif
97 
98 
99 #ifndef VERSION
100 #define VERSION "2.1"
101 #endif
102 
103 #ifndef VPATH
104 #define VPATH "."
105 #endif
106 
107 #ifndef PREFIX
108 #  ifdef __VMS
109 #    define PREFIX ""
110 #  else
111 #    define PREFIX "/usr/local"
112 #  endif
113 #endif
114 
115 #ifndef EXEC_PREFIX
116 #define EXEC_PREFIX PREFIX
117 #endif
118 
119 #ifndef PYTHONPATH
120 #define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
121               EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
122 #endif
123 
124 #ifndef LANDMARK
125 #define LANDMARK "os.py"
126 #endif
127 
128 static char prefix[MAXPATHLEN+1];
129 static char exec_prefix[MAXPATHLEN+1];
130 static char progpath[MAXPATHLEN+1];
131 static char *module_search_path = NULL;
132 static char lib_python[] = "lib/python" VERSION;
133 
134 static void
reduce(char * dir)135 reduce(char *dir)
136 {
137     size_t i = strlen(dir);
138     while (i > 0 && dir[i] != SEP)
139         --i;
140     dir[i] = '\0';
141 }
142 
143 
144 static int
isfile(char * filename)145 isfile(char *filename)          /* Is file, not directory */
146 {
147     struct stat buf;
148     if (stat(filename, &buf) != 0)
149         return 0;
150     if (!S_ISREG(buf.st_mode))
151         return 0;
152     return 1;
153 }
154 
155 
156 static int
ismodule(char * filename)157 ismodule(char *filename)        /* Is module -- check for .pyc/.pyo too */
158 {
159     if (isfile(filename))
160         return 1;
161 
162     /* Check for the compiled version of prefix. */
163     if (strlen(filename) < MAXPATHLEN) {
164         strcat(filename, Py_OptimizeFlag ? "o" : "c");
165         if (isfile(filename))
166             return 1;
167     }
168     return 0;
169 }
170 
171 
172 static int
isxfile(char * filename)173 isxfile(char *filename)         /* Is executable file */
174 {
175     struct stat buf;
176     if (stat(filename, &buf) != 0)
177         return 0;
178     if (!S_ISREG(buf.st_mode))
179         return 0;
180     if ((buf.st_mode & 0111) == 0)
181         return 0;
182     return 1;
183 }
184 
185 
186 static int
isdir(char * filename)187 isdir(char *filename)                   /* Is directory */
188 {
189     struct stat buf;
190     if (stat(filename, &buf) != 0)
191         return 0;
192     if (!S_ISDIR(buf.st_mode))
193         return 0;
194     return 1;
195 }
196 
197 
198 /* Add a path component, by appending stuff to buffer.
199    buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
200    NUL-terminated string with no more than MAXPATHLEN characters (not counting
201    the trailing NUL).  It's a fatal error if it contains a string longer than
202    that (callers must be careful!).  If these requirements are met, it's
203    guaranteed that buffer will still be a NUL-terminated string with no more
204    than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
205    stuff as fits will be appended.
206 */
207 static void
joinpath(char * buffer,char * stuff)208 joinpath(char *buffer, char *stuff)
209 {
210     size_t n, k;
211     if (stuff[0] == SEP)
212         n = 0;
213     else {
214         n = strlen(buffer);
215         if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
216             buffer[n++] = SEP;
217     }
218     if (n > MAXPATHLEN)
219         Py_FatalError("buffer overflow in getpath.c's joinpath()");
220     k = strlen(stuff);
221     if (n + k > MAXPATHLEN)
222         k = MAXPATHLEN - n;
223     strncpy(buffer+n, stuff, k);
224     buffer[n+k] = '\0';
225 }
226 
227 /* copy_absolute requires that path be allocated at least
228    MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
229 static void
copy_absolute(char * path,char * p)230 copy_absolute(char *path, char *p)
231 {
232     if (p[0] == SEP)
233         strcpy(path, p);
234     else {
235         if (!getcwd(path, MAXPATHLEN)) {
236             /* unable to get the current directory */
237             strcpy(path, p);
238             return;
239         }
240         if (p[0] == '.' && p[1] == SEP)
241             p += 2;
242         joinpath(path, p);
243     }
244 }
245 
246 /* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
247 static void
absolutize(char * path)248 absolutize(char *path)
249 {
250     char buffer[MAXPATHLEN + 1];
251 
252     if (path[0] == SEP)
253         return;
254     copy_absolute(buffer, path);
255     strcpy(path, buffer);
256 }
257 
258 /* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
259    bytes long.
260 */
261 static int
search_for_prefix(char * argv0_path,char * home)262 search_for_prefix(char *argv0_path, char *home)
263 {
264     size_t n;
265     char *vpath;
266 
267     /* If PYTHONHOME is set, we believe it unconditionally */
268     if (home) {
269         char *delim;
270         strncpy(prefix, home, MAXPATHLEN);
271         delim = strchr(prefix, DELIM);
272         if (delim)
273             *delim = '\0';
274         joinpath(prefix, lib_python);
275         joinpath(prefix, LANDMARK);
276         return 1;
277     }
278 
279     /* Check to see if argv[0] is in the build directory */
280     strcpy(prefix, argv0_path);
281     joinpath(prefix, "Modules/Setup");
282     if (isfile(prefix)) {
283         /* Check VPATH to see if argv0_path is in the build directory. */
284         vpath = VPATH;
285         strcpy(prefix, argv0_path);
286         joinpath(prefix, vpath);
287         joinpath(prefix, "Lib");
288         joinpath(prefix, LANDMARK);
289         if (ismodule(prefix))
290             return -1;
291     }
292 
293     /* Search from argv0_path, until root is found */
294     copy_absolute(prefix, argv0_path);
295     do {
296         n = strlen(prefix);
297         joinpath(prefix, lib_python);
298         joinpath(prefix, LANDMARK);
299         if (ismodule(prefix))
300             return 1;
301         prefix[n] = '\0';
302         reduce(prefix);
303     } while (prefix[0]);
304 
305     /* Look at configure's PREFIX */
306     strncpy(prefix, PREFIX, MAXPATHLEN);
307     joinpath(prefix, lib_python);
308     joinpath(prefix, LANDMARK);
309     if (ismodule(prefix))
310         return 1;
311 
312     /* Fail */
313     return 0;
314 }
315 
316 
317 /* search_for_exec_prefix requires that argv0_path be no more than
318    MAXPATHLEN bytes long.
319 */
320 static int
search_for_exec_prefix(char * argv0_path,char * home)321 search_for_exec_prefix(char *argv0_path, char *home)
322 {
323     size_t n;
324 
325     /* If PYTHONHOME is set, we believe it unconditionally */
326     if (home) {
327         char *delim;
328         delim = strchr(home, DELIM);
329         if (delim)
330             strncpy(exec_prefix, delim+1, MAXPATHLEN);
331         else
332             strncpy(exec_prefix, home, MAXPATHLEN);
333         joinpath(exec_prefix, lib_python);
334         joinpath(exec_prefix, "lib-dynload");
335         return 1;
336     }
337 
338     /* Check to see if argv[0] is in the build directory */
339     strcpy(exec_prefix, argv0_path);
340     joinpath(exec_prefix, "Modules/Setup");
341     if (isfile(exec_prefix)) {
342         reduce(exec_prefix);
343         return -1;
344     }
345 
346     /* Search from argv0_path, until root is found */
347     copy_absolute(exec_prefix, argv0_path);
348     do {
349         n = strlen(exec_prefix);
350         joinpath(exec_prefix, lib_python);
351         joinpath(exec_prefix, "lib-dynload");
352         if (isdir(exec_prefix))
353             return 1;
354         exec_prefix[n] = '\0';
355         reduce(exec_prefix);
356     } while (exec_prefix[0]);
357 
358     /* Look at configure's EXEC_PREFIX */
359     strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
360     joinpath(exec_prefix, lib_python);
361     joinpath(exec_prefix, "lib-dynload");
362     if (isdir(exec_prefix))
363         return 1;
364 
365     /* Fail */
366     return 0;
367 }
368 
369 
370 static void
calculate_path(void)371 calculate_path(void)
372 {
373     extern char *Py_GetProgramName(void);
374 
375     static char delimiter[2] = {DELIM, '\0'};
376     static char separator[2] = {SEP, '\0'};
377     char *pythonpath = PYTHONPATH;
378     char *rtpypath = Py_GETENV("PYTHONPATH");
379     char *home = Py_GetPythonHome();
380     char *path = getenv("PATH");
381     char *prog = Py_GetProgramName();
382     char argv0_path[MAXPATHLEN+1];
383     char zip_path[MAXPATHLEN+1];
384     int pfound, efound; /* 1 if found; -1 if found build directory */
385     char *buf;
386     size_t bufsz;
387     size_t prefixsz;
388     char *defpath = pythonpath;
389 #ifdef WITH_NEXT_FRAMEWORK
390     NSModule pythonModule;
391 #endif
392 #ifdef __APPLE__
393 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
394     uint32_t nsexeclength = MAXPATHLEN;
395 #else
396     unsigned long nsexeclength = MAXPATHLEN;
397 #endif
398 #endif
399 
400         /* If there is no slash in the argv0 path, then we have to
401          * assume python is on the user's $PATH, since there's no
402          * other way to find a directory to start the search from.  If
403          * $PATH isn't exported, you lose.
404          */
405         if (strchr(prog, SEP))
406                 strncpy(progpath, prog, MAXPATHLEN);
407 #ifdef __APPLE__
408      /* On Mac OS X, if a script uses an interpreter of the form
409       * "#!/opt/python2.3/bin/python", the kernel only passes "python"
410       * as argv[0], which falls through to the $PATH search below.
411       * If /opt/python2.3/bin isn't in your path, or is near the end,
412       * this algorithm may incorrectly find /usr/bin/python. To work
413       * around this, we can use _NSGetExecutablePath to get a better
414       * hint of what the intended interpreter was, although this
415       * will fail if a relative path was used. but in that case,
416       * absolutize() should help us out below
417       */
418      else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
419        ;
420 #endif /* __APPLE__ */
421         else if (path) {
422                 while (1) {
423                         char *delim = strchr(path, DELIM);
424 
425                         if (delim) {
426                                 size_t len = delim - path;
427                                 if (len > MAXPATHLEN)
428                                         len = MAXPATHLEN;
429                                 strncpy(progpath, path, len);
430                                 *(progpath + len) = '\0';
431                         }
432                         else
433                                 strncpy(progpath, path, MAXPATHLEN);
434 
435                         joinpath(progpath, prog);
436                         if (isxfile(progpath))
437                                 break;
438 
439                         if (!delim) {
440                                 progpath[0] = '\0';
441                                 break;
442                         }
443                         path = delim + 1;
444                 }
445         }
446         else
447                 progpath[0] = '\0';
448         if (progpath[0] != SEP && progpath[0] != '\0')
449                 absolutize(progpath);
450         strncpy(argv0_path, progpath, MAXPATHLEN);
451         argv0_path[MAXPATHLEN] = '\0';
452 
453 #ifdef WITH_NEXT_FRAMEWORK
454         /* On Mac OS X we have a special case if we're running from a framework.
455         ** This is because the python home should be set relative to the library,
456         ** which is in the framework, not relative to the executable, which may
457         ** be outside of the framework. Except when we're in the build directory...
458         */
459     pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
460     /* Use dylib functions to find out where the framework was loaded from */
461     buf = (char *)NSLibraryNameForModule(pythonModule);
462     if (buf != NULL) {
463         /* We're in a framework. */
464         /* See if we might be in the build directory. The framework in the
465         ** build directory is incomplete, it only has the .dylib and a few
466         ** needed symlinks, it doesn't have the Lib directories and such.
467         ** If we're running with the framework from the build directory we must
468         ** be running the interpreter in the build directory, so we use the
469         ** build-directory-specific logic to find Lib and such.
470         */
471         strncpy(argv0_path, buf, MAXPATHLEN);
472         reduce(argv0_path);
473         joinpath(argv0_path, lib_python);
474         joinpath(argv0_path, LANDMARK);
475         if (!ismodule(argv0_path)) {
476                 /* We are in the build directory so use the name of the
477                    executable - we know that the absolute path is passed */
478                 strncpy(argv0_path, progpath, MAXPATHLEN);
479         }
480         else {
481                 /* Use the location of the library as the progpath */
482                 strncpy(argv0_path, buf, MAXPATHLEN);
483         }
484     }
485 #endif
486 
487 #if HAVE_READLINK
488     {
489         char tmpbuffer[MAXPATHLEN+1];
490         int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
491         while (linklen != -1) {
492             /* It's not null terminated! */
493             tmpbuffer[linklen] = '\0';
494             if (tmpbuffer[0] == SEP)
495                 /* tmpbuffer should never be longer than MAXPATHLEN,
496                    but extra check does not hurt */
497                 strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
498             else {
499                 /* Interpret relative to progpath */
500                 reduce(argv0_path);
501                 joinpath(argv0_path, tmpbuffer);
502             }
503             linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
504         }
505     }
506 #endif /* HAVE_READLINK */
507 
508     reduce(argv0_path);
509     /* At this point, argv0_path is guaranteed to be less than
510        MAXPATHLEN bytes long.
511     */
512 
513     if (!(pfound = search_for_prefix(argv0_path, home))) {
514         if (!Py_FrozenFlag)
515             fprintf(stderr,
516                 "Could not find platform independent libraries <prefix>\n");
517         strncpy(prefix, PREFIX, MAXPATHLEN);
518         joinpath(prefix, lib_python);
519     }
520     else
521         reduce(prefix);
522 
523     strncpy(zip_path, prefix, MAXPATHLEN);
524     zip_path[MAXPATHLEN] = '\0';
525     if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
526         reduce(zip_path);
527         reduce(zip_path);
528     }
529     else
530         strncpy(zip_path, PREFIX, MAXPATHLEN);
531     joinpath(zip_path, "lib/python00.zip");
532     bufsz = strlen(zip_path);   /* Replace "00" with version */
533     zip_path[bufsz - 6] = VERSION[0];
534     zip_path[bufsz - 5] = VERSION[2];
535 
536     if (!(efound = search_for_exec_prefix(argv0_path, home))) {
537         if (!Py_FrozenFlag)
538             fprintf(stderr,
539                 "Could not find platform dependent libraries <exec_prefix>\n");
540         strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
541         joinpath(exec_prefix, "lib/lib-dynload");
542     }
543     /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */
544 
545     if ((!pfound || !efound) && !Py_FrozenFlag)
546         fprintf(stderr,
547                 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
548 
549     /* Calculate size of return buffer.
550      */
551     bufsz = 0;
552 
553     if (rtpypath)
554         bufsz += strlen(rtpypath) + 1;
555 
556     prefixsz = strlen(prefix) + 1;
557 
558     while (1) {
559         char *delim = strchr(defpath, DELIM);
560 
561         if (defpath[0] != SEP)
562             /* Paths are relative to prefix */
563             bufsz += prefixsz;
564 
565         if (delim)
566             bufsz += delim - defpath + 1;
567         else {
568             bufsz += strlen(defpath) + 1;
569             break;
570         }
571         defpath = delim + 1;
572     }
573 
574     bufsz += strlen(zip_path) + 1;
575     bufsz += strlen(exec_prefix) + 1;
576 
577     /* This is the only malloc call in this file */
578     buf = (char *)PyMem_Malloc(bufsz);
579 
580     if (buf == NULL) {
581         /* We can't exit, so print a warning and limp along */
582         fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
583         fprintf(stderr, "Using default static PYTHONPATH.\n");
584         module_search_path = PYTHONPATH;
585     }
586     else {
587         /* Run-time value of $PYTHONPATH goes first */
588         if (rtpypath) {
589             strcpy(buf, rtpypath);
590             strcat(buf, delimiter);
591         }
592         else
593             buf[0] = '\0';
594 
595         /* Next is the default zip path */
596         strcat(buf, zip_path);
597         strcat(buf, delimiter);
598 
599         /* Next goes merge of compile-time $PYTHONPATH with
600          * dynamically located prefix.
601          */
602         defpath = pythonpath;
603         while (1) {
604             char *delim = strchr(defpath, DELIM);
605 
606             if (defpath[0] != SEP) {
607                 strcat(buf, prefix);
608                 strcat(buf, separator);
609             }
610 
611             if (delim) {
612                 size_t len = delim - defpath + 1;
613                 size_t end = strlen(buf) + len;
614                 strncat(buf, defpath, len);
615                 *(buf + end) = '\0';
616             }
617             else {
618                 strcat(buf, defpath);
619                 break;
620             }
621             defpath = delim + 1;
622         }
623         strcat(buf, delimiter);
624 
625         /* Finally, on goes the directory for dynamic-load modules */
626         strcat(buf, exec_prefix);
627 
628         /* And publish the results */
629         module_search_path = buf;
630     }
631 
632     /* Reduce prefix and exec_prefix to their essence,
633      * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
634      * If we're loading relative to the build directory,
635      * return the compiled-in defaults instead.
636      */
637     if (pfound > 0) {
638         reduce(prefix);
639         reduce(prefix);
640         /* The prefix is the root directory, but reduce() chopped
641          * off the "/". */
642         if (!prefix[0])
643                 strcpy(prefix, separator);
644     }
645     else
646         strncpy(prefix, PREFIX, MAXPATHLEN);
647 
648     if (efound > 0) {
649         reduce(exec_prefix);
650         reduce(exec_prefix);
651         reduce(exec_prefix);
652         if (!exec_prefix[0])
653                 strcpy(exec_prefix, separator);
654     }
655     else
656         strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
657 }
658 
659 
660 /* External interface */
661 
662 char *
Py_GetPath(void)663 Py_GetPath(void)
664 {
665     if (!module_search_path)
666         calculate_path();
667     return module_search_path;
668 }
669 
670 char *
Py_GetPrefix(void)671 Py_GetPrefix(void)
672 {
673     if (!module_search_path)
674         calculate_path();
675     return prefix;
676 }
677 
678 char *
Py_GetExecPrefix(void)679 Py_GetExecPrefix(void)
680 {
681     if (!module_search_path)
682         calculate_path();
683     return exec_prefix;
684 }
685 
686 char *
Py_GetProgramFullPath(void)687 Py_GetProgramFullPath(void)
688 {
689     if (!module_search_path)
690         calculate_path();
691     return progpath;
692 }
693 
694 
695 #ifdef __cplusplus
696 }
697 #endif
698 
699