From 7ed708df75205903c2a9d294e29a595320229d22 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Tue, 29 May 2007 08:35:27 +0000 Subject: [PATCH] NOT FOR 1.4: a very first step to the new vfs structure, it only does a ls via commandline of the old vfs --- filemanager/ls.php | 230 +++++++++ .../inc/class.iface_stream_wrapper.inc.php | 243 ++++++++++ .../inc/class.oldvfs_stream_wrapper.inc.php | 442 ++++++++++++++++++ 3 files changed, 915 insertions(+) create mode 100755 filemanager/ls.php create mode 100644 phpgwapi/inc/class.iface_stream_wrapper.inc.php create mode 100644 phpgwapi/inc/class.oldvfs_stream_wrapper.inc.php diff --git a/filemanager/ls.php b/filemanager/ls.php new file mode 100755 index 0000000000..000506530b --- /dev/null +++ b/filemanager/ls.php @@ -0,0 +1,230 @@ +#!/usr/bin/php -qC + + * @copyright (c) 2006 by Ralf Becker + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @version $Id$ + */ + +chdir(dirname(__FILE__)); // to enable our relative pathes to work + +if (isset($_SERVER['HTTP_HOST'])) // security precaution: forbit calling admin-cli as web-page +{ + die('

ls.php must NOT be called as web-page --> exiting !!!

'); +} + +/* +// this is kind of a hack, as the autocreate_session_callback can not change the type of the loaded account-class +// so we need to make sure the right one is loaded by setting the domain before the header gets included. +$arg0s = explode(',',@$arguments[0]); +@list(,$_GET['domain']) = explode('@',$arg0s[0]); + +if (is_dir('/tmp')) ini_set('session.save_path','/tmp'); // regular users may have no rights to apache's session dir + +$GLOBALS['egw_info'] = array( + 'flags' => array( + 'currentapp' => 'admin', + 'noheader' => true, + 'autocreate_session_callback' => 'user_pass_from_argv', + ) +); + +include('../header.inc.php'); +*/ + +/** + * callback if the session-check fails, redirects via xajax to login.php + * + * @param array &$account account_info with keys 'login', 'passwd' and optional 'passwd_type' + * @return boolean/string true if we allow the access and account is set, a sessionid or false otherwise + */ +function user_pass_from_argv(&$account) +{ + $account = $GLOBALS['egw_login_data']; + //print_r($account); + if (!($sessionid = $GLOBALS['egw']->session->create($account))) + { + echo "Wrong admin-account or -password !!!\n\n"; + 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; +} + +/** + * Give a usage message and exit + * + * @param string $action=null + * @param int $ret=0 exit-code + */ +function usage($action=null,$ret=0) +{ + $cmd = basename($_SERVER['argv'][0]); + echo "Usage: $cmd URL\n\n"; + + exit; +} +$long=false; +array_shift($_SERVER['argv']); +while(($url = array_shift($_SERVER['argv']))) +{ + if ($url == '-l') + { + $long = true; + continue; + } + switch(parse_url($url,PHP_URL_SCHEME)) + { + case 'webdav': + require_once('HTTP/WebDAV/Client.php'); + break; + case 'oldvfs': + if (!isset($GLOBALS['egw_info'])) + { + $_GET['domain'] = parse_url($url,PHP_URL_HOST); + $GLOBALS['egw_login_data'] = array( + 'login' => parse_url($url,PHP_URL_USER), + 'passwd' => parse_url($url,PHP_URL_PASS), + 'passwd_type' => 'text', + ); + + if (is_dir('/tmp')) ini_set('session.save_path','/tmp'); // regular users may have no rights to apache's session dir + + $GLOBALS['egw_info'] = array( + 'flags' => array( + 'currentapp' => 'admin', + 'noheader' => true, + 'autocreate_session_callback' => 'user_pass_from_argv', + ) + ); + + include('../header.inc.php'); + } + require_once(EGW_API_INC.'/class.oldvfs_stream_wrapper.inc.php'); + break; + case '': + case 'ftp': + break; + default: + 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) +{ + $bname = basename(parse_url($url,PHP_URL_PATH)); + + if ($long) + { + $stat = stat($url); + //print_r($stat); + + $perms = verbosePerms($stat['mode']); + $uid = isset($GLOBALS['egw']) && $stat['uid'] ? $GLOBALS['egw']->accounts->id2name($stat['uid']) : posix_getpwuid($stat['uid']); + if (is_array($uid)) $uid = $uid['name']; + $gid = isset($GLOBALS['egw']) && $stat['gid'] ? $GLOBALS['egw']->accounts->id2name($stat['gid']) : posix_getgrgid($stat['gid']); + if (is_array($gid)) $gid = $gid['name']; + $size = hsize($stat['size']); + $mtime = date('Y-m-d H:i:s',$stat['mtime']); + $nlink = $stat['nlink']; + + echo "$perms $nlink\t$uid\t$gid\t$size\t$mtime\t$bname\n"; + } + else + { + echo "$bname\t"; + } +} + +function hsize($size) +{ + if ($size < 1024) return $size; + if ($size < 1024*1024) return sprintf('%3.1lfk',(float)$size/1024); + return sprintf('%3.1lfM',(float)$size/(1024*1024)); +} + +function verbosePerms( $in_Perms ) +{ + if($in_Perms & 0x1000) // FIFO pipe + { + $sP = 'p'; + } + elseif($in_Perms & 0x2000) // Character special + { + $sP = 'c'; + } + elseif($in_Perms & 0x4000) // Directory + { + $sP = 'd'; + } + elseif($in_Perms & 0x6000) // Block special + { + $sP = 'b'; + } + elseif($in_Perms & 0x8000) // Regular + { + $sP = '-'; + } + elseif($in_Perms & 0xA000) // Symbolic Link + { + $sP = 'l'; + } + elseif($in_Perms & 0xC000) // Socket + { + $sP = 's'; + } + else // UNKNOWN + { + $sP = 'u'; + } + + // owner + $sP .= (($in_Perms & 0x0100) ? 'r' : '-') . + (($in_Perms & 0x0080) ? 'w' : '-') . + (($in_Perms & 0x0040) ? (($in_Perms & 0x0800) ? 's' : 'x' ) : + (($in_Perms & 0x0800) ? 'S' : '-')); + + // group + $sP .= (($in_Perms & 0x0020) ? 'r' : '-') . + (($in_Perms & 0x0010) ? 'w' : '-') . + (($in_Perms & 0x0008) ? (($in_Perms & 0x0400) ? 's' : 'x' ) : + (($in_Perms & 0x0400) ? 'S' : '-')); + + // world + $sP .= (($in_Perms & 0x0004) ? 'r' : '-') . + (($in_Perms & 0x0002) ? 'w' : '-') . + (($in_Perms & 0x0001) ? (($in_Perms & 0x0200) ? 't' : 'x' ) : + (($in_Perms & 0x0200) ? 'T' : '-')); + return $sP; +} + diff --git a/phpgwapi/inc/class.iface_stream_wrapper.inc.php b/phpgwapi/inc/class.iface_stream_wrapper.inc.php new file mode 100644 index 0000000000..efb3f7bd1e --- /dev/null +++ b/phpgwapi/inc/class.iface_stream_wrapper.inc.php @@ -0,0 +1,243 @@ +=') && version_compare(PHP_VERSION,'5.1','<')) + * { + * $eof = !$eof; + * } + * + * @return boolean true if the read/write position is at the end of the stream and no more data availible, false otherwise + */ + function stream_eof ( ); + + /** + * This method is called in response to ftell() calls on the stream. + * + * @return integer current read/write position of the stream + */ + function stream_tell ( ); + + /** + * This method is called in response to fseek() calls on the stream. + * + * You should update the read/write position of the stream according to offset and whence. + * See fseek() for more information about these parameters. + * + * @param integer $offset + * @param integer $whence + * @return boolean TRUE if the position was updated, FALSE otherwise. + */ + function stream_seek ( $offset, $whence ); + + /** + * This method is called in response to fflush() calls on the stream. + * + * If you have cached data in your stream but not yet stored it into the underlying storage, you should do so now. + * + * @return booelan TRUE if the cached data was successfully stored (or if there was no data to store), or FALSE if the data could not be stored. + */ + function stream_flush ( ); + + /** + * This method is called in response to fstat() calls on the stream. + * + * If you plan to use your wrapper in a require_once you need to define stream_stat(). + * If you plan to allow any other tests like is_file()/is_dir(), you have to define url_stat(). + * stream_stat() must define the size of the file, or it will never be included. + * url_stat() must define mode, or is_file()/is_dir()/is_executable(), and any of those functions affected by clearstatcache() simply won't work. + * It's not documented, but directories must be a mode like 040777 (octal), and files a mode like 0100666. + * If you wish the file to be executable, use 7s instead of 6s. + * The last 3 digits are exactly the same thing as what you pass to chmod. + * 040000 defines a directory, and 0100000 defines a file. + * + * @return array containing the same values as appropriate for the stream. + */ + function stream_stat ( ); + + /** + * This method is called in response to unlink() calls on URL paths associated with the wrapper. + * + * It should attempt to delete the item specified by path. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support unlinking! + * + * @param string $path + * @return boolean TRUE on success or FALSE on failure + */ + function unlink ( $path ); + + /** + * This method is called in response to rename() calls on URL paths associated with the wrapper. + * + * It should attempt to rename the item specified by path_from to the specification given by path_to. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support renaming. + * + * @param string $path_from + * @param string $path_to + * @return boolean TRUE on success or FALSE on failure + */ + function rename ( $path_from, $path_to ); + + /** + * This method is called in response to mkdir() calls on URL paths associated with the wrapper. + * + * It should attempt to create the directory specified by path. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support creating directories. + * + * @param string $path + * @param int $mode + * @param int $options Posible values include STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE + * @return boolean TRUE on success or FALSE on failure + */ + function mkdir ( $path, $mode, $options ); + + /** + * This method is called in response to rmdir() calls on URL paths associated with the wrapper. + * + * It should attempt to remove the directory specified by path. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support removing directories. + * + * @param string $path + * @param int $options Possible values include STREAM_REPORT_ERRORS. + * @return boolean TRUE on success or FALSE on failure. + */ + function rmdir ( $path, $options ); + + /** + * 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. + * @return booelan + */ + function dir_opendir ( $path, $options ); + + /** + * This method is called in response to stat() calls on the URL paths associated with the wrapper. + * + * It should return as many elements in common with the system function as possible. + * Unknown or unavailable values should be set to a rational value (usually 0). + * + * If you plan to use your wrapper in a require_once you need to define stream_stat(). + * If you plan to allow any other tests like is_file()/is_dir(), you have to define url_stat(). + * stream_stat() must define the size of the file, or it will never be included. + * url_stat() must define mode, or is_file()/is_dir()/is_executable(), and any of those functions affected by clearstatcache() simply won't work. + * It's not documented, but directories must be a mode like 040777 (octal), and files a mode like 0100666. + * If you wish the file to be executable, use 7s instead of 6s. + * The last 3 digits are exactly the same thing as what you pass to chmod. + * 040000 defines a directory, and 0100000 defines a file. + * + * @param string $path + * @param int $flags holds additional flags set by the streams API. It can hold one or more of the following values OR'd together: + * - STREAM_URL_STAT_LINK For resources with the ability to link to other resource (such as an HTTP Location: forward, + * or a filesystem symlink). This flag specified that only information about the link itself should be returned, + * not the resource pointed to by the link. + * This flag is set in response to calls to lstat(), is_link(), or filetype(). + * - STREAM_URL_STAT_QUIET If this flag is set, your wrapper should not raise any errors. If this flag is not set, + * you are responsible for reporting errors using the trigger_error() function during stating of the path. + * @return array + */ + function url_stat ( $path, $flags ); + + /** + * This method is called in response to readdir(). + * + * It should return a string representing the next filename in the location opened by dir_opendir(). + * + * @return string + */ + function dir_readdir ( ); + + /** + * This method is called in response to rewinddir(). + * + * It should reset the output generated by dir_readdir(). i.e.: + * The next call to dir_readdir() should return the first entry in the location returned by dir_opendir(). + * + * @return boolean + */ + function dir_rewinddir ( ); + + /** + * This method is called in response to closedir(). + * + * You should release any resources which were locked or allocated during the opening and use of the directory stream. + * + * @return boolean + */ + function dir_closedir ( ); +} diff --git a/phpgwapi/inc/class.oldvfs_stream_wrapper.inc.php b/phpgwapi/inc/class.oldvfs_stream_wrapper.inc.php new file mode 100644 index 0000000000..7308ca77a1 --- /dev/null +++ b/phpgwapi/inc/class.oldvfs_stream_wrapper.inc.php @@ -0,0 +1,442 @@ + + * @copyright (c) 2007 by Ralf Becker + * @version $Id$ + */ + +require_once(EGW_API_INC.'/class.vfs_home.inc.php'); +require_once(EGW_API_INC.'/class.iface_stream_wrapper.inc.php'); + +/** + * eGroupWare API: VFS - old (until eGW 1.4 inclusive) VFS stream wrapper + * + * This class uses eGW's vfs_home class to access the vfs. + * + * The interface is according to the docu on php.net + * + * @link http://de.php.net/manual/de/function.stream-wrapper-register.php + */ +class oldvfs_stream_wrapper implements iface_stream_wrapper +{ + /** + * optional context param when opening the stream, null if no context passed + * + * @var mixed + */ + var $context; + + /** + * Instance of the old vfs class + * + * @var vfs_home + */ + static protected $old_vfs; + + /** + * Path off the file opened by stream_open + * + * @var string + */ + protected $opened_path; + /** + * Mode of the file opened by stream_open + * + * @var int + */ + protected $opened_mode; + /** + * Global vfs::ls() cache + * + * @var array + */ + static protected $cache=array(); + /** + * Directory vfs::ls() of path opened with dir_opendir() + * + * @var string + */ + protected $opened_dir; + + /** + * Constructor + * + * @return oldvfs_stream_wrapper + */ + function __construct() + { + error_log('oldvfs_stream_wrapper::__construct()'); + if (!is_object($this->old_vfs)) $this->old_vfs = new vfs_home(); + } + + /** + * 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 $mode mode used to open the file, as detailed for fopen() + * @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_REPORT_ERRORS If this flag is set, you are responsible for raising errors using trigger_error() during opening of the stream. + * If this flag is not set, you should not raise any errors. + * @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 + */ + function stream_open ( $path, $mode, $options, &$opened_path ) + { + + } + + /** + * This method is called when the stream is closed, using fclose(). + * + * You must release any resources that were locked or allocated by the stream. + */ + function stream_close ( ) + { + + } + + /** + * This method is called in response to fread() and fgets() calls on the stream. + * + * You must return up-to count bytes of data from the current read/write position as a string. + * If there are less than count bytes available, return as many as are available. + * If no more data is available, return either FALSE or an empty string. + * You must also update the read/write position of the stream by the number of bytes that were successfully read. + * + * @param int $count + * @return string/false up to count bytes read or false on EOF + */ + function stream_read ( $count ) + { + + } + + /** + * This method is called in response to fwrite() calls on the stream. + * + * You should store data into the underlying storage used by your stream. + * If there is not enough room, try to store as many bytes as possible. + * You should return the number of bytes that were successfully stored in the stream, or 0 if none could be stored. + * You must also update the read/write position of the stream by the number of bytes that were successfully written. + * + * @param string $data + * @return integer + */ + function stream_write ( $data ) + { + + } + + /** + * This method is called in response to feof() calls on the stream. + * + * Important: PHP 5.0 introduced a bug that wasn't fixed until 5.1: the return value has to be the oposite! + * + * if(version_compare(PHP_VERSION,'5.0','>=') && version_compare(PHP_VERSION,'5.1','<')) + * { + * $eof = !$eof; + * } + * + * @return boolean true if the read/write position is at the end of the stream and no more data availible, false otherwise + */ + function stream_eof ( ) + { + + } + + /** + * This method is called in response to ftell() calls on the stream. + * + * @return integer current read/write position of the stream + */ + function stream_tell ( ) + { + + } + + /** + * This method is called in response to fseek() calls on the stream. + * + * You should update the read/write position of the stream according to offset and whence. + * See fseek() for more information about these parameters. + * + * @param integer $offset + * @param integer $whence + * @return boolean TRUE if the position was updated, FALSE otherwise. + */ + function stream_seek ( $offset, $whence ) + { + + } + + /** + * This method is called in response to fflush() calls on the stream. + * + * If you have cached data in your stream but not yet stored it into the underlying storage, you should do so now. + * + * @return booelan TRUE if the cached data was successfully stored (or if there was no data to store), or FALSE if the data could not be stored. + */ + function stream_flush ( ) + { + + } + + /** + * This method is called in response to fstat() calls on the stream. + * + * If you plan to use your wrapper in a require_once you need to define stream_stat(). + * If you plan to allow any other tests like is_file()/is_dir(), you have to define url_stat(). + * stream_stat() must define the size of the file, or it will never be included. + * url_stat() must define mode, or is_file()/is_dir()/is_executable(), and any of those functions affected by clearstatcache() simply won't work. + * It's not documented, but directories must be a mode like 040777 (octal), and files a mode like 0100666. + * If you wish the file to be executable, use 7s instead of 6s. + * The last 3 digits are exactly the same thing as what you pass to chmod. + * 040000 defines a directory, and 0100000 defines a file. + * + * @return array containing the same values as appropriate for the stream. + */ + function stream_stat ( ) + { + + } + + /** + * This method is called in response to unlink() calls on URL paths associated with the wrapper. + * + * It should attempt to delete the item specified by path. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support unlinking! + * + * @param string $path + * @return boolean TRUE on success or FALSE on failure + */ + function unlink ( $path ) + { + + } + + /** + * This method is called in response to rename() calls on URL paths associated with the wrapper. + * + * It should attempt to rename the item specified by path_from to the specification given by path_to. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support renaming. + * + * @param string $path_from + * @param string $path_to + * @return boolean TRUE on success or FALSE on failure + */ + function rename ( $path_from, $path_to ) + { + + } + + /** + * This method is called in response to mkdir() calls on URL paths associated with the wrapper. + * + * It should attempt to create the directory specified by path. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support creating directories. + * + * @param string $path + * @param int $mode + * @param int $options Posible values include STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE + * @return boolean TRUE on success or FALSE on failure + */ + function mkdir ( $path, $mode, $options ) + { + + } + + /** + * This method is called in response to rmdir() calls on URL paths associated with the wrapper. + * + * It should attempt to remove the directory specified by path. + * In order for the appropriate error message to be returned, do not define this method if your wrapper does not support removing directories. + * + * @param string $path + * @param int $options Possible values include STREAM_REPORT_ERRORS. + * @return boolean TRUE on success or FALSE on failure. + */ + function rmdir ( $path, $options ) + { + + } + + /** + * 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. + * @return booelan + */ + function dir_opendir ( $url, $options ) + { + error_log("oldvfs_stream_wrapper::dir_opendir('$path',$options)"); + + if (!is_object($GLOBALS['egw']->vfs)) + { + $GLOBALS['egw']->vfs =& new vfs_home(); + } + $path = parse_url($url,PHP_URL_PATH); + + $this->opened_dir = $GLOBALS['egw']->vfs->ls(array( + 'string' => $path, + 'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root + 'checksubdirs' => false, + 'nofiles' => false, + //'orderby' => '', + //'mime_type' => '', + )); + if (!is_array($this->opened_dir)) + { + $this->opened_dir = null; + return false; + } + //print_r($this->opened_dir); + reset($this->opened_dir); + + return true; + } + + /** + * This method is called in response to stat() calls on the URL paths associated with the wrapper. + * + * It should return as many elements in common with the system function as possible. + * Unknown or unavailable values should be set to a rational value (usually 0). + * + * If you plan to use your wrapper in a require_once you need to define stream_stat(). + * If you plan to allow any other tests like is_file()/is_dir(), you have to define url_stat(). + * stream_stat() must define the size of the file, or it will never be included. + * url_stat() must define mode, or is_file()/is_dir()/is_executable(), and any of those functions affected by clearstatcache() simply won't work. + * It's not documented, but directories must be a mode like 040777 (octal), and files a mode like 0100666. + * If you wish the file to be executable, use 7s instead of 6s. + * The last 3 digits are exactly the same thing as what you pass to chmod. + * 040000 defines a directory, and 0100000 defines a file. + * + * @param string $path + * @param int $flags holds additional flags set by the streams API. It can hold one or more of the following values OR'd together: + * - STREAM_URL_STAT_LINK For resources with the ability to link to other resource (such as an HTTP Location: forward, + * or a filesystem symlink). This flag specified that only information about the link itself should be returned, + * not the resource pointed to by the link. + * This flag is set in response to calls to lstat(), is_link(), or filetype(). + * - STREAM_URL_STAT_QUIET If this flag is set, your wrapper should not raise any errors. If this flag is not set, + * you are responsible for reporting errors using the trigger_error() function during stating of the path. + * @return array + */ + function url_stat ( $url, $flags ) + { + error_log("oldvfs_stream_wrapper::url_stat('$url',$flags)"); + + /*return array( + 'mode' => 0100666, + 'name' => basename(parse_url($path,PHP_URL_PATH)), + 'size' => strlen(basename(parse_url($path,PHP_URL_PATH))), + 'nlink' => 1, + 'uid' => 1000, + 'gid' => 100, + 'mtime' => time(), + );*/ + + if (!is_object($GLOBALS['egw']->vfs)) + { + $GLOBALS['egw']->vfs =& new vfs_home(); + } + $path = parse_url($url,PHP_URL_PATH); + + list($info) = $GLOBALS['egw']->vfs->ls(array( + 'string' => $path, + 'relatives' => array(RELATIVE_ROOT), // filename is relative to the vfs-root + 'checksubdirs' => false, + 'nofiles' => true, + //'orderby' => '', + //'mime_type' => '', + )); + //print_r($info); + + return $info ? $this->vfsinfo2stat($info) : false; + } + + /** + * This method is called in response to readdir(). + * + * It should return a string representing the next filename in the location opened by dir_opendir(). + * + * @return string + */ + function dir_readdir ( ) + { + error_log("oldvfs_stream_wrapper::dir_readdir($this->opened_dir_path)"); + + if (!is_array($this->opened_dir)) return false; + + $file = current($this->opened_dir); next($this->opened_dir); + + return $file ? $file['name'] : false; + } + + /** + * This method is called in response to rewinddir(). + * + * It should reset the output generated by dir_readdir(). i.e.: + * The next call to dir_readdir() should return the first entry in the location returned by dir_opendir(). + * + * @return boolean + */ + function dir_rewinddir ( ) + { + error_log("oldvfs_stream_wrapper::dir_rewinddir($this->opened_dir_path)"); + + if (!is_array($this->opened_dir)) return false; + + reset($this->opened_dir); + + return true; + } + + /** + * This method is called in response to closedir(). + * + * You should release any resources which were locked or allocated during the opening and use of the directory stream. + * + * @return boolean + */ + function dir_closedir ( ) + { + error_log("oldvfs_stream_wrapper::dir_closedir($this->opened_dir_path)"); + + if (!is_array($this->opened_dir)) return false; + + $this->opened_dir = $this->opened_dir_path = null; + + return true; + } + + /** + * Convert a vfs-file-info into a stat array + * + * @param array $info + * @return array + */ + function vfsinfo2stat($info) + { + $stat = array( + 'ino' => $info['file_id'], + 'name' => $info['name'], + 'mode' => $info['mime_type'] == 'Directory' ? 040700 : 0100600, + 'size' => $info['size'], + 'uid' => $info['owner_id'] > 0 ? $info['owner_id'] : 0, + 'gid' => $info['owner_id'] < 0 ? $info['owner_id'] : 0, + 'mtime' => strtotime($info['modified'] ? $info['modified'] : $info['created']), + 'ctime' => strtotime($info['created']), + 'nlink' => $info['mime_type'] == 'Directory' ? 2 : 1, + ); + //print_r($stat); + return $stat; + } +} + +stream_register_wrapper('oldvfs','oldvfs_stream_wrapper');