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