* This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ class OC_Filestorage_Archive extends OC_Filestorage_Common{ /** * underlying local storage used for missing functions * @var OC_Archive */ private $archive; private $path; private static $mounted=array(); private static $enableAutomount=true; private static $rootView; private function stripPath($path){//files should never start with / if(!$path || $path[0]=='/'){ $path=substr($path,1); } return $path; } public function __construct($params){ $this->archive=OC_Archive::open($params['archive']); $this->path=$params['archive']; } public function mkdir($path){ $path=$this->stripPath($path); return $this->archive->addFolder($path); } public function rmdir($path){ $path=$this->stripPath($path); return $this->archive->remove($path.'/'); } public function opendir($path){ if(substr($path,-1)!=='/'){ $path.='/'; } $path=$this->stripPath($path); $files=$this->archive->getFolder($path); $content=array(); foreach($files as $file){ if(substr($file,-1)=='/'){ $file=substr($file,0,-1); } if($file and strpos($file,'/')===false){ $content[]=$file; } } $id=md5($this->path.$path); OC_FakeDirStream::$dirs[$id]=$content; return opendir('fakedir://'.$id); } public function stat($path){ $ctime=-1; $path=$this->stripPath($path); if($path==''){ $stat=stat($this->path); $stat['size']=0; }else{ if($this->is_dir($path)){ $stat=array('size'=>0); $stat['mtime']=filemtime($this->path); }else{ $stat=array(); $stat['mtime']=$this->archive->mtime($path); $stat['size']=$this->archive->filesize($path); if(!$stat['mtime']){ $stat['mtime']=time(); } } } $stat['ctime']=$ctime; return $stat; } public function filetype($path){ $path=$this->stripPath($path); if($path==''){ return 'dir'; } if(substr($path,-1)=='/'){ return $this->archive->fileExists($path)?'dir':'file'; }else{ return $this->archive->fileExists($path.'/')?'dir':'file'; } } public function isReadable($path){ return is_readable($this->path); } public function isUpdatable($path){ return is_writable($this->path); } public function file_exists($path){ $path=$this->stripPath($path); if($path==''){ return file_exists($this->path); } return $this->archive->fileExists($path); } public function unlink($path){ $path=$this->stripPath($path); return $this->archive->remove($path); } public function fopen($path,$mode){ $path=$this->stripPath($path); return $this->archive->getStream($path,$mode); } public function free_space($path){ return 0; } public function touch($path, $mtime=null){ if(is_null($mtime)){ $tmpFile=OCP\Files::tmpFile(); $this->archive->extractFile($path,$tmpFile); $this->archive->addfile($path,$tmpFile); }else{ return false;//not supported } } private function toTmpFile($path){ $tmpFile=OC_Helper::tmpFile($extension); $this->archive->extractFile($path,$tmpFile); return $tmpFile; } public function file_put_contents($path,$data) { $path=$this->stripPath($path); return $this->archive->addFile($path,$data); } public function file_get_contents($path) { $path=$this->stripPath($path); return $this->archive->getFile($path); } /** * automount paths from file hooks * @param aray params */ public static function autoMount($params){ if(!self::$enableAutomount){ return; } $path=$params['path']; if(!self::$rootView){ self::$rootView=new OC_FilesystemView(''); } self::$enableAutomount=false;//prevent recursion $supported=array('zip','tar.gz','tar.bz2','tgz'); foreach($supported as $type){ $ext='.'.$type.'/'; if(($pos=strpos(strtolower($path),$ext))!==false){ $archive=substr($path,0,$pos+strlen($ext)-1); if(self::$rootView->file_exists($archive) and array_search($archive,self::$mounted)===false){ $localArchive=self::$rootView->getLocalFile($archive); OC_Filesystem::mount('OC_Filestorage_Archive',array('archive'=>$localArchive),$archive.'/'); self::$mounted[]=$archive; } } } self::$enableAutomount=true; } public function rename($path1,$path2){ return $this->archive->rename($path1,$path2); } public function hasUpdated($path,$time){ return $this->filemtime($this->path)>$time; } }