/** * Constructor * * The constructor receives a filename as parameter. It uses the normal * PHP include path resolve algorithms to find the location of the file. * * @param name the filename * @param size length of the filename */ File::File(const char *name, size_t size) { // we need the tsrm_ls variable TSRMLS_FETCH(); // resolve the path _path = zend_resolve_path(name, size TSRMLS_CC); // the resolve-path function sometimes returns the original pointer, we // do not want that because we may have to store the pathname in this object if (_path != name) return; // make a full copy of the pathname _path = estrndup(name, size); }
/* {{{ php_fopen_primary_script */ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) { char *path_info; char *filename = NULL; zend_string *resolved_path = NULL; int length; zend_bool orig_display_errors; path_info = SG(request_info).request_uri; #if HAVE_PWD_H if (PG(user_dir) && *PG(user_dir) && path_info && '/' == path_info[0] && '~' == path_info[1]) { char *s = strchr(path_info + 2, '/'); if (s) { /* if there is no path name after the file, do not bother */ char user[32]; /* to try open the directory */ struct passwd *pw; #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) struct passwd pwstruc; long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *pwbuf; if (pwbuflen < 1) { return FAILURE; } pwbuf = emalloc(pwbuflen); #endif length = s - (path_info + 2); if (length > (int)sizeof(user) - 1) { length = sizeof(user) - 1; } memcpy(user, path_info + 2, length); user[length] = '\0'; #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) if (getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw)) { efree(pwbuf); return FAILURE; } #else pw = getpwnam(user); #endif if (pw && pw->pw_dir) { spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */ } else { filename = SG(request_info).path_translated; } #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) efree(pwbuf); #endif } } else #endif if (PG(doc_root) && path_info && (length = (int)strlen(PG(doc_root))) && IS_ABSOLUTE_PATH(PG(doc_root), length)) { int path_len = (int)strlen(path_info); filename = emalloc(length + path_len + 2); if (filename) { memcpy(filename, PG(doc_root), length); if (!IS_SLASH(filename[length - 1])) { /* length is never 0 */ filename[length++] = PHP_DIR_SEPARATOR; } if (IS_SLASH(path_info[0])) { length--; } strncpy(filename + length, path_info, path_len + 1); } } else { filename = SG(request_info).path_translated; } if (filename) { resolved_path = zend_resolve_path(filename, (int)strlen(filename)); } if (!resolved_path) { if (SG(request_info).path_translated != filename) { if (filename) { efree(filename); } } /* we have to free SG(request_info).path_translated here because * php_destroy_request_info assumes that it will get * freed when the include_names hash is emptied, but * we're not adding it in this case */ if (SG(request_info).path_translated) { efree(SG(request_info).path_translated); SG(request_info).path_translated = NULL; } return FAILURE; } zend_string_release(resolved_path); orig_display_errors = PG(display_errors); PG(display_errors) = 0; if (zend_stream_open(filename, file_handle) == FAILURE) { PG(display_errors) = orig_display_errors; if (SG(request_info).path_translated != filename) { if (filename) { efree(filename); } } if (SG(request_info).path_translated) { efree(SG(request_info).path_translated); SG(request_info).path_translated = NULL; } return FAILURE; } PG(display_errors) = orig_display_errors; if (SG(request_info).path_translated != filename) { if (SG(request_info).path_translated) { efree(SG(request_info).path_translated); } SG(request_info).path_translated = filename; } return SUCCESS; }