diff --git a/files/api.php b/files/api.php index fa94a51254..d6e04d4550 100755 --- a/files/api.php +++ b/files/api.php @@ -55,6 +55,9 @@ if($arguments['action']){ case 'getfiles': echo json_encode(OC_FILES::getdirectorycontent($arguments['dir'])); break; + case 'gettree': + echo json_encode(OC_FILES::getTree($arguments['dir'])); + break; case 'find': echo json_encode(OC_FILESYSTEM::find($arguments['path'])); break; diff --git a/inc/HTTP/WebDAV/Server/Filesystem.php b/inc/HTTP/WebDAV/Server/Filesystem.php index a41d368730..ea0625a5a1 100755 --- a/inc/HTTP/WebDAV/Server/Filesystem.php +++ b/inc/HTTP/WebDAV/Server/Filesystem.php @@ -324,7 +324,6 @@ */ function PUT(&$options) { - error_log("put $fspath"); $fspath = $options["path"]; $dir = dirname($fspath); if (!OC_FILESYSTEM::file_exists($dir) || !OC_FILESYSTEM::is_dir($dir)) { diff --git a/inc/lib_base.php b/inc/lib_base.php index 5c9906d361..a806d3e5bd 100755 --- a/inc/lib_base.php +++ b/inc/lib_base.php @@ -82,6 +82,7 @@ oc_require_once('lib_ocs.php'); @oc_require_once('MDB2.php'); @oc_require_once('MDB2/Schema.php'); oc_require_once('lib_connect.php'); +oc_require_once('lib_remotestorage.php'); if(!is_dir($CONFIG_DATADIRECTORY_ROOT)){ diff --git a/inc/lib_connect.php b/inc/lib_connect.php index 0c56d1a01d..9db867715e 100644 --- a/inc/lib_connect.php +++ b/inc/lib_connect.php @@ -75,7 +75,8 @@ class OC_REMOTE_CLOUD{ curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile); curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); - $result=trim(curl_exec($ch)); + $result=curl_exec($ch); + $result=trim($result); $info=curl_getinfo($ch); $httpCode=$info['http_code']; curl_close($ch); @@ -121,6 +122,70 @@ class OC_REMOTE_CLOUD{ $this->cookiefile=false; } + /** + * create a new file or directory + * @param string $dir + * @param string $name + * @param string $type + */ + public function newFile($dir,$name,$type){ + if(!$this->connected){ + return false; + } + return $this->apiCall('new',array('dir'=>$dir,'name'=>$name,'type'=>$type),true); + } + + /** + * deletes a file or directory + * @param string $dir + * @param string $file + */ + public function delete($dir,$name){ + if(!$this->connected){ + return false; + } + return $this->apiCall('delete',array('dir'=>$dir,'file'=>$name),true); + } + + /** + * moves a file or directory + * @param string $sorceDir + * @param string $sorceFile + * @param string $targetDir + * @param string $targetFile + */ + public function move($sourceDir,$sourceFile,$targetDir,$targetFile){ + if(!$this->connected){ + return false; + } + return $this->apiCall('move',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true); + } + + /** + * copies a file or directory + * @param string $sorceDir + * @param string $sorceFile + * @param string $targetDir + * @param string $targetFile + */ + public function copy($sourceDir,$sourceFile,$targetDir,$targetFile){ + if(!$this->connected){ + return false; + } + return $this->apiCall('copy',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true); + } + + /** + * get a file tree + * @param string $dir + */ + public function getTree($dir){ + if(!$this->connected){ + return false; + } + return $this->apiCall('gettree',array('dir'=>$dir),true); + } + /** * get the files inside a directory of the remote cloud * @param string $dir @@ -163,7 +228,12 @@ class OC_REMOTE_CLOUD{ global $WEBROOT; $source=$sourceDir.'/'.$sourceFile; $tmp=OC_FILESYSTEM::toTmpFile($source); - $token=sha1(uniqid().$source); + return $this->sendTmpFile($tmp,$targetDir,$targetFile); + } + + public function sendTmpFile($tmp,$targetDir,$targetFile){ + $token=sha1(uniqid().$tmp); + global $WEBROOT; $file=sys_get_temp_dir().'/'.'remoteCloudFile'.$token; rename($tmp,$file); if((isset($CONFIG_HTTPFORCESSL) and $CONFIG_HTTPFORCESSL) or isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') { diff --git a/inc/lib_files.php b/inc/lib_files.php index 20d40669d7..8f694536f7 100755 --- a/inc/lib_files.php +++ b/inc/lib_files.php @@ -54,7 +54,7 @@ class OC_FILES { $dirs=array(); $file=array(); $files=array(); - if (OC_FILESYSTEM::is_dir($directory)) { + if(OC_FILESYSTEM::is_dir($directory)) { if ($dh = OC_FILESYSTEM::opendir($directory)) { while (($filename = readdir($dh)) !== false) { if($filename<>'.' and $filename<>'..' and substr($filename,0,1)!='.'){ @@ -136,7 +136,11 @@ class OC_FILES { header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); - header('Content-Length: ' . filesize($filename)); + if($zip){ + header('Content-Length: ' . filesize($filename)); + }else{ + header('Content-Length: ' . OC_FILESYSTEM::filesize($filename)); + } }elseif($zip or !OC_FILESYSTEM::file_exists($filename)){ header("HTTP/1.0 404 Not Found"); die('404 Not Found'); @@ -243,6 +247,16 @@ class OC_FILES { return OC_FILESYSTEM::getMimeType($path); } + /** + * get a file tree + * + * @param string path + * @return array + */ + static function getTree($path){ + return OC_FILESYSTEM::getTree($path); + } + /** * pull a file from a remote server * @param string source @@ -257,8 +271,6 @@ class OC_FILES { $url=$source.="/files/pull.php?token=$token"; $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); - curl_setopt($ch,CURLOPT_POST,count($parameters)); - curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string); curl_setopt($ch, CURLOPT_FILE, $fp); curl_exec($ch); fclose($fp); @@ -306,4 +318,46 @@ if(!function_exists('sys_get_temp_dir')) { } } +global $FAKEDIRS; +$FAKEDIRS=array(); + +class fakeDirStream{ + private $name; + private $data; + private $index; + + public function dir_opendir($path,$options){ + global $FAKEDIRS; + $url=parse_url($path); + $this->name=substr($path,strlen('fakedir://')); + $this->index=0; + if(isset($FAKEDIRS[$this->name])){ + $this->data=$FAKEDIRS[$this->name]; + }else{ + $this->data=array(); + } + return true; + } + + public function dir_readdir(){ + if($this->index>=count($this->data)){ + return false; + } + $filename=$this->data[$this->index]; + $this->index++; + return $filename; + } + + public function dir_closedir() { + $this->data=false; + $this->name=''; + return true; + } + + public function dir_rewinddir() { + $this->index=0; + return true; + } +} +stream_wrapper_register("fakedir", "fakeDirStream"); ?> \ No newline at end of file diff --git a/inc/lib_filestorage.php b/inc/lib_filestorage.php index 85382a4444..10266d4eaf 100755 --- a/inc/lib_filestorage.php +++ b/inc/lib_filestorage.php @@ -62,7 +62,7 @@ class OC_FILESTORAGE{ public function filemtime($path){} public function fileatime($path){} public function file_get_contents($path){} - public function file_put_contents($path){} + public function file_put_contents($path,$data){} public function unlink($path){} public function rename($path1,$path2){} public function copy($path1,$path2){} @@ -149,8 +149,8 @@ class OC_FILESTORAGE_LOCAL extends OC_FILESTORAGE{ } return $return; } - public function file_put_contents($path){ - if($return=file_put_contents($this->datadir.$path)){ + public function file_put_contents($path,$data){ + if($return=file_put_contents($this->datadir.$path,$data)){ $this->notifyObservers($path,OC_FILEACTION_WRITE); } } diff --git a/inc/lib_filesystem.php b/inc/lib_filesystem.php index 6eb317f442..492e0c5d38 100755 --- a/inc/lib_filesystem.php +++ b/inc/lib_filesystem.php @@ -199,7 +199,7 @@ class OC_FILESYSTEM{ return $storage->file_get_contents(substr($path,strlen(self::getMountPoint($path)))); } } - static public function file_put_contents($path){ + static public function file_put_contents($path,$data){ if(self::canWrite($path) and $storage=self::getStorage($path)){ $this->notifyObservers($path,OC_FILEACTION_WRITE | OC_FILEACTION_CREATE); return $storage->file_put_contents(substr($path,strlen(self::getMountPoint($path)))); diff --git a/inc/lib_remotestorage.php b/inc/lib_remotestorage.php new file mode 100644 index 0000000000..882f281e41 --- /dev/null +++ b/inc/lib_remotestorage.php @@ -0,0 +1,323 @@ +. +* +*/ + + +class OC_FILESTORAGE_REMOTE extends OC_FILESTORAGE{ + private $url; + private $username; + private $password; + private $remote; + private $statCache; + private $statCacheDir=false; + private $changed=array(); + + private function cacheDir($dir){ + if($this->statCacheDir!=$dir or $this->statCacheDir===false){ + $this->statCache=$this->remote->getFiles($dir); + $keys=array_keys($this->statCache); + $this->statCacheDir=$dir; + } + } + + public function __construct($arguments){ + $this->url=$arguments['url']; + $this->username=$arguments['username']; + $this->password=$arguments['password']; + $this->remote=OC_CONNECT::connect($this->url,$this->username,$this->password); + } + public function mkdir($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $return=$this->remote->newFile($parent,$name,'dir'); + if($return){ + $this->notifyObservers($path,OC_FILEACTION_CREATE); + } + return $return; + } + public function rmdir($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $return=$this->remote->delete($parent,$name); + if($return){ + $this->notifyObservers($path,OC_FILEACTION_DELETE); + } + return $return; + } + public function opendir($path){ + $this->cacheDir($path); + $dirs=array_keys($this->statCache); + $id=uniqid(); + global $FAKEDIRS; + $FAKEDIRS[$id]=$dirs; + if($return=opendir("fakedir://$id")){ + $this->notifyObservers($path,OC_FILEACTION_READ); + } + return $return; + } + public function is_dir($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($path); + if($path=='' or $path=='/'){ + return true; + } + if(!isset($this->statCache[$name])){ + return false; + } + return ($this->statCache[$name]['type'=='dir']); + } + public function is_file($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return ($this->statCache[$name]['type'!='dir']); + } + public function stat($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return $false; + } + return $this->statCache[$name]; + } + public function filetype($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return $this->statCache[$name]['type']; + } + public function filesize($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return $false; + } + return $this->statCache[$name]['size']; + } + public function is_readable($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return $this->statCache[$name]['readable']; + } + public function is_writeable($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return $this->statCache[$name]['writeable']; + } + public function file_exists($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + return isset($this->statCache[$name]); + } + public function readfile($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $file=$this->remote->getFile($parent,$name); + readfile($file); + unlink($file); + } + public function filectime($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return $this->statCache[$name]['ctime']; + } + public function filemtime($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return $this->statCache[$name]['mtime']; + } + public function fileatime($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return $this->statCache[$name]['atime']; + } + public function file_get_contents($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $file=$this->remote->getFile($parent,$name); + file_get_contents($file); + unlink($file); + } + public function file_put_contents($path,$data){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $file=$this->remote->getFile($parent,$name); + $file=tempnam(sys_get_temp_dir(),'oc_'); + file_put_contents($file,$data); + if($return=$this->remote->sendTmpFile($file,$parent,$name)){ + $this->notifyObservers($path,OC_FILEACTION_WRITE); + } + } + public function unlink($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + if($return=$this->remote->delete($paren,$name)){ + $this->notifyObservers($path,OC_FILEACTION_DELETE); + } + return $return; + } + public function rename($path1,$path2){ + $parent1=dirname($path1); + $name1=substr($path1,strlen($parent1)+1); + $parent2=dirname($path2); + $name2=substr($path2,strlen($parent2)+1); + if($return=$this->remote->move($parent1,$name1,$parent2,$name2)){ + $this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME); + } + return $return; + } + public function copy($path1,$path2){ + $parent1=dirname($path1); + $name1=substr($path1,strlen($parent1)+1); + $parent2=dirname($path2); + $name2=substr($path2,strlen($parent2)+1); + if($return=$this->copy->rename($parent1,$name1,$parent2,$name2)){ + $this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME); + } + return $return; + } + public function fopen($path,$mode){ + $changed=false; + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + $file=$this->remote->getFile($parent,$name); + if($return=fopen($file,$mode)){ + switch($mode){ + case 'r': + $this->notifyObservers($path,OC_FILEACTION_READ); + break; + case 'r+': + case 'w+': + case 'x+': + case 'a+': + $this->notifyObservers($path,OC_FILEACTION_READ | OC_FILEACTION_WRITE); + $this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file); + break; + case 'w': + case 'x': + case 'a': + $this->notifyObservers($path,OC_FILEACTION_WRITE); + $this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file); + break; + } + } + return $return; + } + + public function getMimeType($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + if(substr($name,0,1)=='/'){ + $name=substr($name,1); + } + $this->cacheDir($parent); + if(!isset($this->statCache[$name])){ + return false; + } + return $this->statCache[$name]['mime']; + } + + public function toTmpFile($path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + if(substr($name,0,1)=='/'){ + $name=substr($name,1); + } + $filename=$this->remote->getFile($parent,$name); + if($filename){ + $this->notifyObservers($path,OC_FILEACTION_READ); + return $filename; + }else{ + return false; + } + } + + public function fromTmpFile($tmpFile,$path){ + $parent=dirname($path); + $name=substr($path,strlen($parent)+1); + if($this->remote->sendTmpFile($tmpFile,$parent,$name)){ + $this->notifyObservers($path,OC_FILEACTION_CREATE); + return true; + }else{ + return false; + } + } + + public function delTree($dir) { + $parent=dirname($dir); + $name=substr($dir,strlen($parent)+1); + $return=$this->remote->delete($parent,$name); + if($return=rmdir($dir)){ + $this->notifyObservers($dir,OC_FILEACTION_DELETE); + } + return $return; + } + + public function find($path){ + return $this->getTree($path); + } + + public function getTree($dir) { + if($return=$this->remote->getTree($dir)){ + $this->notifyObservers($dir,OC_FILEACTION_READ); + } + return $return; + } + + public function __destruct(){ + foreach($this->changed as $changed){ + $this->remote->sendTmpFile($changed['tmp'],$changed['dir'],$changed['file']); + } + } +} + +?>