/**
 *  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);
}
Exemple #2
0
/* {{{ 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;
}