13ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** @file
23ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Return the initial module search path.
33ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    This file is based upon the Modules/getpath.c file from the Python distribution
5d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    but has had everything not exactly necessary for operation on EDK II stripped
6d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    out.
7d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel
83ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Search in specified locations for the associated Python libraries.
93ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    For the EDK II, UEFI, implementation of Python, PREFIX and EXEC_PREFIX
11d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    are set as follows:
12d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel      PREFIX      = /Efi/StdLib
13d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel      EXEC_PREFIX = PREFIX
14d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel
15d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    The volume is assumed to be the current volume when Python was started.
16d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel
173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_GetPath returns module_search_path.
183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_GetPrefix returns PREFIX
193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_GetExec_Prefix returns PREFIX
203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_GetProgramFullPath returns the full path to the python executable.
213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    These are built dynamically so that the proper volume name can be prefixed
233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    to the paths.
243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
25d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    The following final paths (for Python 2.7.10) are assumed:
263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      /Efi/Tools/Python.efi                     The Python executable.
27d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel      /Efi/StdLib/lib/python27.10               The version dependent Python modules.
28d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel      /Efi/StdLib/lib/python.27                 The version independent Python modules.
29d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel      /Efi/StdLib/lib/python27.10/lib-dynload   Dynamically loadable Python extension modules.
303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
31d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    This program and the accompanying materials are licensed and made available under
343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    the terms and conditions of the BSD License that accompanies this distribution.
353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    The full text of the license may be found at
363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    http://opensource.org/licenses/bsd-license.
373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel**/
413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <Python.h>
423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <osdefs.h>
433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include  <ctype.h>
443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
45d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#define SIFY_I( x ) #x
46d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#define SIFY( y )   SIFY_I( y )
473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* VERSION must be at least two characters long. */
493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifndef VERSION
50d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  #define VERSION     SIFY(PY_MAJOR_VERSION) SIFY(PY_MINOR_VERSION)
513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifndef VPATH
543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  #define VPATH       "."
553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* Search path entry delimiter */
583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef DELIM
593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  #define sDELIM        ";"
603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifndef PREFIX
633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  #define PREFIX      "/Efi/StdLib"
643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifndef EXEC_PREFIX
673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  #define EXEC_PREFIX PREFIX
683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifndef   LIBPYTHON
71d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  #define   LIBPYTHON     "lib/python" VERSION "." SIFY(PY_MICRO_VERSION)
723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifndef PYTHONPATH
75d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  #define PYTHONPATH  LIBPYTHON
763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifndef LANDMARK
79d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  #define LANDMARK    "os.py"
80d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#endif
81d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel
82d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#ifdef __cplusplus
83d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel extern "C" {
843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic char   prefix[MAXPATHLEN+1];
873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic char   exec_prefix[MAXPATHLEN+1];
883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic char   progpath[MAXPATHLEN+1];
893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic char  *module_search_path          = NULL;
903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic char   lib_python[]                = LIBPYTHON;
913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic char   volume_name[32]             = { 0 };
923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Determine if "ch" is a separator character.
943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in]  ch      The character to test.
963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @retval     TRUE    ch is a separator character.
983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @retval     FALSE   ch is NOT a separator character.
993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel**/
1003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
1013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielis_sep(char ch)
1023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
1033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  return ch == SEP || ch == ALTSEP;
1043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
1053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Reduce a path by its last element.
1073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    The last element (everything to the right of the last separator character)
1093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    in the path, dir, is removed from the path.  Parameter dir is modified in place.
1103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in,out]    dir   Pointer to the path to modify.
1123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel**/
1133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
1143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielreduce(char *dir)
1153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
1163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    size_t i = strlen(dir);
1173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    while (i > 0 && !is_sep(dir[i]))
1183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        --i;
1193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    dir[i] = '\0';
1203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
1213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Determine if a path is absolute, or not.
1233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    An absolute path consists of a volume name, "VOL:", followed by a rooted path,
1243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    "/path/elements".  If both of these components are present, the path is absolute.
1253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Let P be a pointer to the path to test.
1273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Let A be a pointer to the first ':' in P.
1283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Let B be a pointer to the first '/' or '\\' in P.
1293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    If A and B are not NULL
1313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      If (A-P+1) == (B-P) then the path is absolute.
1323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Otherwise, the path is NOT absolute.
1333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in]  path    The path to test.
1353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @retval     -1      Path is absolute but lacking volume name.
1373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @retval      0      Path is NOT absolute.
1383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @retval      1      Path is absolute.
1393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*/
1403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
1413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielis_absolute(char *path)
1423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
1433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  char  *A;
1443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  char  *B;
1453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  A = strchr(path, ':');
1473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  B = strpbrk(path, "/\\");
1483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  if(B != NULL) {
1503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if(A == NULL) {
1513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      if(B == path) {
1523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return -1;
1533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      }
1543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
1553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
1563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      if(((A - path) + 1) == (B - path)) {
1573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return 1;
1583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      }
1593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
1603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  }
1613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  return 0;
1623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
1633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Add a path component, by appending stuff to buffer.
1663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
1673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    NUL-terminated string with no more than MAXPATHLEN characters (not counting
1683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    the trailing NUL).  It's a fatal error if it contains a string longer than
1693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    that (callers must be careful!).  If these requirements are met, it's
1703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    guaranteed that buffer will still be a NUL-terminated string with no more
1713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    than MAXPATHLEN characters at exit.  If stuff is too long, only as much of
1723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    stuff as fits will be appended.
1733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in,out]    buffer    The path to be extended.
1753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in]        stuff     The stuff to join onto the path.
1763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*/
1773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
1783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieljoinpath(char *buffer, char *stuff)
1793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
1803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  size_t n, k;
1813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  k = 0;
1833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  if (is_absolute(stuff) == 1) {
1843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    n = 0;
1853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  }
1863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  else {
1873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    n = strlen(buffer);
1883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if(n == 0) {
1893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      strncpy(buffer, volume_name, MAXPATHLEN);
1903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      n = strlen(buffer);
1913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
1923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* We must not use an else clause here because we want to test n again.
1933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        volume_name may have been empty.
1943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    */
1953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (n > 0 && n < MAXPATHLEN) {
1963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      if(!is_sep(buffer[n-1])) {
1973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        buffer[n++] = SEP;
1983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      }
1993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      if(is_sep(stuff[0]))   ++stuff;
2003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  }
2023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  if (n > MAXPATHLEN)
2033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_FatalError("buffer overflow in getpath.c's joinpath()");
2043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  k = strlen(stuff);
2053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  if (n + k > MAXPATHLEN)
2063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    k = MAXPATHLEN - n;
2073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  strncpy(buffer+n, stuff, k);
2083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  buffer[n+k] = '\0';
2093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
2103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Is filename an executable file?
2123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    An executable file:
2143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      1) exists
2153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      2) is a file, not a directory
2163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      3) has a name ending with ".efi"
2173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      4) Only has a single '.' in the name.
2183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    If basename(filename) does not contain a '.', append ".efi" to filename
2203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    If filename ends in ".efi", it is executable, else it isn't.
2213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    This routine is used to when searching for the file named by argv[0].
2233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    As such, there is no need to search for extensions other than ".efi".
2243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in]    filename      The name of the file to test.  It may, or may not, have an extension.
2263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @retval       0     filename already has a path other than ".efi", or it doesn't exist, or is a directory.
2283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @retval       1     filename refers to an executable file.
2293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel**/
2303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
2313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielisxfile(char *filename)
2323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
2333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct stat  buf;
2343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char        *bn;
2353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char        *newbn;
2363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int          bnlen;
2373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    bn = basename(filename);            // Separate off the file name component
2393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reduce(filename);                   // and isolate the path component
2403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    bnlen = strlen(bn);
2413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    newbn = strrchr(bn, '.');           // Does basename contain a period?
2423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if(newbn == NULL) {                   // Does NOT contain a period.
2433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      newbn = &bn[bnlen];
2443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      strncpyX(newbn, ".efi", MAXPATHLEN - bnlen);    // append ".efi" to basename
2453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      bnlen += 4;
2463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if(strcmp(newbn, ".efi") != 0) {
2483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      return 0;                         // File can not be executable.
2493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    joinpath(filename, bn);             // Stitch path and file name back together
2513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (stat(filename, &buf) != 0) {    // Now, verify that file exists
2533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      return 0;
2543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if(S_ISDIR(buf.st_mode)) {          // And it is not a directory.
2563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      return 0;
2573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return 1;
2603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
2613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Copy p into path, ensuring that the result is an absolute path.
2633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    copy_absolute requires that path be allocated at least
2653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes.
2663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[out]     path    Destination to receive the absolute path.
2683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in]      p       Path to be tested and possibly converted.
2693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel**/
2703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
2713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielcopy_absolute(char *path, char *p)
2723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
2733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  if (is_absolute(p) == 1)
2743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        strcpy(path, p);
2753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  else {
2763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!getcwd(path, MAXPATHLEN)) {
2773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      /* unable to get the current directory */
2783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      if(volume_name[0] != 0) {
2793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        strcpy(path, volume_name);
2803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        joinpath(path, p);
2813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      }
2823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      else
2833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        strcpy(path, p);
2843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      return;
2853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (p[0] == '.' && is_sep(p[1]))
2873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        p += 2;
2883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    joinpath(path, p);
2893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  }
2903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
2913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Modify path so that the result is an absolute path.
2933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes.
2943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in,out]    path    The path to be made absolute.
2963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*/
2973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
2983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielabsolutize(char *path)
2993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
3003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char buffer[MAXPATHLEN + 1];
3013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (is_absolute(path) == 1)
3033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return;
3043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    copy_absolute(buffer, path);
3053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    strcpy(path, buffer);
3063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
3073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Extract the volume name from a path.
3093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[out]   Dest    Pointer to location in which to store the extracted volume name.
3113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    @param[in]    path    Pointer to the path to extract the volume name from.
3123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel**/
3133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
3143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielset_volume(char *Dest, char *path)
3153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
3163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  size_t    VolLen;
3173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  if(is_absolute(path)) {
3193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    VolLen = strcspn(path, "/\\:");
3203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if((VolLen != 0) && (path[VolLen] == ':')) {
3213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      (void) strncpyX(Dest, path, VolLen + 1);
3223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
3233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  }
3243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
3253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/** Determine paths.
3283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Two directories must be found, the platform independent directory
3303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (prefix), containing the common .py and .pyc files, and the platform
3313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    dependent directory (exec_prefix), containing the shared library
3323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    modules.  Note that prefix and exec_prefix are the same directory
3333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    for UEFI installations.
3343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Separate searches are carried out for prefix and exec_prefix.
3363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Each search tries a number of different locations until a ``landmark''
3373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    file or directory is found.  If no prefix or exec_prefix is found, a
3383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    warning message is issued and the preprocessor defined PREFIX and
3393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    EXEC_PREFIX are used (even though they may not work); python carries on
3403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    as best as is possible, but some imports may fail.
3413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Before any searches are done, the location of the executable is
3433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    determined.  If argv[0] has one or more slashes in it, it is used
3443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    unchanged.  Otherwise, it must have been invoked from the shell's path,
3453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    so we search %PATH% for the named executable and use that.  If the
3463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    executable was not found on %PATH% (or there was no %PATH% environment
3473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    variable), the original argv[0] string is used.
3483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Finally, argv0_path is set to the directory containing the executable
3503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (i.e. the last component is stripped).
3513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    With argv0_path in hand, we perform a number of steps.  The same steps
3533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    are performed for prefix and for exec_prefix, but with a different
3543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    landmark.
3553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    The prefix landmark will always be lib/python.VERSION/os.py and the
3573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    exec_prefix will always be lib/python.VERSION/dynaload, where VERSION
3583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    is Python's version number as defined at the beginning of this file.
3593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    First. See if the %PYTHONHOME% environment variable points to the
3613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    installed location of the Python libraries.  If %PYTHONHOME% is set, then
3623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    it points to prefix and exec_prefix.  %PYTHONHOME% can be a single
3633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    directory, which is used for both, or the prefix and exec_prefix
3643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    directories separated by the DELIM character.
3653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Next. Search the directories pointed to by the preprocessor variables
3673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PREFIX and EXEC_PREFIX.  These paths are prefixed with the volume name
3683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    extracted from argv0_path.  The volume names correspond to the UEFI
3693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    shell "map" names.
3703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    That's it!
3723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Well, almost.  Once we have determined prefix and exec_prefix, the
3743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    preprocessor variable PYTHONPATH is used to construct a path.  Each
3753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    relative path on PYTHONPATH is prefixed with prefix.  Then the directory
3763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    containing the shared library modules is appended.  The environment
3773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    variable $PYTHONPATH is inserted in front of it all.  Finally, the
3783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    prefix and exec_prefix globals are tweaked so they reflect the values
3793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    expected by other code, by stripping the "lib/python$VERSION/..." stuff
3803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    off.  This seems to make more sense given that currently the only
3813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    known use of sys.prefix and sys.exec_prefix is for the ILU installation
3823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    process to find the installed Python tree.
3833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    The final, fully resolved, paths should look something like:
3853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      fs0:/Efi/Tools/python.efi
3863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      fs0:/Efi/StdLib/lib/python27
3873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      fs0:/Efi/StdLib/lib/python27/dynaload
3883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel**/
3903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
3913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielcalculate_path(void)
3923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
3933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    extern char *Py_GetProgramName(void);
3943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char delimiter[2] = {DELIM, '\0'};
3963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char separator[2] = {SEP, '\0'};
3973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char *pythonpath = PYTHONPATH;
3983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char *rtpypath = Py_GETENV("PYTHONPATH");
3993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    //char *home = Py_GetPythonHome();
400d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    char *path = getenv("path");
4013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char *prog = Py_GetProgramName();
4023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char argv0_path[MAXPATHLEN+1];
4033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char zip_path[MAXPATHLEN+1];
4043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char *buf;
4053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    size_t bufsz;
4063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    size_t prefixsz;
4073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char *defpath;
4083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* ###########################################################################
4113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      Determine path to the Python.efi binary.
4123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      Produces progpath, argv0_path, and volume_name.
4133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel########################################################################### */
4143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* If there is no slash in the argv0 path, then we have to
4163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * assume python is on the user's $PATH, since there's no
4173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * other way to find a directory to start the search from.  If
4183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * $PATH isn't exported, you lose.
4193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     */
4203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (strchr(prog, SEP))
4213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            strncpy(progpath, prog, MAXPATHLEN);
4223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if (path) {
4233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      while (1) {
4243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        char *delim = strchr(path, DELIM);
4253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (delim) {
4273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                size_t len = delim - path;
4283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                if (len > MAXPATHLEN)
4293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        len = MAXPATHLEN;
4303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                strncpy(progpath, path, len);
4313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                *(progpath + len) = '\0';
4323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
4333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        else
4343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                strncpy(progpath, path, MAXPATHLEN);
4353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        joinpath(progpath, prog);
4373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (isxfile(progpath))
4383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                break;
4393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (!delim) {
4413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                progpath[0] = '\0';
4423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                break;
4433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
4443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        path = delim + 1;
4453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      }
4463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
4473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else
4483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            progpath[0] = '\0';
4493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if ( (!is_absolute(progpath)) && (progpath[0] != '\0') )
4503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            absolutize(progpath);
4513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    strncpy(argv0_path, progpath, MAXPATHLEN);
4523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    argv0_path[MAXPATHLEN] = '\0';
4533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    set_volume(volume_name, argv0_path);
4543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reduce(argv0_path);
4563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* At this point, argv0_path is guaranteed to be less than
4573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel       MAXPATHLEN bytes long.
4583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    */
4593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* ###########################################################################
4613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      Build the FULL prefix string, including volume name.
4623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      This is the full path to the platform independent libraries.
4633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel########################################################################### */
4643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
465d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    strncpy(prefix, volume_name, MAXPATHLEN);
466d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    joinpath(prefix, PREFIX);
467d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    joinpath(prefix, lib_python);
4683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* ###########################################################################
4703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      Build the FULL path to the zipped-up Python library.
4713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel########################################################################### */
4723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    strncpy(zip_path, prefix, MAXPATHLEN);
4743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    zip_path[MAXPATHLEN] = '\0';
4753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reduce(zip_path);
4763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    joinpath(zip_path, "python00.zip");
4773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    bufsz = strlen(zip_path);   /* Replace "00" with version */
4783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    zip_path[bufsz - 6] = VERSION[0];
4793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    zip_path[bufsz - 5] = VERSION[1];
4803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* ###########################################################################
4823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      Build the FULL path to dynamically loadable libraries.
4833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel########################################################################### */
4843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
485d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    strncpy(exec_prefix, volume_name, MAXPATHLEN);    // "fs0:"
486d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    joinpath(exec_prefix, EXEC_PREFIX);               // "fs0:/Efi/StdLib"
487d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    joinpath(exec_prefix, lib_python);                // "fs0:/Efi/StdLib/lib/python.27"
488d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    joinpath(exec_prefix, "lib-dynload");             // "fs0:/Efi/StdLib/lib/python.27/lib-dynload"
4893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* ###########################################################################
4913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      Build the module search path.
4923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel########################################################################### */
4933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Reduce prefix and exec_prefix to their essence,
4953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
4963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * If we're loading relative to the build directory,
4973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * return the compiled-in defaults instead.
4983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     */
4993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reduce(prefix);
5003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reduce(prefix);
5013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* The prefix is the root directory, but reduce() chopped
5023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * off the "/". */
5033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!prefix[0]) {
5043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      strcpy(prefix, volume_name);
5053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    bufsz = strlen(prefix);
507d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel    if(prefix[bufsz-1] == ':') {    // if prefix consists solely of a volume_name
508d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel      prefix[bufsz] = SEP;          //    then append SEP indicating the root directory
509d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel      prefix[bufsz+1] = 0;          //    and ensure the new string is terminated
5103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Calculate size of return buffer.
5133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     */
5143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    defpath = pythonpath;
5153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    bufsz = 0;
5163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (rtpypath)
5183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        bufsz += strlen(rtpypath) + 1;
5193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    prefixsz = strlen(prefix) + 1;
5213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    while (1) {
5233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        char *delim = strchr(defpath, DELIM);
5243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (is_absolute(defpath) == 0)
5263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            /* Paths are relative to prefix */
5273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            bufsz += prefixsz;
5283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (delim)
5303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            bufsz += delim - defpath + 1;
5313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        else {
5323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            bufsz += strlen(defpath) + 1;
5333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            break;
5343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
5353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        defpath = delim + 1;
5363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    bufsz += strlen(zip_path) + 1;
5393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    bufsz += strlen(exec_prefix) + 1;
5403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* This is the only malloc call in this file */
5423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    buf = (char *)PyMem_Malloc(bufsz);
5433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (buf == NULL) {
5453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* We can't exit, so print a warning and limp along */
5463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
5473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        fprintf(stderr, "Using default static PYTHONPATH.\n");
5483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        module_search_path = PYTHONPATH;
5493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
5513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* Run-time value of $PYTHONPATH goes first */
5523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (rtpypath) {
5533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            strcpy(buf, rtpypath);
5543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            strcat(buf, delimiter);
5553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
5563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        else
5573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            buf[0] = '\0';
5583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* Next is the default zip path */
5603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        strcat(buf, zip_path);
5613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        strcat(buf, delimiter);
5623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* Next goes merge of compile-time $PYTHONPATH with
5643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel         * dynamically located prefix.
5653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel         */
5663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        defpath = pythonpath;
5673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        while (1) {
5683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            char *delim = strchr(defpath, DELIM);
5693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if (is_absolute(defpath) != 1) {
5713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                strcat(buf, prefix);
5723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                strcat(buf, separator);
5733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
5743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if (delim) {
5763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                size_t len = delim - defpath + 1;
5773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                size_t end = strlen(buf) + len;
5783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                strncat(buf, defpath, len);
5793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                *(buf + end) = '\0';
5803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
5813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            else {
5823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                strcat(buf, defpath);
5833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                break;
5843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
5853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            defpath = delim + 1;
5863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
5873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        strcat(buf, delimiter);
5883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* Finally, on goes the directory for dynamic-load modules */
5903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        strcat(buf, exec_prefix);
5913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* And publish the results */
5933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        module_search_path = buf;
5943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /*  At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib.
5963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            We want to get back to the root value, so we have to remove the final three
5973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            segments to get VOL:/Efi/StdLib.  Because we don't know what VOL is, and
5983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            EXEC_PREFIX is also indeterminate, we just remove the three final segments.
5993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        */
6003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        reduce(exec_prefix);
6013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        reduce(exec_prefix);
6023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        reduce(exec_prefix);
6033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (!exec_prefix[0]) {
6043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel          strcpy(exec_prefix, volume_name);
6053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
6063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        bufsz = strlen(exec_prefix);
6073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if(exec_prefix[bufsz-1] == ':') {
6083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel          exec_prefix[bufsz] = SEP;
6093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel          exec_prefix[bufsz+1] = 0;
6103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
6113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path);
6123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix             = \"%s\"\n", __func__, __LINE__, prefix);
6133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix        = \"%s\"\n", __func__, __LINE__, exec_prefix);
6143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath           = \"%s\"\n", __func__, __LINE__, progpath);
6153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* External interface */
6193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielchar *
6213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPy_GetPath(void)
6223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!module_search_path)
6243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        calculate_path();
6253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return module_search_path;
6263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielchar *
6293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPy_GetPrefix(void)
6303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!module_search_path)
6323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        calculate_path();
6333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return prefix;
6343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielchar *
6373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPy_GetExecPrefix(void)
6383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!module_search_path)
6403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        calculate_path();
6413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return exec_prefix;
6423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielchar *
6453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPy_GetProgramFullPath(void)
6463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!module_search_path)
6483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        calculate_path();
6493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return progpath;
6503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef __cplusplus
6543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
6563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
657