diff options
author | Thomas Tanghus <thomas@tanghus.net> | 2012-03-07 20:57:05 +0100 |
---|---|---|
committer | Thomas Tanghus <thomas@tanghus.net> | 2012-03-07 20:57:05 +0100 |
commit | 57c4d39b1e0becaeeb795cfbfd70f525bd89b9d8 (patch) | |
tree | 5a12c8c7d83574b9bff3e4271e88ec740820c2aa /lib | |
parent | 75323b86d157c48031b9ac8c151e4a41577a1481 (diff) | |
parent | cf5d63f0abc2b4537098962ad5051180861f965b (diff) | |
download | nextcloud-server-57c4d39b1e0becaeeb795cfbfd70f525bd89b9d8.tar.gz nextcloud-server-57c4d39b1e0becaeeb795cfbfd70f525bd89b9d8.zip |
Fix conflict.
Diffstat (limited to 'lib')
33 files changed, 1511 insertions, 667 deletions
diff --git a/lib/app.php b/lib/app.php index 1879a89cee3..f841180ebad 100644 --- a/lib/app.php +++ b/lib/app.php @@ -58,8 +58,8 @@ class OC_App{ $apps = OC_Appconfig::getApps(); foreach( $apps as $app ){ if( self::isEnabled( $app )){ - if(is_file(OC::$SERVERROOT.'/apps/'.$app.'/appinfo/app.php')){ - require( 'apps/'.$app.'/appinfo/app.php' ); + if(is_file(OC::$APPSROOT.'/apps/'.$app.'/appinfo/app.php')){ + require( $app.'/appinfo/app.php' ); } } } @@ -268,7 +268,7 @@ class OC_App{ if(is_file($appid)){ $file=$appid; }else{ - $file=OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/info.xml'; + $file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml'; if(!is_file($file)){ return array(); } @@ -363,9 +363,9 @@ class OC_App{ */ public static function getAllApps(){ $apps=array(); - $dh=opendir(OC::$SERVERROOT.'/apps'); + $dh=opendir(OC::$APPSROOT.'/apps'); while($file=readdir($dh)){ - if(is_file(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/app.php')){ + if(substr($file,0,1)!='.' and is_file(OC::$APPSROOT.'/apps/'.$file.'/appinfo/app.php')){ $apps[]=$file; } } @@ -396,11 +396,11 @@ class OC_App{ * @param string appid */ public static function updateApp($appid){ - if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml')){ - OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml'); + if(file_exists(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/database.xml')){ + OC_DB::updateDbFromStructure(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/database.xml'); } - if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php')){ - include OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php'; + if(file_exists(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php')){ + include OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php'; } } diff --git a/lib/base.php b/lib/base.php index 880645ff79d..9995544f14e 100644 --- a/lib/base.php +++ b/lib/base.php @@ -54,6 +54,22 @@ class OC{ * the folder that stores the data for the root filesystem (e.g. /srv/http/owncloud/data) */ public static $CONFIG_DATADIRECTORY_ROOT = ''; + /** + * The installation path of the 3rdparty folder on the server (e.g. /srv/http/owncloud/3rdparty) + */ + public static $THIRDPARTYROOT = ''; + /** + * the root path of the 3rdparty folder for http requests (e.g. owncloud/3rdparty) + */ + public static $THIRDPARTYWEBROOT = ''; + /** + * The installation path of the apps folder on the server (e.g. /srv/http/owncloud) + */ + public static $APPSROOT = ''; + /** + * the root path of the apps folder for http requests (e.g. owncloud) + */ + public static $APPSWEBROOT = ''; /** * SPL autoload @@ -128,6 +144,12 @@ class OC{ $_SERVER['PHP_AUTH_PW'] = strip_tags($password); } + // register the stream wrappers + require_once('streamwrappers.php'); + stream_wrapper_register("fakedir", "OC_FakeDirStream"); + stream_wrapper_register('static', 'OC_StaticStreamWrapper'); + stream_wrapper_register('close', 'OC_CloseStreamWrapper'); + // calculate the documentroot OC::$DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']); OC::$SERVERROOT=str_replace("\\",'/',substr(__FILE__,0,-13)); @@ -135,15 +157,60 @@ class OC{ $scriptName=$_SERVER["SCRIPT_NAME"]; if(substr($scriptName,-1)=='/'){ $scriptName.='index.php'; + //make sure suburi follows the same rules as scriptName + if(substr(OC::$SUBURI,-9)!='index.php'){ + if(substr(OC::$SUBURI,-1)!='/'){ + OC::$SUBURI=OC::$SUBURI.'/'; + } + OC::$SUBURI=OC::$SUBURI.'index.php'; + } } - OC::$WEBROOT=substr($scriptName,0,strlen($scriptName)-strlen(OC::$SUBURI)); + OC::$WEBROOT=substr($scriptName,0,strlen($scriptName)-strlen(OC::$SUBURI)); + // try a new way to detect the WEBROOT which is simpler and also works with the app directory outside the owncloud folder. let´s see if this works for everybody +// OC::$WEBROOT=substr(OC::$SERVERROOT,strlen(OC::$DOCUMENTROOT)); + if(OC::$WEBROOT!='' and OC::$WEBROOT[0]!=='/'){ OC::$WEBROOT='/'.OC::$WEBROOT; } + // search the 3rdparty folder + if(OC_Config::getValue('3rdpartyroot', '')<>'' and OC_Config::getValue('3rdpartyurl', '')<>''){ + OC::$THIRDPARTYROOT=OC_Config::getValue('3rdpartyroot', ''); + OC::$THIRDPARTYWEBROOT=OC_Config::getValue('3rdpartyurl', ''); + }elseif(file_exists(OC::$SERVERROOT.'/3rdparty')){ + OC::$THIRDPARTYROOT=OC::$SERVERROOT; + OC::$THIRDPARTYWEBROOT=OC::$WEBROOT; + }elseif(file_exists(OC::$SERVERROOT.'/../3rdparty')){ + OC::$THIRDPARTYWEBROOT=rtrim(dirname(OC::$WEBROOT), '/'); + OC::$THIRDPARTYROOT=rtrim(dirname(OC::$SERVERROOT), '/'); + }else{ + echo("3rdparty directory not found! Please put the ownCloud 3rdparty folder in the ownCloud folder or the folder above. You can also configure the location in the config.php file."); + exit; + } + + // search the apps folder + if(file_exists(OC::$SERVERROOT.'/apps')){ + OC::$APPSROOT=OC::$SERVERROOT; + OC::$APPSWEBROOT=OC::$WEBROOT; + }elseif(file_exists(OC::$SERVERROOT.'/../apps')){ + OC::$APPSWEBROOT=rtrim(dirname(OC::$WEBROOT), '/'); + OC::$APPSROOT=rtrim(dirname(OC::$SERVERROOT), '/'); + }else{ + echo("apps directory not found! Please put the ownCloud apps folder in the ownCloud folder or the folder above. You can also configure the location in the config.php file."); + exit; + } + // set the right include path - set_include_path(OC::$SERVERROOT.'/lib'.PATH_SEPARATOR.OC::$SERVERROOT.'/config'.PATH_SEPARATOR.OC::$SERVERROOT.'/3rdparty'.PATH_SEPARATOR.get_include_path().PATH_SEPARATOR.OC::$SERVERROOT); + set_include_path( + OC::$SERVERROOT.'/lib'.PATH_SEPARATOR. + OC::$SERVERROOT.'/config'.PATH_SEPARATOR. + OC::$THIRDPARTYROOT.'/3rdparty'.PATH_SEPARATOR. + OC::$APPSROOT.PATH_SEPARATOR. + OC::$APPSROOT.'/apps'.PATH_SEPARATOR. + get_include_path().PATH_SEPARATOR. + OC::$SERVERROOT + ); // Redirect to installer if not installed if (!OC_Config::getValue('installed', false) && OC::$SUBURI != '/index.php') { @@ -203,8 +270,10 @@ class OC{ OC_Util::addScript( "jquery-showpassword" ); OC_Util::addScript( "jquery.infieldlabel.min" ); OC_Util::addScript( "jquery-tipsy" ); + OC_Util::addScript( "oc-dialogs" ); OC_Util::addScript( "js" ); OC_Util::addScript( "eventsource" ); + OC_Util::addScript( "config" ); //OC_Util::addScript( "multiselect" ); OC_Util::addScript('search','result'); OC_Util::addStyle( "styles" ); @@ -230,6 +299,7 @@ class OC{ $_SESSION['user_id'] = ''; } + OC_User::useBackend( OC_Config::getValue( "userbackend", "database" )); OC_Group::setBackend( OC_Config::getValue( "groupbackend", "database" )); @@ -246,9 +316,8 @@ class OC{ OC_App::loadApps(); } - // Last part: connect some hooks - OC_HOOK::connect('OC_User', 'post_createUser', 'OC_Connector_Sabre_Principal', 'addPrincipal'); - OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Connector_Sabre_Principal', 'deletePrincipal'); + //make sure temporary files are cleaned up + register_shutdown_function(array('OC_Helper','cleanTmp')); } } @@ -271,15 +340,10 @@ if(!function_exists('get_temp_dir')) { unlink($temp); return dirname($temp); } + if( $temp=sys_get_temp_dir()) return $temp; + return null; } } OC::init(); - -require_once('fakedirstream.php'); - - - -// FROM search.php -new OC_Search_Provider_File(); diff --git a/lib/connector/sabre/auth.php b/lib/connector/sabre/auth.php index 1e87c7cee08..8964ef7d0de 100644 --- a/lib/connector/sabre/auth.php +++ b/lib/connector/sabre/auth.php @@ -23,6 +23,7 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { * @return bool */ protected function validateUserPass($username, $password){ + OC_Util::setUpFS();//login hooks may need early access to the filesystem if(OC_User::login($username,$password)){ OC_Util::setUpFS(); return true; diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index bb03851e39d..cc37bf22d5d 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -73,8 +73,8 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $nodes = array(); // foreach(scandir($this->path) as $node) if($node!='.' && $node!='..') $nodes[] = $this->getChild($node); - if( OC_Filesystem::is_dir($this->path)){ - $dh = OC_Filesystem::opendir($this->path); + if( OC_Filesystem::is_dir($this->path . '/')){ + $dh = OC_Filesystem::opendir($this->path . '/'); while(( $node = readdir($dh)) !== false ){ if($node!='.' && $node!='..'){ $nodes[] = $this->getChild($node); diff --git a/lib/connector/sabre/principal.php b/lib/connector/sabre/principal.php index 72e180c65c0..28a36438e87 100644 --- a/lib/connector/sabre/principal.php +++ b/lib/connector/sabre/principal.php @@ -9,50 +9,6 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend { /** - * TODO: write doc - */ - public static function addPrincipal($params){ - // Add the user - $uri = 'principals/'.$params['uid']; - $displayname = $params['uid']; - $query = OC_DB::prepare('INSERT INTO *PREFIX*principals (uri,displayname) VALUES(?,?)'); - $query->execute(array($uri,$displayname)); - - // Add calendar and addressbook read and write support (sharing calendars) - $uri = 'principals/'.$params['uid'].'/calendar-proxy-read'; - $displayname = null; - $query->execute(array($uri,$displayname)); - $uri = 'principals/'.$params['uid'].'/calendar-proxy-write'; - $query->execute(array($uri,$displayname)); - $uri = 'principals/'.$params['uid'].'/addressbook-proxy-read'; - $query->execute(array($uri,$displayname)); - $uri = 'principals/'.$params['uid'].'/addressbook-proxy-write'; - $query->execute(array($uri,$displayname)); - - return true; - } - - /** - * TODO: write doc - */ - public static function deletePrincipal($params){ - $query = OC_DB::prepare('SELECT * FROM *PREFIX*principals'); - $result = $query->execute(); - - $deleteprincipal = OC_DB::prepare('DELETE FROM *PREFIX*principals WHERE id = ?'); - $deletegroup = OC_DB::prepare('DELETE FROM *PREFIX*principalgroups WHERE principal_id = ? OR member_id = ?'); - // We have to delete the principals and relations! Principals include - while($row = $result->fetchRow()){ - // Checking if the principal is in the prefix - $array = explode('/',$row['uri']); - if ($array[1] != $params['uid']) continue; - $deleteprincipal->execute(array($row['id'])); - $deletegroup->execute(array($row['id'],$row['id'])); - } - return true; - } - - /** * Returns a list of principals based on a prefix. * * This prefix will often contain something like 'principals'. You are only diff --git a/lib/crypt.php b/lib/crypt.php deleted file mode 100644 index 60020679480..00000000000 --- a/lib/crypt.php +++ /dev/null @@ -1,165 +0,0 @@ -<?php -/** - * ownCloud - * - * @author Frank Karlitschek - * @copyright 2010 Frank Karlitschek karlitschek@kde.org - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - - - -// Todo: -// - Crypt/decrypt button in the userinterface -// - Setting if crypto should be on by default -// - Add a setting "Don´t encrypt files larger than xx because of performance reasons" -// - Transparent decrypt/encrpt in filesystem.php. Autodetect if a file is encrypted (.encrypted extensio) -// - Don't use a password directly as encryption key. but a key which is stored on the server and encrypted with the user password. -> password change faster -// - IMPORTANT! Check if the block lenght of the encrypted data stays the same - - -require_once('Crypt_Blowfish/Blowfish.php'); - -/** - * This class is for crypting and decrypting - */ -class OC_Crypt { - - static $encription_extension='.encrypted'; - - public static function init($login,$password) { - $_SESSION['user_password'] = $password; // save the password as passcode for the encryption - if(OC_User::isLoggedIn()){ - // does key exist? - if(!file_exists(OC_Config::getValue( "datadirectory").'/'.$login.'/encryption.key')){ - OC_Crypt::createkey($_SESSION['user_password']); - } - } - } - - - - public static function createkey($passcode) { - if(OC_User::isLoggedIn()){ - // generate a random key - $key=mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999); - - // encrypt the key with the passcode of the user - $enckey=OC_Crypt::encrypt($key,$passcode); - - // Write the file - $username=OC_USER::getUser(); - @file_put_contents(OC_Config::getValue( "datadirectory").'/'.$username.'/encryption.key', $enckey ); - } - } - - public static function changekeypasscode( $newpasscode) { - if(OC_User::isLoggedIn()){ - $username=OC_USER::getUser(); - - // read old key - $key=file_get_contents(OC_Config::getValue( "datadirectory").'/'.$username.'/encryption.key'); - - // decrypt key with old passcode - $key=OC_Crypt::decrypt($key, $_SESSION['user_password']); - - // encrypt again with new passcode - $key=OC_Crypt::encrypt($key,$newpassword); - - // store the new key - file_put_contents(OC_Config::getValue( "datadirectory").'/'.$username.'/encryption.key', $key ); - - $_SESSION['user_password']=$newpasscode; - } - } - - /** - * @brief encrypts an content - * @param $content the cleartext message you want to encrypt - * @param $key the encryption key - * @returns encrypted content - * - * This function encrypts an content - */ - public static function encrypt( $content, $key) { - $bf = new Crypt_Blowfish($key); - return($bf->encrypt($content)); - } - - - /** - * @brief decryption of an content - * @param $content the cleartext message you want to decrypt - * @param $key the encryption key - * @returns cleartext content - * - * This function decrypts an content - */ - public static function decrypt( $content, $key) { - $bf = new Crypt_Blowfish($key); - return($bf->encrypt($contents)); - } - - - /** - * @brief encryption of a file - * @param $filename - * @param $key the encryption key - * - * This function encrypts a file - */ - public static function encryptfile( $filename, $key) { - $handleread = fopen($filename, "rb"); - if($handleread<>FALSE) { - $handlewrite = fopen($filename.OC_Crypt::$encription_extension, "wb"); - while (!feof($handleread)) { - $content = fread($handleread, 8192); - $enccontent=OC_CRYPT::encrypt( $content, $key); - fwrite($handlewrite, $enccontent); - } - fclose($handlewrite); - unlink($filename); - } - fclose($handleread); - } - - - /** - * @brief decryption of a file - * @param $filename - * @param $key the decryption key - * - * This function decrypts a file - */ - public static function decryptfile( $filename, $key) { - $handleread = fopen($filename.OC_Crypt::$encription_extension, "rb"); - if($handleread<>FALSE) { - $handlewrite = fopen($filename, "wb"); - while (!feof($handleread)) { - $content = fread($handleread, 8192); - $enccontent=OC_CRYPT::decrypt( $content, $key); - fwrite($handlewrite, $enccontent); - } - fclose($handlewrite); - unlink($filename.OC_Crypt::$encription_extension); - } - fclose($handleread); - } - - - - -} diff --git a/lib/db.php b/lib/db.php index 9d3c20e0145..9fab51edfcd 100644 --- a/lib/db.php +++ b/lib/db.php @@ -316,8 +316,11 @@ class OC_DB { // read file $content = file_get_contents( $file ); - // Make changes and save them to a temporary file - $file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' ); + // Make changes and save them to an in-memory file + $file2 = 'static://db_scheme'; + if($file2 == ''){ + die('could not create tempfile in get_temp_dir() - aborting'); + } $content = str_replace( '*dbname*', $CONFIG_DBNAME, $content ); $content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content ); if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't @@ -328,7 +331,7 @@ class OC_DB { // Try to create tables $definition = self::$schema->parseDatabaseDefinitionFile( $file2 ); - // Delete our temporary file + //clean up memory unlink( $file2 ); // Die in case something went wrong @@ -368,8 +371,8 @@ class OC_DB { return false; } - // Make changes and save them to a temporary file - $file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' ); + // Make changes and save them to an in-memory file + $file2 = 'static://db_scheme'; $content = str_replace( '*dbname*', $previousSchema['name'], $content ); $content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content ); if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't @@ -378,7 +381,7 @@ class OC_DB { file_put_contents( $file2, $content ); $op = self::$schema->updateDatabase($file2, $previousSchema, array(), false); - // Delete our temporary file + //clean up memory unlink( $file2 ); if (PEAR::isError($op)) { @@ -505,6 +508,21 @@ class OC_DB { self::$connection->commit(); self::$inTransaction=false; } + + /** + * check if a result is an error, works with MDB2 and PDOException + * @param mixed $result + * @return bool + */ + public static function isError($result){ + if(!$result){ + return true; + }elseif(self::$backend==self::BACKEND_MDB2 and PEAR::isError($result)){ + return true; + }else{ + return false; + } + } } /** @@ -524,11 +542,15 @@ class PDOStatementWrapper{ public function execute($input=array()){ $this->lastArguments=$input; if(count($input)>0){ - $this->statement->execute($input); + $result=$this->statement->execute($input); + }else{ + $result=$this->statement->execute(); + } + if($result){ + return $this; }else{ - $this->statement->execute(); + return false; } - return $this; } /** diff --git a/lib/fakedirstream.php b/lib/fakedirstream.php deleted file mode 100644 index fa3e64da62c..00000000000 --- a/lib/fakedirstream.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -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"); - diff --git a/lib/filecache.php b/lib/filecache.php index 6ae2f8253db..be2a00a19a0 100644 --- a/lib/filecache.php +++ b/lib/filecache.php @@ -28,6 +28,8 @@ * It will try to keep the data up to date but changes from outside ownCloud can invalidate the cache */ class OC_FileCache{ + private static $savedData=array(); + /** * get the filesystem info from the cache * @param string path @@ -93,6 +95,14 @@ class OC_FileCache{ self::update($id,$data); return; } + if(isset(self::$savedData[$path])){ + $data=array_merge($data,self::$savedData[$path]); + unset(self::$savedData[$path]); + } + if(!isset($data['size']) or !isset($data['mtime'])){//save incomplete data for the next time we write it + self::$savedData[$path]=$data; + return; + } if(!isset($data['encrypted'])){ $data['encrypted']=false; } @@ -101,9 +111,11 @@ class OC_FileCache{ } $mimePart=dirname($data['mimetype']); $user=OC_User::getUser(); - $query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, size, mtime, ctime, mimetype, mimepart,user,writable) VALUES(?,?,?,?,?,?,?,?,?,?)'); - $query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'])); - + $query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, size, mtime, ctime, mimetype, mimepart,user,writable,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)'); + $result=$query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned'])); + if(OC_DB::isError($result)){ + OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR); + } } /** @@ -128,7 +140,10 @@ class OC_FileCache{ $sql = 'UPDATE *PREFIX*fscache SET '.implode(' , ',$queryParts).' WHERE id=?'; $query=OC_DB::prepare($sql); - $query->execute($arguments); + $result=$query->execute($arguments); + if(OC_DB::isError($result)){ + OC_Log::write('files','error while updating file('.$path.') in cache',OC_Log::ERROR); + } } /** @@ -153,19 +168,28 @@ class OC_FileCache{ /** * delete info from the cache - * @param string $path + * @param string/int $file * @param string root (optional) */ - public static function delete($path,$root=''){ - if(!$root){ - $root=OC_Filesystem::getRoot(); - } - if($root=='/'){ - $root=''; + public static function delete($file,$root=''){ + if(!is_numeric($file)){ + if(!$root){ + $root=OC_Filesystem::getRoot(); + } + if($root=='/'){ + $root=''; + } + $path=$root.$file; + self::delete(self::getFileId($path)); + }elseif($file!=-1){ + $query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE parent=?'); + $query->execute(array($file)); + while($child=$query->fetchRow()){ + self::delete(intval($child['id'])); + } + $query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE id=?'); + $query->execute(array($file)); } - $path=$root.$path; - $query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE path=?'); - $query->execute(array($path)); } /** @@ -262,11 +286,20 @@ class OC_FileCache{ */ private static function getFileId($path){ $query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path=?'); - $result=$query->execute(array($path))->fetchRow(); + if(OC_DB::isError($query)){ + OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR); + return -1; + } + $result=$query->execute(array($path)); + if(OC_DB::isError($result)){ + OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR); + return -1; + } + $result=$result->fetchRow(); if(is_array($result)){ return $result['id']; }else{ - OC_Log::write('getFieldId(): file not found in cache ('.$path.')','core',OC_Log::DEBUG); + OC_Log::write('getFileId(): file not found in cache ('.$path.')','core',OC_Log::DEBUG); return -1; } } @@ -299,10 +332,11 @@ class OC_FileCache{ $path=$params['path']; $fullPath=$view->getRoot().$path; $mimetype=$view->getMimeType($path); + $dir=$view->is_dir($path.'/'); //dont use self::get here, we don't want inifinte loops when a file has changed $cachedSize=self::getCachedSize($path,$root); $size=0; - if($mimetype=='httpd/unix-directory'){ + if($dir){ if(self::inCache($path,$root)){ $parent=self::getFileId($fullPath); $query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE parent=?'); @@ -323,7 +357,29 @@ class OC_FileCache{ } self::increaseSize(dirname($fullPath),$size-$cachedSize); } - + + public static function getCached($path,$root=''){ + if(!$root){ + $root=OC_Filesystem::getRoot(); + }else{ + if($root=='/'){ + $root=''; + } + } + $path=$root.$path; + $query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path=?'); + $result=$query->execute(array($path))->fetchRow(); + if(is_array($result)){ + if(isset(self::$savedData[$path])){ + $result=array_merge($result,self::$savedData[$path]); + } + return $result; + }else{ + OC_Log::write('get(): file not found in cache ('.$path.')','core',OC_Log::DEBUG); + return false; + } + } + private static function getCachedSize($path,$root){ if(!$root){ $root=OC_Filesystem::getRoot(); @@ -332,6 +388,7 @@ class OC_FileCache{ $root=''; } } + $path=$root.$path; $query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path=?'); $result=$query->execute(array($path)); if($row=$result->fetchRow()){ @@ -418,13 +475,13 @@ class OC_FileCache{ $view=new OC_FilesystemView(($root=='/')?'':$root); } self::scanFile($path,$root); - $dh=$view->opendir($path); + $dh=$view->opendir($path.'/'); $totalSize=0; if($dh){ while (($filename = readdir($dh)) !== false) { if($filename != '.' and $filename != '..'){ $file=$path.'/'.$filename; - if($view->is_dir($file)){ + if($view->is_dir($file.'/')){ if($eventSource){ $eventSource->send('scanning',array('file'=>$file,'count'=>$count)); } @@ -515,6 +572,9 @@ class OC_FileCache{ } $view=new OC_FilesystemView($root); } + if(!$view->file_exists($path)){ + return false; + } $mtime=$view->filemtime($path); $isDir=$view->is_dir($path); $path=$root.$path; diff --git a/lib/fileproxy.php b/lib/fileproxy.php index 235fc8bf284..46fc2f49c50 100644 --- a/lib/fileproxy.php +++ b/lib/fileproxy.php @@ -34,11 +34,12 @@ * A post-proxy recieves 2 arguments, the filepath and the result of the operation. * The return calue of the post-proxy will be used as the new result of the operation * The operations that have a post-proxy are - * file_get_contents, is_file, is_dir, file_exists, stat, is_readable, is_writable, filemtime, filectime, file_get_contents, getMimeType, hash, free_space and search + * file_get_contents, is_file, is_dir, file_exists, stat, is_readable, is_writable, fileatime, filemtime, filectime, file_get_contents, getMimeType, hash, fopen, free_space and search */ class OC_FileProxy{ private static $proxies=array(); + public static $enabled=true; /** * check if this proxy implments a specific proxy operation @@ -83,16 +84,19 @@ class OC_FileProxy{ return $proxies; } - public static function runPreProxies($operation,$filepath,$filepath2=null){ + public static function runPreProxies($operation,&$filepath,&$filepath2=null){ + if(!self::$enabled){ + return true; + } $proxies=self::getProxies($operation,false); $operation='pre'.$operation; foreach($proxies as $proxy){ - if($filepath2){ - if(!$proxy->$operation($filepath,$filepath2)){ + if(!is_null($filepath2)){ + if($proxy->$operation($filepath,$filepath2)===false){ return false; } }else{ - if(!$proxy->$operation($filepath)){ + if($proxy->$operation($filepath)===false){ return false; } } @@ -101,6 +105,9 @@ class OC_FileProxy{ } public static function runPostProxies($operation,$path,$result){ + if(!self::$enabled){ + return $result; + } $proxies=self::getProxies($operation,true); $operation='post'.$operation; foreach($proxies as $proxy){ diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index 94a49176ee6..9e4c2d0643e 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -26,11 +26,37 @@ */ class OC_FileProxy_Quota extends OC_FileProxy{ + private $userQuota=-1; + + /** + * get the quota for the current user + * @return int + */ + private function getQuota(){ + if($this->userQuota!=-1){ + return $this->userQuota; + } + $userQuota=OC_Preferences::getValue(OC_User::getUser(),'files','quota','default'); + if($userQuota=='default'){ + $userQuota=OC_AppConfig::getValue('files','default_quota','none'); + } + if($userQuota=='none'){ + $this->userQuota=0; + }else{ + $this->userQuota=OC_Helper::computerFileSize($userQuota); + } + return $this->userQuota; + + } + + /** + * get the free space in the users home folder + * @return int + */ private function getFreeSpace(){ $rootInfo=OC_FileCache::get(''); $usedSpace=$rootInfo['size']; - $totalSpace=OC_Preferences::getValue(OC_User::getUser(),'files','quota',0); - $totalSpace=OC_Helper::computerFileSize($totalSpace); + $totalSpace=$this->getQuota(); if($totalSpace==0){ return 0; } diff --git a/lib/filestorage.php b/lib/filestorage.php index 4523144f6f4..fd6497b9478 100644 --- a/lib/filestorage.php +++ b/lib/filestorage.php @@ -23,33 +23,31 @@ /** * Privde a common interface to all different storage options */ -class OC_Filestorage{ +abstract class OC_Filestorage{ public function __construct($parameters){} - public function mkdir($path){} - public function rmdir($path){} - public function opendir($path){} - public function is_dir($path){} - public function is_file($path){} - public function stat($path){} - public function filetype($path){} - public function filesize($path){} - public function is_readable($path){} - public function is_writable($path){} - public function file_exists($path){} - public function readfile($path){} - public function filectime($path){} - public function filemtime($path){} - public function file_get_contents($path){} - public function file_put_contents($path,$data){} - public function unlink($path){} - public function rename($path1,$path2){} - public function copy($path1,$path2){} - public function fopen($path,$mode){} - public function toTmpFile($path){}//copy the file to a temporary file, used for cross-storage file actions - public function fromTmpFile($tmpPath,$path){}//copy a file from a temporary file, used for cross-storage file actions - public function getMimeType($path){} - public function hash($type,$path,$raw){} - public function free_space($path){} - public function search($query){} - public function getLocalFile($path){}// get a path to a local version of the file, whether the original file is local or remote + abstract public function mkdir($path); + abstract public function rmdir($path); + abstract public function opendir($path); + abstract public function is_dir($path); + abstract public function is_file($path); + abstract public function stat($path); + abstract public function filetype($path); + abstract public function filesize($path); + abstract public function is_readable($path); + abstract public function is_writable($path); + abstract public function file_exists($path); + abstract public function filectime($path); + abstract public function filemtime($path); + abstract public function file_get_contents($path); + abstract public function file_put_contents($path,$data); + abstract public function unlink($path); + abstract public function rename($path1,$path2); + abstract public function copy($path1,$path2); + abstract public function fopen($path,$mode); + abstract public function getMimeType($path); + abstract public function hash($type,$path,$raw); + abstract public function free_space($path); + abstract public function search($query); + abstract public function touch($path, $mtime=null); + abstract public function getLocalFile($path);// get a path to a local version of the file, whether the original file is local or remote } diff --git a/lib/filestorage/common.php b/lib/filestorage/common.php new file mode 100644 index 00000000000..f632474df01 --- /dev/null +++ b/lib/filestorage/common.php @@ -0,0 +1,159 @@ +<?php + +/** +* ownCloud +* +* @author Michael Gapczynski +* @copyright 2012 Michael Gapczynski GapczynskiM@gmail.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +*/ + +abstract class OC_Filestorage_Common extends OC_Filestorage { + + public function __construct($parameters){} +// abstract public function mkdir($path); +// abstract public function rmdir($path); +// abstract public function opendir($path); + public function is_dir($path){ + return $this->filetype($path)=='dir'; + } + public function is_file($path){ + return $this->filetype($path)=='file'; + } +// abstract public function stat($path); +// abstract public function filetype($path); + public function filesize($path) { + if($this->is_dir($path)){ + return 0;//by definition + }else{ + $stat = $this->stat($path); + return $stat['size']; + } + } +// abstract public function is_readable($path); +// abstract public function is_writable($path); +// abstract public function file_exists($path); + public function filectime($path) { + $stat = $this->stat($path); + return $stat['ctime']; + } + public function filemtime($path) { + $stat = $this->stat($path); + return $stat['mtime']; + } + public function fileatime($path) { + $stat = $this->stat($path); + return $stat['atime']; + } + public function file_get_contents($path) { + $handle = $this->fopen($path, "r"); + if(!$handle){ + return false; + } + $size=$this->filesize($path); + if($size==0){ + return ''; + } + return fread($handle, $size); + } + public function file_put_contents($path,$data) { + $handle = $this->fopen($path, "w"); + return fwrite($handle, $data); + } +// abstract public function unlink($path); + public function rename($path1,$path2){ + if($this->copy($path1,$path2)){ + return $this->unlink($path1); + }else{ + return false; + } + } + public function copy($path1,$path2) { + $source=$this->fopen($path1,'r'); + $target=$this->fopen($path2,'w'); + $count=OC_Helper::streamCopy($source,$target); + return $count>0; + } +// abstract public function fopen($path,$mode); + public function getMimeType($path){ + if(!$this->file_exists($path)){ + return false; + } + if($this->is_dir($path)){ + return 'httpd/unix-directory'; + } + $source=$this->fopen($path,'r'); + if(!$source){ + return false; + } + $head=fread($source,8192);//8kb should suffice to determine a mimetype + if($pos=strrpos($path,'.')){ + $extention=substr($path,$pos); + }else{ + $extention=''; + } + $tmpFile=OC_Helper::tmpFile($extention); + file_put_contents($tmpFile,$head); + $mime=OC_Helper::getMimeType($tmpFile); + unlink($tmpFile); + return $mime; + } + public function hash($type,$path,$raw){ + $tmpFile=$this->getLocalFile(); + $hash=hash($type,$tmpFile,$raw); + unlink($tmpFile); + return $hash; + } +// abstract public function free_space($path); + public function search($query){ + return $this->searchInDir($query); + } + public function getLocalFile($path){ + return $this->toTmpFile($path); + } + private function toTmpFile($path){//no longer in the storage api, still usefull here + $source=$this->fopen($path,'r'); + if(!$source){ + return false; + } + if($pos=strrpos($path,'.')){ + $extention=substr($path,$pos); + }else{ + $extention=''; + } + $tmpFile=OC_Helper::tmpFile($extention); + $target=fopen($tmpFile,'w'); + $count=OC_Helper::streamCopy($source,$target); + return $tmpFile; + } +// abstract public function touch($path, $mtime=null); + + protected function searchInDir($query,$dir=''){ + $files=array(); + $dh=$this->opendir($dir); + if($dh){ + while($item=readdir($dh)){ + if ($item == '.' || $item == '..') continue; + if(strstr(strtolower($item),strtolower($query))!==false){ + $files[]=$dir.'/'.$item; + } + if($this->is_dir($dir.'/'.$item)){ + $files=array_merge($files,$this->searchInDir($query,$dir.'/'.$item)); + } + } + } + return $files; + } +} diff --git a/lib/filestorage/commontest.php b/lib/filestorage/commontest.php new file mode 100644 index 00000000000..1b01ff856a3 --- /dev/null +++ b/lib/filestorage/commontest.php @@ -0,0 +1,75 @@ +<?php + +/** +* ownCloud +* +* @author Robin Appelman +* @copyright 2012 Robin Appelman icewind@owncloud.com +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/** + * test implementation for OC_FileStorage_Common with OC_FileStorage_Local + */ + +class OC_Filestorage_CommonTest extends OC_Filestorage_Common{ + /** + * underlying local storage used for missing functions + * @var OC_FileStorage_Local + */ + private $storage; + + public function __construct($params){ + $this->storage=new OC_Filestorage_Local($params); + } + + public function mkdir($path){ + return $this->storage->mkdir($path); + } + public function rmdir($path){ + return $this->storage->rmdir($path); + } + public function opendir($path){ + return $this->storage->opendir($path); + } + public function stat($path){ + return $this->storage->stat($path); + } + public function filetype($path){ + return $this->storage->filetype($path); + } + public function is_readable($path){ + return $this->storage->is_readable($path); + } + public function is_writable($path){ + return $this->storage->is_writable($path); + } + public function file_exists($path){ + return $this->storage->file_exists($path); + } + public function unlink($path){ + return $this->storage->unlink($path); + } + public function fopen($path,$mode){ + return $this->storage->fopen($path,$mode); + } + public function free_space($path){ + return $this->storage->free_space($path); + } + public function touch($path, $mtime=null){ + return $this->storage->touch($path,$mtime); + } +}
\ No newline at end of file diff --git a/lib/filestorage/google.php b/lib/filestorage/google.php index fc271f4e4ba..49985548382 100644 --- a/lib/filestorage/google.php +++ b/lib/filestorage/google.php @@ -20,36 +20,322 @@ * License along with this library. If not, see <http://www.gnu.org/licenses/>. */ +require_once 'common.inc.php'; + class OC_Filestorage_Google extends OC_Filestorage_Common { + + private $datadir; + private $consumer; + private $oauth_token; + private $sig_method; + private $entries; + + public function __construct($arguments) { + $this->datadir = $arguments['datadir']; + $consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous'; + $consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous'; + $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); + $this->oauth_token = new OAuthToken($arguments['token'], $arguments['token_secret']); + $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1(); + $this->entries = array(); + } + + private function sendRequest($feedUri, $http_method, $postData = null) { + $feedUri = trim($feedUri); + // create an associative array from each key/value url query param pair. + $params = array(); + $pieces = explode('?', $feedUri); + if (isset($pieces[1])) { + $params = explode_assoc('=', '&', $pieces[1]); + } + // urlencode each url parameter key/value pair + $tempStr = $pieces[0]; + foreach ($params as $key => $value) { + $tempStr .= '&' . urlencode($key) . '=' . urlencode($value); + } + $feedUri = preg_replace('/&/', '?', $tempStr, 1); + $req = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params); + $req->sign_request($this->sig_method, $this->consumer, $this->oauth_token); + $auth_header = $req->to_header(); + $result = send_signed_request($http_method, $feedUri, array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0'), $postData); + // TODO Return false if error is received + if (!$result) { + return false; + } + $result = explode('<', $result, 2); + $result = isset($result[1]) ? '<'.$result[1] : $result[0]; + $dom = new DOMDocument(); + $dom->loadXML($result); + return $dom; + } + + private function getResource($path) { + if (array_key_exists($path, $this->entries)) { + return $this->entries[$path]; + } else { + $title = basename($path); + $dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET'); + // Check if request was successful and entry exists + if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) { + $this->entries[$path] = $entry; + return $entry; + } + return false; + } + } + + private function getExtension($entry) { + $mimetype = $this->getMimeType('', $entry); + switch($mimetype) { + case 'httpd/unix-directory': + return ''; + case 'application/vnd.oasis.opendocument.text': + return 'odt'; + case 'application/vnd.oasis.opendocument.spreadsheet': + return 'ods'; + case 'application/vnd.oasis.opendocument.presentation': + return 'pptx'; + case 'text/html': + return 'html'; + default: + return 'html'; + } + } - private $auth; - public function __construct($parameters) { - + public function mkdir($path) { + $dir = dirname($path); + // Check if path parent is root directory + if ($dir == '/' || $dir == '\.' || $dir == '.') { + $feedUri = 'https://docs.google.com/feeds/default/private/full'; + // Get parent content link + } else if ($dom = $this->getResource(basename($dir))) { + $feedUri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src'); + } + if (isset($feedUri)) { + $title = basename($path); + // Construct post data + $postData = '<?xml version="1.0" encoding="UTF-8"?>'; + $postData .= '<entry xmlns="http://www.w3.org/2005/Atom">'; + $postData .= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#folder"/>'; + $postData .= '<title>'.$title.'</title>'; + $postData .= '</entry>'; + if ($dom = $this->sendRequest($feedUri, 'POST', $postData)) { + return true; + } + } + return false; + } + + public function rmdir($path) { + return $this->unlink($path); + } + + public function opendir($path) { + if ($path == '' || $path == '/') { + $next = 'https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents'; + } else { + if ($entry = $this->getResource($path)) { + $next = $entry->getElementsByTagName('content')->item(0)->getAttribute('src'); + } else { + return false; + } + } + $files = array(); + while ($next) { + $dom = $this->sendRequest($next, 'GET'); + $links = $dom->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'next') { + $next = $link->getAttribute('src'); + break; + } else { + $next = false; + } + } + $entries = $dom->getElementsByTagName('entry'); + foreach ($entries as $entry) { + $name = $entry->getElementsByTagName('title')->item(0)->nodeValue; + // Google Docs resources don't always include extensions in title + if (!strpos($name, '.')) { + $name .= '.'.$this->getExtension($entry); + } + $files[] = $name; + // Cache entry for future use + $this->entries[$name] = $entry; + } + } + OC_FakeDirStream::$dirs['google'] = $files; + return opendir('fakedir://google'); + } + + public function stat($path) { + if ($path == '' || $path == '/') { + $stat['size'] = $this->free_space($path); + $stat['atime'] = time(); + $stat['mtime'] = time(); + $stat['ctime'] = time(); + } else if ($entry = $this->getResource($path)) { + // NOTE: Native resources don't have a file size + $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; + $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue); + $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue); + $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue); + } + return $stat; + } + + public function filetype($path) { + if ($path == '' || $path == '/') { + return 'dir'; + } else if ($entry = $this->getResource($path)) { + $categories = $entry->getElementsByTagName('category'); + foreach ($categories as $category) { + if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') { + $type = $category->getAttribute('label'); + if (strlen(strstr($type, 'folder')) > 0) { + return 'dir'; + } else { + return 'file'; + } + } + } + } + return false; + } + + public function is_readable($path) { + return true; + } + + public function is_writable($path) { + if ($path == '' || $path == '/') { + return true; + } else if ($entry = $this->getResource($path)) { + // Check if edit or edit-media links exist + $links = $entry->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'edit') { + return true; + } else if ($link->getAttribute('rel') == 'edit-media') { + return true; + } + } + } + return false; + } + + public function file_exists($path) { + if ($path == '' || $path == '/') { + return true; + } else if ($this->getResource($path)) { + return true; + } + return false; + } + + public function unlink($path) { + // Get resource self link to trash resource + if ($entry = $this->getResource($path)) { + $links = $entry->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'self') { + $feedUri = $link->getAttribute('href'); + } + } + } + if (isset($feedUri)) { + $this->sendRequest($feedUri, 'DELETE'); + return true; + } + return false; + } + + public function rename($path1, $path2) { + // TODO Add support for moving to different collections + // Get resource edit link to rename resource + if ($entry = $this->getResource($path1)) { + $etag = $entry->getElementsByTagName('entry')->item(0)->getAttribute('gd:etag'); + $links = $entry->getElementsByTagName('link'); + foreach ($links as $link) { + if ($link->getAttribute('rel') == 'edit') { + $feedUri = $link->getAttribute('href'); + } + } + } + if (isset($etag) && isset($feedUri)) { + $title = basename($path2); + // Construct post data + $postData = '<?xml version="1.0" encoding="UTF-8"?>'; + $postData .= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:gd="http://schemas.google.com/g/2005" gd:etag='.$etag.'>'; + $postData .= '<title>'.$title.'</title>'; + $postData .= '</entry>'; + $this->sendRequest($feedUri, 'PUT', $postData); + return true; + } + return false; + } + + public function fopen($path, $mode) { + if ($entry = $this->getResource($path)) { + $extension = $this->getExtension($path); + $downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src'); + // TODO Non-native documents don't need these additional parameters + $downloadUri .= '&exportFormat='.$extension.'&format='.$extension; + } + } + + public function getMimeType($path, $entry = null) { + if ($entry == null) { + if ($path == '' || $path == '/') { + return 'httpd/unix-directory'; + } else { + $entry = $this->getResource($path); + } + } + if ($entry) { + $mimetype = $entry->getElementsByTagName('content')->item(0)->getAttribute('type'); + // Native Google Docs resources often default to text/html, but it may be more useful to default to a corresponding ODF mimetype + // Collections get reported as application/atom+xml, make sure it actually is a folder and fix the mimetype + if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml') { + $categories = $entry->getElementsByTagName('category'); + foreach ($categories as $category) { + if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') { + $type = $category->getAttribute('label'); + if (strlen(strstr($type, 'folder')) > 0) { + return 'httpd/unix-directory'; + } else if (strlen(strstr($type, 'document')) > 0) { + return 'application/vnd.oasis.opendocument.text'; + } else if (strlen(strstr($type, 'spreadsheet')) > 0) { + return 'application/vnd.oasis.opendocument.spreadsheet'; + } else if (strlen(strstr($type, 'presentation')) > 0) { + return 'application/vnd.oasis.opendocument.presentation'; + } else if (strlen(strstr($type, 'drawing')) > 0) { + return 'application/vnd.oasis.opendocument.graphics'; + } else { + // If nothing matches return text/html, all native Google Docs resources can be exported as text/html + return 'text/html'; + } + } + } + } + return $mimetype; + } + return false; } - private function connect() { - - } - public function mkdir($path){} - public function rmdir($path){} - public function opendir($path){} - public function is_dir($path){} - public function is_file($path){} - public function stat($path){} - public function filetype($path){} - public function is_readable($path){} - public function is_writable($path){} - public function file_exists($path){} - public function unlink($path){} - public function rename($path1,$path2){} - public function fopen($path,$mode){} - public function toTmpFile($path){} - public function fromTmpFile($tmpPath,$path){} - public function fromUploadedFile($tmpPath,$path){} - public function getMimeType($path){} - public function hash($type,$path,$raw){} - public function free_space($path){} - public function search($query){} - public function getLocalFile($path){} + public function free_space($path) { + if ($dom = $this->sendRequest('https://docs.google.com/feeds/metadata/default', 'GET')) { + // NOTE: Native Google Docs resources don't count towards quota + $total = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesTotal')->item(0)->nodeValue; + $used = $dom->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; + return $total - $used; + } + return false; + } + + public function search($query) { + + } + }
\ No newline at end of file diff --git a/lib/filestorage/local.php b/lib/filestorage/local.php index dcb516a3afb..688501aee90 100644 --- a/lib/filestorage/local.php +++ b/lib/filestorage/local.php @@ -21,7 +21,10 @@ class OC_Filestorage_Local extends OC_Filestorage{ return opendir($this->datadir.$path); } public function is_dir($path){ - return (is_dir($this->datadir.$path) or substr($path,-1)=='/'); + if(substr($path,-1)=='/'){ + $path=substr($path,0,-1); + } + return is_dir($this->datadir.$path); } public function is_file($path){ return is_file($this->datadir.$path); @@ -52,31 +55,32 @@ class OC_Filestorage_Local extends OC_Filestorage{ public function file_exists($path){ return file_exists($this->datadir.$path); } - public function readfile($path){ - return readfile($this->datadir.$path); - } public function filectime($path){ return filectime($this->datadir.$path); } public function filemtime($path){ return filemtime($this->datadir.$path); } - public function touch($path, $mtime){ + public function touch($path, $mtime=null){ // sets the modification time of the file to the given value. // If mtime is nil the current time is set. // note that the access time of the file always changes to the current time. - if( touch( $this->datadir.$path, $mtime ) ) { + if(!is_null($mtime)){ + $result=touch( $this->datadir.$path, $mtime ); + }else{ + $result=touch( $this->datadir.$path); + } + if( $result ) { clearstatcache( true, $this->datadir.$path ); } - return touch($this->datadir.$path, $mtime); + return $result; } public function file_get_contents($path){ return file_get_contents($this->datadir.$path); } public function file_put_contents($path,$data){ - if($return=file_put_contents($this->datadir.$path,$data)){ - } + return file_put_contents($this->datadir.$path,$data); } public function unlink($path){ return $this->delTree($path); @@ -99,9 +103,7 @@ class OC_Filestorage_Local extends OC_Filestorage{ $source=substr($path1,strrpos($path1,'/')+1); $path2.=$source; } - if($return=copy($this->datadir.$path1,$this->datadir.$path2)){ - } - return $return; + return copy($this->datadir.$path1,$this->datadir.$path2); } public function fopen($path,$mode){ if($return=fopen($this->datadir.$path,$mode)){ @@ -122,72 +124,9 @@ class OC_Filestorage_Local extends OC_Filestorage{ return $return; } - public function getMimeType($fspath){ - if($this->is_readable($fspath)){ - $mimeType='application/octet-stream'; - if ($mimeType=='application/octet-stream') { - self::$mimetypes = include('mimetypes.fixlist.php'); - $extention=strtolower(strrchr(basename($fspath), ".")); - $extention=substr($extention,1);//remove leading . - $mimeType=(isset(self::$mimetypes[$extention]))?self::$mimetypes[$extention]:'application/octet-stream'; - - } - if (@is_dir($this->datadir.$fspath)) { - // directories are easy - return "httpd/unix-directory"; - } - if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){ - $mimeType =strtolower(finfo_file($finfo,$this->datadir.$fspath)); - $mimeType=substr($mimeType,0,strpos($mimeType,';')); - finfo_close($finfo); - } - if ($mimeType=='application/octet-stream' && function_exists("mime_content_type")) { - // use mime magic extension if available - $mimeType = mime_content_type($this->datadir.$fspath); - } - if ($mimeType=='application/octet-stream' && OC_Helper::canExecute("file")) { - // it looks like we have a 'file' command, - // lets see it it does have mime support - $fspath=str_replace("'","\'",$fspath); - $fp = popen("file -i -b '{$this->datadir}$fspath' 2>/dev/null", "r"); - $reply = fgets($fp); - pclose($fp); - - //trim the character set from the end of the response - $mimeType=substr($reply,0,strrpos($reply,' ')); - } - if ($mimeType=='application/octet-stream') { - // Fallback solution: (try to guess the type by the file extension - if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){ - self::$mimetypes=include('mimetypes.list.php'); - } - $extention=strtolower(strrchr(basename($fspath), ".")); - $extention=substr($extention,1);//remove leading . - $mimeType=(isset(self::$mimetypes[$extention]))?self::$mimetypes[$extention]:'application/octet-stream'; - } - return $mimeType; - }else{ - return false; - } - } - - public function toTmpFile($path){ - $tmpFolder=get_temp_dir(); - $filename=tempnam($tmpFolder,'OC_TEMP_FILE_'.substr($path,strrpos($path,'.'))); - $fileStats = stat($this->datadir.$path); - if(copy($this->datadir.$path,$filename)){ - touch($filename, $fileStats['mtime'], $fileStats['atime']); - return $filename; - }else{ - return false; - } - } - - public function fromTmpFile($tmpFile,$path){ - $fileStats = stat($tmpFile); - if(rename($tmpFile,$this->datadir.$path)){ - touch($this->datadir.$path, $fileStats['mtime'], $fileStats['atime']); - return true; + public function getMimeType($path){ + if($this->is_readable($path)){ + return OC_Helper::getMimeType($this->datadir.$path); }else{ return false; } diff --git a/lib/filestoragecommon.php b/lib/filestoragecommon.php deleted file mode 100644 index f522d15c4e9..00000000000 --- a/lib/filestoragecommon.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php - -/** -* ownCloud -* -* @author Michael Gapczynski -* @copyright 2012 Michael Gapczynski GapczynskiM@gmail.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -*/ - -class OC_Filestorage_Common extends OC_Filestorage { - - public function __construct($parameters){} - public function mkdir($path){} - public function rmdir($path){} - public function opendir($path){} - public function is_dir($path){} - public function is_file($path){} - public function stat($path){} - public function filetype($path){} - public function filesize($path) { - $stat = $this->stat($path); - return $stat['size']; - } - public function is_readable($path){} - public function is_writable($path){} - public function file_exists($path){} - public function readfile($path) { - $handle = $this->fopen($path, "r"); - $chunk = 1024; - while (!feof($handle)) { - echo fread($handle, $chunk); - } - return $this->filesize($path); - } - public function filectime($path) { - $stat = $this->stat($path); - return $stat['ctime']; - } - public function filemtime($path) { - $stat = $this->stat($path); - return $stat['mtime']; - } - public function fileatime($path) { - $stat = $this->stat($path); - return $stat['atime']; - } - public function file_get_contents($path) { - $handle = $this->fopen($path, "r"); - return fread($handle, $this->filesize($path)); - } - public function file_put_contents($path,$data) { - $handle = $this->fopen($path, "w"); - return fwrite($handle, $data); - } - public function unlink($path){} - public function rename($path1,$path2){} - public function copy($path1,$path2) { - $data = $this->file_get_contents($path1); - return $this->file_put_contents($path2, $data); - } - public function fopen($path,$mode){} - public function toTmpFile($path){} - public function fromTmpFile($tmpPath,$path){} - public function fromUploadedFile($tmpPath,$path){} - public function getMimeType($path){} - public function hash($type,$path,$raw){} - public function free_space($path){} - public function search($query){} - public function getLocalFile($path){} -} diff --git a/lib/filesystem.php b/lib/filesystem.php index 90195bc2130..12905d189f9 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -146,20 +146,15 @@ class OC_Filesystem{ * @return string */ static public function getMountPoint($path){ + OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path)); if(!$path){ $path='/'; } if(substr($path,0,1)!=='/'){ $path='/'.$path; } - if(substr($path,-1)!=='/'){ - $path=$path.'/'; - } $foundMountPoint=''; foreach(OC_Filesystem::$mounts as $mountpoint=>$storage){ - if(substr($mountpoint,-1)!=='/'){ - $mountpoint=$mountpoint.'/'; - } if($mountpoint==$path){ return $mountpoint; } @@ -259,6 +254,9 @@ class OC_Filesystem{ * @param string mountpoint */ static public function mount($class,$arguments,$mountpoint){ + if(substr($mountpoint,-1)!=='/'){ + $mountpoint=$mountpoint.'/'; + } if(substr($mountpoint,0,1)!=='/'){ $mountpoint='/'.$mountpoint; } @@ -345,7 +343,7 @@ class OC_Filesystem{ static public function filemtime($path){ return self::$defaultInstance->filemtime($path); } - static public function touch($path, $mtime){ + static public function touch($path, $mtime=null){ return self::$defaultInstance->touch($path, $mtime); } static public function file_get_contents($path){ diff --git a/lib/filesystemview.php b/lib/filesystemview.php index 91c6cd17720..89e0385fe9c 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -136,7 +136,14 @@ class OC_FilesystemView { return $this->basicOperation('filesize',$path); } public function readfile($path){ - return $this->basicOperation('readfile',$path,array('read')); + $handle=$this->fopen($path,'r'); + $chunkSize = 1024*1024;// 1 MB chunks + while (!feof($handle)) { + echo fread($handle, $chunkSize); + @ob_flush(); + flush(); + } + return $this->filesize($path); } public function is_readable($path){ return $this->basicOperation('is_readable',$path); @@ -156,14 +163,27 @@ class OC_FilesystemView { public function filemtime($path){ return $this->basicOperation('filemtime',$path); } - public function touch($path, $mtime){ + public function touch($path, $mtime=null){ return $this->basicOperation('touch', $path, array('write'), $mtime); } public function file_get_contents($path){ return $this->basicOperation('file_get_contents',$path,array('read')); } public function file_put_contents($path,$data){ - return $this->basicOperation('file_put_contents',$path,array('create','write'),$data); + if(is_resource($data)){//not having to deal with streams in file_put_contents makes life easier + $target=$this->fopen($path,'w'); + if($target){ + $count=OC_Helper::streamCopy($data,$target); + fclose($target); + fclose($data); + OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path)); + return $count>0; + }else{ + return false; + } + }else{ + return $this->basicOperation('file_put_contents',$path,array('create','write'),$data); + } } public function unlink($path){ return $this->basicOperation('unlink',$path,array('delete')); @@ -179,10 +199,13 @@ class OC_FilesystemView { if($storage=$this->getStorage($path1)){ $result=$storage->rename($this->getInternalPath($path1),$this->getInternalPath($path2)); } - }elseif($storage1=$this->getStorage($path1) and $storage2=$this->getStorage($path2)){ - $tmpFile=$storage1->toTmpFile($this->getInternalPath($path1)); - $result=$storage2->fromTmpFile($tmpFile,$this->getInternalPath($path2)); + }else{ + $source=$this->fopen($path1,'r'); + $target=$this->fopen($path2,'w'); + $count=OC_Helper::streamCopy($data,$target); + $storage1=$this->getStorage($path1); $storage1->unlink($this->getInternalPath($path1)); + $result=$count>0; } OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, array( OC_Filesystem::signal_param_oldpath => $path1, OC_Filesystem::signal_param_newpath=>$path2)); return $result; @@ -207,9 +230,10 @@ class OC_FilesystemView { if($storage=$this->getStorage($path1)){ $result=$storage->copy($this->getInternalPath($path1),$this->getInternalPath($path2)); } - }elseif($storage1=$this->getStorage($path1) and $storage2=$this->getStorage($path2)){ - $tmpFile=$storage1->toTmpFile($this->getInternalPath($path1)); - $result=$storage2->fromTmpFile($tmpFile,$this->getInternalPath($path2)); + }else{ + $source=$this->fopen($path1,'r'); + $target=$this->fopen($path2,'w'); + $count=OC_Helper::streamCopy($data,$target); } OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2)); if(!$exists){ @@ -224,18 +248,26 @@ class OC_FilesystemView { $hooks=array(); switch($mode){ case 'r': + case 'rb': $hooks[]='read'; break; case 'r+': + case 'rb+': case 'w+': + case 'wb+': case 'x+': + case 'xb+': case 'a+': + case 'ab+': $hooks[]='read'; $hooks[]='write'; break; case 'w': + case 'wb': case 'x': + case 'xb': case 'a': + case 'ab': $hooks[]='write'; break; default: @@ -245,29 +277,29 @@ class OC_FilesystemView { return $this->basicOperation('fopen',$path,$hooks,$mode); } public function toTmpFile($path){ - if(OC_FileProxy::runPreProxies('toTmpFile',$path) and OC_Filesystem::isValidPath($path) and $storage=$this->getStorage($path)){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_read, array( OC_Filesystem::signal_param_path => $path)); - return $storage->toTmpFile($this->getInternalPath($path)); + if(OC_Filesystem::isValidPath($path)){ + $source=$this->fopen($path,'r'); + if($source){ + $extention=substr($path,strrpos($path,'.')); + $tmpFile=OC_Helper::tmpFile($extention); + return file_put_contents($tmpFile,$source); + } } } public function fromTmpFile($tmpFile,$path){ - if(OC_FileProxy::runPreProxies('copy',$tmpFile,$path) and OC_Filesystem::isValidPath($path) and $storage=$this->getStorage($path)){ - $run=true; - $exists=$this->file_exists($path); - if(!$exists){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); + if(OC_Filesystem::isValidPath($path)){ + if(!$tmpFile){ + debug_print_backtrace(); } - if($run){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); - } - if($run){ - $result=$storage->fromTmpFile($tmpFile,$this->getInternalPath($path)); - if(!$exists){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path)); - } - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path)); - return $result; + $source=fopen($tmpFile,'r'); + if($source){ + $this->file_put_contents($path,$source); + unlink($tmpFile); + return true; + }else{ } + }else{ + return false; } } @@ -291,26 +323,32 @@ class OC_FilesystemView { * @return mixed */ private function basicOperation($operation,$path,$hooks=array(),$extraParam=null){ - if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and OC_Filesystem::isValidPath($path) and $storage=$this->getStorage($path)){ + if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and OC_Filesystem::isValidPath($path)){ $interalPath=$this->getInternalPath($path); $run=true; - foreach($hooks as $hook){ - if($hook!='read'){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); - }else{ - OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path)); + if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){ + foreach($hooks as $hook){ + if($hook!='read'){ + OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); + }else{ + OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path)); + } } } - if($run){ - if($extraParam){ + if($run and $storage=$this->getStorage($path)){ + if(!is_null($extraParam)){ $result=$storage->$operation($interalPath,$extraParam); }else{ $result=$storage->$operation($interalPath); } $result=OC_FileProxy::runPostProxies($operation,$path,$result); - foreach($hooks as $hook){ - if($hook!='read'){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, 'post_'.$hook, array( OC_Filesystem::signal_param_path => $path)); + if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){ + if($operation!='fopen'){//no post hooks for fopen, the file stream is still open + foreach($hooks as $hook){ + if($hook!='read'){ + OC_Hook::emit( OC_Filesystem::CLASSNAME, 'post_'.$hook, array( OC_Filesystem::signal_param_path => $path)); + } + } } } return $result; diff --git a/lib/geo.php b/lib/geo.php new file mode 100644 index 00000000000..a967ab28a96 --- /dev/null +++ b/lib/geo.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +class OC_Geo{ + /* + * @brief returns the closest timezone to coordinates + * @param (string) $latitude - Latitude + * @param (string) $longitude - Longitude + * @return (string) $timezone - closest timezone + */ + public static function timezone($latitude, $longitude){ + $alltimezones = DateTimeZone::listIdentifiers(); + $variances = array(); + //calculate for all timezones the system know + foreach($alltimezones as $timezone){ + $datetimezoneobj = new DateTimeZone($timezone); + $locationinformations = $datetimezoneobj->getLocation(); + $latitudeoftimezone = $locationinformations['latitude']; + $longitudeoftimezone = $locationinformations['longitude']; + $variances[abs($latitudeoftimezone - $latitude) + abs($longitudeoftimezone - $longitude)] = $timezone; + } + //sort array and return the timezone with the smallest difference + ksort($variances); + reset($variances); + return current($variances); + } +}
\ No newline at end of file diff --git a/lib/group/database.php b/lib/group/database.php index f35f61434f0..1afd4b5fe4c 100644 --- a/lib/group/database.php +++ b/lib/group/database.php @@ -130,7 +130,7 @@ class OC_Group_Database extends OC_Group_Backend { * removes the user from a group. */ public static function removeFromGroup( $uid, $gid ){ - $query = OC_DB::prepare( "DELETE FROM `*PREFIX*group_user` WHERE `uid` = ? AND `gid` = ?" ); + $query = OC_DB::prepare( "DELETE FROM *PREFIX*group_user WHERE uid = ? AND gid = ?" ); $result = $query->execute( array( $uid, $gid )); return true; diff --git a/lib/helper.php b/lib/helper.php index 2f71bdad2dc..0c6c73aa76b 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -25,6 +25,9 @@ * Collection of useful functions */ class OC_Helper { + private static $mimetypes=array(); + private static $tmpFiles=array(); + /** * @brief Creates an url * @param $app app @@ -37,8 +40,8 @@ class OC_Helper { if( $app != '' ){ $app .= '/'; // Check if the app is in the app folder - if( file_exists( OC::$SERVERROOT . '/apps/'. $app.$file )){ - $urlLinkTo = OC::$WEBROOT . '/apps/' . $app . $file; + if( file_exists( OC::$APPSROOT . '/apps/'. $app.$file )){ + $urlLinkTo = OC::$APPSWEBROOT . '/apps/' . $app . $file; } else{ $urlLinkTo = OC::$WEBROOT . '/' . $app . $file; @@ -81,24 +84,27 @@ class OC_Helper { * Returns the path to the image. */ public static function imagePath( $app, $image ){ - // Read the selected theme from the config file - $theme=OC_Config::getValue( "theme" ); + // Read the selected theme from the config file + $theme=OC_Config::getValue( "theme" ); - // Check if the app is in the app folder - if( file_exists( OC::$SERVERROOT."/themes/$theme/apps/$app/img/$image" )){ - return OC::$WEBROOT."/themes/$theme/apps/$app/img/$image"; - }elseif( file_exists( OC::$SERVERROOT."/apps/$app/img/$image" )){ - return OC::$WEBROOT."/apps/$app/img/$image"; - }elseif( !empty( $app ) and file_exists( OC::$SERVERROOT."/themes/$theme/$app/img/$image" )){ - return OC::$WEBROOT."/themes/$theme/$app/img/$image"; - }elseif( !empty( $app ) and file_exists( OC::$SERVERROOT."/$app/img/$image" )){ - return OC::$WEBROOT."/$app/img/$image"; - }elseif( file_exists( OC::$SERVERROOT."/themes/$theme/core/img/$image" )){ - return OC::$WEBROOT."/themes/$theme/core/img/$image"; - }else{ - return OC::$WEBROOT."/core/img/$image"; - } - } + // Check if the app is in the app folder + if( file_exists( OC::$SERVERROOT."/themes/$theme/apps/$app/img/$image" )){ + return OC::$WEBROOT."/themes/$theme/apps/$app/img/$image"; + }elseif( file_exists( OC::$APPSROOT."/apps/$app/img/$image" )){ + return OC::$APPSWEBROOT."/apps/$app/img/$image"; + }elseif( !empty( $app ) and file_exists( OC::$SERVERROOT."/themes/$theme/$app/img/$image" )){ + return OC::$WEBROOT."/themes/$theme/$app/img/$image"; + }elseif( !empty( $app ) and file_exists( OC::$SERVERROOT."/$app/img/$image" )){ + return OC::$WEBROOT."/$app/img/$image"; + }elseif( file_exists( OC::$SERVERROOT."/themes/$theme/core/img/$image" )){ + return OC::$WEBROOT."/themes/$theme/core/img/$image"; + }elseif( file_exists( OC::$SERVERROOT."/core/img/$image" )){ + return OC::$WEBROOT."/core/img/$image"; + }else{ + echo('image not found: image:'.$image.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT); + die(); + } + } /** * @brief get path to icon of file type @@ -194,7 +200,7 @@ class OC_Helper { $bytes *= $bytes_array[$matches[1]]; } - $bytes = intval(round($bytes, 2)); + $bytes = round($bytes, 2); return $bytes; } @@ -267,6 +273,62 @@ class OC_Helper { unlink($dir); } } + + /** + * get the mimetype form a local file + * @param string path + * @return string + * does NOT work for ownClouds filesystem, use OC_FileSystem::getMimeType instead + */ + static function getMimeType($path){ + $isWrapped=(strpos($path,'://')!==false) and (substr($path,0,7)=='file://'); + $mimeType='application/octet-stream'; + if ($mimeType=='application/octet-stream') { + if(count(self::$mimetypes)>0){ + self::$mimetypes = include('mimetypes.fixlist.php'); + } + $extention=strtolower(strrchr(basename($path), ".")); + $extention=substr($extention,1);//remove leading . + $mimeType=(isset(self::$mimetypes[$extention]))?self::$mimetypes[$extention]:'application/octet-stream'; + + } + if (@is_dir($path)) { + // directories are easy + return "httpd/unix-directory"; + } + if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){ + $info = @strtolower(finfo_file($finfo,$path)); + if($info){ + $mimeType=substr($info,0,strpos($info,';')); + } + finfo_close($finfo); + } + if (!$isWrapped and $mimeType=='application/octet-stream' && function_exists("mime_content_type")) { + // use mime magic extension if available + $mimeType = mime_content_type($path); + } + if (!$isWrapped and $mimeType=='application/octet-stream' && OC_Helper::canExecute("file")) { + // it looks like we have a 'file' command, + // lets see it it does have mime support + $path=str_replace("'","\'",$path); + $fp = popen("file -i -b '$path' 2>/dev/null", "r"); + $reply = fgets($fp); + pclose($fp); + + //trim the character set from the end of the response + $mimeType=substr($reply,0,strrpos($reply,' ')); + } + if ($mimeType=='application/octet-stream') { + // Fallback solution: (try to guess the type by the file extension + if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){ + self::$mimetypes=include('mimetypes.list.php'); + } + $extention=strtolower(strrchr(basename($path), ".")); + $extention=substr($extention,1);//remove leading . + $mimeType=(isset(self::$mimetypes[$extention]))?self::$mimetypes[$extention]:'application/octet-stream'; + } + return $mimeType; + } /** * @brief Checks $_REQUEST contains a var for the $s key. If so, returns the html-escaped value of this var; otherwise returns the default value provided by $d. @@ -340,4 +402,47 @@ class OC_Helper { } return false; } + + /** + * copy the contents of one stream to another + * @param resource source + * @param resource target + * @return int the number of bytes copied + */ + public static function streamCopy($source,$target){ + if(!$source or !$target){ + return false; + } + $count=0; + while(!feof($source)){ + $count+=fwrite($target,fread($source,8192)); + } + return $count; + } + + /** + * create a temporary file with an unique filename + * @param string postfix + * @return string + * + * temporary files are automatically cleaned up after the script is finished + */ + public static function tmpFile($postfix=''){ + $file=get_temp_dir().'/'.md5(time().rand()).$postfix; + $fh=fopen($file,'w'); + fclose($fh); + self::$tmpFiles[]=$file; + return $file; + } + + /** + * remove all files created by self::tmpFile + */ + public static function cleanTmp(){ + foreach(self::$tmpFiles as $file){ + if(file_exists($file)){ + unlink($file); + } + } + } } diff --git a/lib/installer.php b/lib/installer.php index b2f817e702f..2a9676998f6 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -62,7 +62,7 @@ class OC_Installer{ //download the file if necesary if($data['source']=='http'){ - $path=tempnam(get_temp_dir(),'oc_installer_'); + $path=OC_Helper::tmpFile('.zip'); if(!isset($data['href'])){ OC_Log::write('core','No href specified when installing app from http',OC_Log::ERROR); return false; @@ -103,7 +103,7 @@ class OC_Installer{ return false; } $info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml'); - $basedir=OC::$SERVERROOT.'/apps/'.$info['id']; + $basedir=OC::$APPSROOT.'/apps/'.$info['id']; //check if an app with the same id is already installed if(self::isInstalled( $info['id'] )){ @@ -142,9 +142,6 @@ class OC_Installer{ //remove temporary files OC_Helper::rmdirr($extractDir); - if($data['source']=='http'){ - unlink($path); - } //install the database if(is_file($basedir.'/appinfo/database.xml')){ @@ -244,10 +241,10 @@ class OC_Installer{ * If $enabled is false, apps are installed as disabled. */ public static function installShippedApps(){ - $dir = opendir( OC::$SERVERROOT."/apps" ); + $dir = opendir( OC::$APPSROOT."/apps" ); while( false !== ( $filename = readdir( $dir ))){ - if( substr( $filename, 0, 1 ) != '.' and is_dir(OC::$SERVERROOT."/apps/$filename") ){ - if( file_exists( OC::$SERVERROOT."/apps/$filename/appinfo/app.php" )){ + if( substr( $filename, 0, 1 ) != '.' and is_dir(OC::$APPSROOT."/apps/$filename") ){ + if( file_exists( OC::$APPSROOT."/apps/$filename/appinfo/app.php" )){ if(!OC_Installer::isInstalled($filename)){ $info = OC_Installer::installShippedApp($filename); $enabled = isset($info['default_enable']); @@ -270,15 +267,15 @@ class OC_Installer{ */ public static function installShippedApp($app){ //install the database - if(is_file(OC::$SERVERROOT."/apps/$app/appinfo/database.xml")){ - OC_DB::createDbFromStructure(OC::$SERVERROOT."/apps/$app/appinfo/database.xml"); + if(is_file(OC::$APPSROOT."/apps/$app/appinfo/database.xml")){ + OC_DB::createDbFromStructure(OC::$APPSROOT."/apps/$app/appinfo/database.xml"); } //run appinfo/install.php - if(is_file(OC::$SERVERROOT."/apps/$app/appinfo/install.php")){ - include(OC::$SERVERROOT."/apps/$app/appinfo/install.php"); + if(is_file(OC::$APPSROOT."/apps/$app/appinfo/install.php")){ + include(OC::$APPSROOT."/apps/$app/appinfo/install.php"); } - $info=OC_App::getAppInfo(OC::$SERVERROOT."/apps/$app/appinfo/info.xml"); + $info=OC_App::getAppInfo(OC::$APPSROOT."/apps/$app/appinfo/info.xml"); OC_Appconfig::setValue($app,'installed_version',$info['version']); return $info; } diff --git a/lib/l10n.php b/lib/l10n.php index a5544eb3a27..636326f9864 100644 --- a/lib/l10n.php +++ b/lib/l10n.php @@ -243,8 +243,8 @@ class OC_L10N{ $i18ndir = OC::$SERVERROOT.'/core/l10n/'; if($app != ''){ // Check if the app is in the app folder - if(file_exists(OC::$SERVERROOT.'/apps/'.$app.'/l10n/')){ - $i18ndir = OC::$SERVERROOT.'/apps/'.$app.'/l10n/'; + if(file_exists(OC::$APPSROOT.'/apps/'.$app.'/l10n/')){ + $i18ndir = OC::$APPSROOT.'/apps/'.$app.'/l10n/'; } else{ $i18ndir = OC::$SERVERROOT.'/'.$app.'/l10n/'; diff --git a/lib/log.php b/lib/log.php index 446ddd48848..4e450a027f5 100644 --- a/lib/log.php +++ b/lib/log.php @@ -3,7 +3,7 @@ * ownCloud * * @author Robin Appelman - * @copyright 2011 Robin Appelman icewind1991@gmail.com + * @copyright 2012 Robin Appelman icewind1991@gmail.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -50,25 +50,29 @@ class OC_Log{ fclose($fh); } } - - public static function getEntries(){ + + /** + * get entries from the log in reverse chronological order + * @param int limit + * @param int offset + * @return array + */ + public static function getEntries($limit=50,$offset=0){ $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' ); $logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' ); $entries=array(); if(!file_exists($logFile)){ return array(); } - $fh=fopen($logFile,'r'); - if($fh === false){ // Unable to read log file! + $contents=file($logFile); + if(!$contents){//error while reading log return array(); } - while(!feof($fh)){ - $line=fgets($fh); - if($line){ - $entries[]=json_decode($line); - } + $end=max(count($contents)-$offset-1,0); + $start=max($end-$limit,0); + for($i=$end;$i>$start;$i--){ + $entries[]=json_decode($contents[$i]); } - fclose($fh); return $entries; } } diff --git a/lib/search.php b/lib/search.php index f6f805bfe65..6b33fa38140 100644 --- a/lib/search.php +++ b/lib/search.php @@ -29,7 +29,7 @@ class OC_Search{ /** * register a new search provider to be used - * @param OC_Search_Provider $provider + * @param string $provider class name of a OC_Search_Provider */ public static function registerProvider($provider){ self::$providers[]=$provider; @@ -43,7 +43,7 @@ class OC_Search{ public static function search($query){ $results=array(); foreach(self::$providers as $provider){ - $results=array_merge($results,$provider->search($query)); + $results=array_merge($results, $provider::search($query)); } return $results; } diff --git a/lib/search/provider.php b/lib/search/provider.php index cceed8b04a3..9487ca51f2b 100644 --- a/lib/search/provider.php +++ b/lib/search/provider.php @@ -2,15 +2,11 @@ /** * provides search functionalty */ -abstract class OC_Search_Provider{ - public function __construct(){ - OC_Search::registerProvider($this); - } - +interface OC_Search_Provider { /** * search for $query * @param string $query * @return array An array of OC_Search_Result's */ - abstract function search($query); + static function search($query); } diff --git a/lib/search/provider/file.php b/lib/search/provider/file.php index 34803c75aeb..3bdb3bcd2af 100644 --- a/lib/search/provider/file.php +++ b/lib/search/provider/file.php @@ -1,15 +1,15 @@ <?php -class OC_Search_Provider_File extends OC_Search_Provider{ - function search($query){ +class OC_Search_Provider_File implements OC_Search_Provider{ + static function search($query){ $files=OC_FileCache::search($query,true); $results=array(); foreach($files as $fileData){ $file=$fileData['path']; - if($fileData['mime']=='httpd/unix-directory'){ + $mime=$fileData['mimetype']; + if($mime=='httpd/unix-directory'){ $results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'index.php' ).'?dir='.$file,'Files'); }else{ - $mime=$fileData['mime']; $mimeBase=$fileData['mimepart']; switch($mimeBase){ case 'audio': diff --git a/lib/streamwrappers.php b/lib/streamwrappers.php new file mode 100644 index 00000000000..f1e0fa0e1d9 --- /dev/null +++ b/lib/streamwrappers.php @@ -0,0 +1,306 @@ +<?php +global $FAKEDIRS; +$FAKEDIRS=array(); + +class OC_FakeDirStream{ + public static $dirs=array(); + private $name; + 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(self::$dirs[$this->name])){ + self::$dirs[$this->name]=array(); + } + return true; + } + + public function dir_readdir(){ + if($this->index>=count(self::$dirs[$this->name])){ + return false; + } + $filename=self::$dirs[$this->name][$this->index]; + $this->index++; + return $filename; + } + + public function dir_closedir() { + $this->name=''; + return true; + } + + public function dir_rewinddir() { + $this->index=0; + return true; + } +} + +class OC_StaticStreamWrapper { + public $context; + protected static $data = array(); + + protected $path = ''; + protected $pointer = 0; + protected $writable = false; + + public function stream_close() {} + + public function stream_eof() { + return $this->pointer >= strlen(self::$data[$this->path]); + } + + public function stream_flush() {} + + public function stream_open($path, $mode, $options, &$opened_path) { + switch ($mode[0]) { + case 'r': + if (!isset(self::$data[$path])) return false; + $this->path = $path; + $this->writable = isset($mode[1]) && $mode[1] == '+'; + break; + case 'w': + self::$data[$path] = ''; + $this->path = $path; + $this->writable = true; + break; + case 'a': + if (!isset(self::$data[$path])) self::$data[$path] = ''; + $this->path = $path; + $this->writable = true; + $this->pointer = strlen(self::$data[$path]); + break; + case 'x': + if (isset(self::$data[$path])) return false; + $this->path = $path; + $this->writable = true; + break; + case 'c': + if (!isset(self::$data[$path])) self::$data[$path] = ''; + $this->path = $path; + $this->writable = true; + break; + default: + return false; + } + $opened_path = $this->path; + return true; + } + + public function stream_read($count) { + $bytes = min(strlen(self::$data[$this->path]) - $this->pointer, $count); + $data = substr(self::$data[$this->path], $this->pointer, $bytes); + $this->pointer += $bytes; + return $data; + } + + public function stream_seek($offset, $whence = SEEK_SET) { + $len = strlen(self::$data[$this->path]); + switch ($whence) { + case SEEK_SET: + if ($offset <= $len) { + $this->pointer = $offset; + return true; + } + break; + case SEEK_CUR: + if ($this->pointer + $offset <= $len) { + $this->pointer += $offset; + return true; + } + break; + case SEEK_END: + if ($len + $offset <= $len) { + $this->pointer = $len + $offset; + return true; + } + break; + } + return false; + } + + public function stream_stat() { + $size = strlen(self::$data[$this->path]); + $time = time(); + return array( + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 0777, + 'mode' => 0777, + 3 => 1, + 'nlink' => 1, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => '', + 'rdev' => '', + 7 => $size, + 'size' => $size, + 8 => $time, + 'atime' => $time, + 9 => $time, + 'mtime' => $time, + 10 => $time, + 'ctime' => $time, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ); + } + + public function stream_tell() { + return $this->pointer; + } + + public function stream_write($data) { + if (!$this->writable) return 0; + $size = strlen($data); + $len = strlen(self::$data[$this->path]); + if ($this->stream_eof()) { + self::$data[$this->path] .= $data; + } else { + self::$data[$this->path] = substr_replace( + self::$data[$this->path], + $data, + $this->pointer + ); + } + $this->pointer += $size; + return $size; + } + + public function unlink($path) { + if (isset(self::$data[$path])) { + unset(self::$data[$path]); + } + return true; + } + + public function url_stat($path) { + if (isset(self::$data[$path])) { + $size = strlen(self::$data[$path]); + $time = time(); + return array( + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 0777, + 'mode' => 0777, + 3 => 1, + 'nlink' => 1, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => '', + 'rdev' => '', + 7 => $size, + 'size' => $size, + 8 => $time, + 'atime' => $time, + 9 => $time, + 'mtime' => $time, + 10 => $time, + 'ctime' => $time, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ); + } + return false; + } +} + +/** + * stream wrapper that provides a callback on stream close + */ +class OC_CloseStreamWrapper{ + public static $callBacks=array(); + private $path=''; + private $source; + private static $open=array(); + public function stream_open($path, $mode, $options, &$opened_path){ + $path=substr($path,strlen('close://')); + $this->path=$path; + $this->source=fopen($path,$mode); + if(is_resource($this->source)){ + $this->meta=stream_get_meta_data($this->source); + } + self::$open[]=$path; + return is_resource($this->source); + } + + public function stream_seek($offset, $whence=SEEK_SET){ + fseek($this->source,$offset,$whence); + } + + public function stream_tell(){ + return ftell($this->source); + } + + public function stream_read($count){ + return fread($this->source,$count); + } + + public function stream_write($data){ + return fwrite($this->source,$data); + } + + public function stream_set_option($option,$arg1,$arg2){ + switch($option){ + case STREAM_OPTION_BLOCKING: + stream_set_blocking($this->source,$arg1); + break; + case STREAM_OPTION_READ_TIMEOUT: + stream_set_timeout($this->source,$arg1,$arg2); + break; + case STREAM_OPTION_WRITE_BUFFER: + stream_set_write_buffer($this->source,$arg1,$arg2); + } + } + + public function stream_stat(){ + return fstat($this->source); + } + + public function stream_lock($mode){ + flock($this->source,$mode); + } + + public function stream_flush(){ + return fflush($this->source); + } + + public function stream_eof(){ + return feof($this->source); + } + + public function url_stat($path) { + $path=substr($path,strlen('close://')); + if(file_exists($path)){ + return stat($path); + }else{ + return false; + } + } + + public function stream_close(){ + fclose($this->source); + if(isset(self::$callBacks[$this->path])){ + call_user_func(self::$callBacks[$this->path],$this->path); + } + } + + public function unlink($path){ + $path=substr($path,strlen('close://')); + return unlink($path); + } +} diff --git a/lib/template.php b/lib/template.php index d991759fbcd..eea2925975c 100644 --- a/lib/template.php +++ b/lib/template.php @@ -171,7 +171,7 @@ class OC_Template{ // Check if it is a app template or not. if( $app != "" ){ // Check if the app is in the app folder or in the root - if( file_exists( OC::$SERVERROOT."/apps/$app/templates/" )){ + if( file_exists( OC::$APPSROOT."/apps/$app/templates/" )){ // Check if the template is overwritten by the selected theme if( file_exists( OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name$fext.php" )){ $template = OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name$fext.php"; @@ -179,12 +179,12 @@ class OC_Template{ }elseif( file_exists( OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name.php" )){ $template = OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"."$name.php"; $path = OC::$SERVERROOT."/themes/$theme/apps/$app/templates/"; - }elseif( OC::$SERVERROOT."/apps/$app/templates/"."$name$fext.php" ){ - $template = OC::$SERVERROOT."/apps/$app/templates/"."$name$fext.php"; - $path = OC::$SERVERROOT."/apps/$app/templates/"; + }elseif( OC::$APPSROOT."/apps/$app/templates/"."$name$fext.php" ){ + $template = OC::$APPSROOT."/apps/$app/templates/"."$name$fext.php"; + $path = OC::$APPSROOT."/apps/$app/templates/"; }else{ - $template = OC::$SERVERROOT."/apps/$app/templates/"."$name.php"; - $path = OC::$SERVERROOT."/apps/$app/templates/"; + $template = OC::$APPSROOT."/apps/$app/templates/"."$name.php"; + $path = OC::$APPSROOT."/apps/$app/templates/"; } }else{ // Check if the template is overwritten by the selected theme @@ -197,12 +197,15 @@ class OC_Template{ }elseif( file_exists( OC::$SERVERROOT."/$app/templates/"."$name$fext.php" )){ $template = OC::$SERVERROOT."/$app/templates/"."$name$fext.php"; $path = OC::$SERVERROOT."/$app/templates/"; - }else{ + }elseif( file_exists( OC::$SERVERROOT."/$app/templates/"."$name.php" )){ $template = OC::$SERVERROOT."/$app/templates/"."$name.php"; $path = OC::$SERVERROOT."/$app/templates/"; + }else{ + echo('template not found: template:'.$name.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT); + die(); } - } + } }else{ // Check if the template is overwritten by the selected theme if( file_exists( OC::$SERVERROOT."/themes/$theme/core/templates/"."$name$fext.php" )){ @@ -346,52 +349,76 @@ class OC_Template{ // Add the core js files or the js files provided by the selected theme foreach(OC_Util::$scripts as $script){ - if(is_file(OC::$SERVERROOT."/themes/$theme/apps/$script$fext.js" )){ + // Is it in 3rd party? + if(is_file(OC::$THIRDPARTYROOT."/$script.js" )){ + $page->append( "jsfiles", OC::$THIRDPARTYWEBROOT."/$script.js" ); + + // Is it in apps and overwritten by the theme? + }elseif(is_file(OC::$SERVERROOT."/themes/$theme/apps/$script$fext.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/apps/$script$fext.js" ); }elseif(is_file(OC::$SERVERROOT."/themes/$theme/apps/$script.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/apps/$script.js" ); - }elseif(is_file(OC::$SERVERROOT."/apps/$script$fext.js" )){ - $page->append( "jsfiles", OC::$WEBROOT."/apps/$script$fext.js" ); - }elseif(is_file(OC::$SERVERROOT."/apps/$script.js" )){ - $page->append( "jsfiles", OC::$WEBROOT."/apps/$script.js" ); + // Is it part of an app? + }elseif(is_file(OC::$APPSROOT."/apps/$script$fext.js" )){ + $page->append( "jsfiles", OC::$APPSWEBROOT."/apps/$script$fext.js" ); + }elseif(is_file(OC::$APPSROOT."/apps/$script.js" )){ + $page->append( "jsfiles", OC::$APPSWEBROOT."/apps/$script.js" ); + // Is it in the owncloud root but overwritten by the theme? }elseif(is_file(OC::$SERVERROOT."/themes/$theme/$script$fext.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/$script$fext.js" ); }elseif(is_file(OC::$SERVERROOT."/themes/$theme/$script.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/$script.js" ); - + + // Is it in the owncloud root ? }elseif(is_file(OC::$SERVERROOT."/$script$fext.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/$script$fext.js" ); }elseif(is_file(OC::$SERVERROOT."/$script.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/$script.js" ); + // Is in core but overwritten by a theme? }elseif(is_file(OC::$SERVERROOT."/themes/$theme/core/$script$fext.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/core/$script$fext.js" ); }elseif(is_file(OC::$SERVERROOT."/themes/$theme/core/$script.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/themes/$theme/core/$script.js" ); + // Is it in core? }elseif(is_file(OC::$SERVERROOT."/core/$script$fext.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/core/$script$fext.js" ); - }else{ + }elseif(is_file(OC::$SERVERROOT."/core/$script.js" )){ $page->append( "jsfiles", OC::$WEBROOT."/core/$script.js" ); + }else{ + echo('js file not found: script:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT); + die(); + } } // Add the css files foreach(OC_Util::$styles as $style){ - if(is_file(OC::$SERVERROOT."/apps/$style$fext.css" )){ - $page->append( "cssfiles", OC::$WEBROOT."/apps/$style$fext.css" ); - }elseif(is_file(OC::$SERVERROOT."/apps/$style.css" )){ - $page->append( "cssfiles", OC::$WEBROOT."/apps/$style.css" ); + // is it in 3rdparty? + if(is_file(OC::$THIRDPARTYROOT."/$style.css" )){ + $page->append( "cssfiles", OC::$THIRDPARTYWEBROOT."/$style.css" ); + // or in apps? + }elseif(is_file(OC::$APPSROOT."/apps/$style$fext.css" )){ + $page->append( "cssfiles", OC::$APPSWEBROOT."/apps/$style$fext.css" ); + }elseif(is_file(OC::$APPSROOT."/apps/$style.css" )){ + $page->append( "cssfiles", OC::$APPSWEBROOT."/apps/$style.css" ); + // or in the owncloud root? }elseif(is_file(OC::$SERVERROOT."/$style$fext.css" )){ $page->append( "cssfiles", OC::$WEBROOT."/$style$fext.css" ); }elseif(is_file(OC::$SERVERROOT."/$style.css" )){ $page->append( "cssfiles", OC::$WEBROOT."/$style.css" ); + // or in core ? }elseif(is_file(OC::$SERVERROOT."/core/$style$fext.css" )){ $page->append( "cssfiles", OC::$WEBROOT."/core/$style$fext.css" ); - }else{ + }elseif(is_file(OC::$SERVERROOT."/core/$style.css" )){ $page->append( "cssfiles", OC::$WEBROOT."/core/$style.css" ); + + }else{ + echo('css file not found: style:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT); + die(); } } // Add the theme css files. you can override the default values here diff --git a/lib/user.php b/lib/user.php index 34f44f572e0..fda19a33154 100644 --- a/lib/user.php +++ b/lib/user.php @@ -195,8 +195,9 @@ class OC_User { if( $run ){ $uid=self::checkPassword( $uid, $password ); if($uid){ - OC_Crypt::init($uid,$password); - return self::setUserId($uid); + self::setUserId($uid); + OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>$password )); + return true; } } return false; @@ -209,7 +210,6 @@ class OC_User { */ public static function setUserId($uid) { $_SESSION['user_id'] = $uid; - OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid )); return true; } @@ -321,7 +321,10 @@ class OC_User { $users=array(); foreach(self::$_usedBackends as $backend){ if($backend->implementsActions(OC_USER_BACKEND_GET_USERS)){ - $users=array_merge($users,$backend->getUsers()); + $backendUsers=$backend->getUsers(); + if(is_array($backendUsers)){ + $users=array_merge($users,$backendUsers); + } } } return $users; diff --git a/lib/user/database.php b/lib/user/database.php index 452709c1fb9..3eade276dd9 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -33,12 +33,28 @@ * */ +require_once 'phpass/PasswordHash.php'; + /** * Class for user management in a SQL Database (e.g. MySQL, SQLite) */ class OC_User_Database extends OC_User_Backend { static private $userGroupCache=array(); + /** + * @var PasswordHash + */ + static private $hasher=null; + + private function getHasher(){ + if(!self::$hasher){ + //we don't want to use DES based crypt(), since it doesn't return a has with a recognisable prefix + $forcePortable=(CRYPT_BLOWFISH!=1); + self::$hasher=new PasswordHash(8,$forcePortable); + } + return self::$hasher; + } + /** * @brief Create a new user * @param $uid The username of the user to create @@ -51,10 +67,11 @@ class OC_User_Database extends OC_User_Backend { public function createUser( $uid, $password ){ if( $this->userExists($uid) ){ return false; - } - else{ + }else{ + $hasher=$this->getHasher(); + $hash = $hasher->HashPassword($password); $query = OC_DB::prepare( "INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )" ); - $result = $query->execute( array( $uid, sha1( $password ))); + $result = $query->execute( array( $uid, $hash)); return $result ? true : false; } @@ -84,8 +101,10 @@ class OC_User_Database extends OC_User_Backend { */ public function setPassword( $uid, $password ){ if( $this->userExists($uid) ){ + $hasher=$this->getHasher(); + $hash = $hasher->HashPassword($password); $query = OC_DB::prepare( "UPDATE *PREFIX*users SET password = ? WHERE uid = ?" ); - $result = $query->execute( array( sha1( $password ), $uid )); + $result = $query->execute( array( $hash, $uid )); return true; } @@ -103,12 +122,28 @@ class OC_User_Database extends OC_User_Backend { * Check if the password is correct without logging in the user */ public function checkPassword( $uid, $password ){ - $query = OC_DB::prepare( "SELECT uid FROM *PREFIX*users WHERE uid LIKE ? AND password = ?" ); - $result = $query->execute( array( $uid, sha1( $password ))); + $query = OC_DB::prepare( "SELECT uid, password FROM *PREFIX*users WHERE uid LIKE ?" ); + $result = $query->execute( array( $uid)); $row=$result->fetchRow(); if($row){ - return $row['uid']; + $storedHash=$row['password']; + if (substr($storedHash,0,1)=='$'){//the new phpass based hashing + $hasher=$this->getHasher(); + if($hasher->CheckPassword($password, $storedHash)){ + return $row['uid']; + }else{ + return false; + } + }else{//old sha1 based hashing + if(sha1($password)==$storedHash){ + //upgrade to new hashing + $this->setPassword($row['uid'],$password); + return $row['uid']; + }else{ + return false; + } + } }else{ return false; } diff --git a/lib/util.php b/lib/util.php index 1b1e29b6749..fa5b3daaab6 100644 --- a/lib/util.php +++ b/lib/util.php @@ -8,6 +8,7 @@ class OC_Util { public static $scripts=array(); public static $styles=array(); public static $headers=array(); + private static $rootMounted=false; private static $fsSetup=false; // Can be set up @@ -35,9 +36,12 @@ class OC_Util { $user = OC_User::getUser(); } - if( $user != "" ){ //if we aren't logged in, there is no use to set up the filesystem - //first set up the local "root" storage + //first set up the local "root" storage + if(!self::$rootMounted){ OC_Filesystem::mount('OC_Filestorage_Local',array('datadir'=>$CONFIG_DATADIRECTORY_ROOT),'/'); + self::$rootMounted=true; + } + if( $user != "" ){ //if we aren't logged in, there is no use to set up the filesystem OC::$CONFIG_DATADIRECTORY = $CONFIG_DATADIRECTORY_ROOT."/$user/$root"; if( !is_dir( OC::$CONFIG_DATADIRECTORY )){ @@ -62,7 +66,7 @@ class OC_Util { * @return array */ public static function getVersion(){ - return array(3,00,1); + return array(3,00,3); } /** |