mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-23 07:09:20 +01:00
implement PHP 5.4+ stream_metadata method for VFS, allowing to use that functionality from other stream-wrappers like php-smbclient
This commit is contained in:
parent
7f919ed0e3
commit
52be4ee14b
@ -94,6 +94,14 @@ class Vfs
|
|||||||
* Name of the lock table
|
* Name of the lock table
|
||||||
*/
|
*/
|
||||||
const LOCK_TABLE = 'egw_locks';
|
const LOCK_TABLE = 'egw_locks';
|
||||||
|
/**
|
||||||
|
* How much should be logged to the apache error-log
|
||||||
|
*
|
||||||
|
* 0 = Nothing
|
||||||
|
* 1 = only errors
|
||||||
|
* 2 = all function calls and errors (contains passwords too!)
|
||||||
|
*/
|
||||||
|
const LOG_LEVEL = 1;
|
||||||
/**
|
/**
|
||||||
* Current user has root rights, no access checks performed!
|
* Current user has root rights, no access checks performed!
|
||||||
*
|
*
|
||||||
@ -618,8 +626,10 @@ class Vfs
|
|||||||
|
|
||||||
if ($options['url'])
|
if ($options['url'])
|
||||||
{
|
{
|
||||||
$lstat = @lstat($path);
|
if (($stat = @lstat($path)))
|
||||||
$stat = array_slice($lstat,13); // remove numerical indices 0-12
|
{
|
||||||
|
$stat = array_slice($stat,13); // remove numerical indices 0-12
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2160,6 +2170,21 @@ class Vfs
|
|||||||
return $vfs->resolve_url_symlinks($_path, $file_exists, $resolve_last_symlink, $stat);
|
return $vfs->resolve_url_symlinks($_path, $file_exists, $resolve_last_symlink, $stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the given path according to our fstab
|
||||||
|
*
|
||||||
|
* @param string $_path
|
||||||
|
* @param boolean $do_symlink =true is a direct match allowed, default yes (must be false for a lstat or readlink!)
|
||||||
|
* @param boolean $use_symlinkcache =true
|
||||||
|
* @param boolean $replace_user_pass_host =true replace $user,$pass,$host in url, default true, if false result is not cached
|
||||||
|
* @param boolean $fix_url_query =false true append relativ path to url query parameter, default not
|
||||||
|
* @return string|boolean false if the url cant be resolved, should not happen if fstab has a root entry
|
||||||
|
*/
|
||||||
|
static function resolve_url($_path,$do_symlink=true,$use_symlinkcache=true,$replace_user_pass_host=true,$fix_url_query=false)
|
||||||
|
{
|
||||||
|
Vfs\StreamWrapper::resolve_url($_path, $do_symlink, $use_symlinkcache, $replace_user_pass_host, $fix_url_query);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called in response to mkdir() calls on URL paths associated with the wrapper.
|
* This method is called in response to mkdir() calls on URL paths associated with the wrapper.
|
||||||
*
|
*
|
||||||
@ -2277,7 +2302,7 @@ class Vfs
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
* touch just running on VFS path
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param int $time =null modification time (unix timestamp), default null = current time
|
* @param int $time =null modification time (unix timestamp), default null = current time
|
||||||
@ -2286,11 +2311,11 @@ class Vfs
|
|||||||
*/
|
*/
|
||||||
static function touch($path,$time=null,$atime=null)
|
static function touch($path,$time=null,$atime=null)
|
||||||
{
|
{
|
||||||
return self::_call_on_backend('touch',array($path,$time,$atime));
|
return $path[0] == '/' && touch(self::PREFIX.$path, $time, $atime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
* chmod just running on VFS path
|
||||||
*
|
*
|
||||||
* Requires owner or root rights!
|
* Requires owner or root rights!
|
||||||
*
|
*
|
||||||
@ -2300,35 +2325,35 @@ class Vfs
|
|||||||
*/
|
*/
|
||||||
static function chmod($path,$mode)
|
static function chmod($path,$mode)
|
||||||
{
|
{
|
||||||
return self::_call_on_backend('chmod',array($path,$mode));
|
return $path[0] == '/' && chmod(self::PREFIX.$path, $mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
* chmod just running on VFS path
|
||||||
*
|
*
|
||||||
* Requires root rights!
|
* Requires root rights!
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param int $owner numeric user id
|
* @param int|string $owner numeric user id or account-name
|
||||||
* @return boolean true on success, false otherwise
|
* @return boolean true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
static function chown($path,$owner)
|
static function chown($path,$owner)
|
||||||
{
|
{
|
||||||
return self::_call_on_backend('chown',array($path,$owner));
|
return $path[0] == '/' && chown(self::PREFIX.$path, $owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
* chgrp just running on VFS path
|
||||||
*
|
*
|
||||||
* Requires owner or root rights!
|
* Requires owner or root rights!
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param int $group numeric group id
|
* @param int|string $group numeric group id or group-name
|
||||||
* @return boolean true on success, false otherwise
|
* @return boolean true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
static function chgrp($path,$group)
|
static function chgrp($path,$group)
|
||||||
{
|
{
|
||||||
return self::_call_on_backend('chgrp',array($path,$group));
|
return $path[0] == '/' && chown(self::PREFIX.$path, $group);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -432,16 +432,27 @@ class StreamWrapper implements Vfs\StreamWrapperIface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
* StreamWrapper method (PHP 5.4+) for touch, chmod, chown and chgrp
|
||||||
|
*
|
||||||
|
* We only implement touch, as other functionality would require webserver to run as root.
|
||||||
*
|
*
|
||||||
* @param string $url
|
* @param string $url
|
||||||
* @param int $time =null modification time (unix timestamp), default null = current time
|
* @param int $option STREAM_META_(TOUCH|ACCESS|((OWNER|GROUP)(_NAME)?))
|
||||||
* @param int $atime =null access time (unix timestamp), default null = current time, not implemented in the vfs!
|
* @param array|int|string $value
|
||||||
* @return boolean true on success, false otherwise
|
* - STREAM_META_TOUCH array($time, $atime)
|
||||||
|
* - STREAM_META_ACCESS int
|
||||||
|
* - STREAM_(OWNER|GROUP) int
|
||||||
|
* - STREAM_(OWNER|GROUP)_NAME string
|
||||||
|
* @return boolean true on success, false on failure
|
||||||
*/
|
*/
|
||||||
static function touch($url,$time=null,$atime=null)
|
function stream_metadata($url, $option, $value)
|
||||||
{
|
{
|
||||||
$path = Vfs::decodePath(Vfs::parse_url($url,PHP_URL_PATH));
|
if ($option != STREAM_META_TOUCH)
|
||||||
|
{
|
||||||
|
return false; // not implemented / supported
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = Vfs::decodePath(Vfs::parse_url($url, PHP_URL_PATH));
|
||||||
$parent = dirname($path);
|
$parent = dirname($path);
|
||||||
|
|
||||||
// check access rights (in real filesystem AND by mount perms)
|
// check access rights (in real filesystem AND by mount perms)
|
||||||
@ -450,55 +461,9 @@ class StreamWrapper implements Vfs\StreamWrapperIface
|
|||||||
if (self::LOG_LEVEL) error_log(__METHOD__."($url) permission denied!");
|
if (self::LOG_LEVEL) error_log(__METHOD__."($url) permission denied!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return touch($path,$time,$atime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
array_unshift($value, $path);
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
return call_user_func_array('touch', $value);
|
||||||
*
|
|
||||||
* Not supported, as it would require root rights!
|
|
||||||
*
|
|
||||||
* @param string $path
|
|
||||||
* @param string $mode mode string see Vfs::mode2int
|
|
||||||
* @return boolean true on success, false otherwise
|
|
||||||
*/
|
|
||||||
static function chmod($path,$mode)
|
|
||||||
{
|
|
||||||
unset($path, $mode); // not used, but required by interface
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
|
||||||
*
|
|
||||||
* Not supported, as it would require root rights!
|
|
||||||
*
|
|
||||||
* @param string $path
|
|
||||||
* @param int $owner numeric user id
|
|
||||||
* @return boolean true on success, false otherwise
|
|
||||||
*/
|
|
||||||
static function chown($path,$owner)
|
|
||||||
{
|
|
||||||
unset($path, $owner); // not used, but required by interface
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
|
||||||
*
|
|
||||||
* Not supported, as it would require root rights!
|
|
||||||
*
|
|
||||||
* @param string $path
|
|
||||||
* @param int $group numeric group id
|
|
||||||
* @return boolean true on success, false otherwise
|
|
||||||
*/
|
|
||||||
static function chgrp($path,$group)
|
|
||||||
{
|
|
||||||
unset($path, $group); // not used, but required by interface
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -329,6 +329,29 @@ class StreamWrapper extends LinksParent
|
|||||||
return parent::dir_opendir($url, $options);
|
return parent::dir_opendir($url, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reimplemented to create an entry directory on the fly AND delete our stat cache!
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param int $time =null modification time (unix timestamp), default null = current time
|
||||||
|
* @param int $atime =null access time (unix timestamp), default null = current time, not implemented in the vfs!
|
||||||
|
*/
|
||||||
|
protected function touch($url,$time=null,$atime=null)
|
||||||
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url,$time,$atime)");
|
||||||
|
|
||||||
|
if (!($stat = self::url_stat($url,STREAM_URL_STAT_QUIET)))
|
||||||
|
{
|
||||||
|
// file does not exist --> create an empty one
|
||||||
|
if (!($f = fopen(self::SCHEME.'://default'.Vfs::parse_url($url,PHP_URL_PATH),'w')) || !fclose($f))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_null($time) ? true : parent::touch($url,$time,$atime);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register this stream-wrapper
|
* Register this stream-wrapper
|
||||||
*/
|
*/
|
||||||
|
@ -835,6 +835,49 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamWrapper method (PHP 5.4+) for touch, chmod, chown and chgrp
|
||||||
|
*
|
||||||
|
* We use protected helper methods touch, chmod, chown and chgrp to implement the functionality.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param int $option STREAM_META_(TOUCH|ACCESS|((OWNER|GROUP)(_NAME)?))
|
||||||
|
* @param array|int|string $value
|
||||||
|
* - STREAM_META_TOUCH array($time, $atime)
|
||||||
|
* - STREAM_META_ACCESS int
|
||||||
|
* - STREAM_(OWNER|GROUP) int
|
||||||
|
* - STREAM_(OWNER|GROUP)_NAME string
|
||||||
|
* @return boolean true on success, false on failure
|
||||||
|
*/
|
||||||
|
function stream_metadata($path, $option, $value)
|
||||||
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($path, $option, ".array2string($value).")");
|
||||||
|
|
||||||
|
switch($option)
|
||||||
|
{
|
||||||
|
case STREAM_META_TOUCH:
|
||||||
|
return $this->touch($path, $value[0]); // atime is not supported
|
||||||
|
|
||||||
|
case STREAM_META_ACCESS:
|
||||||
|
return $this->chmod($path, $value);
|
||||||
|
|
||||||
|
case STREAM_META_OWNER_NAME:
|
||||||
|
if (($value = $GLOBALS['egw']->account->name2id($value, 'account_lid', 'u')) === false)
|
||||||
|
return false;
|
||||||
|
// fall through
|
||||||
|
case STREAM_META_OWNER:
|
||||||
|
return $this->chown($path, $value);
|
||||||
|
|
||||||
|
case STREAM_META_GROUP_NAME:
|
||||||
|
if (($value = $GLOBALS['egw']->account->name2id($value, 'account_lid', 'g')) === false)
|
||||||
|
return false;
|
||||||
|
// fall through
|
||||||
|
case STREAM_META_GROUP:
|
||||||
|
return $this->chgrp($path, $value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
|
||||||
*
|
*
|
||||||
@ -842,7 +885,7 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
|
|||||||
* @param int $time =null modification time (unix timestamp), default null = current time
|
* @param int $time =null modification time (unix timestamp), default null = current time
|
||||||
* @param int $atime =null access time (unix timestamp), default null = current time, not implemented in the vfs!
|
* @param int $atime =null access time (unix timestamp), default null = current time, not implemented in the vfs!
|
||||||
*/
|
*/
|
||||||
static function touch($url,$time=null,$atime=null)
|
protected function touch($url,$time=null,$atime=null)
|
||||||
{
|
{
|
||||||
unset($atime); // not used
|
unset($atime); // not used
|
||||||
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url, $time)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url, $time)");
|
||||||
@ -880,7 +923,7 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
|
|||||||
* @param int $owner
|
* @param int $owner
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
static function chown($url,$owner)
|
protected function chown($url,$owner)
|
||||||
{
|
{
|
||||||
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url,$owner)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url,$owner)");
|
||||||
|
|
||||||
@ -925,7 +968,7 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
|
|||||||
* @param int $owner
|
* @param int $owner
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
static function chgrp($url,$owner)
|
protected function chgrp($url,$owner)
|
||||||
{
|
{
|
||||||
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url,$owner)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url,$owner)");
|
||||||
|
|
||||||
@ -971,7 +1014,7 @@ class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface
|
|||||||
* @param int $mode
|
* @param int $mode
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
static function chmod($url,$mode)
|
protected function chmod($url,$mode)
|
||||||
{
|
{
|
||||||
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url, $mode)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url, $mode)");
|
||||||
|
|
||||||
|
@ -480,6 +480,55 @@ class StreamWrapper implements StreamWrapperIface
|
|||||||
return fstat($this->opened_stream);
|
return fstat($this->opened_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamWrapper method (PHP 5.4+) for touch, chmod, chown and chgrp
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param int $option STREAM_META_(TOUCH|ACCESS|((OWNER|GROUP)(_NAME)?))
|
||||||
|
* @param array|int|string $value
|
||||||
|
* - STREAM_META_TOUCH array($time, $atime)
|
||||||
|
* - STREAM_META_ACCESS int
|
||||||
|
* - STREAM_(OWNER|GROUP) int
|
||||||
|
* - STREAM_(OWNER|GROUP)_NAME string
|
||||||
|
* @return boolean true on success, false on failure
|
||||||
|
*/
|
||||||
|
function stream_metadata($path, $option, $value)
|
||||||
|
{
|
||||||
|
if (!($url = $this->resolve_url_symlinks($path, $option == STREAM_META_TOUCH, false))) // true,false file need to exist, but do not resolve last component
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (self::url_is_readonly($url))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."('$path', $option, ".array2string($value).") url=$url");
|
||||||
|
|
||||||
|
switch($option)
|
||||||
|
{
|
||||||
|
case STREAM_META_TOUCH:
|
||||||
|
return touch($url, $value[0]); // atime is not supported
|
||||||
|
|
||||||
|
case STREAM_META_ACCESS:
|
||||||
|
return chmod($url, $value);
|
||||||
|
|
||||||
|
case STREAM_META_OWNER_NAME:
|
||||||
|
if (($value = $GLOBALS['egw']->account->name2id($value, 'account_lid', 'u')) === false)
|
||||||
|
return false;
|
||||||
|
// fall through
|
||||||
|
case STREAM_META_OWNER:
|
||||||
|
return chown($url, $value);
|
||||||
|
|
||||||
|
case STREAM_META_GROUP_NAME:
|
||||||
|
if (($value = $GLOBALS['egw']->account->name2id($value, 'account_lid', 'g')) === false)
|
||||||
|
return false;
|
||||||
|
// fall through
|
||||||
|
case STREAM_META_GROUP:
|
||||||
|
return chgrp($url, $value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called in response to unlink() calls on URL paths associated with the wrapper.
|
* This method is called in response to unlink() calls on URL paths associated with the wrapper.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user