fixed mount command and enhanced egw_vfs::find()

This commit is contained in:
Ralf Becker 2008-02-29 07:27:49 +00:00
parent ea5cda5310
commit 3cd2ce8dd2
2 changed files with 141 additions and 31 deletions

View File

@ -173,6 +173,10 @@ class egw_vfs extends vfs_stream_wrapper
{ {
return self::$fstab; return self::$fstab;
} }
if (!self::$is_root)
{
return false; // only root can mount
}
if (isset(self::$fstab[$path])) if (isset(self::$fstab[$path]))
{ {
return true; // already mounted return true; // already mounted
@ -198,6 +202,10 @@ class egw_vfs extends vfs_stream_wrapper
*/ */
static function umount($path) static function umount($path)
{ {
if (!self::$is_root)
{
return false; // only root can mount
}
if (!isset(self::$fstab[$path]) && ($path = array_search($path,self::$fstab)) === false) if (!isset(self::$fstab[$path]) && ($path = array_search($path,self::$fstab)) === false)
{ {
return false; // $path not mounted return false; // $path not mounted
@ -214,18 +222,59 @@ class egw_vfs extends vfs_stream_wrapper
* find = recursive search over the filesystem * find = recursive search over the filesystem
* *
* @param string/array $base base of the search * @param string/array $base base of the search
* @param array $params=null * @param array $options=null the following keys are allowed:
* - type => {d|f} d=dirs, f=files, default both
* - dirs_last => {true|false(default)} put the dirs behind the files they contain
* - name,path => pattern with *,? wildcards, eg. "*.php"
* - name_preg,path_preg => preg regular expresion, eg. "/(vfs|wrapper)/"
* - uid,user,gid,group,nouser,nogroup file belongs to user/group with given name or (numerical) id
* - mime => type[/subtype]
* - empty,size => (+|-|)N
* - cmin/mmin => (+|-|)N file/dir create/modified in the last N minutes
* - ctime/mtime => (+|-|)N file/dir created/modified in the last N days
* @param string/array/true $exec=null function to call with each found file or dir as first param or * @param string/array/true $exec=null function to call with each found file or dir as first param or
* true to return file => stat pairs * true to return file => stat pairs
* @param array $exec_params=null further params for exec as array, path is always the first param! * @param array $exec_params=null further params for exec as array, path is always the first param!
* @return array of pathes if no $exec, otherwise path => stat pairs * @return array of pathes if no $exec, otherwise path => stat pairs
*/ */
function find($base,$params=null,$exec=null,$exec_params=null) function find($base,$options=null,$exec=null,$exec_params=null)
{ {
//error_log(__METHOD__."(".print_r($base,true).",".print_r($params,true).",".print_r($exec,true).",".print_r($exec_params,true).")\n"); //error_log(__METHOD__."(".print_r($base,true).",".print_r($options,true).",".print_r($exec,true).",".print_r($exec_params,true).")\n");
$type = $params['type']; // 'd' or 'f' $type = $options['type']; // 'd' or 'f'
$dirs_last = $params['dirs_last']; // list dirs after the files they contain $dirs_last = $options['dirs_last']; // list dirs after the files they contain
// process some of the options (need to be done only once)
if (isset($options['name']) && !isset($options['name_preg'])) // change from simple *,? wildcards to preg regular expression once
{
$options['name_preg'] = '/^'.str_replace(array('\\?','\\*'),array('.{1}','.*'),preg_quote($options['name'])).'$/';
}
if (isset($options['path']) && !isset($options['preg_path'])) // change from simple *,? wildcards to preg regular expression once
{
$options['path_preg'] = '/^'.str_replace(array('\\?','\\*'),array('.{1}','.*'),preg_quote($options['path'])).'$/';
}
if (!isset($options['uid']))
{
if (isset($options['user']))
{
$options['uid'] = $GLOBALS['egw']->accounts->name2id($options['user'],'account_lid','u');
}
elseif (isset($options['nouser']))
{
$options['uid'] = 0;
}
}
if (!isset($options['gid']))
{
if (isset($options['group']))
{
$options['gid'] = abs($GLOBALS['egw']->accounts->name2id($options['group'],'account_lid','g'));
}
elseif (isset($options['nogroup']))
{
$options['gid'] = 0;
}
}
if (!is_array($base)) if (!is_array($base))
{ {
@ -246,32 +295,23 @@ class egw_vfs extends vfs_stream_wrapper
$result = array(); $result = array();
foreach($base as $path) foreach($base as $path)
{ {
/* if (($scheme = parse_url($path,PHP_URL_SCHEME))) $is_dir = is_dir($path);
if (!$dirs_last || !$is_dir)
{ {
self::load_wrapper(); self::_check_add($options,$path,$result);
}*/
if (!$type || ($type[0]=='d') == is_dir($path))
{
if (!($stat = self::url_stat($path,0))) continue;
if (!$dirs_last || !is_dir($path))
{
$result[$path] = $stat;
}
} }
if (is_dir($path) && ($dir = opendir($path))) if ($is_dir && ($dir = opendir($path)))
{ {
while($file = readdir($dir)) while($file = readdir($dir))
{ {
$file = $path.'/'.$file; $file = $path.'/'.$file;
if (!$type || ($type[0]=='d') == is_dir($file))
{ self::_check_add($options,$file,$result);
if (!($stat = self::url_stat($file,0))) continue;
$result[$file] = $stat;
}
if (is_dir($file)) if (is_dir($file))
{ {
foreach(self::find($file,$params,true) as $p => $s) foreach(self::find($file,$options,true) as $p => $s)
{ {
unset($result[$p]); unset($result[$p]);
$result[$p] = $s; $result[$p] = $s;
@ -282,7 +322,7 @@ class egw_vfs extends vfs_stream_wrapper
if ($dirs_last) if ($dirs_last)
{ {
$result[$path] = $stat; self::_check_add($options,$path,$result);
} }
} }
} }
@ -295,10 +335,10 @@ class egw_vfs extends vfs_stream_wrapper
} }
foreach($result as $path => &$stat) foreach($result as $path => &$stat)
{ {
$params = $exec_params; $options = $exec_params;
array_unshift($params,$path); array_unshift($options,$path);
//echo "calling ".print_r($exec,true).print_r($params,true)."\n"; //echo "calling ".print_r($exec,true).print_r($options,true)."\n";
$stat = call_user_func_array($exec,$params); $stat = call_user_func_array($exec,$options);
} }
return $result; return $result;
} }
@ -308,6 +348,75 @@ class egw_vfs extends vfs_stream_wrapper
} }
return $result; return $result;
} }
/**
* Function carying out the various (optional) checks, before files&dirs get returned as result of find
*
* @param array $options options, see egw_vfs::find(,$options)
* @param string $path name of path to add
* @param array &$result here we add the stat for the key $path, if the checks are successful
*/
private function _check_add($options,$path,&$result)
{
$type = $options['type']; // 'd' or 'f'
if ($type && ($type == 'd') !== is_dir($path))
{
return; // wrong type
}
if (!($stat = self::url_stat($path,0)))
{
return; // not found, should not happen
}
if (isset($options['name_preg']) && !preg_match($options['name_preg'],basename($path)) ||
isset($options['path_preg']) && !preg_match($options['path_preg'],$path))
{
return; // wrong name or path
}
if (isset($options['gid']) && $stat['gid'] != $options['gid'] ||
isset($options['uid']) && $stat['uid'] != $options['uid'])
{
return; // wrong user or group
}
if (isset($options['mime']) && $options['mime'] != ($mime = self::mime_content_type($path)))
{
list($type,$subtype) = explode('/',$options['mime']);
// no subtype (eg. 'image') --> check only the main type
if ($sub_type || substr($mime,0,strlen($type)+1) != $type.'/')
{
return; // wrong mime-type
}
}
if (isset($options['size']) && !self::_check_num($stat['size'],$options['size']) ||
(isset($options['empty']) && !!$options['empty'] !== !$stat['size']))
{
return; // wrong size
}
if (isset($options['cmin']) && !self::_check_num(round((time()-$stat['ctime'])/60),$options['cmin']) ||
isset($options['mmin']) && !self::_check_num(round((time()-$stat['mtime'])/60),$options['mmin']) ||
isset($options['ctime']) && !self::_check_num(round((time()-$stat['ctime'])/86400),$options['ctime']) ||
isset($options['mtime']) && !self::_check_num(round((time()-$stat['ctime'])/86400),$options['mtime']))
{
return; // not create/modified in the spezified time
}
$result[$path] = $stat;
}
private function _check_num($value,$argument)
{
if (is_int($argument) && $argument >= 0 || $argument[0] != '-' && $argument[0] != '+')
{
//echo "_check_num($value,$argument) check = == ".(int)($value == $argument)."\n";
return $value == $argument;
}
if ($argument < 0)
{
//echo "_check_num($value,$argument) check < == ".(int)($value < abs($argument))."\n";
return $value < abs($argument);
}
//echo "_check_num($value,$argument) check > == ".(int)($value > (int)substr($argument,1))."\n";
return $value > (int) substr($argument,1);
}
/** /**
* Recursiv remove all given url's, including it's content if they are files * Recursiv remove all given url's, including it's content if they are files

View File

@ -537,7 +537,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
$basepath = parse_url($this->opened_dir_url,PHP_URL_PATH); $basepath = parse_url($this->opened_dir_url,PHP_URL_PATH);
foreach(self::$fstab as $mounted => $nul) foreach(self::$fstab as $mounted => $nul)
{ {
if (dirname($mounted) == $basepath) if (dirname($mounted) == $basepath && $mounted != '/')
{ {
$this->extra_dirs[] = basename($mounted); $this->extra_dirs[] = basename($mounted);
} }
@ -693,9 +693,10 @@ class vfs_stream_wrapper implements iface_stream_wrapper
{ {
stream_register_wrapper(self::SCHEME,__CLASS__); stream_register_wrapper(self::SCHEME,__CLASS__);
if ($GLOBALS['egw_info']['server']['vfs_fstab'] && is_array($GLOBALS['egw_info']['server']['vfs_fstab'])) if ($GLOBALS['egw_info']['server']['vfs_fstab'] &&
is_array($fstab = unserialize($GLOBALS['egw_info']['server']['vfs_fstab'])))
{ {
self::$fstab = $GLOBALS['egw_info']['server']['vfs_fstab']; self::$fstab = $fstab;
} }
} }
} }