From 92efd68a3a13e49fe7bbfb8441611c0dcd639415 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 30 Dec 2013 01:03:32 +0100 Subject: Début de mode multi-utilisateur avec http_auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + Légère optimisation de Minz_View. + Encore plus de tests de bibliothèques dans install.php Contribue à https://github.com/marienfressinaud/FreshRSS/issues/126 et https://github.com/marienfressinaud/FreshRSS/issues/303 --- app/actualize_script.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'app/actualize_script.php') diff --git a/app/actualize_script.php b/app/actualize_script.php index 20438128a..e0c560ff7 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -1,6 +1,8 @@ init (); -Minz_Session::_param('mail', true); // permet de se passer de la phase de connexion -$front_controller->run (); -invalidateHttpCache(); + +$users = listUsers(); +shuffle($users); + +foreach ($users as $user) { + $front_controller->init($user); + $front_controller->run(); + invalidateHttpCache($user); +} -- cgit v1.2.3 From bd5d7a7bcb16cff1c01f4445ceee765fc11e3b50 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 30 Dec 2013 15:00:41 +0100 Subject: Cache HTTP compatible multi-utilisateur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contribue à https://github.com/marienfressinaud/FreshRSS/issues/126 --- app/Controllers/configureController.php | 2 +- app/Controllers/indexController.php | 4 +-- app/FreshRSS.php | 51 ++++++++++++++++++++++++--------- app/Models/LogDAO.php | 8 ++++-- app/actualize_script.php | 12 +++++--- app/views/configure/users.phtml | 6 ++-- lib/Minz/Configuration.php | 13 ++------- lib/Minz/Log.php | 2 +- lib/Minz/ModelPdo.php | 3 +- lib/Minz/Session.php | 10 ++----- lib/lib_rss.php | 9 ++---- p/i/index.php | 13 +++++---- 12 files changed, 73 insertions(+), 60 deletions(-) (limited to 'app/actualize_script.php') diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 656e2ac89..2260e978b 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -322,7 +322,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { Minz_Session::_param('mail', $this->view->conf->mail_login); - if (Minz_Configuration::isAdmin()) { + if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { $anon = Minz_Request::param('anon_access', false); $anon = ((bool)$anon) && ($anon !== 'no'); $auth_type = Minz_Request::param('auth_type', 'none'); diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index cc851a1fa..7309169a6 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -218,10 +218,10 @@ class FreshRSS_index_Controller extends Minz_ActionController { Minz_View::prependTitle (Minz_Translate::t ('logs') . ' - '); if (Minz_Request::isPost ()) { - file_put_contents(LOG_PATH . '/' . Minz_Configuration::currentUser() . '.log', ''); //Truncate + FreshRSS_LogDAO::truncate(); } - $logs = FreshRSS_LogDAO::lines(Minz_Configuration::currentUser()); //TODO: ask only the necessary lines + $logs = FreshRSS_LogDAO::lines(); //TODO: ask only the necessary lines //gestion pagination $page = Minz_Request::param ('page', 1); diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 10f362717..0e166cc3b 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -1,22 +1,24 @@ accessControl($currentUser); + public function init() { + if (!isset($_SESSION)) { + Minz_Session::init('FreshRSS'); + } + $this->accessControl(Minz_Session::param('currentUser', '')); $this->loadParamsView(); $this->loadStylesAndScripts(); $this->loadNotifications(); } private function accessControl($currentUser) { - if ($currentUser === null) { + if ($currentUser == '') { switch (Minz_Configuration::authType()) { case 'http_auth': $currentUser = httpAuthUser(); $loginOk = $currentUser != ''; break; case 'persona': - $currentUser = Minz_Configuration::defaultUser(); + $currentUser = Minz_Configuration::defaultUser(); //TODO: Make Persona compatible with multi-user $loginOk = Minz_Session::param('mail') != ''; break; case 'none': @@ -24,28 +26,49 @@ class FreshRSS extends Minz_FrontController { $loginOk = true; break; default: + $currentUser = Minz_Configuration::defaultUser(); $loginOk = false; break; } - } elseif ((PHP_SAPI === 'cli') && (Minz_Request::actionName() === 'actualize')) { //Command line - Minz_Configuration::_authType('none'); + } else { $loginOk = true; } - if (!$loginOk || !isValidUser($currentUser)) { - $currentUser = Minz_Configuration::defaultUser(); - $loginOk = false; + if (!ctype_alnum($currentUser)) { + Minz_Session::_param('currentUser', ''); + die('Invalid username [' . $currentUser . ']!'); } - Minz_Configuration::_currentUser($currentUser); - Minz_View::_param ('loginOk', $loginOk); try { $this->conf = new FreshRSS_Configuration($currentUser); } catch (Minz_Exception $e) { - // Permission denied or conf file does not exist - die($e->getMessage()); + Minz_Session::_param('currentUser', ''); + die('Invalid configuration for user [' . $currentUser . ']! ' . $e->getMessage()); //Permission denied or conf file does not exist } Minz_View::_param ('conf', $this->conf); + Minz_Session::_param('currentUser', $currentUser); + + if ($loginOk) { + switch (Minz_Configuration::authType()) { + case 'http_auth': + $loginOk = $currentUser === httpAuthUser(); + break; + case 'persona': + $loginOk = Minz_Session::param('mail') === $this->conf->mail_login; + break; + case 'none': + $loginOk = true; + break; + default: + $loginOk = false; + break; + } + if ((!$loginOk) && (PHP_SAPI === 'cli') && (Minz_Request::actionName() === 'actualize')) { //Command line + Minz_Configuration::_authType('none'); + $loginOk = true; + } + } + Minz_View::_param ('loginOk', $loginOk); } private function loadParamsView () { diff --git a/app/Models/LogDAO.php b/app/Models/LogDAO.php index 6205468bd..d1e515200 100644 --- a/app/Models/LogDAO.php +++ b/app/Models/LogDAO.php @@ -1,9 +1,9 @@ init($user); - $front_controller->run(); - invalidateHttpCache($user); + Minz_Session::init('FreshRSS'); + Minz_Session::_param('currentUser', $user); + $freshRSS->init(); + $freshRSS->run(); + //invalidateHttpCache(); + touch(LOG_PATH . '/' . $user . '.log'); + Minz_Session::unset_session(true); } diff --git a/app/views/configure/users.phtml b/app/views/configure/users.phtml index db57448f6..cb6579a6b 100644 --- a/app/views/configure/users.phtml +++ b/app/views/configure/users.phtml @@ -9,10 +9,10 @@
- + $_SERVER['REMOTE_USER'] =
@@ -34,7 +34,7 @@
- + diff --git a/lib/Minz/Configuration.php b/lib/Minz/Configuration.php index e6d7ae471..1513af6d0 100644 --- a/lib/Minz/Configuration.php +++ b/lib/Minz/Configuration.php @@ -51,7 +51,6 @@ class Minz_Configuration { private static $cache_enabled = false; private static $delay_cache = 3600; private static $default_user = ''; - private static $current_user = ''; private static $allow_anonymous = false; private static $auth_type = 'none'; @@ -95,11 +94,8 @@ class Minz_Configuration { public static function defaultUser () { return self::$default_user; } - public static function currentUser () { - return self::$current_user; - } - public static function isAdmin () { - return self::$current_user === self::$default_user; + public static function isAdmin($currentUser) { + return $currentUser === self::$default_user; } public static function allowAnonymous() { return self::$allow_anonymous; @@ -127,10 +123,6 @@ class Minz_Configuration { break; } } - public static function _currentUser($user) { - self::$current_user = $user; - } - /** * Initialise les variables de configuration @@ -255,7 +247,6 @@ class Minz_Configuration { } if (isset ($general['default_user'])) { self::$default_user = $general['default_user']; - self::$current_user = self::$default_user; } if (isset ($general['allow_anonymous'])) { self::$allow_anonymous = ((bool)($general['allow_anonymous'])) && ($general['allow_anonymous'] !== 'no'); diff --git a/lib/Minz/Log.php b/lib/Minz/Log.php index 968301c81..e710aad4a 100644 --- a/lib/Minz/Log.php +++ b/lib/Minz/Log.php @@ -37,7 +37,7 @@ class Minz_Log { || ($env === Minz_Configuration::PRODUCTION && ($level >= Minz_Log::NOTICE)))) { if ($file_name === null) { - $file_name = LOG_PATH . '/' . Minz_Configuration::currentUser() . '.log'; + $file_name = LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log'; } switch ($level) { diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php index 9655539b2..1ea68e104 100644 --- a/lib/Minz/ModelPdo.php +++ b/lib/Minz/ModelPdo.php @@ -60,8 +60,7 @@ class Minz_ModelPdo { ); self::$sharedBd = $this->bd; - $userPrefix = Minz_Configuration::currentUser (); - $this->prefix = $db['prefix'] . (empty($userPrefix) ? '' : ($userPrefix . '_')); + $this->prefix = $db['prefix'] . Minz_Session::param('currentUser', '_') . '_'; self::$sharedPrefix = $this->prefix; } catch (Exception $e) { throw new Minz_PDOConnectionException ( diff --git a/lib/Minz/Session.php b/lib/Minz/Session.php index 6e45fd226..3f6ed88a3 100644 --- a/lib/Minz/Session.php +++ b/lib/Minz/Session.php @@ -8,7 +8,7 @@ class Minz_Session { /** * $session stocke les variables de session */ - private static $session = array (); + private static $session = array (); //TODO: Try to avoid having another local copy /** * Initialise la session, avec un nom @@ -33,13 +33,7 @@ class Minz_Session { * @return la valeur de la variable de session, false si n'existe pas */ public static function param ($p, $default = false) { - if (isset (self::$session[$p])) { - $return = self::$session[$p]; - } else { - $return = $default; - } - - return $return; + return isset(self::$session[$p]) ? self::$session[$p] : $default; } diff --git a/lib/lib_rss.php b/lib/lib_rss.php index b266fa5c7..7489f2bf5 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -163,8 +163,9 @@ function uSecString() { return str_pad($t['usec'], 6, '0'); } -function invalidateHttpCache($currentUser = '') { //TODO: Make multi-user compatible - file_put_contents(DATA_PATH . '/touch.txt', uTimeString()); +function invalidateHttpCache() { + //touch(LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log'); + Minz_Session::_param('touch', uTimeString()); } function usernameFromPath($userPath) { @@ -175,10 +176,6 @@ function usernameFromPath($userPath) { } } -function isValidUser($user) { - return $user != '' && ctype_alnum($user) && file_exists(DATA_PATH . '/' . $user . '_user.php'); -} - function listUsers() { return array_map('usernameFromPath', glob(DATA_PATH . '/*_user.php')); } diff --git a/p/i/index.php b/p/i/index.php index 8d9343a30..3dcf659c9 100755 --- a/p/i/index.php +++ b/p/i/index.php @@ -22,22 +22,23 @@ if (file_exists ('install.php')) { require('install.php'); } else { require('../../constants.php'); + require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader session_cache_limiter(''); + Minz_Session::init('FreshRSS'); + if (!file_exists(DATA_PATH . '/no-cache.txt')) { - require (LIB_PATH . '/http-conditional.php'); - $dateLastModification = max( - @filemtime(DATA_PATH . '/touch.txt'), + require(LIB_PATH . '/http-conditional.php'); + $currentUser = Minz_Session::param('currentUser', ''); + $dateLastModification = $currentUser === '' ? time() : max( + @filemtime(LOG_PATH . '/' . $currentUser . '.log'), @filemtime(DATA_PATH . '/config.php') ); - $_SERVER['QUERY_STRING'] .= '&utime=' . file_get_contents(DATA_PATH . '/touch.txt'); //For ETag if (httpConditional($dateLastModification, 0, 0, false, false, true)) { exit(); //No need to send anything } } - require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader - try { $front_controller = new FreshRSS(); $front_controller->init (); -- cgit v1.2.3 From b4c477ca41a7ecaa6364dd6a97603829b14b11ef Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 2 Jan 2014 01:47:03 +0100 Subject: actualize_script compatible multi-utilisateur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Messages plus verbeux dans actualize_script * Ajout d'un message syslog lorsque SimplePie fait une requête HTTP * Minz_Session ne fermait pas les sessions complètement. * Nouvelle option dans Minz_Dispatcher et Minz_FrontController pour ne pas utiliser ob_gzhandler. Contribue à https://github.com/marienfressinaud/FreshRSS/issues/126 --- app/actualize_script.php | 36 ++++++++++++++++++++++++++---------- app/views/feed/actualize.phtml | 2 +- lib/Minz/Dispatcher.php | 23 +++++++++++++++++------ lib/Minz/FrontController.php | 15 ++++++++++++++- lib/Minz/ModelPdo.php | 5 +++++ lib/Minz/Session.php | 2 +- lib/SimplePie/SimplePie/File.php | 1 + 7 files changed, 65 insertions(+), 19 deletions(-) (limited to 'app/actualize_script.php') diff --git a/app/actualize_script.php b/app/actualize_script.php index efe21fab6..e0f995afe 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -3,24 +3,40 @@ require(dirname(__FILE__) . '/../constants.php'); //TODO: check if already running -$_GET['c'] = 'feed'; -$_GET['a'] = 'actualize'; -$_GET['force'] = true; -$_SERVER['HTTP_HOST'] = ''; - require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader -$freshRSS = new FreshRSS (); +session_cache_limiter(''); +ob_implicit_flush(false); +ob_start(); +echo 'Results: ', "\n"; //Buffered $users = listUsers(); shuffle($users); -foreach ($users as $user) { +foreach ($users as $myUser) { + syslog(LOG_INFO, 'FreshRSS actualize ' . $myUser); + fwrite(STDOUT, 'Actualize ' . $myUser . "...\n"); //Unbuffered + echo $myUser, ' '; //Buffered + + $_GET['c'] = 'feed'; + $_GET['a'] = 'actualize'; + $_GET['ajax'] = 1; + $_GET['force'] = true; + $_SERVER['HTTP_HOST'] = ''; + + $freshRSS = new FreshRSS(); + $freshRSS->_useOb(false); + Minz_Session::init('FreshRSS'); - Minz_Session::_param('currentUser', $user); + Minz_Session::_param('currentUser', $myUser); + $freshRSS->init(); $freshRSS->run(); - //invalidateHttpCache(); - touch(LOG_PATH . '/' . $user . '.log'); + + invalidateHttpCache(); Minz_Session::unset_session(true); + Minz_ModelPdo::clean(); } +syslog(LOG_INFO, 'FreshRSS actualize done.'); +ob_end_flush(); +fwrite(STDOUT, 'Done.' . "\n"); diff --git a/app/views/feed/actualize.phtml b/app/views/feed/actualize.phtml index a0aba9318..d86bac9de 100644 --- a/app/views/feed/actualize.phtml +++ b/app/views/feed/actualize.phtml @@ -1 +1 @@ -OK \ No newline at end of file +OK diff --git a/lib/Minz/Dispatcher.php b/lib/Minz/Dispatcher.php index c2c5e7f65..71dfe8ac6 100644 --- a/lib/Minz/Dispatcher.php +++ b/lib/Minz/Dispatcher.php @@ -40,19 +40,26 @@ class Minz_Dispatcher { * Remplit le body de Response à partir de la Vue * @exception Minz_Exception */ - public function run () { + public function run ($ob = true) { $cache = new Minz_Cache(); // Le ob_start est dupliqué : sans ça il y a un bug sous Firefox // ici on l'appelle avec 'ob_gzhandler', après sans. // Vraisemblablement la compression fonctionne mais c'est sale // J'ignore les effets de bord :( - ob_start ('ob_gzhandler'); + if ($ob) { + ob_start ('ob_gzhandler'); + } if (Minz_Cache::isEnabled () && !$cache->expired ()) { - ob_start (); + if ($ob) { + ob_start (); + } $cache->render (); - $text = ob_get_clean(); + if ($ob) { + $text = ob_get_clean(); + } } else { + $text = ''; //TODO: Clean this code while (Minz_Request::$reseted) { Minz_Request::$reseted = false; @@ -67,9 +74,13 @@ class Minz_Dispatcher { $this->controller->lastAction (); if (!Minz_Request::$reseted) { - ob_start (); + if ($ob) { + ob_start (); + } $this->controller->view ()->build (); - $text = ob_get_clean(); + if ($ob) { + $text = ob_get_clean(); + } } } catch (Minz_Exception $e) { throw $e; diff --git a/lib/Minz/FrontController.php b/lib/Minz/FrontController.php index 8e9c511a6..7b8526bc8 100644 --- a/lib/Minz/FrontController.php +++ b/lib/Minz/FrontController.php @@ -26,6 +26,8 @@ class Minz_FrontController { protected $dispatcher; protected $router; + private $useOb = true; + /** * Constructeur * Initialise le router et le dispatcher @@ -61,7 +63,7 @@ class Minz_FrontController { */ public function run () { try { - $this->dispatcher->run (); + $this->dispatcher->run ($this->useOb); Minz_Response::send (); } catch (Minz_Exception $e) { try { @@ -94,4 +96,15 @@ class Minz_FrontController { } exit ('### Application problem ###
'."\n".$txt); } + + public function useOb() { + return $this->useOb; + } + + /** + * Use ob_start('ob_gzhandler') or not. + */ + public function _useOb($ob) { + return $this->useOb = (bool)$ob; + } } diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php index a643da1f0..831df13a2 100644 --- a/lib/Minz/ModelPdo.php +++ b/lib/Minz/ModelPdo.php @@ -93,6 +93,11 @@ class Minz_ModelPdo { $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0); return $res[0]; } + + public static function clean() { + self::$sharedBd = null; + self::$sharedPrefix = ''; + } } class FreshPDO extends PDO { diff --git a/lib/Minz/Session.php b/lib/Minz/Session.php index 3f6ed88a3..37faff0fb 100644 --- a/lib/Minz/Session.php +++ b/lib/Minz/Session.php @@ -60,7 +60,7 @@ class Minz_Session { public static function unset_session ($force = false) { $language = self::param ('language'); - session_unset (); + session_destroy(); self::$session = array (); if (!$force) { diff --git a/lib/SimplePie/SimplePie/File.php b/lib/SimplePie/SimplePie/File.php index 063ad955e..cf926cf5a 100644 --- a/lib/SimplePie/SimplePie/File.php +++ b/lib/SimplePie/SimplePie/File.php @@ -77,6 +77,7 @@ class SimplePie_File $this->useragent = $useragent; if (preg_match('/^http(s)?:\/\//i', $url)) { + syslog(LOG_INFO, 'SimplePie GET ' . $url); //FreshRSS if ($useragent === null) { $useragent = ini_get('user_agent'); -- cgit v1.2.3 From 3b23ca881c63fe6e1cc8ef98ae5a5af645d4870a Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 2 Jan 2014 14:38:06 +0100 Subject: Mutex pour actualize_script Nouveau fichier temporaire ./data/actualize.lock.txt --- app/Controllers/indexController.php | 2 +- app/FreshRSS.php | 2 +- app/actualize_script.php | 20 ++++++++++++++++++-- data/.gitignore | 1 + 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'app/actualize_script.php') diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 5b51b3e28..690ca57be 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -133,7 +133,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { // Si on a récupéré aucun article "non lus" // on essaye de récupérer tous les articles - if ($state === 'not_read' && empty($entries)) { //TODO: Remove in v0.8 + if ($state === 'not_read' && empty($entries)) { Minz_Log::record ('Conflicting information about nbNotRead!', Minz_Log::DEBUG); $this->view->state = 'all'; $entries = $this->entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min, $keepHistoryDefault); diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 4ebb6d631..f9857a4cb 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -6,7 +6,7 @@ class FreshRSS extends Minz_FrontController { } $this->accessControl(Minz_Session::param('currentUser', '')); $this->loadParamsView(); - $this->loadStylesAndScripts(); + $this->loadStylesAndScripts(); //TODO: Do not load that when not needed, e.g. some Ajax requests $this->loadNotifications(); } diff --git a/app/actualize_script.php b/app/actualize_script.php index e0f995afe..6009ad849 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -1,7 +1,19 @@ +$lock = DATA_PATH . '/actualize.lock.txt'; +if (file_exists($lock) && ((time() - @filemtime($lock)) > 3600)) { + @unlink($lock); +} +if (($handle = @fopen($lock, 'x')) === false) { + syslog(LOG_INFO, 'FreshRSS actualize already running?'); + return; +} +register_shutdown_function('unlink', $lock); +//Could use http://php.net/function.pcntl-signal.php to catch interruptions +@fclose($handle); +// require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader @@ -10,8 +22,12 @@ ob_implicit_flush(false); ob_start(); echo 'Results: ', "\n"; //Buffered +Minz_Configuration::init(); + $users = listUsers(); -shuffle($users); +shuffle($users); //Process users in random order +array_unshift($users, Minz_Configuration::defaultUser()); //But always start with admin +$users = array_unique($users); foreach ($users as $myUser) { syslog(LOG_INFO, 'FreshRSS actualize ' . $myUser); diff --git a/data/.gitignore b/data/.gitignore index 005982b00..afb16d9aa 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -5,3 +5,4 @@ config.php touch.txt no-cache.txt *.bak.php +*.lock.txt -- cgit v1.2.3 From cd10140346ae26d9583ff341107a12406a505976 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 2 Jan 2014 15:05:34 +0100 Subject: actualize_script : messages d'erreur --- app/actualize_script.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/actualize_script.php') diff --git a/app/actualize_script.php b/app/actualize_script.php index 6009ad849..9ac80a852 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -7,7 +7,8 @@ if (file_exists($lock) && ((time() - @filemtime($lock)) > 3600)) { @unlink($lock); } if (($handle = @fopen($lock, 'x')) === false) { - syslog(LOG_INFO, 'FreshRSS actualize already running?'); + syslog(LOG_NOTICE, 'FreshRSS actualize already running?'); + fwrite(STDERR, 'FreshRSS actualize already running?' . "\n"); return; } register_shutdown_function('unlink', $lock); -- cgit v1.2.3