From 2a5ee9512ee88da53dcba862a32279bdc7096bfb Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 12 Jun 2011 00:57:43 +0200 Subject: allow tear down of filesystem. also fix a bug when chrooting to '/' --- lib/filesystem.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'lib/filesystem.php') diff --git a/lib/filesystem.php b/lib/filesystem.php index 2b5c3a56b6e..27a937f5e4c 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -67,6 +67,16 @@ class OC_FILESYSTEM{ return array_keys(self::$storageTypes); } + /** + * tear down the filesystem, removing all storage providers + */ + static public function tearDown(){ + foreach(self::$storages as $mountpoint=>$storage){ + unset(self::$storages[$mountpoint]); + } + $fakeRoot=''; + } + /** * create a new storage of a specific type * @param string type @@ -91,8 +101,10 @@ class OC_FILESYSTEM{ * @return bool */ static public function chroot($fakeRoot){ - if($fakeRoot[0]!=='/'){ - $fakeRoot='/'.$fakeRoot; + if(!$fakeRoot==''){ + if($fakeRoot[0]!=='/'){ + $fakeRoot='/'.$fakeRoot; + } } self::$fakeRoot=$fakeRoot; } -- cgit v1.2.3 From 300b8c06cfacbae7df4f7886851cea8c895111c5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 16 Jun 2011 22:44:16 +0200 Subject: allow plugins to cancel filesystem operations using the provided hooks --- lib/filesystem.php | 152 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 103 insertions(+), 49 deletions(-) (limited to 'lib/filesystem.php') diff --git a/lib/filesystem.php b/lib/filesystem.php index 27a937f5e4c..0faa7404700 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -29,10 +29,13 @@ * * Hooks provided: * read(path) - * write(path) - * create(path) (when a file is created both, write and create will be emited) - * delete(path) - * rename(oldpath,newpath) + * write(path, &run) + * create(path, &run) (when a file is created, both create and write will be emited in that order) + * delete(path, &run) + * rename(oldpath,newpath, &run) + * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order) + * + * the &run parameter can be set to false to prevent the operation from occuring */ class OC_FILESYSTEM{ static private $storages=array(); @@ -222,14 +225,23 @@ class OC_FILESYSTEM{ static public function mkdir($path){ $parent=substr($path,0,strrpos($path,'/')); if(self::canWrite($parent) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); - return $storage->mkdir(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + return $storage->mkdir(self::getInternalPath($path)); + } } } static public function rmdir($path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path)); - return $storage->rmdir(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); + if($run){ + return $storage->rmdir(self::getInternalPath($path)); + } } } static public function opendir($path){ @@ -319,55 +331,76 @@ class OC_FILESYSTEM{ } static public function file_put_contents($path,$data){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); + $run=true; if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + return $storage->file_put_contents(self::getInternalPath($path),$data); } - return $storage->file_put_contents(self::getInternalPath($path),$data); } } static public function unlink($path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path)); - return $storage->unlink(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); + if($run){ + return $storage->unlink(self::getInternalPath($path)); + } } } static public function rename($path1,$path2){ if(self::canWrite($path1) and self::canWrite($path2)){ - $mp1=self::getMountPoint($path1); - $mp2=self::getMountPoint($path2); - if($mp1==$mp2){ - if($storage=self::getStorage($path1)){ - return $storage->rename(self::getInternalPath($path1),self::getInternalPath($path2)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'rename', array( 'oldpath' => $path1 ,'newpath'=>$path2, 'run' => &$run)); + if($run){ + $mp1=self::getMountPoint($path1); + $mp2=self::getMountPoint($path2); + if($mp1==$mp2){ + if($storage=self::getStorage($path1)){ + return $storage->rename(self::getInternalPath($path1),self::getInternalPath($path2)); + } + }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ + $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); + $result=$storage2->fromTmpFile(self::getInternalPath($path2)); + $storage1->unlink(self::getInternalPath($path1)); + return $result; } - }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ - $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); - $result=$storage2->fromTmpFile(self::getInternalPath($path2)); - $storage1->unlink(self::getInternalPath($path1)); - return $result; } - OC_HOOK::emit( 'OC_FILESYSTEM', 'rename', array( 'oldpath' => $path1 ,'newpath'=>$path2)); } } static public function copy($path1,$path2){ if(self::canRead($path1) and self::canWrite($path2)){ - $mp1=self::getMountPoint($path1); - $mp2=self::getMountPoint($path2); - if($mp1==$mp2){ - if($storage=self::getStorage($path1)){ - return $storage->copy(self::getInternalPath($path1),self::getInternalPath($path2)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'copy', array( 'oldpath' => $path1 ,'newpath'=>$path2, 'run' => &$run)); + if($run and !self::file_exists($path2)){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path2, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path2, 'run' => &$run)); + } + if($run){ + $mp1=self::getMountPoint($path1); + $mp2=self::getMountPoint($path2); + if($mp1==$mp2){ + if($storage=self::getStorage($path1)){ + return $storage->copy(self::getInternalPath($path1),self::getInternalPath($path2)); + } + }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ + $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); + return $storage2->fromTmpFile(self::getInternalPath($path2)); } - }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ - $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); - return $storage2->fromTmpFile(self::getInternalPath($path2)); } - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path2)); } } static public function fopen($path,$mode){ $allowed=((strpos($path,'r')===false and strpos($path,'r+')!==false and self::canRead) or self::canWrite($path)); if($allowed){ if($storage=self::getStorage($path)){ + $run=true; switch($mode){ case 'r': OC_HOOK::emit( 'OC_FILESYSTEM', 'read', array( 'path' => $path)); @@ -377,21 +410,27 @@ class OC_FILESYSTEM{ case 'x+': case 'a+': OC_HOOK::emit( 'OC_FILESYSTEM', 'read', array( 'path' => $path)); - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); if(!self::file_exists($path)){ OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } break; case 'w': case 'x': case 'a': - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); if(!self::file_exists($path)){ OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } break; } - return $storage->fopen(self::getInternalPath($path),$mode); + if($run){ + return $storage->fopen(self::getInternalPath($path),$mode); + } } } } @@ -403,20 +442,30 @@ class OC_FILESYSTEM{ } static public function fromTmpFile($tmpFile,$path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); + $run=true; if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + return $storage->fromTmpFile($tmpFile,self::getInternalPath($path)); } - return $storage->fromTmpFile($tmpFile,self::getInternalPath($path)); } } static public function fromUploadedFile($tmpFile,$path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + $run=true; + if($run and !self::file_exists($path)){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + return $storage->fromUploadedFile($tmpFile,self::getInternalPath($path)); } - return $storage->fromUploadedFile($tmpFile,self::getInternalPath($path)); } } static public function getMimeType($path){ @@ -426,8 +475,11 @@ class OC_FILESYSTEM{ } static public function delTree($path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path)); - return $storage->delTree(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); + if($run){ + return $storage->delTree(self::getInternalPath($path)); + } } } static public function find($path){ @@ -475,10 +527,12 @@ class OC_FILESYSTEM{ $fakeRootLength=strlen(self::$fakeRoot); foreach(self::$storages as $mountpoint=>$storage){ $results=$storage->search($query); - foreach($results as $result){ - $file=str_replace('//','/',$mountpoint.$result); - $file=substr($file,$fakeRootLength); - $files[]=$file; + if(is_array($results)){ + foreach($results as $result){ + $file=str_replace('//','/',$mountpoint.$result); + $file=substr($file,$fakeRootLength); + $files[]=$file; + } } } return $files; -- cgit v1.2.3 From 07f2fcf7ec249d45dfe1a4e38439d1e756a0bc86 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 19 Jun 2011 22:23:05 +0200 Subject: add post_* hooks to filesystem for write, create, delete, rename and copy --- lib/filesystem.php | 103 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 27 deletions(-) (limited to 'lib/filesystem.php') diff --git a/lib/filesystem.php b/lib/filesystem.php index 0faa7404700..e6b1638d8d7 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -30,10 +30,15 @@ * Hooks provided: * read(path) * write(path, &run) + * post_write(path) * create(path, &run) (when a file is created, both create and write will be emited in that order) + * post_create(path) * delete(path, &run) + * post_delete(path) * rename(oldpath,newpath, &run) + * post_rename(oldpath,newpath) * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order) + * post_rename(oldpath,newpath) * * the &run parameter can be set to false to prevent the operation from occuring */ @@ -231,7 +236,10 @@ class OC_FILESYSTEM{ OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); } if($run){ - return $storage->mkdir(self::getInternalPath($path)); + $result=$storage->mkdir(self::getInternalPath($path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } } } @@ -240,7 +248,9 @@ class OC_FILESYSTEM{ $run=true; OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); if($run){ - return $storage->rmdir(self::getInternalPath($path)); + $result=$storage->rmdir(self::getInternalPath($path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_delete', array( 'path' => $path)); + return $result; } } } @@ -332,14 +342,20 @@ class OC_FILESYSTEM{ static public function file_put_contents($path,$data){ if(self::canWrite($path) and $storage=self::getStorage($path)){ $run=true; - if(!self::file_exists($path)){ + $exists=self::file_exists($path); + if(!$exists){ OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); } if($run){ OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); } if($run){ - return $storage->file_put_contents(self::getInternalPath($path),$data); + $result=$storage->file_put_contents(self::getInternalPath($path),$data); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } } } @@ -348,7 +364,9 @@ class OC_FILESYSTEM{ $run=true; OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); if($run){ - return $storage->unlink(self::getInternalPath($path)); + $result=$storage->unlink(self::getInternalPath($path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_delete', array( 'path' => $path)); + return $result; } } } @@ -361,14 +379,15 @@ class OC_FILESYSTEM{ $mp2=self::getMountPoint($path2); if($mp1==$mp2){ if($storage=self::getStorage($path1)){ - return $storage->rename(self::getInternalPath($path1),self::getInternalPath($path2)); + $result=$storage->rename(self::getInternalPath($path1),self::getInternalPath($path2)); } }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); $result=$storage2->fromTmpFile(self::getInternalPath($path2)); $storage1->unlink(self::getInternalPath($path1)); - return $result; } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_rename', array( 'oldpath' => $path1, 'newpath'=>$path2)); + return $result; } } } @@ -376,7 +395,8 @@ class OC_FILESYSTEM{ if(self::canRead($path1) and self::canWrite($path2)){ $run=true; OC_HOOK::emit( 'OC_FILESYSTEM', 'copy', array( 'oldpath' => $path1 ,'newpath'=>$path2, 'run' => &$run)); - if($run and !self::file_exists($path2)){ + $exists=self::file_exists($path2); + if($run and !$exists){ OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path2, 'run' => &$run)); } if($run){ @@ -387,12 +407,18 @@ class OC_FILESYSTEM{ $mp2=self::getMountPoint($path2); if($mp1==$mp2){ if($storage=self::getStorage($path1)){ - return $storage->copy(self::getInternalPath($path1),self::getInternalPath($path2)); + $result=$storage->copy(self::getInternalPath($path1),self::getInternalPath($path2)); } }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); - return $storage2->fromTmpFile(self::getInternalPath($path2)); + $result=$storage2->fromTmpFile(self::getInternalPath($path2)); } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_copy', array( 'oldpath' => $path1 ,'newpath'=>$path2)); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } } } @@ -401,6 +427,8 @@ class OC_FILESYSTEM{ if($allowed){ if($storage=self::getStorage($path)){ $run=true; + $exists=self::file_exists($path); + $write=false; switch($mode){ case 'r': OC_HOOK::emit( 'OC_FILESYSTEM', 'read', array( 'path' => $path)); @@ -410,26 +438,33 @@ class OC_FILESYSTEM{ case 'x+': case 'a+': OC_HOOK::emit( 'OC_FILESYSTEM', 'read', array( 'path' => $path)); - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); - } - if($run){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); - } + $write=true; break; case 'w': case 'x': case 'a': - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); - } - if($run){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); - } + $write=true; break; } + if($write){ + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + } if($run){ - return $storage->fopen(self::getInternalPath($path),$mode); + $result=$storage->fopen(self::getInternalPath($path),$mode); + if($write){ + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + } + } + return $result; } } } @@ -443,28 +478,42 @@ class OC_FILESYSTEM{ static public function fromTmpFile($tmpFile,$path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ $run=true; - if(!self::file_exists($path)){ + $exists=self::file_exists($path); + if(!$exists){ OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); } if($run){ OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); } if($run){ - return $storage->fromTmpFile($tmpFile,self::getInternalPath($path)); + $result=$storage->fromTmpFile($tmpFile,self::getInternalPath($path)); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } } } static public function fromUploadedFile($tmpFile,$path){ + error_log('upload'); if(self::canWrite($path) and $storage=self::getStorage($path)){ $run=true; - if($run and !self::file_exists($path)){ + $exists=self::file_exists($path); + if(!$exists){ OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); } if($run){ OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); } + error_log('upload2'); if($run){ - return $storage->fromUploadedFile($tmpFile,self::getInternalPath($path)); + $result=$storage->fromUploadedFile($tmpFile,self::getInternalPath($path)); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } } } -- cgit v1.2.3