mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-22 07:53:39 +01:00
oldvfs stream-wrapper can now also open/read/write files and uses a direct filesystem stream to overcome memory_limit limitations, eg. with filemanager/ls.php --cp /tmp/xyz.iso oldvfs://user:password@default/home/user you can copy now a cd image to the vfs!
This commit is contained in:
parent
10f3a93947
commit
88cb04b87b
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/php -qC
|
#!/usr/bin/php -qC
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Admin - Command line interface
|
* Filemanager - Command line interface: ls
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @package admin
|
* @package admin
|
||||||
@ -13,9 +13,9 @@
|
|||||||
|
|
||||||
chdir(dirname(__FILE__)); // to enable our relative pathes to work
|
chdir(dirname(__FILE__)); // to enable our relative pathes to work
|
||||||
|
|
||||||
if (isset($_SERVER['HTTP_HOST'])) // security precaution: forbit calling admin-cli as web-page
|
if (isset($_SERVER['HTTP_HOST'])) // security precaution: forbit calling ls as web-page
|
||||||
{
|
{
|
||||||
die('<h1>ls.php must NOT be called as web-page --> exiting !!!</h1>');
|
die('<h1>'.basename(__FILE__).' must NOT be called as web-page --> exiting !!!</h1>');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -52,11 +52,6 @@ function user_pass_from_argv(&$account)
|
|||||||
echo "Wrong admin-account or -password !!!\n\n";
|
echo "Wrong admin-account or -password !!!\n\n";
|
||||||
usage('',1);
|
usage('',1);
|
||||||
}
|
}
|
||||||
if (!$GLOBALS['egw_info']['user']['apps']['admin']) // will be tested by the header too, but whould give html error-message
|
|
||||||
{
|
|
||||||
echo "Permission denied !!!\n\n";
|
|
||||||
usage('',2);
|
|
||||||
}
|
|
||||||
return $sessionid;
|
return $sessionid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,20 +63,109 @@ function user_pass_from_argv(&$account)
|
|||||||
*/
|
*/
|
||||||
function usage($action=null,$ret=0)
|
function usage($action=null,$ret=0)
|
||||||
{
|
{
|
||||||
$cmd = basename($_SERVER['argv'][0]);
|
$cmd = basename(__FILE__);
|
||||||
echo "Usage: $cmd URL\n\n";
|
echo "Usage: $cmd URL\n";
|
||||||
|
echo "\t$cmd --cat URL\n";
|
||||||
|
echo "\t$cmd --cp URL-from URL-to\n";
|
||||||
|
echo "\t$cmd --cp URL-from1 [URL-from2 ...] URL-to-directory\n";
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$long=false;
|
$long = $numeric = false;
|
||||||
array_shift($_SERVER['argv']);
|
$argv = $_SERVER['argv'];
|
||||||
while(($url = array_shift($_SERVER['argv'])))
|
$cmd = basename(array_shift($argv),'.php');
|
||||||
|
|
||||||
|
if (!$argv) $argv = array('-h');
|
||||||
|
|
||||||
|
foreach($argv as $key => $option)
|
||||||
{
|
{
|
||||||
if ($url == '-l')
|
if ($option[0] != '-') continue;
|
||||||
|
|
||||||
|
unset($argv[$key]);
|
||||||
|
|
||||||
|
switch($option)
|
||||||
{
|
{
|
||||||
$long = true;
|
default:
|
||||||
continue;
|
case '-h': case '--help':
|
||||||
|
usage();
|
||||||
|
|
||||||
|
case '-l': case '--long':
|
||||||
|
$long = true;
|
||||||
|
continue 2; // switch is counting too!
|
||||||
|
|
||||||
|
case '-n': case '--numeric':
|
||||||
|
$numeric = true;
|
||||||
|
continue 2; // switch is counting too!
|
||||||
|
|
||||||
|
case '--cat': // cat files (!) to stdout
|
||||||
|
case '--cp': // cp files
|
||||||
|
case '--rm': // rm files
|
||||||
|
$cmd = substr($option,2);
|
||||||
|
continue 2; // switch is counting too!
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
$argv = array_values($argv);
|
||||||
|
$argc = count($argv);
|
||||||
|
|
||||||
|
switch($cmd)
|
||||||
|
{
|
||||||
|
case 'cp':
|
||||||
|
do_cp($argv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
while($url = array_shift($argv))
|
||||||
|
{
|
||||||
|
load_wrapper($url);
|
||||||
|
//echo "$cmd $url (long=".(int)$long.", numeric=".(int)$numeric.")\n";
|
||||||
|
|
||||||
|
if ($cmd == 'rm')
|
||||||
|
{
|
||||||
|
unlink($url);
|
||||||
|
}
|
||||||
|
elseif (is_dir($url) && ($dir = opendir($url)))
|
||||||
|
{
|
||||||
|
if ($argc)
|
||||||
|
{
|
||||||
|
echo "\n".basename(parse_url($url,PHP_URL_PATH)).":\n";
|
||||||
|
}
|
||||||
|
while(($file = readdir($dir)) !== false)
|
||||||
|
{
|
||||||
|
do_stat($url.'/'.$file,$long,$numeric);
|
||||||
|
}
|
||||||
|
closedir($dir);
|
||||||
|
}
|
||||||
|
elseif ($cmd == 'cat')
|
||||||
|
{
|
||||||
|
if (!($f = fopen($url,'r')))
|
||||||
|
{
|
||||||
|
echo "File $url not found !!!\n\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($argc)
|
||||||
|
{
|
||||||
|
echo "\n".basename(parse_url($url,PHP_URL_PATH)).":\n";
|
||||||
|
}
|
||||||
|
fpassthru($f);
|
||||||
|
fclose($f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do_stat($url,$long,$numeric);
|
||||||
|
}
|
||||||
|
if (!$long && $cmd == 'ls') echo "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the necessary wrapper for an url
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
*/
|
||||||
|
function load_wrapper($url)
|
||||||
|
{
|
||||||
switch(parse_url($url,PHP_URL_SCHEME))
|
switch(parse_url($url,PHP_URL_SCHEME))
|
||||||
{
|
{
|
||||||
case 'webdav':
|
case 'webdav':
|
||||||
@ -101,7 +185,7 @@ while(($url = array_shift($_SERVER['argv'])))
|
|||||||
|
|
||||||
$GLOBALS['egw_info'] = array(
|
$GLOBALS['egw_info'] = array(
|
||||||
'flags' => array(
|
'flags' => array(
|
||||||
'currentapp' => 'admin',
|
'currentapp' => 'filemanager',
|
||||||
'noheader' => true,
|
'noheader' => true,
|
||||||
'autocreate_session_callback' => 'user_pass_from_argv',
|
'autocreate_session_callback' => 'user_pass_from_argv',
|
||||||
)
|
)
|
||||||
@ -117,31 +201,18 @@ while(($url = array_shift($_SERVER['argv'])))
|
|||||||
default:
|
default:
|
||||||
die("Unknown scheme in $url !!!\n\n");
|
die("Unknown scheme in $url !!!\n\n");
|
||||||
}
|
}
|
||||||
if (($dir = opendir($url)))
|
|
||||||
{
|
|
||||||
if ($_SERVER['argc'] > 2)
|
|
||||||
{
|
|
||||||
echo "\n".basename(parse_url($url,PHP_URL_PATH)).":\n";
|
|
||||||
}
|
|
||||||
while(($file = readdir($dir)) !== false)
|
|
||||||
{
|
|
||||||
do_stat($url.'/'.$file,$long);
|
|
||||||
}
|
|
||||||
closedir($dir);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do_stat($url,$long);
|
|
||||||
}
|
|
||||||
/* else
|
|
||||||
{
|
|
||||||
echo "File or directory not found !!!\n\n";
|
|
||||||
}*/
|
|
||||||
if (!$long) echo "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function do_stat($url,$long=false)
|
/**
|
||||||
|
* Give the stats for one file
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param boolean $long=false true=long listing with owner,group,size,perms, default false only filename
|
||||||
|
* @param boolean $numeric=false true=give numeric uid&gid, else resolve the id to a name
|
||||||
|
*/
|
||||||
|
function do_stat($url,$long=false,$numeric=false)
|
||||||
{
|
{
|
||||||
|
//echo "do_stat($url,$long,$numeric)\n";
|
||||||
$bname = basename(parse_url($url,PHP_URL_PATH));
|
$bname = basename(parse_url($url,PHP_URL_PATH));
|
||||||
|
|
||||||
if ($long)
|
if ($long)
|
||||||
@ -150,10 +221,26 @@ function do_stat($url,$long=false)
|
|||||||
//print_r($stat);
|
//print_r($stat);
|
||||||
|
|
||||||
$perms = verbosePerms($stat['mode']);
|
$perms = verbosePerms($stat['mode']);
|
||||||
$uid = isset($GLOBALS['egw']) && $stat['uid'] ? $GLOBALS['egw']->accounts->id2name($stat['uid']) : posix_getpwuid($stat['uid']);
|
if ($numeric)
|
||||||
if (is_array($uid)) $uid = $uid['name'];
|
{
|
||||||
$gid = isset($GLOBALS['egw']) && $stat['gid'] ? $GLOBALS['egw']->accounts->id2name($stat['gid']) : posix_getgrgid($stat['gid']);
|
$uid = $stat['uid'];
|
||||||
if (is_array($gid)) $gid = $gid['name'];
|
$gid = $stat['gid'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($stat['uid'])
|
||||||
|
{
|
||||||
|
$uid = isset($GLOBALS['egw']) ? $GLOBALS['egw']->accounts->id2name($stat['uid']) : posix_getpwuid($stat['uid']);
|
||||||
|
if (is_array($uid)) $uid = $uid['name'];
|
||||||
|
}
|
||||||
|
if (!isset($uid)) $uid = 'none';
|
||||||
|
if ($stat['gid'])
|
||||||
|
{
|
||||||
|
$gid = isset($GLOBALS['egw']) ? $GLOBALS['egw']->accounts->id2name($stat['gid']) : posix_getgrgid($stat['gid']);
|
||||||
|
if (is_array($gid)) $gid = $gid['name'];
|
||||||
|
}
|
||||||
|
if (!isset($gid)) $gid = 'none';
|
||||||
|
}
|
||||||
$size = hsize($stat['size']);
|
$size = hsize($stat['size']);
|
||||||
$mtime = date('Y-m-d H:i:s',$stat['mtime']);
|
$mtime = date('Y-m-d H:i:s',$stat['mtime']);
|
||||||
$nlink = $stat['nlink'];
|
$nlink = $stat['nlink'];
|
||||||
@ -228,3 +315,47 @@ function verbosePerms( $in_Perms )
|
|||||||
return $sP;
|
return $sP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function do_cp($argv)
|
||||||
|
{
|
||||||
|
$to = array_pop($argv);
|
||||||
|
load_wrapper($to);
|
||||||
|
|
||||||
|
if (count($argv) > 1 && !is_dir($to))
|
||||||
|
{
|
||||||
|
die ("Usage: cp from-file to-file | cp file1 [file2 ...] dir\n\n");
|
||||||
|
}
|
||||||
|
if (count($argv) > 1)
|
||||||
|
{
|
||||||
|
foreach($argv as $from)
|
||||||
|
{
|
||||||
|
do_cp(array($from,$to));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$from = array_shift($argv);
|
||||||
|
load_wrapper($from);
|
||||||
|
|
||||||
|
if (!($from_fp = fopen($from,'r')))
|
||||||
|
{
|
||||||
|
die("File $from not found!");
|
||||||
|
}
|
||||||
|
if (is_dir($to))
|
||||||
|
{
|
||||||
|
$path = parse_url($from,PHP_URL_PATH);
|
||||||
|
$to .= '/'.basename($path);
|
||||||
|
}
|
||||||
|
if (!($to_fp = fopen($to,'w')))
|
||||||
|
{
|
||||||
|
die("Can't open $to from writing!");
|
||||||
|
}
|
||||||
|
$count = stream_copy_to_stream($from_fp,$to_fp);
|
||||||
|
|
||||||
|
echo hsize($count)." bytes written to $to\n";
|
||||||
|
|
||||||
|
fclose($from_fp);
|
||||||
|
|
||||||
|
if (!fclose($to_fp))
|
||||||
|
{
|
||||||
|
die("Error closing $to!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -100,7 +100,9 @@ interface iface_stream_wrapper
|
|||||||
* See fseek() for more information about these parameters.
|
* See fseek() for more information about these parameters.
|
||||||
*
|
*
|
||||||
* @param integer $offset
|
* @param integer $offset
|
||||||
* @param integer $whence
|
* @param integer $whence SEEK_SET - Set position equal to offset bytes
|
||||||
|
* SEEK_CUR - Set position to current location plus offset.
|
||||||
|
* SEEK_END - Set position to end-of-file plus offset. (To move to a position before the end-of-file, you need to pass a negative value in offset.)
|
||||||
* @return boolean TRUE if the position was updated, FALSE otherwise.
|
* @return boolean TRUE if the position was updated, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
function stream_seek ( $offset, $whence );
|
function stream_seek ( $offset, $whence );
|
||||||
@ -139,7 +141,7 @@ interface iface_stream_wrapper
|
|||||||
* @param string $path
|
* @param string $path
|
||||||
* @return boolean TRUE on success or FALSE on failure
|
* @return boolean TRUE on success or FALSE on failure
|
||||||
*/
|
*/
|
||||||
function unlink ( $path );
|
static function unlink ( $path );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called in response to rename() calls on URL paths associated with the wrapper.
|
* This method is called in response to rename() calls on URL paths associated with the wrapper.
|
||||||
|
@ -25,6 +25,20 @@ require_once(EGW_API_INC.'/class.iface_stream_wrapper.inc.php');
|
|||||||
*/
|
*/
|
||||||
class oldvfs_stream_wrapper implements iface_stream_wrapper
|
class oldvfs_stream_wrapper implements iface_stream_wrapper
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* If this class should do the operations direct in the filesystem, instead of going through the vfs
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const USE_FILESYSTEM_DIRECT = true;
|
||||||
|
/**
|
||||||
|
* How much should be logged to the apache error-log
|
||||||
|
*
|
||||||
|
* 0 = Nothing
|
||||||
|
* 1 = only errors
|
||||||
|
* 2 = all function calls and errors
|
||||||
|
*/
|
||||||
|
const LOG_LEVEL = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* optional context param when opening the stream, null if no context passed
|
* optional context param when opening the stream, null if no context passed
|
||||||
*
|
*
|
||||||
@ -51,6 +65,18 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected $opened_mode;
|
protected $opened_mode;
|
||||||
|
/**
|
||||||
|
* Content of the opened file, as the old vfs can only read/write the whole file
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $opened_data;
|
||||||
|
/**
|
||||||
|
* Position in the opened file
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $opened_pos;
|
||||||
/**
|
/**
|
||||||
* Global vfs::ls() cache
|
* Global vfs::ls() cache
|
||||||
*
|
*
|
||||||
@ -71,14 +97,18 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function __construct()
|
function __construct()
|
||||||
{
|
{
|
||||||
error_log('oldvfs_stream_wrapper::__construct()');
|
if (self::LOG_LEVEL > 1) error_log('oldvfs_stream_wrapper::__construct()');
|
||||||
if (!is_object($this->old_vfs)) $this->old_vfs = new vfs_home();
|
|
||||||
|
if (!is_object(self::$old_vfs))
|
||||||
|
{
|
||||||
|
self::$old_vfs =& new vfs_home();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called immediately after your stream object is created.
|
* This method is called immediately after your stream object is created.
|
||||||
*
|
*
|
||||||
* @param string $path URL that was passed to fopen() and that this object is expected to retrieve
|
* @param string $url URL that was passed to fopen() and that this object is expected to retrieve
|
||||||
* @param string $mode mode used to open the file, as detailed for fopen()
|
* @param string $mode mode used to open the file, as detailed for fopen()
|
||||||
* @param int $options additional flags set by the streams API (or'ed together):
|
* @param int $options additional flags set by the streams API (or'ed together):
|
||||||
* - STREAM_USE_PATH If path is relative, search for the resource using the include_path.
|
* - STREAM_USE_PATH If path is relative, search for the resource using the include_path.
|
||||||
@ -87,9 +117,67 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
* @param string $opened_path full path of the file/resource, if the open was successfull and STREAM_USE_PATH was set
|
* @param string $opened_path full path of the file/resource, if the open was successfull and STREAM_USE_PATH was set
|
||||||
* @return boolean true if the ressource was opened successful, otherwise false
|
* @return boolean true if the ressource was opened successful, otherwise false
|
||||||
*/
|
*/
|
||||||
function stream_open ( $path, $mode, $options, &$opened_path )
|
function stream_open ( $url, $mode, $options, &$opened_path )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url,$mode,$options)");
|
||||||
|
|
||||||
|
$path = parse_url($url,PHP_URL_PATH);
|
||||||
|
|
||||||
|
$this->opened_path = $path;
|
||||||
|
$this->opened_mode = $mode;
|
||||||
|
$this->opened_data = null;
|
||||||
|
|
||||||
|
if (!self::$old_vfs->file_exists($data = array( // file does not exists
|
||||||
|
'string' => $path,
|
||||||
|
'relatives' => array(RELATIVE_ROOT),
|
||||||
|
)) || $mode[0] == 'x') // or file should NOT exist
|
||||||
|
{
|
||||||
|
if ($mode[0] == 'r' || // does $mode require the file to exist (r,r+)
|
||||||
|
$mode[0] == 'x' || // or file should not exist, but does
|
||||||
|
!self::$old_vfs->acl_check($data+array( // or we are not allowed to create it
|
||||||
|
'operation' => EGW_ACL_ADD,
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
if (self::LOG_LEVEL) error_log(__METHOD__."($url,$mode,$options) file does not exist or can not be created!");
|
||||||
|
$this->opened_data = $this->opened_path = $this->opened_mode = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// new file
|
||||||
|
$this->opened_data = '';
|
||||||
|
$this->opened_pos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($mode != 'r' && !self::$old_vfs->acl_check($data+array( // we are not allowed to edit it
|
||||||
|
'operation' => EGW_ACL_EDIT,
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
if (self::LOG_LEVEL) error_log(__METHOD__."($url,$mode,$options) file can not be edited!");
|
||||||
|
$this->opened_data = $this->opened_path = $this->opened_mode = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($mode[0] == 'w') // w or w+ truncates the file to 0 size
|
||||||
|
{
|
||||||
|
$this->opened_data = '';
|
||||||
|
$this->opened_pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// can we operate directly on a filesystem stream?
|
||||||
|
if (self::$old_vfs->file_actions && self::USE_FILESYSTEM_DIRECT)
|
||||||
|
{
|
||||||
|
$p = self::$old_vfs->path_parts($data);
|
||||||
|
|
||||||
|
if (!($this->opened_data = fopen($p->real_full_path,$mode,false)))
|
||||||
|
{
|
||||||
|
if (self::LOG_LEVEL) error_log(__METHOD__."($url,$mode,$options) file $p->real_full_path can not be opened!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($mode[0] == 'a') // append modes: a, a+
|
||||||
|
{
|
||||||
|
$this->stream_seek(0,SEEK_END);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +187,38 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function stream_close ( )
|
function stream_close ( )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."()");
|
||||||
|
|
||||||
|
if (is_null($this->opened_path)) return false;
|
||||||
|
|
||||||
|
$ret = true;
|
||||||
|
if (is_resource($this->opened_data))
|
||||||
|
{
|
||||||
|
$ret = fclose($this->opened_data);
|
||||||
|
|
||||||
|
if ($this->opened_mode != 'r')
|
||||||
|
{
|
||||||
|
// touch creates file (if necessary) and sets the modification or creation time and owner
|
||||||
|
self::$old_vfs->touch($data = array(
|
||||||
|
'string' => $this->opened_path,
|
||||||
|
'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root
|
||||||
|
));
|
||||||
|
// we read the size from the filesystem and write it to our db-based metadata
|
||||||
|
$p = self::$old_vfs->path_parts($data);
|
||||||
|
$data['attributes'] = array(
|
||||||
|
'size' => filesize($p->real_full_path),
|
||||||
|
);
|
||||||
|
self::$old_vfs->set_attributes($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif ($this->opened_mode != 'r')
|
||||||
|
{
|
||||||
|
// store the changes
|
||||||
|
self::$old_vfs->write($this->opened_data);
|
||||||
|
}
|
||||||
|
$this->opened_data = $this->opened_path = $this->opened_mode = null;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,7 +234,30 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function stream_read ( $count )
|
function stream_read ( $count )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($count) pos=$this->opened_pos");
|
||||||
|
|
||||||
|
if (is_resource($this->opened_data))
|
||||||
|
{
|
||||||
|
return fread($this->opened_data,$count);
|
||||||
|
}
|
||||||
|
if (is_null($this->opened_data))
|
||||||
|
{
|
||||||
|
if (($this->opened_data = self::$old_vfs->read(array(
|
||||||
|
'string' => $this->opened_path,
|
||||||
|
'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root
|
||||||
|
))) === false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->opened_pos = 0;
|
||||||
|
}
|
||||||
|
if ($this->stream_eof()) return false; // nothing more to read
|
||||||
|
|
||||||
|
$start = $this->opened_pos;
|
||||||
|
$this->opened_pos += $count;
|
||||||
|
|
||||||
|
// multibyte save substr!
|
||||||
|
return self::substr($this->opened_data,$start,$count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,7 +273,19 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function stream_write ( $data )
|
function stream_write ( $data )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($data)");
|
||||||
|
|
||||||
|
if (is_resource($this->opened_data))
|
||||||
|
{
|
||||||
|
return fwrite($this->opened_data,$data);
|
||||||
|
}
|
||||||
|
$len = bytes($data);
|
||||||
|
// multibyte save substr!
|
||||||
|
self::substr($this->opened_data,$this->opened_pos);
|
||||||
|
|
||||||
|
$this->opened_pos += $len;
|
||||||
|
|
||||||
|
return $len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,7 +302,18 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function stream_eof ( )
|
function stream_eof ( )
|
||||||
{
|
{
|
||||||
|
if (is_resource($this->opened_data))
|
||||||
|
{
|
||||||
|
return feof($this->opened_data);
|
||||||
|
}
|
||||||
|
if (!is_null($this->opened_data))
|
||||||
|
{
|
||||||
|
$len = bytes($this->opened_data);
|
||||||
|
$eof = $this->opened_pos >= $len;
|
||||||
|
}
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."() pos=$this->opened_pos >= $len=len --> ".($eof ? 'true' : 'false'));
|
||||||
|
|
||||||
|
return $eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,7 +323,13 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function stream_tell ( )
|
function stream_tell ( )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."()");
|
||||||
|
|
||||||
|
if (is_resource($this->opened_data))
|
||||||
|
{
|
||||||
|
return ftell($this->opened_data);
|
||||||
|
}
|
||||||
|
return $this->opened_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,12 +339,35 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
* See fseek() for more information about these parameters.
|
* See fseek() for more information about these parameters.
|
||||||
*
|
*
|
||||||
* @param integer $offset
|
* @param integer $offset
|
||||||
* @param integer $whence
|
* @param integer $whence SEEK_SET - Set position equal to offset bytes
|
||||||
|
* SEEK_CUR - Set position to current location plus offset.
|
||||||
|
* SEEK_END - Set position to end-of-file plus offset. (To move to a position before the end-of-file, you need to pass a negative value in offset.)
|
||||||
* @return boolean TRUE if the position was updated, FALSE otherwise.
|
* @return boolean TRUE if the position was updated, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
function stream_seek ( $offset, $whence )
|
function stream_seek ( $offset, $whence )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($offset,$whence)");
|
||||||
|
|
||||||
|
if (is_resource($this->opened_data))
|
||||||
|
{
|
||||||
|
return fseek($this->opened_data,$offset,$whence);
|
||||||
|
}
|
||||||
|
if (is_null($this->opened_path)) return false;
|
||||||
|
|
||||||
|
switch($whence)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case SEEK_SET:
|
||||||
|
$this->opened_pos = $offset;
|
||||||
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
$this->opened_pos = bytes($this->opened_data);
|
||||||
|
// fall through
|
||||||
|
case SEEK_CUR:
|
||||||
|
$this->opened_pos += $offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,7 +379,13 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function stream_flush ( )
|
function stream_flush ( )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."()");
|
||||||
|
|
||||||
|
if (is_resource($this->opened_data))
|
||||||
|
{
|
||||||
|
return fflush($this->opened_data);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,7 +404,9 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function stream_stat ( )
|
function stream_stat ( )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($this->opened_path)");
|
||||||
|
|
||||||
|
return $this->url_stat($this->opened_path,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,9 +418,26 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
* @param string $path
|
* @param string $path
|
||||||
* @return boolean TRUE on success or FALSE on failure
|
* @return boolean TRUE on success or FALSE on failure
|
||||||
*/
|
*/
|
||||||
function unlink ( $path )
|
static function unlink ( $path )
|
||||||
{
|
{
|
||||||
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($path)");
|
||||||
|
|
||||||
|
if (!is_object(self::$old_vfs))
|
||||||
|
{
|
||||||
|
self::$old_vfs =& new vfs_home();
|
||||||
|
}
|
||||||
|
$data=array(
|
||||||
|
'string' => $path,
|
||||||
|
'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root
|
||||||
|
);
|
||||||
|
if (!self::$old_vfs->acl_check($data+array(
|
||||||
|
'operation' => EGW_ACL_DELETE
|
||||||
|
)) /*|| ($type = self::$old_vfs->file_type($data)) === 'Directory'*/)
|
||||||
|
{
|
||||||
|
if (self::LOG_LEVEL) error_log(__METHOD__."($path) (type=$type) permission denied!");
|
||||||
|
return false; // no permission or file does not exist
|
||||||
|
}
|
||||||
|
return self::$old_vfs->rm($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -233,6 +452,7 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function rename ( $path_from, $path_to )
|
function rename ( $path_from, $path_to )
|
||||||
{
|
{
|
||||||
|
error_log(__METHOD__."($path_from, $path_to) not yet implemented!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +469,7 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function mkdir ( $path, $mode, $options )
|
function mkdir ( $path, $mode, $options )
|
||||||
{
|
{
|
||||||
|
error_log(__METHOD__."($path, $mode, $options) not yet implemented!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +485,7 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function rmdir ( $path, $options )
|
function rmdir ( $path, $options )
|
||||||
{
|
{
|
||||||
|
error_log(__METHOD__."($path, $options) not yet implemented!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,19 +493,20 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
* This method is called immediately when your stream object is created for examining directory contents with opendir().
|
* This method is called immediately when your stream object is created for examining directory contents with opendir().
|
||||||
*
|
*
|
||||||
* @param string $path URL that was passed to opendir() and that this object is expected to explore.
|
* @param string $path URL that was passed to opendir() and that this object is expected to explore.
|
||||||
|
* @param $options
|
||||||
* @return booelan
|
* @return booelan
|
||||||
*/
|
*/
|
||||||
function dir_opendir ( $url, $options )
|
function dir_opendir ( $url, $options )
|
||||||
{
|
{
|
||||||
error_log("oldvfs_stream_wrapper::dir_opendir('$path',$options)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."('$url',$options)");
|
||||||
|
|
||||||
if (!is_object($GLOBALS['egw']->vfs))
|
if (!is_object(self::$old_vfs))
|
||||||
{
|
{
|
||||||
$GLOBALS['egw']->vfs =& new vfs_home();
|
self::$old_vfs =& new vfs_home();
|
||||||
}
|
}
|
||||||
$path = parse_url($url,PHP_URL_PATH);
|
$path = parse_url($url,PHP_URL_PATH);
|
||||||
|
|
||||||
$this->opened_dir = $GLOBALS['egw']->vfs->ls(array(
|
$this->opened_dir = self::$old_vfs->ls(array(
|
||||||
'string' => $path,
|
'string' => $path,
|
||||||
'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root
|
'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root
|
||||||
'checksubdirs' => false,
|
'checksubdirs' => false,
|
||||||
@ -291,7 +514,10 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
//'orderby' => '',
|
//'orderby' => '',
|
||||||
//'mime_type' => '',
|
//'mime_type' => '',
|
||||||
));
|
));
|
||||||
if (!is_array($this->opened_dir))
|
if (!is_array($this->opened_dir) ||
|
||||||
|
// we also need to return false, if $url is not a directory!
|
||||||
|
count($this->opened_dir) == 1 && $path == $this->opened_dir[0]['directory'].'/'.$this->opened_dir[0]['name'] &&
|
||||||
|
$this->opened_dir[0]['mime_type'] != 'Directory')
|
||||||
{
|
{
|
||||||
$this->opened_dir = null;
|
$this->opened_dir = null;
|
||||||
return false;
|
return false;
|
||||||
@ -329,7 +555,7 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function url_stat ( $url, $flags )
|
function url_stat ( $url, $flags )
|
||||||
{
|
{
|
||||||
error_log("oldvfs_stream_wrapper::url_stat('$url',$flags)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."('$url',$flags)");
|
||||||
|
|
||||||
/*return array(
|
/*return array(
|
||||||
'mode' => 0100666,
|
'mode' => 0100666,
|
||||||
@ -341,13 +567,13 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
'mtime' => time(),
|
'mtime' => time(),
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
if (!is_object($GLOBALS['egw']->vfs))
|
if (!is_object(self::$old_vfs))
|
||||||
{
|
{
|
||||||
$GLOBALS['egw']->vfs =& new vfs_home();
|
self::$old_vfs =& new vfs_home();
|
||||||
}
|
}
|
||||||
$path = parse_url($url,PHP_URL_PATH);
|
$path = parse_url($url,PHP_URL_PATH);
|
||||||
|
|
||||||
list($info) = $GLOBALS['egw']->vfs->ls(array(
|
list($info) = self::$old_vfs->ls(array(
|
||||||
'string' => $path,
|
'string' => $path,
|
||||||
'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root
|
'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root
|
||||||
'checksubdirs' => false,
|
'checksubdirs' => false,
|
||||||
@ -369,7 +595,7 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function dir_readdir ( )
|
function dir_readdir ( )
|
||||||
{
|
{
|
||||||
error_log("oldvfs_stream_wrapper::dir_readdir($this->opened_dir_path)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($this->opened_dir_path)");
|
||||||
|
|
||||||
if (!is_array($this->opened_dir)) return false;
|
if (!is_array($this->opened_dir)) return false;
|
||||||
|
|
||||||
@ -388,7 +614,7 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function dir_rewinddir ( )
|
function dir_rewinddir ( )
|
||||||
{
|
{
|
||||||
error_log("oldvfs_stream_wrapper::dir_rewinddir($this->opened_dir_path)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($this->opened_dir_path)");
|
||||||
|
|
||||||
if (!is_array($this->opened_dir)) return false;
|
if (!is_array($this->opened_dir)) return false;
|
||||||
|
|
||||||
@ -406,7 +632,7 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
*/
|
*/
|
||||||
function dir_closedir ( )
|
function dir_closedir ( )
|
||||||
{
|
{
|
||||||
error_log("oldvfs_stream_wrapper::dir_closedir($this->opened_dir_path)");
|
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($this->opened_dir_path)");
|
||||||
|
|
||||||
if (!is_array($this->opened_dir)) return false;
|
if (!is_array($this->opened_dir)) return false;
|
||||||
|
|
||||||
@ -437,6 +663,23 @@ class oldvfs_stream_wrapper implements iface_stream_wrapper
|
|||||||
//print_r($stat);
|
//print_r($stat);
|
||||||
return $stat;
|
return $stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multibyte save substr
|
||||||
|
*
|
||||||
|
* @param string $str
|
||||||
|
* @param int $start
|
||||||
|
* @param int $length=null
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static function substr($str,$start,$length=null)
|
||||||
|
{
|
||||||
|
static $func_overload;
|
||||||
|
|
||||||
|
if (is_null($func_overload)) $func_overload = extension_loaded('mbstring') ? ini_get('mbstring.func_overload') : 0;
|
||||||
|
|
||||||
|
return $func_overload & 2 ? mb_substr($str,$start,$length,'ascii') : substr($str,$start,$length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_register_wrapper('oldvfs','oldvfs_stream_wrapper');
|
stream_register_wrapper('oldvfs','oldvfs_stream_wrapper');
|
||||||
|
Loading…
Reference in New Issue
Block a user