Exemplo n.º 1
0
static void
calculate_path(void)
{
    wchar_t argv0_path[MAXPATHLEN+1];
    wchar_t *buf;
    size_t bufsz;
    wchar_t *pythonhome = Py_GetPythonHome();
    wchar_t *envpath = NULL;

    int skiphome, skipdefault;
    wchar_t *machinepath = NULL;
    wchar_t *userpath = NULL;
    wchar_t zip_path[MAXPATHLEN+1];

    if (!Py_IgnoreEnvironmentFlag) {
        envpath = _wgetenv(L"PYTHONPATH");
    }

    get_progpath();
    /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
    wcscpy_s(argv0_path, MAXPATHLEN+1, progpath);
    reduce(argv0_path);

    /* Search for a sys.path file */
    {
        wchar_t spbuffer[MAXPATHLEN+1];

        if ((dllpath[0] && !change_ext(spbuffer, dllpath, L"._pth") && exists(spbuffer)) ||
            (progpath[0] && !change_ext(spbuffer, progpath, L"._pth") && exists(spbuffer))) {

            if (!read_pth_file(spbuffer, prefix, &Py_IsolatedFlag, &Py_NoSiteFlag)) {
                return;
            }
        }
    }

    /* Search for an environment configuration file, first in the
       executable's directory and then in the parent directory.
       If found, open it for use when searching for prefixes.
    */

    {
        wchar_t envbuffer[MAXPATHLEN+1];
        wchar_t tmpbuffer[MAXPATHLEN+1];
        const wchar_t *env_cfg = L"pyvenv.cfg";
        FILE * env_file = NULL;

        wcscpy_s(envbuffer, MAXPATHLEN+1, argv0_path);
        join(envbuffer, env_cfg);
        env_file = _Py_wfopen(envbuffer, L"r");
        if (env_file == NULL) {
            errno = 0;
            reduce(envbuffer);
            reduce(envbuffer);
            join(envbuffer, env_cfg);
            env_file = _Py_wfopen(envbuffer, L"r");
            if (env_file == NULL) {
                errno = 0;
            }
        }
        if (env_file != NULL) {
            /* Look for a 'home' variable and set argv0_path to it, if found */
            if (find_env_config_value(env_file, L"home", tmpbuffer)) {
                wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer);
            }
            fclose(env_file);
            env_file = NULL;
        }
    }

    /* Calculate zip archive path from DLL or exe path */
    change_ext(zip_path, dllpath[0] ? dllpath : progpath, L".zip");

    if (pythonhome == NULL || *pythonhome == '\0') {
        if (zip_path[0] && exists(zip_path)) {
            wcscpy_s(prefix, MAXPATHLEN+1, zip_path);
            reduce(prefix);
            pythonhome = prefix;
        } else if (search_for_prefix(argv0_path, LANDMARK))
            pythonhome = prefix;
        else
            pythonhome = NULL;
    }
    else
        wcscpy_s(prefix, MAXPATHLEN+1, pythonhome);

    if (envpath && *envpath == '\0')
        envpath = NULL;


    skiphome = pythonhome==NULL ? 0 : 1;
#ifdef Py_ENABLE_SHARED
    machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
    userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
#endif
    /* We only use the default relative PYTHONPATH if we havent
       anything better to use! */
    skipdefault = envpath!=NULL || pythonhome!=NULL || \
                  machinepath!=NULL || userpath!=NULL;

    /* We need to construct a path from the following parts.
       (1) the PYTHONPATH environment variable, if set;
       (2) for Win32, the zip archive file path;
       (3) for Win32, the machinepath and userpath, if set;
       (4) the PYTHONPATH config macro, with the leading "."
           of each component replaced with pythonhome, if set;
       (5) the directory containing the executable (argv0_path).
       The length calculation calculates #4 first.
       Extra rules:
       - If PYTHONHOME is set (in any way) item (3) is ignored.
       - If registry values are used, (4) and (5) are ignored.
    */

    /* Calculate size of return buffer */
    if (pythonhome != NULL) {
        wchar_t *p;
        bufsz = 1;
        for (p = PYTHONPATH; *p; p++) {
            if (*p == DELIM)
                bufsz++; /* number of DELIM plus one */
        }
        bufsz *= wcslen(pythonhome);
    }
    else
        bufsz = 0;
    bufsz += wcslen(PYTHONPATH) + 1;
    bufsz += wcslen(argv0_path) + 1;
    if (userpath)
        bufsz += wcslen(userpath) + 1;
    if (machinepath)
        bufsz += wcslen(machinepath) + 1;
    bufsz += wcslen(zip_path) + 1;
    if (envpath != NULL)
        bufsz += wcslen(envpath) + 1;

    module_search_path = buf = PyMem_RawMalloc(bufsz*sizeof(wchar_t));
    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
        if (envpath) {
            fprintf(stderr, "Using environment $PYTHONPATH.\n");
            module_search_path = envpath;
        }
        else {
            fprintf(stderr, "Using default static path.\n");
            module_search_path = PYTHONPATH;
        }
        PyMem_RawFree(machinepath);
        PyMem_RawFree(userpath);
        return;
    }

    if (envpath) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), envpath))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (zip_path[0]) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (userpath) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
        PyMem_RawFree(userpath);
    }
    if (machinepath) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), machinepath))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
        PyMem_RawFree(machinepath);
    }
    if (pythonhome == NULL) {
        if (!skipdefault) {
            if (wcscpy_s(buf, bufsz - (buf - module_search_path), PYTHONPATH))
                Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
            buf = wcschr(buf, L'\0');
            *buf++ = DELIM;
        }
    } else {
        wchar_t *p = PYTHONPATH;
        wchar_t *q;
        size_t n;
        for (;;) {
            q = wcschr(p, DELIM);
            if (q == NULL)
                n = wcslen(p);
            else
                n = q-p;
            if (p[0] == '.' && is_sep(p[1])) {
                if (wcscpy_s(buf, bufsz - (buf - module_search_path), pythonhome))
                    Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
                buf = wcschr(buf, L'\0');
                p++;
                n--;
            }
            wcsncpy(buf, p, n);
            buf += n;
            *buf++ = DELIM;
            if (q == NULL)
                break;
            p = q+1;
        }
    }
    if (argv0_path) {
        wcscpy(buf, argv0_path);
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    *(buf - 1) = L'\0';
    /* Now to pull one last hack/trick.  If sys.prefix is
       empty, then try and find it somewhere on the paths
       we calculated.  We scan backwards, as our general policy
       is that Python core directories are at the *end* of
       sys.path.  We assume that our "lib" directory is
       on the path, and that our 'prefix' directory is
       the parent of that.
    */
    if (*prefix==L'\0') {
        wchar_t lookBuf[MAXPATHLEN+1];
        wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
        while (1) {
            Py_ssize_t nchars;
            wchar_t *lookEnd = look;
            /* 'look' will end up one character before the
               start of the path in question - even if this
               is one character before the start of the buffer
            */
            while (look >= module_search_path && *look != DELIM)
                look--;
            nchars = lookEnd-look;
            wcsncpy(lookBuf, look+1, nchars);
            lookBuf[nchars] = L'\0';
            /* Up one level to the parent */
            reduce(lookBuf);
            if (search_for_prefix(lookBuf, LANDMARK)) {
                break;
            }
            /* If we are out of paths to search - give up */
            if (look < module_search_path)
                break;
            look--;
        }
    }
}
Exemplo n.º 2
0
static void
calculate_path(void)
{
    char argv0_path[MAXPATHLEN+1];
    char *buf;
    size_t bufsz;
    char *pythonhome = Py_GetPythonHome();
    char *envpath = Py_GETENV("PYTHONPATH");

#ifdef MS_WINDOWS
    int skiphome, skipdefault;
    char *machinepath = NULL;
    char *userpath = NULL;
    char zip_path[MAXPATHLEN+1];
    size_t len;
#endif

    get_progpath();
    /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
    strcpy(argv0_path, progpath);
    reduce(argv0_path);
    if (pythonhome == NULL || *pythonhome == '\0') {
        if (search_for_prefix(argv0_path, LANDMARK))
            pythonhome = prefix;
        else
            pythonhome = NULL;
    }
    else
        strncpy(prefix, pythonhome, MAXPATHLEN);

    if (envpath && *envpath == '\0')
        envpath = NULL;


#ifdef MS_WINDOWS
    /* Calculate zip archive path */
    if (dllpath[0])             /* use name of python DLL */
        strncpy(zip_path, dllpath, MAXPATHLEN);
    else                        /* use name of executable program */
        strncpy(zip_path, progpath, MAXPATHLEN);
    zip_path[MAXPATHLEN] = '\0';
    len = strlen(zip_path);
    if (len > 4) {
        zip_path[len-3] = 'z';          /* change ending to "zip" */
        zip_path[len-2] = 'i';
        zip_path[len-1] = 'p';
    }
    else {
        zip_path[0] = 0;
    }

    skiphome = pythonhome==NULL ? 0 : 1;
#ifdef Py_ENABLE_SHARED
    machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
    userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
#endif
    /* We only use the default relative PYTHONPATH if we havent
       anything better to use! */
    skipdefault = envpath!=NULL || pythonhome!=NULL || \
                  machinepath!=NULL || userpath!=NULL;
#endif

    /* We need to construct a path from the following parts.
       (1) the PYTHONPATH environment variable, if set;
       (2) for Win32, the zip archive file path;
       (3) for Win32, the machinepath and userpath, if set;
       (4) the PYTHONPATH config macro, with the leading "."
           of each component replaced with pythonhome, if set;
       (5) the directory containing the executable (argv0_path).
       The length calculation calculates #4 first.
       Extra rules:
       - If PYTHONHOME is set (in any way) item (3) is ignored.
       - If registry values are used, (4) and (5) are ignored.
    */

    /* Calculate size of return buffer */
    if (pythonhome != NULL) {
        char *p;
        bufsz = 1;
        for (p = PYTHONPATH; *p; p++) {
            if (*p == DELIM)
                bufsz++; /* number of DELIM plus one */
        }
        bufsz *= strlen(pythonhome);
    }
    else
        bufsz = 0;
    bufsz += strlen(PYTHONPATH) + 1;
    bufsz += strlen(argv0_path) + 1;
#ifdef MS_WINDOWS
    if (userpath)
        bufsz += strlen(userpath) + 1;
    if (machinepath)
        bufsz += strlen(machinepath) + 1;
    bufsz += strlen(zip_path) + 1;
#endif
    if (envpath != NULL)
        bufsz += strlen(envpath) + 1;

    module_search_path = buf = malloc(bufsz);
    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
        if (envpath) {
            fprintf(stderr, "Using environment $PYTHONPATH.\n");
            module_search_path = envpath;
        }
        else {
            fprintf(stderr, "Using default static path.\n");
            module_search_path = PYTHONPATH;
        }
#ifdef MS_WINDOWS
        if (machinepath)
            free(machinepath);
        if (userpath)
            free(userpath);
#endif /* MS_WINDOWS */
        return;
    }

    if (envpath) {
        strcpy(buf, envpath);
        buf = strchr(buf, '\0');
        *buf++ = DELIM;
    }
#ifdef MS_WINDOWS
    if (zip_path[0]) {
        strcpy(buf, zip_path);
        buf = strchr(buf, '\0');
        *buf++ = DELIM;
    }
    if (userpath) {
        strcpy(buf, userpath);
        buf = strchr(buf, '\0');
        *buf++ = DELIM;
        free(userpath);
    }
    if (machinepath) {
        strcpy(buf, machinepath);
        buf = strchr(buf, '\0');
        *buf++ = DELIM;
        free(machinepath);
    }
    if (pythonhome == NULL) {
        if (!skipdefault) {
            strcpy(buf, PYTHONPATH);
            buf = strchr(buf, '\0');
        }
    }
#else
    if (pythonhome == NULL) {
        strcpy(buf, PYTHONPATH);
        buf = strchr(buf, '\0');
    }
#endif /* MS_WINDOWS */
    else {
        char *p = PYTHONPATH;
        char *q;
        size_t n;
        for (;;) {
            q = strchr(p, DELIM);
            if (q == NULL)
                n = strlen(p);
            else
                n = q-p;
            if (p[0] == '.' && is_sep(p[1])) {
                strcpy(buf, pythonhome);
                buf = strchr(buf, '\0');
                p++;
                n--;
            }
            strncpy(buf, p, n);
            buf += n;
            if (q == NULL)
                break;
            *buf++ = DELIM;
            p = q+1;
        }
    }
    if (argv0_path) {
        *buf++ = DELIM;
        strcpy(buf, argv0_path);
        buf = strchr(buf, '\0');
    }
    *buf = '\0';
    /* Now to pull one last hack/trick.  If sys.prefix is
       empty, then try and find it somewhere on the paths
       we calculated.  We scan backwards, as our general policy
       is that Python core directories are at the *end* of
       sys.path.  We assume that our "lib" directory is
       on the path, and that our 'prefix' directory is
       the parent of that.
    */
    if (*prefix=='\0') {
        char lookBuf[MAXPATHLEN+1];
        char *look = buf - 1; /* 'buf' is at the end of the buffer */
        while (1) {
            Py_ssize_t nchars;
            char *lookEnd = look;
            /* 'look' will end up one character before the
               start of the path in question - even if this
               is one character before the start of the buffer
            */
            while (look >= module_search_path && *look != DELIM)
                look--;
            nchars = lookEnd-look;
            strncpy(lookBuf, look+1, nchars);
            lookBuf[nchars] = '\0';
            /* Up one level to the parent */
            reduce(lookBuf);
            if (search_for_prefix(lookBuf, LANDMARK)) {
                break;
            }
            /* If we are out of paths to search - give up */
            if (look < module_search_path)
                break;
            look--;
        }
    }
}
Exemplo n.º 3
0
static _PyInitError
calculate_module_search_path(const _PyCoreConfig *core_config,
                             PyCalculatePath *calculate, _PyPathConfig *config,
                             wchar_t *prefix)
{
    int skiphome = calculate->home==NULL ? 0 : 1;
#ifdef Py_ENABLE_SHARED
    calculate->machine_path = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
    calculate->user_path = getpythonregpath(HKEY_CURRENT_USER, skiphome);
#endif
    /* We only use the default relative PYTHONPATH if we haven't
       anything better to use! */
    int skipdefault = (core_config->module_search_path_env != NULL ||
                       calculate->home != NULL ||
                       calculate->machine_path != NULL ||
                       calculate->user_path != NULL);

    /* We need to construct a path from the following parts.
       (1) the PYTHONPATH environment variable, if set;
       (2) for Win32, the zip archive file path;
       (3) for Win32, the machine_path and user_path, if set;
       (4) the PYTHONPATH config macro, with the leading "."
           of each component replaced with home, if set;
       (5) the directory containing the executable (argv0_path).
       The length calculation calculates #4 first.
       Extra rules:
       - If PYTHONHOME is set (in any way) item (3) is ignored.
       - If registry values are used, (4) and (5) are ignored.
    */

    /* Calculate size of return buffer */
    size_t bufsz = 0;
    if (calculate->home != NULL) {
        const wchar_t *p;
        bufsz = 1;
        for (p = PYTHONPATH; *p; p++) {
            if (*p == DELIM) {
                bufsz++; /* number of DELIM plus one */
            }
        }
        bufsz *= wcslen(calculate->home);
    }
    bufsz += wcslen(PYTHONPATH) + 1;
    bufsz += wcslen(calculate->argv0_path) + 1;
    if (calculate->user_path) {
        bufsz += wcslen(calculate->user_path) + 1;
    }
    if (calculate->machine_path) {
        bufsz += wcslen(calculate->machine_path) + 1;
    }
    bufsz += wcslen(calculate->zip_path) + 1;
    if (core_config->module_search_path_env != NULL) {
        bufsz += wcslen(core_config->module_search_path_env) + 1;
    }

    wchar_t *buf, *start_buf;
    buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
        if (core_config->module_search_path_env) {
            fprintf(stderr, "Using environment $PYTHONPATH.\n");
            config->module_search_path = core_config->module_search_path_env;
        }
        else {
            fprintf(stderr, "Using default static path.\n");
            config->module_search_path = PYTHONPATH;
        }
        return _Py_INIT_OK();
    }
    start_buf = buf;

    if (core_config->module_search_path_env) {
        if (wcscpy_s(buf, bufsz - (buf - start_buf),
                     core_config->module_search_path_env)) {
            return INIT_ERR_BUFFER_OVERFLOW();
        }
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (calculate->zip_path[0]) {
        if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->zip_path)) {
            return INIT_ERR_BUFFER_OVERFLOW();
        }
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (calculate->user_path) {
        if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->user_path)) {
            return INIT_ERR_BUFFER_OVERFLOW();
        }
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (calculate->machine_path) {
        if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->machine_path)) {
            return INIT_ERR_BUFFER_OVERFLOW();
        }
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (calculate->home == NULL) {
        if (!skipdefault) {
            if (wcscpy_s(buf, bufsz - (buf - start_buf), PYTHONPATH)) {
                return INIT_ERR_BUFFER_OVERFLOW();
            }
            buf = wcschr(buf, L'\0');
            *buf++ = DELIM;
        }
    } else {
        const wchar_t *p = PYTHONPATH;
        const wchar_t *q;
        size_t n;
        for (;;) {
            q = wcschr(p, DELIM);
            if (q == NULL) {
                n = wcslen(p);
            }
            else {
                n = q-p;
            }
            if (p[0] == '.' && is_sep(p[1])) {
                if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->home)) {
                    return INIT_ERR_BUFFER_OVERFLOW();
                }
                buf = wcschr(buf, L'\0');
                p++;
                n--;
            }
            wcsncpy(buf, p, n);
            buf += n;
            *buf++ = DELIM;
            if (q == NULL) {
                break;
            }
            p = q+1;
        }
    }
    if (calculate->argv0_path) {
        wcscpy(buf, calculate->argv0_path);
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    *(buf - 1) = L'\0';

    /* Now to pull one last hack/trick.  If sys.prefix is
       empty, then try and find it somewhere on the paths
       we calculated.  We scan backwards, as our general policy
       is that Python core directories are at the *end* of
       sys.path.  We assume that our "lib" directory is
       on the path, and that our 'prefix' directory is
       the parent of that.
    */
    if (prefix[0] == L'\0') {
        wchar_t lookBuf[MAXPATHLEN+1];
        const wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
        while (1) {
            Py_ssize_t nchars;
            const wchar_t *lookEnd = look;
            /* 'look' will end up one character before the
               start of the path in question - even if this
               is one character before the start of the buffer
            */
            while (look >= start_buf && *look != DELIM)
                look--;
            nchars = lookEnd-look;
            wcsncpy(lookBuf, look+1, nchars);
            lookBuf[nchars] = L'\0';
            /* Up one level to the parent */
            reduce(lookBuf);
            if (search_for_prefix(prefix, lookBuf, LANDMARK)) {
                break;
            }
            /* If we are out of paths to search - give up */
            if (look < start_buf) {
                break;
            }
            look--;
        }
    }

    config->module_search_path = start_buf;
    return _Py_INIT_OK();
}