219 lines
5.9 KiB
PHP
219 lines
5.9 KiB
PHP
|
<?php
|
||
|
if( !defined( '_JEXEC' ) && !defined( '_VALID_MOS' ) ) die( 'Restricted access' );
|
||
|
/**
|
||
|
* @version $Id: path.php 9854 2008-01-04 15:44:02Z jinx $
|
||
|
* @package Joomla.Framework
|
||
|
* @subpackage FileSystem
|
||
|
* @copyright Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
|
||
|
* @license GNU/GPL, see LICENSE.php
|
||
|
* Joomla! is free software. This version may have been modified pursuant
|
||
|
* to the GNU General Public License, and as distributed it includes or
|
||
|
* is derivative of works licensed under the GNU General Public License or
|
||
|
* other free or open source software licenses.
|
||
|
* See COPYRIGHT.php for copyright notices and details.
|
||
|
*/
|
||
|
|
||
|
/** boolean True if a Windows based host */
|
||
|
define('EXTPATH_ISWIN', (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'));
|
||
|
/** boolean True if a Mac based host */
|
||
|
define('EXTPATH_ISMAC', (strtoupper(substr(PHP_OS, 0, 3)) === 'MAC'));
|
||
|
|
||
|
if (!defined('DS')) {
|
||
|
/** string Shortcut for the DIRECTORY_SEPARATOR define */
|
||
|
define('DS', DIRECTORY_SEPARATOR);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* A Path handling class
|
||
|
*
|
||
|
* @static
|
||
|
* @package Joomla.Framework
|
||
|
* @subpackage FileSystem
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
class extPath
|
||
|
{
|
||
|
/**
|
||
|
* Checks if a path's permissions can be changed
|
||
|
*
|
||
|
* @param string $path Path to check
|
||
|
* @return boolean True if path can have mode changed
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
function canChmod($path)
|
||
|
{
|
||
|
$perms = fileperms($path);
|
||
|
if ($perms !== false)
|
||
|
{
|
||
|
if (@ chmod($path, $perms ^ 0001))
|
||
|
{
|
||
|
@chmod($path, $perms);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Chmods files and directories recursivly to given permissions
|
||
|
*
|
||
|
* @param string $path Root path to begin changing mode [without trailing slash]
|
||
|
* @param string $filemode Octal representation of the value to change file mode to [null = no change]
|
||
|
* @param string $foldermode Octal representation of the value to change folder mode to [null = no change]
|
||
|
* @return boolean True if successful [one fail means the whole operation failed]
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
function setPermissions($path, $filemode = '0644', $foldermode = '0755') {
|
||
|
|
||
|
// Initialize return value
|
||
|
$ret = true;
|
||
|
|
||
|
if (is_dir($path))
|
||
|
{
|
||
|
$dh = opendir($path);
|
||
|
while ($file = readdir($dh))
|
||
|
{
|
||
|
if ($file != '.' && $file != '..') {
|
||
|
$fullpath = $path.'/'.$file;
|
||
|
if (is_dir($fullpath)) {
|
||
|
if (!extpath::setPermissions($fullpath, $filemode, $foldermode)) {
|
||
|
$ret = false;
|
||
|
}
|
||
|
} else {
|
||
|
if (isset ($filemode)) {
|
||
|
if (!@ chmod($fullpath, octdec($filemode))) {
|
||
|
$ret = false;
|
||
|
}
|
||
|
}
|
||
|
} // if
|
||
|
} // if
|
||
|
} // while
|
||
|
closedir($dh);
|
||
|
if (isset ($foldermode)) {
|
||
|
if (!@ chmod($path, octdec($foldermode))) {
|
||
|
$ret = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (isset ($filemode)) {
|
||
|
$ret = @ chmod($path, octdec($filemode));
|
||
|
}
|
||
|
} // if
|
||
|
return $ret;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the permissions of the file/folder at a give path
|
||
|
*
|
||
|
* @param string $path The path of a file/folder
|
||
|
* @return string Filesystem permissions
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
function getPermissions($path)
|
||
|
{
|
||
|
$path = extpath::clean($path);
|
||
|
$mode = @ decoct(@ fileperms($path) & 0777);
|
||
|
|
||
|
if (strlen($mode) < 3) {
|
||
|
return '---------';
|
||
|
}
|
||
|
$parsed_mode = '';
|
||
|
for ($i = 0; $i < 3; $i ++)
|
||
|
{
|
||
|
// read
|
||
|
$parsed_mode .= ($mode { $i } & 04) ? "r" : "-";
|
||
|
// write
|
||
|
$parsed_mode .= ($mode { $i } & 02) ? "w" : "-";
|
||
|
// execute
|
||
|
$parsed_mode .= ($mode { $i } & 01) ? "x" : "-";
|
||
|
}
|
||
|
return $parsed_mode;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks for snooping outside of the file system root
|
||
|
*
|
||
|
* @param string $path A file system path to check
|
||
|
* @return string A cleaned version of the path
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
function check($path)
|
||
|
{
|
||
|
if (strpos($path, '..') !== false) {
|
||
|
JError::raiseError( 20, 'extpath::check Use of relative paths not permitted'); // don't translate
|
||
|
die();
|
||
|
}
|
||
|
$path = extpath::clean($path);
|
||
|
if (strpos($path, extpath::clean(_EXT_PATH)) !== 0) {
|
||
|
JError::raiseError( 20, 'extpath::check Snooping out of bounds @ '.$path); // don't translate
|
||
|
die();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function to strip additional / or \ in a path name
|
||
|
*
|
||
|
* @static
|
||
|
* @param string $path The path to clean
|
||
|
* @param string $ds Directory separator (optional)
|
||
|
* @return string The cleaned path
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
function clean($path, $ds=DS)
|
||
|
{
|
||
|
$path = trim($path);
|
||
|
|
||
|
if (empty($path)) {
|
||
|
$path = _EXT_PATH;
|
||
|
} else {
|
||
|
// Remove double slashes and backslahses and convert all slashes and backslashes to DS
|
||
|
$path = preg_replace('#[/\\\\]+#', $ds, $path);
|
||
|
}
|
||
|
|
||
|
return $path;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Searches the directory paths for a given file.
|
||
|
*
|
||
|
* @access protected
|
||
|
* @param array|string $path An path or array of path to search in
|
||
|
* @param string $file The file name to look for.
|
||
|
* @return mixed The full path and file name for the target file, or boolean false if the file is not found in any of the paths.
|
||
|
* @since 1.5
|
||
|
*/
|
||
|
function find($paths, $file)
|
||
|
{
|
||
|
settype($paths, 'array'); //force to array
|
||
|
|
||
|
// start looping through the path set
|
||
|
foreach ($paths as $path)
|
||
|
{
|
||
|
// get the path to the file
|
||
|
$fullname = $path.DS.$file;
|
||
|
|
||
|
// is the path based on a stream?
|
||
|
if (strpos($path, '://') === false)
|
||
|
{
|
||
|
// not a stream, so do a realpath() to avoid directory
|
||
|
// traversal attempts on the local file system.
|
||
|
$path = realpath($path); // needed for substr() later
|
||
|
$fullname = realpath($fullname);
|
||
|
}
|
||
|
|
||
|
// the substr() check added to make sure that the realpath()
|
||
|
// results in a directory registered so that
|
||
|
// non-registered directores are not accessible via directory
|
||
|
// traversal attempts.
|
||
|
if (file_exists($fullname) && substr($fullname, 0, strlen($path)) == $path) {
|
||
|
return $fullname;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// could not find the file in the set of paths
|
||
|
return false;
|
||
|
}
|
||
|
}
|