diff options
Diffstat (limited to 'lib')
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], + ]; + } + + +} |