summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base.php16
-rw-r--r--lib/l10n/cs_CZ.js1
-rw-r--r--lib/l10n/cs_CZ.json1
-rw-r--r--lib/l10n/de.js3
-rw-r--r--lib/l10n/de.json3
-rw-r--r--lib/l10n/de_DE.js3
-rw-r--r--lib/l10n/de_DE.json3
-rw-r--r--lib/l10n/eo.js37
-rw-r--r--lib/l10n/eo.json37
-rw-r--r--lib/l10n/es.js1
-rw-r--r--lib/l10n/es.json1
-rw-r--r--lib/l10n/fi_FI.js1
-rw-r--r--lib/l10n/fi_FI.json1
-rw-r--r--lib/l10n/fr.js1
-rw-r--r--lib/l10n/fr.json1
-rw-r--r--lib/l10n/gl.js1
-rw-r--r--lib/l10n/gl.json1
-rw-r--r--lib/l10n/it.js1
-rw-r--r--lib/l10n/it.json1
-rw-r--r--lib/l10n/nb_NO.js1
-rw-r--r--lib/l10n/nb_NO.json1
-rw-r--r--lib/l10n/nl.js1
-rw-r--r--lib/l10n/nl.json1
-rw-r--r--lib/l10n/pt_BR.js1
-rw-r--r--lib/l10n/pt_BR.json1
-rw-r--r--lib/l10n/sr.js20
-rw-r--r--lib/l10n/sr.json20
-rw-r--r--lib/l10n/uk.js1
-rw-r--r--lib/l10n/uk.json1
-rw-r--r--lib/private/backgroundjob/joblist.php3
-rw-r--r--lib/private/cache.php129
-rw-r--r--lib/private/cache/broker.php80
-rw-r--r--lib/private/cache/file.php174
-rw-r--r--lib/private/cache/fileglobal.php107
-rw-r--r--lib/private/cache/fileglobalgc.php80
-rw-r--r--lib/private/cache/usercache.php93
-rw-r--r--lib/private/connector/sabre/directory.php24
-rw-r--r--lib/private/connector/sabre/exception/filelocked.php2
-rw-r--r--lib/private/connector/sabre/file.php17
-rw-r--r--lib/private/connector/sabre/filesplugin.php6
-rw-r--r--lib/private/connector/sabre/objecttree.php17
-rw-r--r--lib/private/encryption/manager.php53
-rw-r--r--lib/private/encryption/util.php51
-rw-r--r--lib/private/files/storage/common.php29
-rw-r--r--lib/private/files/storage/storage.php23
-rw-r--r--lib/private/files/storage/wrapper/encryption.php8
-rw-r--r--lib/private/files/storage/wrapper/jail.php29
-rw-r--r--lib/private/files/storage/wrapper/wrapper.php29
-rw-r--r--lib/private/files/view.php199
-rw-r--r--lib/private/lock/memcachelockingprovider.php58
-rw-r--r--lib/private/lock/nooplockingprovider.php67
-rw-r--r--lib/private/memcache/factory.php23
-rw-r--r--lib/private/memcache/null.php18
-rw-r--r--lib/private/repair.php2
-rw-r--r--lib/private/route/router.php2
-rw-r--r--lib/private/server.php41
-rw-r--r--lib/public/files/storage.php24
-rw-r--r--lib/public/iservercontainer.php8
-rw-r--r--lib/public/lock/ilockingprovider.php14
-rw-r--r--lib/repair/dropoldjobs.php78
60 files changed, 879 insertions, 771 deletions
diff --git a/lib/base.php b/lib/base.php
index b7f19c96406..77b0a89a90b 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -652,7 +652,6 @@ class OC {
OC_User::setupBackends();
}
- self::registerCacheHooks();
self::registerFilesystemHooks();
if (\OC::$server->getSystemConfig()->getValue('enable_previews', true)) {
self::registerPreviewHooks();
@@ -666,6 +665,8 @@ class OC {
//make sure temporary files are cleaned up
$tmpManager = \OC::$server->getTempManager();
register_shutdown_function(array($tmpManager, 'clean'));
+ $lockProvider = \OC::$server->getLockingProvider();
+ register_shutdown_function(array($lockProvider, 'releaseAll'));
if ($systemConfig->getValue('installed', false) && !self::checkUpgrade(false)) {
if (\OC::$server->getConfig()->getAppValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') {
@@ -735,19 +736,6 @@ class OC {
/**
* register hooks for the cache
*/
- public static function registerCacheHooks() {
- if (\OC::$server->getSystemConfig()->getValue('installed', false) && !\OCP\Util::needUpgrade()) { //don't try to do this before we are properly setup
- \OCP\BackgroundJob::registerJob('OC\Cache\FileGlobalGC');
-
- // NOTE: This will be replaced to use OCP
- $userSession = \OC_User::getUserSession();
- $userSession->listen('postLogin', '\OC\Cache\File', 'loginListener');
- }
- }
-
- /**
- * register hooks for the cache
- */
public static function registerLogRotate() {
$systemConfig = \OC::$server->getSystemConfig();
if ($systemConfig->getValue('installed', false) && $systemConfig->getValue('log_rotate_size', false) && !\OCP\Util::needUpgrade()) {
diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js
index 01817f5cde5..342f345033f 100644
--- a/lib/l10n/cs_CZ.js
+++ b/lib/l10n/cs_CZ.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["před %n minutou","před %n minutami","před %n minutami"],
"seconds ago" : "před pár sekundami",
"web services under your control" : "webové služby pod Vaší kontrolou",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Modul s id: %s neexistuje. Povolte ho prosím ve svých nastaveních aplikací nebo kontaktujte svého administrátora.",
"Empty filename is not allowed" : "Prázdné jméno souboru není povoleno",
"Dot files are not allowed" : "Jména souborů začínající tečkou nejsou povolena",
"4-byte characters are not supported in file names" : "4-bytové znaky nejsou podporovány ve jménech souborů",
diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json
index ab5e4662633..73c05b89f37 100644
--- a/lib/l10n/cs_CZ.json
+++ b/lib/l10n/cs_CZ.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["před %n minutou","před %n minutami","před %n minutami"],
"seconds ago" : "před pár sekundami",
"web services under your control" : "webové služby pod Vaší kontrolou",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Modul s id: %s neexistuje. Povolte ho prosím ve svých nastaveních aplikací nebo kontaktujte svého administrátora.",
"Empty filename is not allowed" : "Prázdné jméno souboru není povoleno",
"Dot files are not allowed" : "Jména souborů začínající tečkou nejsou povolena",
"4-byte characters are not supported in file names" : "4-bytové znaky nejsou podporovány ve jménech souborů",
diff --git a/lib/l10n/de.js b/lib/l10n/de.js
index 39ee0169d7c..32d4121a4a5 100644
--- a/lib/l10n/de.js
+++ b/lib/l10n/de.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["Vor %n Minute","Vor %n Minuten"],
"seconds ago" : "Gerade eben",
"web services under your control" : "Web-Dienste unter Deiner Kontrolle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Das Modul mit der ID: %s existiert nicht. Bitte aktiviere es in Deinen App-Einstellungen oder kontaktiere Deinen Administrator.",
"Empty filename is not allowed" : "Ein leerer Dateiname ist nicht erlaubt",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
"4-byte characters are not supported in file names" : "4-Byte Zeichen sind in Dateinamen nicht erlaubt",
@@ -133,7 +134,7 @@ OC.L10N.register(
"PHP setting \"%s\" is not set to \"%s\"." : "PHP-Einstellung „%s“ ist nicht auf „%s“ gesetzt.",
"Adjusting this setting in php.ini will make ownCloud run again" : "Durch das Anpassen dieser Einstellung in der php.ini wird ownCloud wieder laufen",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload ist nicht auf den erwarteten Wert „0“, sondern stattdessen auf „%s“ gesetzt",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Setze in Deiner php.ini <code>mbstring.func_overload</code> auf <code>-0</code>, um dieses Problem zu beheben.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Bitte setze zum Beheben dieses Problems <code>mbstring.func_overload</code> in Deiner php.ini auf <code>0</code>.",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ist offenbar so konfiguriert, dass PHPDoc-Blöcke in der Anweisung entfernt werden. Dadurch sind mehrere Kern-Apps nicht erreichbar.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dies wird wahrscheinlich durch Zwischenspeicher/Beschleuniger wie etwa Zend OPcache oder eAccelerator verursacht.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP-Module wurden installiert, werden aber als noch fehlend gelistet?",
diff --git a/lib/l10n/de.json b/lib/l10n/de.json
index 513c75fc94a..c886a42dacb 100644
--- a/lib/l10n/de.json
+++ b/lib/l10n/de.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["Vor %n Minute","Vor %n Minuten"],
"seconds ago" : "Gerade eben",
"web services under your control" : "Web-Dienste unter Deiner Kontrolle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Das Modul mit der ID: %s existiert nicht. Bitte aktiviere es in Deinen App-Einstellungen oder kontaktiere Deinen Administrator.",
"Empty filename is not allowed" : "Ein leerer Dateiname ist nicht erlaubt",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
"4-byte characters are not supported in file names" : "4-Byte Zeichen sind in Dateinamen nicht erlaubt",
@@ -131,7 +132,7 @@
"PHP setting \"%s\" is not set to \"%s\"." : "PHP-Einstellung „%s“ ist nicht auf „%s“ gesetzt.",
"Adjusting this setting in php.ini will make ownCloud run again" : "Durch das Anpassen dieser Einstellung in der php.ini wird ownCloud wieder laufen",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload ist nicht auf den erwarteten Wert „0“, sondern stattdessen auf „%s“ gesetzt",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Setze in Deiner php.ini <code>mbstring.func_overload</code> auf <code>-0</code>, um dieses Problem zu beheben.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Bitte setze zum Beheben dieses Problems <code>mbstring.func_overload</code> in Deiner php.ini auf <code>0</code>.",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ist offenbar so konfiguriert, dass PHPDoc-Blöcke in der Anweisung entfernt werden. Dadurch sind mehrere Kern-Apps nicht erreichbar.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dies wird wahrscheinlich durch Zwischenspeicher/Beschleuniger wie etwa Zend OPcache oder eAccelerator verursacht.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP-Module wurden installiert, werden aber als noch fehlend gelistet?",
diff --git a/lib/l10n/de_DE.js b/lib/l10n/de_DE.js
index bbc3919647f..4007e21bffd 100644
--- a/lib/l10n/de_DE.js
+++ b/lib/l10n/de_DE.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["Vor %n Minute","Vor %n Minuten"],
"seconds ago" : "Gerade eben",
"web services under your control" : "Web-Dienste unter Ihrer Kontrolle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Das Modul mit der ID: %s existiert nicht. Bitte aktivieren Sie es in Ihren App-Einstellungen oder kontaktieren Sie Ihren Administrator.",
"Empty filename is not allowed" : "Ein leerer Dateiname ist nicht erlaubt",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
"4-byte characters are not supported in file names" : "4-Byte-Zeichen werden in Dateinamen nicht unterstützt",
@@ -133,7 +134,7 @@ OC.L10N.register(
"PHP setting \"%s\" is not set to \"%s\"." : "PHP-Einstellung „%s“ ist nicht auf „%s“ gesetzt.",
"Adjusting this setting in php.ini will make ownCloud run again" : "Durch das Anpassen dieser Einstellung in der php.ini wird ownCloud wieder laufen",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload ist nicht auf den erwarteten Wert „0“, sondern stattdessen auf „%s“ gesetzt",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Setzen Sie in Ihrer php.ini <code>mbstring.func_overload</code> auf <code>-0</code>, um dieses Problem zu beheben.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Bitte setzen Sie zum Beheben dieses Problems <code>mbstring.func_overload</code> in Ihrer php.ini auf <code>0</code>.",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ist offenbar so konfiguriert, dass PHPDoc-Blöcke in der Anweisung entfernt werden. Dadurch sind mehrere Kern-Apps nicht erreichbar.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dies wird wahrscheinlich durch Zwischenspeicher/Beschleuniger wie etwa Zend OPcache oder eAccelerator verursacht.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP-Module wurden installiert, werden aber als noch fehlend gelistet?",
diff --git a/lib/l10n/de_DE.json b/lib/l10n/de_DE.json
index e1433fb5339..1e977f2be51 100644
--- a/lib/l10n/de_DE.json
+++ b/lib/l10n/de_DE.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["Vor %n Minute","Vor %n Minuten"],
"seconds ago" : "Gerade eben",
"web services under your control" : "Web-Dienste unter Ihrer Kontrolle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Das Modul mit der ID: %s existiert nicht. Bitte aktivieren Sie es in Ihren App-Einstellungen oder kontaktieren Sie Ihren Administrator.",
"Empty filename is not allowed" : "Ein leerer Dateiname ist nicht erlaubt",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
"4-byte characters are not supported in file names" : "4-Byte-Zeichen werden in Dateinamen nicht unterstützt",
@@ -131,7 +132,7 @@
"PHP setting \"%s\" is not set to \"%s\"." : "PHP-Einstellung „%s“ ist nicht auf „%s“ gesetzt.",
"Adjusting this setting in php.ini will make ownCloud run again" : "Durch das Anpassen dieser Einstellung in der php.ini wird ownCloud wieder laufen",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload ist nicht auf den erwarteten Wert „0“, sondern stattdessen auf „%s“ gesetzt",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Setzen Sie in Ihrer php.ini <code>mbstring.func_overload</code> auf <code>-0</code>, um dieses Problem zu beheben.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Bitte setzen Sie zum Beheben dieses Problems <code>mbstring.func_overload</code> in Ihrer php.ini auf <code>0</code>.",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ist offenbar so konfiguriert, dass PHPDoc-Blöcke in der Anweisung entfernt werden. Dadurch sind mehrere Kern-Apps nicht erreichbar.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dies wird wahrscheinlich durch Zwischenspeicher/Beschleuniger wie etwa Zend OPcache oder eAccelerator verursacht.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP-Module wurden installiert, werden aber als noch fehlend gelistet?",
diff --git a/lib/l10n/eo.js b/lib/l10n/eo.js
index c32a71ef0c3..ad565d590b7 100644
--- a/lib/l10n/eo.js
+++ b/lib/l10n/eo.js
@@ -1,20 +1,33 @@
OC.L10N.register(
"lib",
{
+ "Cannot write into \"config\" directory!" : "Ne skribeblas la dosierujo “config”!",
"See %s" : "Vidi %s",
"PHP %s or higher is required." : "PHP %s aŭ pli alta necesas.",
+ "PHP with a version lower than %s is required." : "Necesas pli malalta eldono de PHP ol %s.",
+ "Following databases are supported: %s" : "La jenan datumbazoj kongruas: %s",
+ "The command line tool %s could not be found" : "La komandolinia ilo %s ne troviĝis",
+ "The library %s is not available." : "La biblioteko %s ne haveblas.",
+ "ownCloud %s or higher is required." : "ownCloud %s aŭ pli alta necesas.",
+ "ownCloud with a version lower than %s is required." : "Eldono de ownCloud pli malalta ol %s necesas.",
"Help" : "Helpo",
"Personal" : "Persona",
"Users" : "Uzantoj",
"Admin" : "Administranto",
+ "Recommended" : "Rekomendata",
"Unknown filetype" : "Ne konatas dosiertipo",
"Invalid image" : "Ne validas bildo",
"today" : "hodiaŭ",
"yesterday" : "hieraŭ",
+ "_%n day ago_::_%n days ago_" : ["antaŭ %n tago","antaŭ %n tagoj"],
"last month" : "lastamonate",
"last year" : "lastajare",
+ "_%n year ago_::_%n years ago_" : ["antaŭ %n jaro","antaŭ %n jaroj"],
"seconds ago" : "sekundoj antaŭe",
"web services under your control" : "TTT-servoj regataj de vi",
+ "Empty filename is not allowed" : "Malplena dosiernomo ne permesatas",
+ "File name is too long" : "La dosiernomo tro longas",
+ "Can't read file" : "Ne legeblas dosiero",
"App directory already exists" : "La dosierujo de la aplikaĵo jam ekzistas",
"App does not provide an info.xml file" : "La aplikaĵo ne provizas dosieron info.xml",
"App can't be installed because it is not compatible with this version of ownCloud" : "La aplikaĵo ne povas instaliĝi ĉar ĝi ne kongruas kun ĉi tiu eldono de ownCloud",
@@ -35,15 +48,37 @@ OC.L10N.register(
"PostgreSQL username and/or password not valid" : "La uzantonomo de PostgreSQL aŭ la pasvorto ne validas",
"Set an admin username." : "Starigi administran uzantonomon.",
"Set an admin password." : "Starigi administran pasvorton.",
+ "Can't create or write into the data directory %s" : "Ne kreeblas aŭ ne skribeblas la dosierujo de datumoj %s",
"%s shared »%s« with you" : "%s kunhavigis “%s” kun vi",
+ "%s via %s" : "%s per %s",
+ "Sharing %s failed, because the file does not exist" : "Kunhavigo de %s malsukcesis, ĉar la dosiero ne ekzistas",
"You are not allowed to share %s" : "Vi ne permesatas kunhavigi %s",
+ "Sharing %s failed, because the user %s is the item owner" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s posedas la eron",
+ "Sharing %s failed, because the user %s does not exist" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s ne ekzistas",
+ "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s estas ano de neniu grupo, de kiu %s estas ano",
+ "Sharing %s failed, because this item is already shared with %s" : "Kunhavigo de %s malsukcesis, ĉar la ero jam kunhavatas kun %s",
+ "Sharing %s failed, because the group %s does not exist" : "Kunhavigo de %s malsukcesis, ĉar la grupo %s ne ekzistas",
+ "Sharing %s failed, because %s is not a member of the group %s" : "Kunhavigo de %s malsukcesis, ĉar %s ne estas ano de la grupo %s",
+ "Sharing %s failed, because sharing with links is not allowed" : "Kunhavo de %s malsukcesis, ĉar kunhavo per ligiloj ne permesatas",
+ "Sharing %s failed, because the user %s is the original sharer" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s estas la origina kunhaviginto",
+ "Sharing %s failed, because resharing is not allowed" : "Kunhavigo de %s malsukcesis, ĉar rekunhavigo ne permesatas",
"Could not find category \"%s\"" : "Ne troviĝis kategorio “%s”",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Nur la jenaj signoj permesatas en uzantonomo: «a-z», «A-Z», «0-9» kaj «_.@-»",
"A valid username must be provided" : "Valida uzantonomo devas proviziĝi",
"A valid password must be provided" : "Valida pasvorto devas proviziĝi",
"The username is already being used" : "La uzantonomo jam uzatas",
+ "Microsoft Windows Platform is not supported" : "La platformo Microsoft Vindozo ne kongruas",
+ "Cannot write into \"config\" directory" : "Ne skribeblas la dosierujo “config”",
+ "Cannot write into \"apps\" directory" : "Ne skribeblas la dosierujo “apps”",
+ "Cannot create \"data\" directory (%s)" : "Ne kreeblas la dosierujo “data” (%s)",
"Please ask your server administrator to install the module." : "Bonvolu peti vian sistemadministranton, ke ĝi instalu la modulon.",
"PHP module %s not installed." : "La PHP-modulo %s ne instalitas.",
- "PostgreSQL >= 9 required" : "PostgreSQL >= 9 necesas"
+ "Please ask your server administrator to restart the web server." : "Bonvolu peti viajn serviladministranton, ke ŝi/li reekfunkciigu la TTT-servilon.",
+ "PostgreSQL >= 9 required" : "PostgreSQL >= 9 necesas",
+ "Please upgrade your database version" : "Bonvolu ĝisdatigi la eldonon de via datumbazo",
+ "Error occurred while checking PostgreSQL version" : "Eraro okazis dum kontrolo de eldono de PostgreSQL",
+ "Data directory (%s) is readable by other users" : "Dosierujo de datumoj (%s) legeblas de aliaj uzantoj",
+ "Data directory (%s) must be an absolute path" : "Dosierujo de datumoj (%s) devas specifiĝi per absoluta vojo",
+ "Data directory (%s) is invalid" : "Dosierujo de datumoj (%s) ne validas"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/eo.json b/lib/l10n/eo.json
index 8b0ea2b6763..e7f8810e310 100644
--- a/lib/l10n/eo.json
+++ b/lib/l10n/eo.json
@@ -1,18 +1,31 @@
{ "translations": {
+ "Cannot write into \"config\" directory!" : "Ne skribeblas la dosierujo “config”!",
"See %s" : "Vidi %s",
"PHP %s or higher is required." : "PHP %s aŭ pli alta necesas.",
+ "PHP with a version lower than %s is required." : "Necesas pli malalta eldono de PHP ol %s.",
+ "Following databases are supported: %s" : "La jenan datumbazoj kongruas: %s",
+ "The command line tool %s could not be found" : "La komandolinia ilo %s ne troviĝis",
+ "The library %s is not available." : "La biblioteko %s ne haveblas.",
+ "ownCloud %s or higher is required." : "ownCloud %s aŭ pli alta necesas.",
+ "ownCloud with a version lower than %s is required." : "Eldono de ownCloud pli malalta ol %s necesas.",
"Help" : "Helpo",
"Personal" : "Persona",
"Users" : "Uzantoj",
"Admin" : "Administranto",
+ "Recommended" : "Rekomendata",
"Unknown filetype" : "Ne konatas dosiertipo",
"Invalid image" : "Ne validas bildo",
"today" : "hodiaŭ",
"yesterday" : "hieraŭ",
+ "_%n day ago_::_%n days ago_" : ["antaŭ %n tago","antaŭ %n tagoj"],
"last month" : "lastamonate",
"last year" : "lastajare",
+ "_%n year ago_::_%n years ago_" : ["antaŭ %n jaro","antaŭ %n jaroj"],
"seconds ago" : "sekundoj antaŭe",
"web services under your control" : "TTT-servoj regataj de vi",
+ "Empty filename is not allowed" : "Malplena dosiernomo ne permesatas",
+ "File name is too long" : "La dosiernomo tro longas",
+ "Can't read file" : "Ne legeblas dosiero",
"App directory already exists" : "La dosierujo de la aplikaĵo jam ekzistas",
"App does not provide an info.xml file" : "La aplikaĵo ne provizas dosieron info.xml",
"App can't be installed because it is not compatible with this version of ownCloud" : "La aplikaĵo ne povas instaliĝi ĉar ĝi ne kongruas kun ĉi tiu eldono de ownCloud",
@@ -33,15 +46,37 @@
"PostgreSQL username and/or password not valid" : "La uzantonomo de PostgreSQL aŭ la pasvorto ne validas",
"Set an admin username." : "Starigi administran uzantonomon.",
"Set an admin password." : "Starigi administran pasvorton.",
+ "Can't create or write into the data directory %s" : "Ne kreeblas aŭ ne skribeblas la dosierujo de datumoj %s",
"%s shared »%s« with you" : "%s kunhavigis “%s” kun vi",
+ "%s via %s" : "%s per %s",
+ "Sharing %s failed, because the file does not exist" : "Kunhavigo de %s malsukcesis, ĉar la dosiero ne ekzistas",
"You are not allowed to share %s" : "Vi ne permesatas kunhavigi %s",
+ "Sharing %s failed, because the user %s is the item owner" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s posedas la eron",
+ "Sharing %s failed, because the user %s does not exist" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s ne ekzistas",
+ "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s estas ano de neniu grupo, de kiu %s estas ano",
+ "Sharing %s failed, because this item is already shared with %s" : "Kunhavigo de %s malsukcesis, ĉar la ero jam kunhavatas kun %s",
+ "Sharing %s failed, because the group %s does not exist" : "Kunhavigo de %s malsukcesis, ĉar la grupo %s ne ekzistas",
+ "Sharing %s failed, because %s is not a member of the group %s" : "Kunhavigo de %s malsukcesis, ĉar %s ne estas ano de la grupo %s",
+ "Sharing %s failed, because sharing with links is not allowed" : "Kunhavo de %s malsukcesis, ĉar kunhavo per ligiloj ne permesatas",
+ "Sharing %s failed, because the user %s is the original sharer" : "Kunhavigo de %s malsukcesis, ĉar la uzanto %s estas la origina kunhaviginto",
+ "Sharing %s failed, because resharing is not allowed" : "Kunhavigo de %s malsukcesis, ĉar rekunhavigo ne permesatas",
"Could not find category \"%s\"" : "Ne troviĝis kategorio “%s”",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Nur la jenaj signoj permesatas en uzantonomo: «a-z», «A-Z», «0-9» kaj «_.@-»",
"A valid username must be provided" : "Valida uzantonomo devas proviziĝi",
"A valid password must be provided" : "Valida pasvorto devas proviziĝi",
"The username is already being used" : "La uzantonomo jam uzatas",
+ "Microsoft Windows Platform is not supported" : "La platformo Microsoft Vindozo ne kongruas",
+ "Cannot write into \"config\" directory" : "Ne skribeblas la dosierujo “config”",
+ "Cannot write into \"apps\" directory" : "Ne skribeblas la dosierujo “apps”",
+ "Cannot create \"data\" directory (%s)" : "Ne kreeblas la dosierujo “data” (%s)",
"Please ask your server administrator to install the module." : "Bonvolu peti vian sistemadministranton, ke ĝi instalu la modulon.",
"PHP module %s not installed." : "La PHP-modulo %s ne instalitas.",
- "PostgreSQL >= 9 required" : "PostgreSQL >= 9 necesas"
+ "Please ask your server administrator to restart the web server." : "Bonvolu peti viajn serviladministranton, ke ŝi/li reekfunkciigu la TTT-servilon.",
+ "PostgreSQL >= 9 required" : "PostgreSQL >= 9 necesas",
+ "Please upgrade your database version" : "Bonvolu ĝisdatigi la eldonon de via datumbazo",
+ "Error occurred while checking PostgreSQL version" : "Eraro okazis dum kontrolo de eldono de PostgreSQL",
+ "Data directory (%s) is readable by other users" : "Dosierujo de datumoj (%s) legeblas de aliaj uzantoj",
+ "Data directory (%s) must be an absolute path" : "Dosierujo de datumoj (%s) devas specifiĝi per absoluta vojo",
+ "Data directory (%s) is invalid" : "Dosierujo de datumoj (%s) ne validas"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index 8eb15106ed1..dfa41b3a6f3 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"],
"seconds ago" : "hace segundos",
"web services under your control" : "Servicios web bajo su control",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Módulo con ID: %s no existe. Por favor habilítelo en los ajustes de sus aplicaciones o contáctese con su administrador.",
"Empty filename is not allowed" : "No se puede dejar el nombre en blanco.",
"Dot files are not allowed" : "Los archivos Dot no están permitidos",
"4-byte characters are not supported in file names" : " No están permitidos caractéres de 4-bytes",
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index 81983ec11f4..de64cb113e3 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["Hace %n minuto","Hace %n minutos"],
"seconds ago" : "hace segundos",
"web services under your control" : "Servicios web bajo su control",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Módulo con ID: %s no existe. Por favor habilítelo en los ajustes de sus aplicaciones o contáctese con su administrador.",
"Empty filename is not allowed" : "No se puede dejar el nombre en blanco.",
"Dot files are not allowed" : "Los archivos Dot no están permitidos",
"4-byte characters are not supported in file names" : " No están permitidos caractéres de 4-bytes",
diff --git a/lib/l10n/fi_FI.js b/lib/l10n/fi_FI.js
index 28d4556cc12..9531d13a91b 100644
--- a/lib/l10n/fi_FI.js
+++ b/lib/l10n/fi_FI.js
@@ -37,6 +37,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["%n minuutti sitten","%n minuuttia sitten"],
"seconds ago" : "sekuntia sitten",
"web services under your control" : "verkkopalvelut hallinnassasi",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Moduulia tunnisteella %s ei ole olemassa. Ota se käyttöön sovellustesi asetuksista tai ota yhteys ylläpitoon.",
"Empty filename is not allowed" : "Tiedostonimi ei voi olla tyhjä",
"Dot files are not allowed" : "Pistetiedostot eivät ole sallittuja",
"4-byte characters are not supported in file names" : "4 tavun merkit eivät ole tuettuja tiedostojen nimissä",
diff --git a/lib/l10n/fi_FI.json b/lib/l10n/fi_FI.json
index d6842c69102..07a058fecd4 100644
--- a/lib/l10n/fi_FI.json
+++ b/lib/l10n/fi_FI.json
@@ -35,6 +35,7 @@
"_%n minute ago_::_%n minutes ago_" : ["%n minuutti sitten","%n minuuttia sitten"],
"seconds ago" : "sekuntia sitten",
"web services under your control" : "verkkopalvelut hallinnassasi",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Moduulia tunnisteella %s ei ole olemassa. Ota se käyttöön sovellustesi asetuksista tai ota yhteys ylläpitoon.",
"Empty filename is not allowed" : "Tiedostonimi ei voi olla tyhjä",
"Dot files are not allowed" : "Pistetiedostot eivät ole sallittuja",
"4-byte characters are not supported in file names" : "4 tavun merkit eivät ole tuettuja tiedostojen nimissä",
diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js
index 819a4a76be2..782573f40c8 100644
--- a/lib/l10n/fr.js
+++ b/lib/l10n/fr.js
@@ -37,6 +37,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["il y a %n minute","il y a %n minutes"],
"seconds ago" : "il y a quelques secondes",
"web services under your control" : "services web sous votre contrôle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Le module avec l'id: %s n'existe pas. Merci de l'activer dans les paramètres applications ou de contacter votre administrateur.",
"Empty filename is not allowed" : "Le nom de fichier ne peut pas être vide",
"Dot files are not allowed" : "Le nom de fichier ne peut pas commencer par un point",
"4-byte characters are not supported in file names" : "Les caractères sur 4 octets ne sont pas pris en charge dans les noms de fichiers",
diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json
index d0801954c1b..73da8da4361 100644
--- a/lib/l10n/fr.json
+++ b/lib/l10n/fr.json
@@ -35,6 +35,7 @@
"_%n minute ago_::_%n minutes ago_" : ["il y a %n minute","il y a %n minutes"],
"seconds ago" : "il y a quelques secondes",
"web services under your control" : "services web sous votre contrôle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Le module avec l'id: %s n'existe pas. Merci de l'activer dans les paramètres applications ou de contacter votre administrateur.",
"Empty filename is not allowed" : "Le nom de fichier ne peut pas être vide",
"Dot files are not allowed" : "Le nom de fichier ne peut pas commencer par un point",
"4-byte characters are not supported in file names" : "Les caractères sur 4 octets ne sont pas pris en charge dans les noms de fichiers",
diff --git a/lib/l10n/gl.js b/lib/l10n/gl.js
index cbb6914ddef..e90aa96d21b 100644
--- a/lib/l10n/gl.js
+++ b/lib/l10n/gl.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["hai %n minuto","hai %n minutos"],
"seconds ago" : "segundos atrás",
"web services under your control" : "servizos web baixo o seu control",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Non existe o módulo co ID: %s. Actíveo nos axustes de aplicacións ou contacte co administrador.",
"Empty filename is not allowed" : "Non está permitido deixar baleiro o nome de ficheiro",
"Dot files are not allowed" : "Non se admiten os ficheiros con punto",
"4-byte characters are not supported in file names" : "Non se admiten os caracteres de 4 bytes nos nomes de ficheiro",
diff --git a/lib/l10n/gl.json b/lib/l10n/gl.json
index 393eca2d9a1..e8c55d7451b 100644
--- a/lib/l10n/gl.json
+++ b/lib/l10n/gl.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["hai %n minuto","hai %n minutos"],
"seconds ago" : "segundos atrás",
"web services under your control" : "servizos web baixo o seu control",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Non existe o módulo co ID: %s. Actíveo nos axustes de aplicacións ou contacte co administrador.",
"Empty filename is not allowed" : "Non está permitido deixar baleiro o nome de ficheiro",
"Dot files are not allowed" : "Non se admiten os ficheiros con punto",
"4-byte characters are not supported in file names" : "Non se admiten os caracteres de 4 bytes nos nomes de ficheiro",
diff --git a/lib/l10n/it.js b/lib/l10n/it.js
index e16004cb95b..131a8e53109 100644
--- a/lib/l10n/it.js
+++ b/lib/l10n/it.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["%n minuto fa","%n minuti fa"],
"seconds ago" : "secondi fa",
"web services under your control" : "servizi web nelle tue mani",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Il modulo con id: %s non esiste. Abilitalo nelle impostazioni delle applicazioni o contatta il tuo amministratore.",
"Empty filename is not allowed" : "Un nome di file vuoto non è consentito",
"Dot files are not allowed" : "I file con un punto iniziale non sono consentiti",
"4-byte characters are not supported in file names" : "I caratteri di 4 byte non sono supportati nei nomi dei file",
diff --git a/lib/l10n/it.json b/lib/l10n/it.json
index 57f833529ef..9574dd52c97 100644
--- a/lib/l10n/it.json
+++ b/lib/l10n/it.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["%n minuto fa","%n minuti fa"],
"seconds ago" : "secondi fa",
"web services under your control" : "servizi web nelle tue mani",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Il modulo con id: %s non esiste. Abilitalo nelle impostazioni delle applicazioni o contatta il tuo amministratore.",
"Empty filename is not allowed" : "Un nome di file vuoto non è consentito",
"Dot files are not allowed" : "I file con un punto iniziale non sono consentiti",
"4-byte characters are not supported in file names" : "I caratteri di 4 byte non sono supportati nei nomi dei file",
diff --git a/lib/l10n/nb_NO.js b/lib/l10n/nb_NO.js
index 25503f21866..b433375eff6 100644
--- a/lib/l10n/nb_NO.js
+++ b/lib/l10n/nb_NO.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["for %n minutt siden","for %n minutter siden"],
"seconds ago" : "for få sekunder siden",
"web services under your control" : "webtjenester som du kontrollerer",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Modul med id: %s eksisterer ikke. Aktiver den i app-innstillingene eller kontakt en administrator.",
"Empty filename is not allowed" : "Tomt filnavn er ikke tillatt",
"Dot files are not allowed" : "Punktum-filer er ikke tillatt",
"4-byte characters are not supported in file names" : "4-byte tegn er ikke tillatt i filnavn",
diff --git a/lib/l10n/nb_NO.json b/lib/l10n/nb_NO.json
index e495dc5ac7b..6abcc9cf841 100644
--- a/lib/l10n/nb_NO.json
+++ b/lib/l10n/nb_NO.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["for %n minutt siden","for %n minutter siden"],
"seconds ago" : "for få sekunder siden",
"web services under your control" : "webtjenester som du kontrollerer",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Modul med id: %s eksisterer ikke. Aktiver den i app-innstillingene eller kontakt en administrator.",
"Empty filename is not allowed" : "Tomt filnavn er ikke tillatt",
"Dot files are not allowed" : "Punktum-filer er ikke tillatt",
"4-byte characters are not supported in file names" : "4-byte tegn er ikke tillatt i filnavn",
diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js
index 8e4c9660328..881ebcacbd7 100644
--- a/lib/l10n/nl.js
+++ b/lib/l10n/nl.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["%n minuut geleden","%n minuten geleden"],
"seconds ago" : "seconden geleden",
"web services under your control" : "Webdiensten in eigen beheer",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Module met id: %s bestaat niet. Activeer het in uw apps instellingen, of neem contact op met uw beheerder.",
"Empty filename is not allowed" : "Een lege bestandsnaam is niet toegestaan",
"Dot files are not allowed" : "Punt bestanden zijn niet toegestaan",
"4-byte characters are not supported in file names" : "4-byte tekens in bestandsnamen worden niet ondersteund",
diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json
index 4e22238c1a9..f3ba6080677 100644
--- a/lib/l10n/nl.json
+++ b/lib/l10n/nl.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["%n minuut geleden","%n minuten geleden"],
"seconds ago" : "seconden geleden",
"web services under your control" : "Webdiensten in eigen beheer",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Module met id: %s bestaat niet. Activeer het in uw apps instellingen, of neem contact op met uw beheerder.",
"Empty filename is not allowed" : "Een lege bestandsnaam is niet toegestaan",
"Dot files are not allowed" : "Punt bestanden zijn niet toegestaan",
"4-byte characters are not supported in file names" : "4-byte tekens in bestandsnamen worden niet ondersteund",
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index ffdbedb9660..a61e712bfa3 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -35,6 +35,7 @@ OC.L10N.register(
"_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"],
"seconds ago" : "segundos atrás",
"web services under your control" : "serviços web sob seu controle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Não existe módulo com id: %s. Por favor habilite na configuração de seus aplicativos ou faça contato com o seu administrador.",
"Empty filename is not allowed" : "Um nome de arquivo vazio não é permitido.",
"Dot files are not allowed" : "Dot arquivos não são permitidos",
"4-byte characters are not supported in file names" : "Caracteres de 4-bytes não são suportados em nomes de arquivos",
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index 50f61e2a627..3278a3e070d 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -33,6 +33,7 @@
"_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"],
"seconds ago" : "segundos atrás",
"web services under your control" : "serviços web sob seu controle",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Não existe módulo com id: %s. Por favor habilite na configuração de seus aplicativos ou faça contato com o seu administrador.",
"Empty filename is not allowed" : "Um nome de arquivo vazio não é permitido.",
"Dot files are not allowed" : "Dot arquivos não são permitidos",
"4-byte characters are not supported in file names" : "Caracteres de 4-bytes não são suportados em nomes de arquivos",
diff --git a/lib/l10n/sr.js b/lib/l10n/sr.js
index 0fb893092b2..7cfd77e9285 100644
--- a/lib/l10n/sr.js
+++ b/lib/l10n/sr.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"_%n minute ago_::_%n minutes ago_" : ["пре %n минут","пре %n минута","пре %n минута"],
"seconds ago" : "пре неколико секунди",
"web services under your control" : "веб сервиси под вашом контролом",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Модул ИД-а: %s не постоји. Укључите га у поставкама апликација или контактирајте вашег администратора.",
"Empty filename is not allowed" : "Празан назив није дозвољен",
"Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени",
"4-byte characters are not supported in file names" : "4-бајтни знакови нису подржани у називу фајлова",
@@ -49,10 +50,10 @@ OC.L10N.register(
"Can't create app folder. Please fix permissions. %s" : "Не могу да креирам фасциклу за апликацију. Исправите дозволе. %s",
"No source specified when installing app" : "Није наведен извор за инсталирање апликације",
"No href specified when installing app from http" : "Није наведена адреса за инсталирање апликације преко http",
- "No path specified when installing app from local file" : "Није наведена путања за инсталирање апликације преко локалне датотеке",
+ "No path specified when installing app from local file" : "Није наведена путања за инсталирање апликације са локалног фајла",
"Archives of type %s are not supported" : "%s архиве нису подржане",
"Failed to open archive when installing app" : "Неуспешно отварање архиве приликом инсталације апликације",
- "App does not provide an info.xml file" : "Апликација не поседује info.xml датотеку",
+ "App does not provide an info.xml file" : "Апликација не поседује info.xml фајл",
"App can't be installed because of not allowed code in the App" : "Апликације не може бити инсталирана због недозвољеног кода у апликацији",
"App can't be installed because it is not compatible with this version of ownCloud" : "Апликације не може бити инсталирана јер није компатибилна са овом верзијом оунКлауда",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "Апликација се не може инсталирати јер садржи ознаку <shipped>тачно</shipped> која није дозвољена за неиспоручене апликације",
@@ -64,9 +65,9 @@ OC.L10N.register(
"%s enter the database username." : "%s унеси корисничко име базе података.",
"%s enter the database name." : "%s унеси име базе података.",
"%s you may not use dots in the database name" : "%s не можете користити тачке у имену базе података",
- "MS SQL username and/or password not valid: %s" : "MS SQL корисничко име и/или лозинка нису важећи: %s",
+ "MS SQL username and/or password not valid: %s" : "MS SQL корисничко име и/или лозинка нису исправни: %s",
"You need to enter either an existing account or the administrator." : "Потребно је да унесете или постојећи налог или администраторски.",
- "MySQL/MariaDB username and/or password not valid" : "MySQL/MariaDB корисничко име и/или лозинка нису важећи",
+ "MySQL/MariaDB username and/or password not valid" : "MySQL/MariaDB корисничко име и/или лозинка нису исправни",
"DB Error: \"%s\"" : "Грешка базе података: \"%s\"",
"Offending command was: \"%s\"" : "Неисправна команда је: „%s“",
"MySQL/MariaDB user '%s'@'localhost' exists already." : "MySQL/MariaDB корисник '%s'@'localhost' већ постоји.",
@@ -74,9 +75,9 @@ OC.L10N.register(
"MySQL/MariaDB user '%s'@'%%' already exists" : "MySQL/MariaDB корисник '%s'@'%%' већ постоји",
"Drop this user from MySQL/MariaDB." : "Обришите овог корисника из MySQL/MariaDB.",
"Oracle connection could not be established" : "Веза са базом података Oracle не може бити успостављена",
- "Oracle username and/or password not valid" : "Oracle корисничко име и/или лозинка нису важећи",
+ "Oracle username and/or password not valid" : "Oracle корисничко име и/или лозинка нису исправни",
"Offending command was: \"%s\", name: %s, password: %s" : "Неисправна команда је: „%s“, назив: %s, лозинка: %s",
- "PostgreSQL username and/or password not valid" : "PostgreSQL корисничко име и/или лозинка нису важећи",
+ "PostgreSQL username and/or password not valid" : "PostgreSQL корисничко име и/или лозинка нису исправни",
"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Мек ОС Икс није подржан и %s неће радити исправно на овој платформи. Користите га на сопствени ризик!",
"For the best results, please consider using a GNU/Linux server instead." : "За најбоље резултате, размотрите употребу ГНУ/Линукс сервера.",
"It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Изгледа да %s ради у 32-битном ПХП окружењу а open_basedir је подешен у php.ini фајлу. То може довести до проблема са фајловима већим од 4 GB те стога није препоручљиво.",
@@ -87,7 +88,7 @@ OC.L10N.register(
"%s shared »%s« with you" : "%s подели „%s“ са вама",
"%s via %s" : "%s путем %s",
"Sharing %s failed, because the backend does not allow shares from type %i" : "Дељење %s није успело зато што поздина не дозвољава дељење од типа %i",
- "Sharing %s failed, because the file does not exist" : "Дељење %s није успело зато што датотека не постоји",
+ "Sharing %s failed, because the file does not exist" : "Дељење %s није успело зато што фајл не постоји",
"You are not allowed to share %s" : "Није вам дозвољено да делите %s",
"Sharing %s failed, because the user %s is the item owner" : "Дељење %s није успело зато што је корисник %s власник дељене ставке",
"Sharing %s failed, because the user %s does not exist" : "Дељење %s није успело зато што не постоји корисник %s",
@@ -98,7 +99,7 @@ OC.L10N.register(
"You need to provide a password to create a public link, only protected links are allowed" : "Морате да обезбедите лозинку за креирање јавне везе, дозвољене су само заштићене везе",
"Sharing %s failed, because sharing with links is not allowed" : "Дељење %s није успело зато што дељење са везама није дозвољено",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Дељење %s није успело, није могуће пронаћи %s, можда сервер тренутно није доступан.",
- "Share type %s is not valid for %s" : "Тип датотека за дељење %s није валидан за %s",
+ "Share type %s is not valid for %s" : "Тип фајла за дељење %s није исправан за %s",
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Постављање дозвола за %s није успело зато што дозволе превазилазе дозволе гарантоване за %s",
"Setting permissions for %s failed, because the item was not found" : "Постављање дозвола за %s није успело зато што ставка није пронађена",
"Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Не могу поставити датум трајања. Дељења не могу истицати касније од %s пошто су активирана",
@@ -111,7 +112,7 @@ OC.L10N.register(
"Sharing %s failed, because the permissions exceed permissions granted to %s" : "Дељење %s није успело зато што дозволе превазилазе дозволе гарантоване за %s",
"Sharing %s failed, because resharing is not allowed" : "Дељење %s није успело зато што даље дељење није дозвољено",
"Sharing %s failed, because the sharing backend for %s could not find its source" : "Дељење %s није успело зато што позадина дељења за %s није могла да нађе извор",
- "Sharing %s failed, because the file could not be found in the file cache" : "Дељење %s није успело, зато што датотека не може бити пронађена у кешу датотека",
+ "Sharing %s failed, because the file could not be found in the file cache" : "Дељење %s није успело зато што фајл није нађен у кешу фајлова",
"Could not find category \"%s\"" : "Не могу да пронађем категорију „%s“.",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Само су следећи знакови дозвољени за корисничко име: „a-z“, „A-Z“, „0-9“ и „_.@-“",
"A valid username must be provided" : "Морате унети исправно корисничко име",
@@ -134,6 +135,7 @@ OC.L10N.register(
"Adjusting this setting in php.ini will make ownCloud run again" : "Подешавање ове поставке у php.ini фајлу ће омогућити да оунКлауд поново ради",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload је постављено на „%s“ уместо на очекивану вредност „0“",
"To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Да би решили овај проблем поставите <code>mbstring.func_overload</code> на <code>0</code> у фајлу php.ini",
+ "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "ПХП је очигледно подешен да скида уметнуте doc блокове. То ће учинити неколико кључних апликација недоступним.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Ово је вероватно изазвано кешом или акцелератором као што су ЗендОПкеш или еАкцелератор.",
"PHP modules have been installed, but they are still listed as missing?" : "ПХП модули су инсталирани али се и даље воде као недостајући?",
"Please ask your server administrator to restart the web server." : "Замолите вашег администратора сервера да поново покрене веб сервер.",
diff --git a/lib/l10n/sr.json b/lib/l10n/sr.json
index bb37abe0ee6..f42b4303ed9 100644
--- a/lib/l10n/sr.json
+++ b/lib/l10n/sr.json
@@ -36,6 +36,7 @@
"_%n minute ago_::_%n minutes ago_" : ["пре %n минут","пре %n минута","пре %n минута"],
"seconds ago" : "пре неколико секунди",
"web services under your control" : "веб сервиси под вашом контролом",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Модул ИД-а: %s не постоји. Укључите га у поставкама апликација или контактирајте вашег администратора.",
"Empty filename is not allowed" : "Празан назив није дозвољен",
"Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени",
"4-byte characters are not supported in file names" : "4-бајтни знакови нису подржани у називу фајлова",
@@ -47,10 +48,10 @@
"Can't create app folder. Please fix permissions. %s" : "Не могу да креирам фасциклу за апликацију. Исправите дозволе. %s",
"No source specified when installing app" : "Није наведен извор за инсталирање апликације",
"No href specified when installing app from http" : "Није наведена адреса за инсталирање апликације преко http",
- "No path specified when installing app from local file" : "Није наведена путања за инсталирање апликације преко локалне датотеке",
+ "No path specified when installing app from local file" : "Није наведена путања за инсталирање апликације са локалног фајла",
"Archives of type %s are not supported" : "%s архиве нису подржане",
"Failed to open archive when installing app" : "Неуспешно отварање архиве приликом инсталације апликације",
- "App does not provide an info.xml file" : "Апликација не поседује info.xml датотеку",
+ "App does not provide an info.xml file" : "Апликација не поседује info.xml фајл",
"App can't be installed because of not allowed code in the App" : "Апликације не може бити инсталирана због недозвољеног кода у апликацији",
"App can't be installed because it is not compatible with this version of ownCloud" : "Апликације не може бити инсталирана јер није компатибилна са овом верзијом оунКлауда",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "Апликација се не може инсталирати јер садржи ознаку <shipped>тачно</shipped> која није дозвољена за неиспоручене апликације",
@@ -62,9 +63,9 @@
"%s enter the database username." : "%s унеси корисничко име базе података.",
"%s enter the database name." : "%s унеси име базе података.",
"%s you may not use dots in the database name" : "%s не можете користити тачке у имену базе података",
- "MS SQL username and/or password not valid: %s" : "MS SQL корисничко име и/или лозинка нису важећи: %s",
+ "MS SQL username and/or password not valid: %s" : "MS SQL корисничко име и/или лозинка нису исправни: %s",
"You need to enter either an existing account or the administrator." : "Потребно је да унесете или постојећи налог или администраторски.",
- "MySQL/MariaDB username and/or password not valid" : "MySQL/MariaDB корисничко име и/или лозинка нису важећи",
+ "MySQL/MariaDB username and/or password not valid" : "MySQL/MariaDB корисничко име и/или лозинка нису исправни",
"DB Error: \"%s\"" : "Грешка базе података: \"%s\"",
"Offending command was: \"%s\"" : "Неисправна команда је: „%s“",
"MySQL/MariaDB user '%s'@'localhost' exists already." : "MySQL/MariaDB корисник '%s'@'localhost' већ постоји.",
@@ -72,9 +73,9 @@
"MySQL/MariaDB user '%s'@'%%' already exists" : "MySQL/MariaDB корисник '%s'@'%%' већ постоји",
"Drop this user from MySQL/MariaDB." : "Обришите овог корисника из MySQL/MariaDB.",
"Oracle connection could not be established" : "Веза са базом података Oracle не може бити успостављена",
- "Oracle username and/or password not valid" : "Oracle корисничко име и/или лозинка нису важећи",
+ "Oracle username and/or password not valid" : "Oracle корисничко име и/или лозинка нису исправни",
"Offending command was: \"%s\", name: %s, password: %s" : "Неисправна команда је: „%s“, назив: %s, лозинка: %s",
- "PostgreSQL username and/or password not valid" : "PostgreSQL корисничко име и/или лозинка нису важећи",
+ "PostgreSQL username and/or password not valid" : "PostgreSQL корисничко име и/или лозинка нису исправни",
"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Мек ОС Икс није подржан и %s неће радити исправно на овој платформи. Користите га на сопствени ризик!",
"For the best results, please consider using a GNU/Linux server instead." : "За најбоље резултате, размотрите употребу ГНУ/Линукс сервера.",
"It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Изгледа да %s ради у 32-битном ПХП окружењу а open_basedir је подешен у php.ini фајлу. То може довести до проблема са фајловима већим од 4 GB те стога није препоручљиво.",
@@ -85,7 +86,7 @@
"%s shared »%s« with you" : "%s подели „%s“ са вама",
"%s via %s" : "%s путем %s",
"Sharing %s failed, because the backend does not allow shares from type %i" : "Дељење %s није успело зато што поздина не дозвољава дељење од типа %i",
- "Sharing %s failed, because the file does not exist" : "Дељење %s није успело зато што датотека не постоји",
+ "Sharing %s failed, because the file does not exist" : "Дељење %s није успело зато што фајл не постоји",
"You are not allowed to share %s" : "Није вам дозвољено да делите %s",
"Sharing %s failed, because the user %s is the item owner" : "Дељење %s није успело зато што је корисник %s власник дељене ставке",
"Sharing %s failed, because the user %s does not exist" : "Дељење %s није успело зато што не постоји корисник %s",
@@ -96,7 +97,7 @@
"You need to provide a password to create a public link, only protected links are allowed" : "Морате да обезбедите лозинку за креирање јавне везе, дозвољене су само заштићене везе",
"Sharing %s failed, because sharing with links is not allowed" : "Дељење %s није успело зато што дељење са везама није дозвољено",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Дељење %s није успело, није могуће пронаћи %s, можда сервер тренутно није доступан.",
- "Share type %s is not valid for %s" : "Тип датотека за дељење %s није валидан за %s",
+ "Share type %s is not valid for %s" : "Тип фајла за дељење %s није исправан за %s",
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Постављање дозвола за %s није успело зато што дозволе превазилазе дозволе гарантоване за %s",
"Setting permissions for %s failed, because the item was not found" : "Постављање дозвола за %s није успело зато што ставка није пронађена",
"Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Не могу поставити датум трајања. Дељења не могу истицати касније од %s пошто су активирана",
@@ -109,7 +110,7 @@
"Sharing %s failed, because the permissions exceed permissions granted to %s" : "Дељење %s није успело зато што дозволе превазилазе дозволе гарантоване за %s",
"Sharing %s failed, because resharing is not allowed" : "Дељење %s није успело зато што даље дељење није дозвољено",
"Sharing %s failed, because the sharing backend for %s could not find its source" : "Дељење %s није успело зато што позадина дељења за %s није могла да нађе извор",
- "Sharing %s failed, because the file could not be found in the file cache" : "Дељење %s није успело, зато што датотека не може бити пронађена у кешу датотека",
+ "Sharing %s failed, because the file could not be found in the file cache" : "Дељење %s није успело зато што фајл није нађен у кешу фајлова",
"Could not find category \"%s\"" : "Не могу да пронађем категорију „%s“.",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Само су следећи знакови дозвољени за корисничко име: „a-z“, „A-Z“, „0-9“ и „_.@-“",
"A valid username must be provided" : "Морате унети исправно корисничко име",
@@ -132,6 +133,7 @@
"Adjusting this setting in php.ini will make ownCloud run again" : "Подешавање ове поставке у php.ini фајлу ће омогућити да оунКлауд поново ради",
"mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload је постављено на „%s“ уместо на очекивану вредност „0“",
"To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Да би решили овај проблем поставите <code>mbstring.func_overload</code> на <code>0</code> у фајлу php.ini",
+ "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "ПХП је очигледно подешен да скида уметнуте doc блокове. То ће учинити неколико кључних апликација недоступним.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Ово је вероватно изазвано кешом или акцелератором као што су ЗендОПкеш или еАкцелератор.",
"PHP modules have been installed, but they are still listed as missing?" : "ПХП модули су инсталирани али се и даље воде као недостајући?",
"Please ask your server administrator to restart the web server." : "Замолите вашег администратора сервера да поново покрене веб сервер.",
diff --git a/lib/l10n/uk.js b/lib/l10n/uk.js
index 0c6324ff041..8b209470ec3 100644
--- a/lib/l10n/uk.js
+++ b/lib/l10n/uk.js
@@ -35,6 +35,7 @@ OC.L10N.register(
"_%n year ago_::_%n years ago_" : ["%n рік тому","%n років тому","%n років тому"],
"seconds ago" : "секунди тому",
"web services under your control" : "підконтрольні Вам веб-сервіси",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Модуль з id: %s не існує. Будь ласка, увімкніть його в налаштуваннях програми або зверніться до адміністратора.",
"Empty filename is not allowed" : "Порожні імена файлів не допускаються",
"Dot files are not allowed" : "Файли які починаються з крапки не допустимі",
"4-byte characters are not supported in file names" : "4-х байтові символи в імені файлів не допустимі",
diff --git a/lib/l10n/uk.json b/lib/l10n/uk.json
index e4b6b053dbc..7126dec178d 100644
--- a/lib/l10n/uk.json
+++ b/lib/l10n/uk.json
@@ -33,6 +33,7 @@
"_%n year ago_::_%n years ago_" : ["%n рік тому","%n років тому","%n років тому"],
"seconds ago" : "секунди тому",
"web services under your control" : "підконтрольні Вам веб-сервіси",
+ "Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator." : "Модуль з id: %s не існує. Будь ласка, увімкніть його в налаштуваннях програми або зверніться до адміністратора.",
"Empty filename is not allowed" : "Порожні імена файлів не допускаються",
"Dot files are not allowed" : "Файли які починаються з крапки не допустимі",
"4-byte characters are not supported in file names" : "4-х байтові символи в імені файлів не допустимі",
diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php
index c568873bb46..e8915b47f24 100644
--- a/lib/private/backgroundjob/joblist.php
+++ b/lib/private/backgroundjob/joblist.php
@@ -172,9 +172,6 @@ class JobList implements IJobList {
/**
* @var Job $job
*/
- if ($class === 'OC_Cache_FileGlobalGC') {
- $class = '\OC\Cache\FileGlobalGC';
- }
if (!class_exists($class)) {
// job from disabled app or old version of an app, no need to do anything
return null;
diff --git a/lib/private/cache.php b/lib/private/cache.php
deleted file mode 100644
index 095a1ddcd4d..00000000000
--- a/lib/private/cache.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-/**
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Thomas Tanghus <thomas@tanghus.net>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC;
-
-class Cache {
- /**
- * @var Cache $user_cache
- */
- static protected $user_cache;
- /**
- * @var Cache $global_cache
- */
- static protected $global_cache;
-
- /**
- * get the global cache
- * @return Cache
- */
- static public function getGlobalCache() {
- if (!self::$global_cache) {
- self::$global_cache = new Cache\FileGlobal();
- }
- return self::$global_cache;
- }
-
- /**
- * get the user cache
- * @return Cache
- */
- static public function getUserCache() {
- if (!self::$user_cache) {
- self::$user_cache = new Cache\File();
- }
- return self::$user_cache;
- }
-
- /**
- * get a value from the user cache
- * @param string $key
- * @return mixed
- */
- static public function get($key) {
- $user_cache = self::getUserCache();
- return $user_cache->get($key);
- }
-
- /**
- * set a value in the user cache
- * @param string $key
- * @param mixed $value
- * @param int $ttl
- * @return bool
- */
- static public function set($key, $value, $ttl=0) {
- if (empty($key)) {
- return false;
- }
- $user_cache = self::getUserCache();
- return $user_cache->set($key, $value, $ttl);
- }
-
- /**
- * check if a value is set in the user cache
- * @param string $key
- * @return bool
- */
- static public function hasKey($key) {
- $user_cache = self::getUserCache();
- return $user_cache->hasKey($key);
- }
-
- /**
- * remove an item from the user cache
- * @param string $key
- * @return bool
- */
- static public function remove($key) {
- $user_cache = self::getUserCache();
- return $user_cache->remove($key);
- }
-
- /**
- * clear the user cache of all entries starting with a prefix
- * @param string $prefix (optional)
- * @return bool
- */
- static public function clear($prefix='') {
- $user_cache = self::getUserCache();
- return $user_cache->clear($prefix);
- }
-
- /**
- * creates cache key based on the files given
- * @param string[] $files
- * @return string
- */
- static public function generateCacheKeyFromFiles($files) {
- $key = '';
- sort($files);
- foreach($files as $file) {
- $stat = stat($file);
- $key .= $file.$stat['mtime'].$stat['size'];
- }
- return md5($key);
- }
-}
diff --git a/lib/private/cache/broker.php b/lib/private/cache/broker.php
deleted file mode 100644
index a52fb220f00..00000000000
--- a/lib/private/cache/broker.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/**
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Thomas Tanghus <thomas@tanghus.net>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Cache;
-
-class Broker {
-
- /**
- * @var \OC\Cache
- */
- protected $fast_cache;
-
- /**
- * @var \OC\Cache
- */
- protected $slow_cache;
-
- public function __construct($fast_cache, $slow_cache) {
- $this->fast_cache = $fast_cache;
- $this->slow_cache = $slow_cache;
- }
-
- public function get($key) {
- if ($r = $this->fast_cache->get($key)) {
- return $r;
- }
- return $this->slow_cache->get($key);
- }
-
- public function set($key, $value, $ttl=0) {
- if (!$this->fast_cache->set($key, $value, $ttl)) {
- if ($this->fast_cache->hasKey($key)) {
- $this->fast_cache->remove($key);
- }
- return $this->slow_cache->set($key, $value, $ttl);
- }
- return true;
- }
-
- public function hasKey($key) {
- if ($this->fast_cache->hasKey($key)) {
- return true;
- }
- return $this->slow_cache->hasKey($key);
- }
-
- public function remove($key) {
- if ($this->fast_cache->remove($key)) {
- return true;
- }
- return $this->slow_cache->remove($key);
- }
-
- public function clear($prefix='') {
- $this->fast_cache->clear($prefix);
- $this->slow_cache->clear($prefix);
- }
-}
diff --git a/lib/private/cache/file.php b/lib/private/cache/file.php
deleted file mode 100644
index c70698eb7f8..00000000000
--- a/lib/private/cache/file.php
+++ /dev/null
@@ -1,174 +0,0 @@
-<?php
-/**
- * @author Arthur Schiwon <blizzz@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Thomas Tanghus <thomas@tanghus.net>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Cache;
-
-use OC\Files\Filesystem;
-use OC\Files\View;
-use OCP\Security\ISecureRandom;
-
-class File {
- protected $storage;
-
- /**
- * Returns the cache storage for the logged in user
- *
- * @return \OC\Files\View cache storage
- */
- protected function getStorage() {
- if (isset($this->storage)) {
- return $this->storage;
- }
- if (\OC_User::isLoggedIn()) {
- $rootView = new View();
- $user = \OC::$server->getUserSession()->getUser();
- Filesystem::initMountPoints($user->getUID());
- if (!$rootView->file_exists('/' . $user->getUID() . '/cache')) {
- $rootView->mkdir('/' . $user->getUID() . '/cache');
- }
- $this->storage = new View('/' . $user->getUID() . '/cache');
- return $this->storage;
- } else {
- \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR);
- throw new \OC\ForbiddenException('Can\t get cache storage, user not logged in');
- }
- }
-
- /**
- * @param string $key
- */
- public function get($key) {
- $result = null;
- if ($this->hasKey($key)) {
- $storage = $this->getStorage();
- $result = $storage->file_get_contents($key);
- }
- return $result;
- }
-
- /**
- * Returns the size of the stored/cached data
- *
- * @param string $key
- * @return int
- */
- public function size($key) {
- $result = 0;
- if ($this->hasKey($key)) {
- $storage = $this->getStorage();
- $result = $storage->filesize($key);
- }
- return $result;
- }
-
- /**
- * @param string $key
- */
- public function set($key, $value, $ttl = 0) {
- $storage = $this->getStorage();
- $result = false;
- // unique id to avoid chunk collision, just in case
- $uniqueId = \OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate(
- 16,
- ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER
- );
-
- // use part file to prevent hasKey() to find the key
- // while it is being written
- $keyPart = $key . '.' . $uniqueId . '.part';
- if ($storage and $storage->file_put_contents($keyPart, $value)) {
- if ($ttl === 0) {
- $ttl = 86400; // 60*60*24
- }
- $result = $storage->touch($keyPart, time() + $ttl);
- $result &= $storage->rename($keyPart, $key);
- }
- return $result;
- }
-
- public function hasKey($key) {
- $storage = $this->getStorage();
- if ($storage && $storage->is_file($key) && $storage->isReadable($key)) {
- return true;
- }
- return false;
- }
-
- /**
- * @param string $key
- */
- public function remove($key) {
- $storage = $this->getStorage();
- if (!$storage) {
- return false;
- }
- return $storage->unlink($key);
- }
-
- public function clear($prefix = '') {
- $storage = $this->getStorage();
- if ($storage and $storage->is_dir('/')) {
- $dh = $storage->opendir('/');
- if (is_resource($dh)) {
- while (($file = readdir($dh)) !== false) {
- if ($file != '.' and $file != '..' and ($prefix === '' || strpos($file, $prefix) === 0)) {
- $storage->unlink('/' . $file);
- }
- }
- }
- }
- return true;
- }
-
- public function gc() {
- $storage = $this->getStorage();
- if ($storage and $storage->is_dir('/')) {
- $now = time();
- $dh = $storage->opendir('/');
- if (!is_resource($dh)) {
- return null;
- }
- while (($file = readdir($dh)) !== false) {
- if ($file != '.' and $file != '..') {
- $mtime = $storage->filemtime('/' . $file);
- if ($mtime < $now) {
- $storage->unlink('/' . $file);
- }
- }
- }
- }
- }
-
- public static function loginListener() {
- $c = new self();
- $c->gc();
- }
-}
diff --git a/lib/private/cache/fileglobal.php b/lib/private/cache/fileglobal.php
deleted file mode 100644
index b808c0dd8ff..00000000000
--- a/lib/private/cache/fileglobal.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-/**
- * @author Arthur Schiwon <blizzz@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Thomas Tanghus <thomas@tanghus.net>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Cache;
-
-class FileGlobal {
- static protected function getCacheDir() {
- $cache_dir = get_temp_dir().'/owncloud-' . \OC_Util::getInstanceId().'/';
- if (!is_dir($cache_dir)) {
- mkdir($cache_dir);
- }
- return $cache_dir;
- }
-
- protected function fixKey($key) {
- return str_replace('/', '_', $key);
- }
-
- /**
- * @param string $key
- */
- public function get($key) {
- $key = $this->fixKey($key);
- if ($this->hasKey($key)) {
- $cache_dir = self::getCacheDir();
- return file_get_contents($cache_dir.$key);
- }
- return null;
- }
-
- /**
- * @param string $key
- * @param string $value
- */
- public function set($key, $value, $ttl=0) {
- $key = $this->fixKey($key);
- $cache_dir = self::getCacheDir();
- if ($cache_dir and file_put_contents($cache_dir.$key, $value)) {
- if ($ttl === 0) {
- $ttl = 86400; // 60*60*24
- }
- return touch($cache_dir.$key, time() + $ttl);
- }
- return false;
- }
-
- public function hasKey($key) {
- $key = $this->fixKey($key);
- $cache_dir = self::getCacheDir();
- if ($cache_dir && is_file($cache_dir.$key) && is_readable($cache_dir.$key)) {
- $mtime = filemtime($cache_dir.$key);
- if ($mtime < time()) {
- unlink($cache_dir.$key);
- return false;
- }
- return true;
- }
- return false;
- }
-
- public function remove($key) {
- $cache_dir = self::getCacheDir();
- if(!$cache_dir) {
- return false;
- }
- $key = $this->fixKey($key);
- return unlink($cache_dir.$key);
- }
-
- public function clear($prefix='') {
- $cache_dir = self::getCacheDir();
- $prefix = $this->fixKey($prefix);
- if($cache_dir and is_dir($cache_dir)) {
- $dh=opendir($cache_dir);
- if(is_resource($dh)) {
- while (($file = readdir($dh)) !== false) {
- if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)) {
- unlink($cache_dir.$file);
- }
- }
- }
- }
- }
-}
diff --git a/lib/private/cache/fileglobalgc.php b/lib/private/cache/fileglobalgc.php
deleted file mode 100644
index 0d966282383..00000000000
--- a/lib/private/cache/fileglobalgc.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
- * @author Thomas Tanghus <thomas@tanghus.net>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-namespace OC\Cache;
-
-use OC\BackgroundJob\Job;
-use OCP\IConfig;
-
-class FileGlobalGC extends Job {
- // only do cleanup every 5 minutes
- const CLEANUP_TTL_SEC = 300;
-
- public function run($argument) {
- $this->gc(\OC::$server->getConfig(), $this->getCacheDir());
- }
-
- protected function getCacheDir() {
- return get_temp_dir() . '/owncloud-' . \OC_Util::getInstanceId() . '/';
- }
-
- /**
- * @param string $cacheDir
- * @param int $now
- * @return string[]
- */
- public function getExpiredPaths($cacheDir, $now) {
- $files = scandir($cacheDir);
- $files = array_filter($files, function ($file) {
- return $file != '.' and $file != '..';
- });
- $paths = array_map(function ($file) use ($cacheDir) {
- return $cacheDir . $file;
- }, $files);
- return array_values(array_filter($paths, function ($path) use ($now) {
- return is_file($path) and (filemtime($path) < $now);
- }));
- }
-
- /**
- * @param \OCP\IConfig $config
- * @param string $cacheDir
- */
- public function gc(IConfig $config, $cacheDir) {
- $lastRun = $config->getAppValue('core', 'global_cache_gc_lastrun', 0);
- $now = time();
- if (($now - $lastRun) < self::CLEANUP_TTL_SEC) {
- return;
- }
- $config->setAppValue('core', 'global_cache_gc_lastrun', $now);
- if (!is_dir($cacheDir)) {
- return;
- }
- $paths = $this->getExpiredPaths($cacheDir, $now);
- array_walk($paths, function($file) {
- if (file_exists($file)) {
- unlink($file);
- }
- });
- }
-}
diff --git a/lib/private/cache/usercache.php b/lib/private/cache/usercache.php
deleted file mode 100644
index bbf5b7eda69..00000000000
--- a/lib/private/cache/usercache.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Scrutinizer Auto-Fixer <auto-fixer@scrutinizer-ci.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Thomas Tanghus <thomas@tanghus.net>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-namespace OC\Cache;
-
-/**
- * This interface defines method for accessing the file based user cache.
- */
-class UserCache implements \OCP\ICache {
-
- /**
- * @var \OC\Cache\File $userCache
- */
- protected $userCache;
-
- public function __construct() {
- $this->userCache = new File();
- }
-
- /**
- * Get a value from the user cache
- *
- * @param string $key
- * @return mixed
- */
- public function get($key) {
- return $this->userCache->get($key);
- }
-
- /**
- * Set a value in the user cache
- *
- * @param string $key
- * @param string $value
- * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
- * @return bool
- */
- public function set($key, $value, $ttl = 0) {
- if (empty($key)) {
- return false;
- }
- return $this->userCache->set($key, $value, $ttl);
- }
-
- /**
- * Check if a value is set in the user cache
- *
- * @param string $key
- * @return bool
- */
- public function hasKey($key) {
- return $this->userCache->hasKey($key);
- }
-
- /**
- * Remove an item from the user cache
- *
- * @param string $key
- * @return bool
- */
- public function remove($key) {
- return $this->userCache->remove($key);
- }
-
- /**
- * clear the user cache of all entries starting with a prefix
- * @param string $prefix (optional)
- * @return bool
- */
- public function clear($prefix = '') {
- return $this->userCache->clear($prefix);
- }
-}
diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index 67fdbb28dea..82e1b55d763 100644
--- a/lib/private/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -27,6 +27,10 @@
*/
namespace OC\Connector\Sabre;
+use OC\Connector\Sabre\Exception\InvalidPath;
+use OC\Connector\Sabre\Exception\FileLocked;
+use OCP\Lock\LockedException;
+
class Directory extends \OC\Connector\Sabre\Node
implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota {
@@ -91,6 +95,8 @@ class Directory extends \OC\Connector\Sabre\Node
}
}
+ $this->fileView->verifyPath($this->path, $name);
+
$path = $this->fileView->getAbsolutePath($this->path) . '/' . $name;
// using a dummy FileInfo is acceptable here since it will be refreshed after the put is complete
$info = new \OC\Files\FileInfo($path, null, null, array(), null);
@@ -98,6 +104,8 @@ class Directory extends \OC\Connector\Sabre\Node
return $node->put($data);
} catch (\OCP\Files\StorageNotAvailableException $e) {
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
}
@@ -114,12 +122,17 @@ class Directory extends \OC\Connector\Sabre\Node
throw new \Sabre\DAV\Exception\Forbidden();
}
+ $this->fileView->verifyPath($this->path, $name);
$newPath = $this->path . '/' . $name;
if (!$this->fileView->mkdir($newPath)) {
throw new \Sabre\DAV\Exception\Forbidden('Could not create directory ' . $newPath);
}
} catch (\OCP\Files\StorageNotAvailableException $e) {
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
+ } catch (\OCP\Files\InvalidPathException $ex) {
+ throw new InvalidPath($ex->getMessage());
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
}
@@ -204,11 +217,14 @@ class Directory extends \OC\Connector\Sabre\Node
throw new \Sabre\DAV\Exception\Forbidden();
}
- if (!$this->fileView->rmdir($this->path)) {
- // assume it wasn't possible to remove due to permission issue
- throw new \Sabre\DAV\Exception\Forbidden();
+ try {
+ if (!$this->fileView->rmdir($this->path)) {
+ // assume it wasn't possible to remove due to permission issue
+ throw new \Sabre\DAV\Exception\Forbidden();
+ }
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
-
}
/**
diff --git a/lib/private/connector/sabre/exception/filelocked.php b/lib/private/connector/sabre/exception/filelocked.php
index 2405059bfb1..1657a7ae376 100644
--- a/lib/private/connector/sabre/exception/filelocked.php
+++ b/lib/private/connector/sabre/exception/filelocked.php
@@ -42,6 +42,6 @@ class FileLocked extends \Sabre\DAV\Exception {
*/
public function getHTTPCode() {
- return 503;
+ return 423;
}
}
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 8e4460ef3b5..3e1b29a4f28 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -45,6 +45,8 @@ use OCP\Files\InvalidPathException;
use OCP\Files\LockNotAcquiredException;
use OCP\Files\NotPermittedException;
use OCP\Files\StorageNotAvailableException;
+use OCP\Lock\ILockingProvider;
+use OCP\Lock\LockedException;
use Sabre\DAV\Exception;
use Sabre\DAV\Exception\BadRequest;
use Sabre\DAV\Exception\Forbidden;
@@ -79,6 +81,7 @@ class File extends Node implements IFile {
* @throws Exception
* @throws EntityTooLarge
* @throws ServiceUnavailable
+ * @throws FileLocked
* @return string|null
*/
public function put($data) {
@@ -110,6 +113,12 @@ class File extends Node implements IFile {
$partFilePath = $this->path;
}
+ try {
+ $this->fileView->lockFile($this->path, ILockingProvider::LOCK_EXCLUSIVE);
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
+ }
+
// the part file and target file might be on a different storage in case of a single file storage (e.g. single file share)
/** @var \OC\Files\Storage\Storage $partStorage */
list($partStorage, $internalPartPath) = $this->fileView->resolvePath($partFilePath);
@@ -232,6 +241,8 @@ class File extends Node implements IFile {
throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage());
}
+ $this->fileView->unlockFile($this->path, ILockingProvider::LOCK_EXCLUSIVE);
+
return '"' . $this->info->getEtag() . '"';
}
@@ -252,6 +263,8 @@ class File extends Node implements IFile {
throw new ServiceUnavailable("Encryption not ready: " . $e->getMessage());
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("Failed to open file: " . $e->getMessage());
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
}
@@ -273,6 +286,8 @@ class File extends Node implements IFile {
}
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("Failed to unlink: " . $e->getMessage());
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
}
@@ -378,6 +393,8 @@ class File extends Node implements IFile {
return $info->getEtag();
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable("Failed to put file: " . $e->getMessage());
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
}
diff --git a/lib/private/connector/sabre/filesplugin.php b/lib/private/connector/sabre/filesplugin.php
index 3c79f5a7a2a..09d931be606 100644
--- a/lib/private/connector/sabre/filesplugin.php
+++ b/lib/private/connector/sabre/filesplugin.php
@@ -89,6 +89,12 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin {
$this->server->on('afterBind', array($this, 'sendFileIdHeader'));
$this->server->on('afterWriteContent', array($this, 'sendFileIdHeader'));
$this->server->on('afterMethod:GET', [$this,'httpGet']);
+ $this->server->on('afterResponse', function($request, ResponseInterface $response) {
+ $body = $response->getBody();
+ if (is_resource($body)) {
+ fclose($body);
+ }
+ });
}
/**
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index 8def14e8e9c..c56fd7ee4db 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -26,10 +26,12 @@
namespace OC\Connector\Sabre;
use OC\Connector\Sabre\Exception\InvalidPath;
+use OC\Connector\Sabre\Exception\FileLocked;
use OC\Files\FileInfo;
use OC\Files\Mount\MoveableMount;
use OCP\Files\StorageInvalidException;
use OCP\Files\StorageNotAvailableException;
+use OCP\Lock\LockedException;
class ObjectTree extends \Sabre\DAV\Tree {
@@ -221,8 +223,10 @@ class ObjectTree extends \Sabre\DAV\Tree {
if (!$renameOkay) {
throw new \Sabre\DAV\Exception\Forbidden('');
}
- } catch (\OCP\Files\StorageNotAvailableException $e) {
+ } catch (StorageNotAvailableException $e) {
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
$this->markDirty($sourceDir);
@@ -249,10 +253,19 @@ class ObjectTree extends \Sabre\DAV\Tree {
// this will trigger existence check
$this->getNodeForPath($source);
+ list($destinationDir, $destinationName) = \Sabre\HTTP\URLUtil::splitPath($destination);
+ try {
+ $this->fileView->verifyPath($destinationDir, $destinationName);
+ } catch (\OCP\Files\InvalidPathException $ex) {
+ throw new InvalidPath($ex->getMessage());
+ }
+
try {
$this->fileView->copy($source, $destination);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
+ } catch (StorageNotAvailableException $e) {
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
+ } catch (LockedException $e) {
+ throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
list($destinationDir,) = \Sabre\HTTP\URLUtil::splitPath($destination);
diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php
index ecbb86993ec..eeddea26b1a 100644
--- a/lib/private/encryption/manager.php
+++ b/lib/private/encryption/manager.php
@@ -208,49 +208,16 @@ class Manager implements IManager {
return $this->config->getAppValue('core', 'default_encryption_module');
}
+ /**
+ * Add storage wrapper
+ */
public static function setupStorage() {
- \OC\Files\Filesystem::addStorageWrapper('oc_encryption', function ($mountPoint, $storage, IMountPoint $mount) {
- $parameters = [
- 'storage' => $storage,
- 'mountPoint' => $mountPoint,
- 'mount' => $mount];
-
- if (!($storage instanceof Shared)) {
- $manager = \OC::$server->getEncryptionManager();
- $util = new Util(
- new View(),
- \OC::$server->getUserManager(),
- \OC::$server->getGroupManager(),
- \OC::$server->getConfig()
- );
- $user = \OC::$server->getUserSession()->getUser();
- $logger = \OC::$server->getLogger();
- $mountManager = Filesystem::getMountManager();
- $uid = $user ? $user->getUID() : null;
- $fileHelper = \OC::$server->getEncryptionFilesHelper();
- $keyStorage = \OC::$server->getEncryptionKeyStorage();
- $update = new Update(
- new View(),
- $util,
- Filesystem::getMountManager(),
- $manager,
- $fileHelper,
- $uid
- );
- return new Encryption(
- $parameters,
- $manager,
- $util,
- $logger,
- $fileHelper,
- $uid,
- $keyStorage,
- $update,
- $mountManager
- );
- } else {
- return $storage;
- }
- }, 2);
+ $util = new Util(
+ new View(),
+ \OC::$server->getUserManager(),
+ \OC::$server->getGroupManager(),
+ \OC::$server->getConfig()
+ );
+ \OC\Files\Filesystem::addStorageWrapper('oc_encryption', array($util, 'wrapStorage'), 2);
}
}
diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php
index b77672d2f6b..80499249561 100644
--- a/lib/private/encryption/util.php
+++ b/lib/private/encryption/util.php
@@ -26,8 +26,11 @@ use OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException;
use OC\Encryption\Exceptions\EncryptionHeaderToLargeException;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
use OC\Files\Filesystem;
+use OC\Files\Storage\Wrapper\Encryption;
use OC\Files\View;
use OCP\Encryption\IEncryptionModule;
+use OCP\Files\Mount\IMountPoint;
+use OCP\Files\Storage;
use OCP\IConfig;
class Util {
@@ -386,4 +389,52 @@ class Util {
return ($enabled === '1') ? true : false;
}
+ /**
+ * Wraps the given storage when it is not a shared storage
+ *
+ * @param string $mountPoint
+ * @param Storage $storage
+ * @param IMountPoint $mount
+ * @return Encryption|Storage
+ */
+ public function wrapStorage($mountPoint, Storage $storage, IMountPoint $mount) {
+ $parameters = [
+ 'storage' => $storage,
+ 'mountPoint' => $mountPoint,
+ 'mount' => $mount];
+
+ if (!$storage->instanceOfStorage('OC\Files\Storage\Shared')
+ && !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')
+ && !$storage->instanceOfStorage('OC\Files\Storage\OwnCloud')) {
+
+ $manager = \OC::$server->getEncryptionManager();
+ $user = \OC::$server->getUserSession()->getUser();
+ $logger = \OC::$server->getLogger();
+ $mountManager = Filesystem::getMountManager();
+ $uid = $user ? $user->getUID() : null;
+ $fileHelper = \OC::$server->getEncryptionFilesHelper();
+ $keyStorage = \OC::$server->getEncryptionKeyStorage();
+ $update = new Update(
+ new View(),
+ $this,
+ Filesystem::getMountManager(),
+ $manager,
+ $fileHelper,
+ $uid
+ );
+ return new Encryption(
+ $parameters,
+ $manager,
+ $this,
+ $logger,
+ $fileHelper,
+ $uid,
+ $keyStorage,
+ $update,
+ $mountManager
+ );
+ } else {
+ return $storage;
+ }
+ }
}
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index 1257a14dd04..847cb8492fe 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -43,6 +43,7 @@ use OCP\Files\FileNameTooLongException;
use OCP\Files\InvalidCharacterInPathException;
use OCP\Files\InvalidPathException;
use OCP\Files\ReservedWordException;
+use OCP\Lock\ILockingProvider;
/**
* Storage backend class for providing common filesystem operation methods
@@ -621,4 +622,32 @@ abstract class Common implements Storage {
return $data;
}
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ */
+ public function acquireLock($path, $type, ILockingProvider $provider) {
+ $provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
+ }
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function releaseLock($path, $type, ILockingProvider $provider) {
+ $provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
+ }
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function changeLock($path, $type, ILockingProvider $provider) {
+ $provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
+ }
}
diff --git a/lib/private/files/storage/storage.php b/lib/private/files/storage/storage.php
index 07b5633c908..bd809099e1f 100644
--- a/lib/private/files/storage/storage.php
+++ b/lib/private/files/storage/storage.php
@@ -21,6 +21,7 @@
*/
namespace OC\Files\Storage;
+use OCP\Lock\ILockingProvider;
/**
* Provide a common interface to all different storage options
@@ -76,4 +77,26 @@ interface Storage extends \OCP\Files\Storage {
*/
public function getMetaData($path);
+ /**
+ * @param string $path The path of the file to acquire the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ */
+ public function acquireLock($path, $type, ILockingProvider $provider);
+
+ /**
+ * @param string $path The path of the file to release the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function releaseLock($path, $type, ILockingProvider $provider);
+
+ /**
+ * @param string $path The path of the file to change the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ */
+ public function changeLock($path, $type, ILockingProvider $provider);
}
diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php
index d1e22bb6d40..056f823c18b 100644
--- a/lib/private/files/storage/wrapper/encryption.php
+++ b/lib/private/files/storage/wrapper/encryption.php
@@ -535,7 +535,13 @@ class Encryption extends Wrapper {
* @return string
*/
public function getLocalFile($path) {
- return $this->getCachedFile($path);
+ if ($this->encryptionManager->isEnabled()) {
+ $cachedFile = $this->getCachedFile($path);
+ if (is_string($cachedFile)) {
+ return $cachedFile;
+ }
+ }
+ return $this->storage->getLocalFile($path);
}
/**
diff --git a/lib/private/files/storage/wrapper/jail.php b/lib/private/files/storage/wrapper/jail.php
index b86b4e6405d..2857e74de46 100644
--- a/lib/private/files/storage/wrapper/jail.php
+++ b/lib/private/files/storage/wrapper/jail.php
@@ -23,6 +23,7 @@
namespace OC\Files\Storage\Wrapper;
use OC\Files\Cache\Wrapper\CacheJail;
+use OCP\Lock\ILockingProvider;
/**
* Jail to a subdirectory of the wrapped storage
@@ -424,4 +425,32 @@ class Jail extends Wrapper {
public function getETag($path) {
return $this->storage->getETag($this->getSourcePath($path));
}
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ */
+ public function acquireLock($path, $type, ILockingProvider $provider) {
+ $this->storage->acquireLock($this->getSourcePath($path), $type, $provider);
+ }
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function releaseLock($path, $type, ILockingProvider $provider) {
+ $this->storage->releaseLock($this->getSourcePath($path), $type, $provider);
+ }
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function changeLock($path, $type, ILockingProvider $provider) {
+ $this->storage->changeLock($this->getSourcePath($path), $type, $provider);
+ }
}
diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
index 14024addec4..d1414880beb 100644
--- a/lib/private/files/storage/wrapper/wrapper.php
+++ b/lib/private/files/storage/wrapper/wrapper.php
@@ -25,6 +25,7 @@
namespace OC\Files\Storage\Wrapper;
use OCP\Files\InvalidPathException;
+use OCP\Lock\ILockingProvider;
class Wrapper implements \OC\Files\Storage\Storage {
/**
@@ -541,4 +542,32 @@ class Wrapper implements \OC\Files\Storage\Storage {
public function getMetaData($path) {
return $this->storage->getMetaData($path);
}
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ */
+ public function acquireLock($path, $type, ILockingProvider $provider) {
+ $this->storage->acquireLock($path, $type, $provider);
+ }
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function releaseLock($path, $type, ILockingProvider $provider) {
+ $this->storage->releaseLock($path, $type, $provider);
+ }
+
+ /**
+ * @param string $path
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function changeLock($path, $type, ILockingProvider $provider) {
+ $this->storage->changeLock($path, $type, $provider);
+ }
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 63af2b616cf..b98842f5eb7 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -41,12 +41,15 @@
namespace OC\Files;
+use Icewind\Streams\CallbackWrapper;
use OC\Files\Cache\Updater;
use OC\Files\Mount\MoveableMount;
use OCP\Files\FileNameTooLongException;
use OCP\Files\InvalidCharacterInPathException;
use OCP\Files\InvalidPathException;
use OCP\Files\ReservedWordException;
+use OCP\Lock\ILockingProvider;
+use OCP\Lock\LockedException;
/**
* Class to provide access to ownCloud filesystem via a "view", and methods for
@@ -72,6 +75,11 @@ class View {
protected $updater;
/**
+ * @var \OCP\Lock\ILockingProvider
+ */
+ private $lockingProvider;
+
+ /**
* @param string $root
* @throws \Exception If $root contains an invalid path
*/
@@ -79,12 +87,13 @@ class View {
if (is_null($root)) {
throw new \InvalidArgumentException('Root can\'t be null');
}
- if(!Filesystem::isValidPath($root)) {
+ if (!Filesystem::isValidPath($root)) {
throw new \Exception();
}
$this->fakeRoot = $root;
$this->updater = new Updater($this);
+ $this->lockingProvider = \OC::$server->getLockingProvider();
}
public function getAbsolutePath($path = '/') {
@@ -137,7 +146,7 @@ class View {
return $path;
}
- if (rtrim($path,'/') === rtrim($this->fakeRoot, '/')) {
+ if (rtrim($path, '/') === rtrim($this->fakeRoot, '/')) {
return '/';
}
@@ -525,6 +534,7 @@ class View {
and !Filesystem::isFileBlacklisted($path)
) {
$path = $this->getRelativePath($absolutePath);
+
$exists = $this->file_exists($path);
$run = true;
if ($this->shouldEmitHooks($path)) {
@@ -604,6 +614,10 @@ class View {
if ($path1 == null or $path2 == null) {
return false;
}
+
+ $this->lockFile($path1, ILockingProvider::LOCK_SHARED);
+ $this->lockFile($path2, ILockingProvider::LOCK_SHARED);
+
$run = true;
if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
// if it was a rename from a part file to a regular file it was a write and not a rename operation
@@ -629,6 +643,9 @@ class View {
$internalPath1 = $mount1->getInternalPath($absolutePath1);
$internalPath2 = $mount2->getInternalPath($absolutePath2);
+ $this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE);
+ $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE);
+
if ($internalPath1 === '' and $mount1 instanceof MoveableMount) {
if ($this->isTargetAllowed($absolutePath2)) {
/**
@@ -649,6 +666,15 @@ class View {
} else {
$result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
}
+
+ $this->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE);
+ $this->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE);
+
+ if ($internalPath1 === '' and $mount1 instanceof MoveableMount) {
+ // since $path2 now points to a different storage we need to unlock the path on the old storage separately
+ $storage2->releaseLock($internalPath2, ILockingProvider::LOCK_EXCLUSIVE, $this->lockingProvider);
+ }
+
if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
// if it was a rename from a part file to a regular file it was a write and not a rename operation
$this->updater->update($path2);
@@ -676,6 +702,8 @@ class View {
}
return $result;
} else {
+ $this->unlockFile($path1, ILockingProvider::LOCK_SHARED);
+ $this->unlockFile($path2, ILockingProvider::LOCK_SHARED);
return false;
}
} else {
@@ -707,6 +735,10 @@ class View {
return false;
}
$run = true;
+
+ $this->lockFile($path2, ILockingProvider::LOCK_SHARED);
+ $this->lockFile($path1, ILockingProvider::LOCK_SHARED);
+
$exists = $this->file_exists($path2);
if ($this->shouldEmitHooks()) {
\OC_Hook::emit(
@@ -727,6 +759,9 @@ class View {
$internalPath1 = $mount1->getInternalPath($absolutePath1);
$storage2 = $mount2->getStorage();
$internalPath2 = $mount2->getInternalPath($absolutePath2);
+
+ $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE);
+
if ($mount1->getMountPoint() == $mount2->getMountPoint()) {
if ($storage1) {
$result = $storage1->copy($internalPath1, $internalPath2);
@@ -737,6 +772,10 @@ class View {
$result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2);
}
$this->updater->update($path2);
+
+ $this->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE);
+ $this->unlockFile($path1, ILockingProvider::LOCK_SHARED);
+
if ($this->shouldEmitHooks() && $result !== false) {
\OC_Hook::emit(
Filesystem::CLASSNAME,
@@ -750,6 +789,8 @@ class View {
}
return $result;
} else {
+ $this->unlockFile($path2, ILockingProvider::LOCK_SHARED);
+ $this->unlockFile($path1, ILockingProvider::LOCK_SHARED);
return false;
}
} else {
@@ -929,13 +970,30 @@ class View {
return false;
}
+ if(in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) {
+ // always a shared lock during pre-hooks so the hook can read the file
+ $this->lockFile($path, ILockingProvider::LOCK_SHARED);
+ }
+
$run = $this->runHooks($hooks, $path);
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
if ($run and $storage) {
- if (!is_null($extraParam)) {
- $result = $storage->$operation($internalPath, $extraParam);
- } else {
- $result = $storage->$operation($internalPath);
+ if (in_array('write', $hooks) || in_array('delete', $hooks)) {
+ $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
+ }
+ try {
+ if (!is_null($extraParam)) {
+ $result = $storage->$operation($internalPath, $extraParam);
+ } else {
+ $result = $storage->$operation($internalPath);
+ }
+ } catch (\Exception $e) {
+ if (in_array('write', $hooks) || in_array('delete', $hooks)) {
+ $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
+ } else if (in_array('read', $hooks)) {
+ $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
+ }
+ throw $e;
}
if (in_array('delete', $hooks) and $result) {
@@ -948,12 +1006,31 @@ class View {
$this->updater->update($path, $extraParam);
}
+ if ($operation === 'fopen' and $result) {
+ $result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) {
+ if (in_array('write', $hooks)) {
+ $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
+ } else if (in_array('read', $hooks)) {
+ $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
+ }
+ });
+ } else {
+ if (in_array('write', $hooks) || in_array('delete', $hooks)) {
+ $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
+ } else if (in_array('read', $hooks)) {
+ $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
+ }
+ }
+
+
if ($this->shouldEmitHooks($path) && $result !== false) {
if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open
$this->runHooks($hooks, $path, true);
}
}
return $result;
+ } else {
+ $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
}
}
return null;
@@ -1553,4 +1630,114 @@ class View {
throw new InvalidPathException($l10n->t('File name is too long'));
}
}
+
+ /**
+ * get all parent folders of $path
+ *
+ * @param string $path
+ * @return string[]
+ */
+ private function getParents($path) {
+ $path = trim($path, '/');
+ if (!$path) {
+ return [];
+ }
+
+ $parts = explode('/', $path);
+
+ // remove the single file
+ array_pop($parts);
+ $result = array('/');
+ $resultPath = '';
+ foreach ($parts as $part) {
+ if ($part) {
+ $resultPath .= '/' . $part;
+ $result[] = $resultPath;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * @param string $path the path of the file to lock, relative to the view
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ */
+ private function lockPath($path, $type) {
+ $mount = $this->getMount($path);
+ if ($mount) {
+ $mount->getStorage()->acquireLock(
+ $mount->getInternalPath(
+ $this->getAbsolutePath($path)
+ ),
+ $type,
+ $this->lockingProvider
+ );
+ }
+ }
+
+ /**
+ * @param string $path the path of the file to lock, relative to the view
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ */
+ private function changeLock($path, $type) {
+ $mount = $this->getMount($path);
+ if ($mount) {
+ $mount->getStorage()->changeLock(
+ $mount->getInternalPath(
+ $this->getAbsolutePath($path)
+ ),
+ $type,
+ $this->lockingProvider
+ );
+ }
+ }
+
+ /**
+ * @param string $path the path of the file to unlock, relative to the view
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ */
+ private function unlockPath($path, $type) {
+ $mount = $this->getMount($path);
+ if ($mount) {
+ $mount->getStorage()->releaseLock(
+ $mount->getInternalPath(
+ $this->getAbsolutePath($path)
+ ),
+ $type,
+ $this->lockingProvider
+ );
+ }
+ }
+
+ /**
+ * Lock a path and all its parents up to the root of the view
+ *
+ * @param string $path the path of the file to lock relative to the view
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ */
+ public function lockFile($path, $type) {
+ $path = '/' . trim($path, '/');
+ $this->lockPath($path, $type);
+
+ $parents = $this->getParents($path);
+ foreach ($parents as $parent) {
+ $this->lockPath($parent, ILockingProvider::LOCK_SHARED);
+ }
+ }
+
+ /**
+ * Unlock a path and all its parents up to the root of the view
+ *
+ * @param string $path the path of the file to lock relative to the view
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ */
+ public function unlockFile($path, $type) {
+ $path = rtrim($path, '/');
+ $this->unlockPath($path, $type);
+
+ $parents = $this->getParents($path);
+ foreach ($parents as $parent) {
+ $this->unlockPath($parent, ILockingProvider::LOCK_SHARED);
+ }
+ }
}
diff --git a/lib/private/lock/memcachelockingprovider.php b/lib/private/lock/memcachelockingprovider.php
index 9c8c7235462..3f32ab1d8c5 100644
--- a/lib/private/lock/memcachelockingprovider.php
+++ b/lib/private/lock/memcachelockingprovider.php
@@ -31,6 +31,11 @@ class MemcacheLockingProvider implements ILockingProvider {
*/
private $memcache;
+ private $acquiredLocks = [
+ 'shared' => [],
+ 'exclusive' => []
+ ];
+
/**
* @param \OCP\IMemcache $memcache
*/
@@ -64,11 +69,16 @@ class MemcacheLockingProvider implements ILockingProvider {
if (!$this->memcache->inc($path)) {
throw new LockedException($path);
}
+ if (!isset($this->acquiredLocks['shared'][$path])) {
+ $this->acquiredLocks['shared'][$path] = 0;
+ }
+ $this->acquiredLocks['shared'][$path]++;
} else {
$this->memcache->add($path, 0);
if (!$this->memcache->cas($path, 0, 'exclusive')) {
throw new LockedException($path);
}
+ $this->acquiredLocks['exclusive'][$path] = true;
}
}
@@ -78,9 +88,55 @@ class MemcacheLockingProvider implements ILockingProvider {
*/
public function releaseLock($path, $type) {
if ($type === self::LOCK_SHARED) {
- $this->memcache->dec($path);
+ if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) {
+ $this->memcache->dec($path);
+ $this->acquiredLocks['shared'][$path]--;
+ }
} else if ($type === self::LOCK_EXCLUSIVE) {
$this->memcache->cas($path, 'exclusive', 0);
+ unset($this->acquiredLocks['exclusive'][$path]);
+ }
+ }
+
+ /**
+ * Change the type of an existing lock
+ *
+ * @param string $path
+ * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
+ * @throws \OCP\Lock\LockedException
+ */
+ public function changeLock($path, $targetType) {
+ if ($targetType === self::LOCK_SHARED) {
+ if (!$this->memcache->cas($path, 'exclusive', 1)) {
+ throw new LockedException($path);
+ }
+ unset($this->acquiredLocks['exclusive'][$path]);
+ if (!isset($this->acquiredLocks['shared'][$path])) {
+ $this->acquiredLocks['shared'][$path] = 0;
+ }
+ $this->acquiredLocks['shared'][$path]++;
+ } else if ($targetType === self::LOCK_EXCLUSIVE) {
+ // we can only change a shared lock to an exclusive if there's only a single owner of the shared lock
+ if (!$this->memcache->cas($path, 1, 'exclusive')) {
+ throw new LockedException($path);
+ }
+ $this->acquiredLocks['exclusive'][$path] = true;
+ $this->acquiredLocks['shared'][$path]--;
+ }
+ }
+
+ /**
+ * release all lock acquired by this instance
+ */
+ public function releaseAll() {
+ foreach ($this->acquiredLocks['shared'] as $path => $count) {
+ for ($i = 0; $i < $count; $i++) {
+ $this->releaseLock($path, self::LOCK_SHARED);
+ }
+ }
+
+ foreach ($this->acquiredLocks['exclusive'] as $path => $hasLock) {
+ $this->releaseLock($path, self::LOCK_EXCLUSIVE);
}
}
}
diff --git a/lib/private/lock/nooplockingprovider.php b/lib/private/lock/nooplockingprovider.php
new file mode 100644
index 00000000000..4f33b881555
--- /dev/null
+++ b/lib/private/lock/nooplockingprovider.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Lock;
+
+use OCP\Lock\ILockingProvider;
+
+/**
+ * Locking provider that does nothing.
+ *
+ * To be used when locking is disabled.
+ */
+class NoopLockingProvider implements ILockingProvider {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLocked($path, $type) {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function acquireLock($path, $type) {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function releaseLock($path, $type) {
+ // do nothing
+ }
+
+ /**1
+ * {@inheritdoc}
+ */
+ public function releaseAll() {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function changeLock($path, $targetType) {
+ // do nothing
+ }
+}
diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php
index bbfd775c774..6e9aaa11d85 100644
--- a/lib/private/memcache/factory.php
+++ b/lib/private/memcache/factory.php
@@ -47,12 +47,18 @@ class Factory implements ICacheFactory {
private $distributedCacheClass;
/**
+ * @var string $lockingCacheClass
+ */
+ private $lockingCacheClass;
+
+ /**
* @param string $globalPrefix
* @param string|null $localCacheClass
* @param string|null $distributedCacheClass
+ * @param string|null $lockingCacheClass
*/
public function __construct($globalPrefix,
- $localCacheClass = null, $distributedCacheClass = null)
+ $localCacheClass = null, $distributedCacheClass = null, $lockingCacheClass = null)
{
$this->globalPrefix = $globalPrefix;
@@ -62,8 +68,23 @@ class Factory implements ICacheFactory {
if (!($distributedCacheClass && $distributedCacheClass::isAvailable())) {
$distributedCacheClass = $localCacheClass;
}
+ if (!($lockingCacheClass && $lockingCacheClass::isAvailable())) {
+ // dont fallback since the fallback might not be suitable for storing lock
+ $lockingCacheClass = '\OC\Memcache\Null';
+ }
$this->localCacheClass = $localCacheClass;
$this->distributedCacheClass = $distributedCacheClass;
+ $this->lockingCacheClass = $lockingCacheClass;
+ }
+
+ /**
+ * create a cache instance for storing locks
+ *
+ * @param string $prefix
+ * @return \OCP\IMemcache
+ */
+ public function createLocking($prefix = '') {
+ return new $this->lockingCacheClass($this->globalPrefix . '/' . $prefix);
}
/**
diff --git a/lib/private/memcache/null.php b/lib/private/memcache/null.php
index 3b8ce0b42da..982f7edc80f 100644
--- a/lib/private/memcache/null.php
+++ b/lib/private/memcache/null.php
@@ -22,7 +22,7 @@
namespace OC\Memcache;
-class Null extends Cache {
+class Null extends Cache implements \OCP\IMemcache {
public function get($key) {
return null;
}
@@ -39,6 +39,22 @@ class Null extends Cache {
return true;
}
+ public function add($key, $value, $ttl = 0) {
+ return true;
+ }
+
+ public function inc($key, $step = 1) {
+ return true;
+ }
+
+ public function dec($key, $step = 1) {
+ return true;
+ }
+
+ public function cas($key, $old, $new) {
+ return true;
+ }
+
public function clear($prefix = '') {
return true;
}
diff --git a/lib/private/repair.php b/lib/private/repair.php
index 0674207bbee..c690fe4a8cd 100644
--- a/lib/private/repair.php
+++ b/lib/private/repair.php
@@ -32,6 +32,7 @@ use OC\Hooks\Emitter;
use OC\Repair\AssetCache;
use OC\Repair\CleanTags;
use OC\Repair\Collation;
+use OC\Repair\DropOldJobs;
use OC\Repair\SqliteAutoincrement;
use OC\Repair\DropOldTables;
use OC\Repair\FillETags;
@@ -106,6 +107,7 @@ class Repair extends BasicEmitter {
new FillETags(\OC_DB::getConnection()),
new CleanTags(\OC_DB::getConnection()),
new DropOldTables(\OC_DB::getConnection()),
+ new DropOldJobs(\OC::$server->getJobList()),
);
}
diff --git a/lib/private/route/router.php b/lib/private/route/router.php
index fd1e4440c4f..48992366092 100644
--- a/lib/private/route/router.php
+++ b/lib/private/route/router.php
@@ -231,6 +231,8 @@ class Router implements IRouter {
if (substr($url, 0, 6) === '/apps/') {
// empty string / 'apps' / $app / rest of the route
list(, , $app,) = explode('/', $url, 4);
+
+ $app = \OC_App::cleanAppId($app);
\OC::$REQUESTEDAPP = $app;
$this->loadRoutes($app);
} else if (substr($url, 0, 6) === '/core/' or substr($url, 0, 10) === '/settings/') {
diff --git a/lib/private/server.php b/lib/private/server.php
index aeea4a6485e..8113080977f 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -38,13 +38,15 @@ use bantu\IniGetWrapper\IniGetWrapper;
use OC\AppFramework\Http\Request;
use OC\AppFramework\Db\Db;
use OC\AppFramework\Utility\SimpleContainer;
-use OC\Cache\UserCache;
use OC\Command\AsyncBus;
use OC\Diagnostics\NullQueryLogger;
use OC\Diagnostics\EventLogger;
use OC\Diagnostics\QueryLogger;
+use OC\Lock\MemcacheLockingProvider;
+use OC\Lock\NoopLockingProvider;
use OC\Mail\Mailer;
use OC\Memcache\ArrayCache;
+use OC\Memcache\Null as NullCache;
use OC\Http\Client\ClientService;
use OC\Security\CertificateManager;
use OC\Files\Node\Root;
@@ -217,13 +219,13 @@ class Server extends SimpleContainer implements IServerContainer {
$this->registerService('AppHelper', function ($c) {
return new \OC\AppHelper();
});
- $this->registerService('UserCache', function ($c) {
- return new UserCache();
+ $this->registerService('NullCache', function ($c) {
+ return new NullCache();
});
$this->registerService('MemCacheFactory', function (Server $c) {
$config = $c->getConfig();
- if($config->getSystemValue('installed', false)) {
+ if($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
$v = \OC_App::getAppVersions();
$v['core'] = implode('.', \OC_Util::getVersion());
$version = implode(',', $v);
@@ -232,12 +234,14 @@ class Server extends SimpleContainer implements IServerContainer {
$prefix = md5($instanceId.'-'.$version.'-'.$path);
return new \OC\Memcache\Factory($prefix,
$config->getSystemValue('memcache.local', null),
- $config->getSystemValue('memcache.distributed', null)
+ $config->getSystemValue('memcache.distributed', null),
+ $config->getSystemValue('memcache.locking', null)
);
}
return new \OC\Memcache\Factory('',
new ArrayCache(),
+ new ArrayCache(),
new ArrayCache()
);
});
@@ -420,6 +424,17 @@ class Server extends SimpleContainer implements IServerContainer {
$this->getLogger()
);
});
+ $this->registerService('LockingProvider', function (Server $c) {
+ if ($c->getConfig()->getSystemValue('filelocking.enabled', false) or (defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
+ /** @var \OC\Memcache\Factory $memcacheFactory */
+ $memcacheFactory = $c->getMemCacheFactory();
+ $memcache = $memcacheFactory->createLocking('lock');
+ if (!($memcache instanceof \OC\Memcache\Null)) {
+ return new MemcacheLockingProvider($memcache);
+ }
+ }
+ return new NoopLockingProvider();
+ });
}
/**
@@ -646,12 +661,14 @@ class Server extends SimpleContainer implements IServerContainer {
}
/**
- * Returns an ICache instance
+ * Returns an ICache instance. Since 8.1.0 it returns a fake cache. Use
+ * getMemCacheFactory() instead.
*
* @return \OCP\ICache
+ * @deprecated 8.1.0 use getMemCacheFactory to obtain a proper cache
*/
public function getCache() {
- return $this->query('UserCache');
+ return $this->query('NullCache');
}
/**
@@ -908,4 +925,14 @@ class Server extends SimpleContainer implements IServerContainer {
public function getTrustedDomainHelper() {
return $this->query('TrustedDomainHelper');
}
+
+ /**
+ * Get the locking provider
+ *
+ * @return \OCP\Lock\ILockingProvider
+ * @since 8.1.0
+ */
+ public function getLockingProvider() {
+ return $this->query('LockingProvider');
+ }
}
diff --git a/lib/public/files/storage.php b/lib/public/files/storage.php
index b89fb49a4be..ee160c50e89 100644
--- a/lib/public/files/storage.php
+++ b/lib/public/files/storage.php
@@ -33,6 +33,7 @@
// This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP\Files;
use OCP\Files\InvalidPathException;
+use OCP\Lock\ILockingProvider;
/**
* Provide a common interface to all different storage options
@@ -413,4 +414,27 @@ interface Storage {
* @since 8.1.0
*/
public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath);
+
+ /**
+ * @param string $path The path of the file to acquire the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ */
+ public function acquireLock($path, $type, ILockingProvider $provider);
+
+ /**
+ * @param string $path The path of the file to acquire the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ */
+ public function releaseLock($path, $type, ILockingProvider $provider);
+
+ /**
+ * @param string $path The path of the file to change the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ */
+ public function changeLock($path, $type, ILockingProvider $provider);
}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index 5dd545aed37..8f0bede6cc8 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -413,4 +413,12 @@ interface IServerContainer {
* @since 8.1.0
*/
public function getMailer();
+
+ /**
+ * Get the locking provider
+ *
+ * @return \OCP\Lock\ILockingProvider
+ * @since 8.1.0
+ */
+ public function getLockingProvider();
}
diff --git a/lib/public/lock/ilockingprovider.php b/lib/public/lock/ilockingprovider.php
index 0b17580faac..6a963b9d7aa 100644
--- a/lib/public/lock/ilockingprovider.php
+++ b/lib/public/lock/ilockingprovider.php
@@ -44,4 +44,18 @@ interface ILockingProvider {
* @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
*/
public function releaseLock($path, $type);
+
+ /**
+ * Change the type of an existing lock
+ *
+ * @param string $path
+ * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
+ * @throws \OCP\Lock\LockedException
+ */
+ public function changeLock($path, $targetType);
+
+ /**
+ * release all lock acquired by this instance
+ */
+ public function releaseAll();
}
diff --git a/lib/repair/dropoldjobs.php b/lib/repair/dropoldjobs.php
new file mode 100644
index 00000000000..89d7f96a144
--- /dev/null
+++ b/lib/repair/dropoldjobs.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * @author Arthur Schiwon <blizzz@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Repair;
+
+use OC\Hooks\BasicEmitter;
+use OC\RepairStep;
+use OCP\BackgroundJob\IJobList;
+
+class DropOldJobs extends BasicEmitter implements RepairStep {
+
+ /** @var IJobList */
+ protected $jobList;
+
+ /**
+ * @param IJobList $jobList
+ */
+ public function __construct(IJobList $jobList) {
+ $this->jobList = $jobList;
+ }
+
+ /**
+ * Returns the step's name
+ *
+ * @return string
+ */
+ public function getName() {
+ return 'Drop old background jobs';
+ }
+
+ /**
+ * Run repair step.
+ * Must throw exception on error.
+ *
+ * @throws \Exception in case of failure
+ */
+ public function run() {
+ $oldJobs = $this->oldJobs();
+ foreach($oldJobs as $job) {
+ if($this->jobList->has($job['class'], $job['arguments'])) {
+ $this->jobList->remove($job['class'], $job['arguments']);
+ }
+ }
+ }
+
+ /**
+ * returns a list of old jobs as an associative array with keys 'class' and
+ * 'arguments'.
+ *
+ * @return array
+ */
+ public function oldJobs() {
+ return [
+ ['class' => 'OC_Cache_FileGlobalGC', 'arguments' => null],
+ ['class' => 'OC\Cache\FileGlobalGC', 'arguments' => null],
+ ];
+ }
+
+
+}