diff --git a/install/scripts/php-sessionclean.php b/install/scripts/php-sessionclean.php new file mode 100755 index 00000000..41f633db --- /dev/null +++ b/install/scripts/php-sessionclean.php @@ -0,0 +1,31 @@ +#!/usr/bin/php + (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Cron + * + */ + +// Check if we're in the CLI +if (@php_sapi_name() !== 'cli') { + die('This script will only work in the shell.'); +} + +require dirname(dirname(__DIR__)) . '/vendor/autoload.php'; + +// give control to command line handler +try { + \Froxlor\Cli\PhpSessioncleanCmd::processParameters($argc, $argv); +} catch (Exception $e) { + \Froxlor\Cli\PhpSessioncleanCmd::printerr($e->getMessage()); +} diff --git a/lib/Froxlor/Cli/Action/PhpSessioncleanAction.php b/lib/Froxlor/Cli/Action/PhpSessioncleanAction.php new file mode 100644 index 00000000..9ad09a15 --- /dev/null +++ b/lib/Froxlor/Cli/Action/PhpSessioncleanAction.php @@ -0,0 +1,100 @@ +validate(); + + if ((int) Settings::Get('phpfpm.enabled') == 1) { + if (isset($this->_args["max-lifetime"]) && is_numeric($this->_args["max-lifetime"]) && $this->_args["max-lifetime"] > 0) { + $this->cleanSessionfiles((int)$this->_args["max-lifetime"]); + } else { + // use default max-lifetime value + $this->cleanSessionfiles(); + } + } + } + + /** + * validates the parsed command line parameters + * + * @throws \Exception + */ + private function validate() + { + global $lng; + + $this->checkConfigParam(true); + $this->parseConfig(); + + require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php'; + } + + private function cleanSessionfiles(int $maxlifetime = 1440) + { + // store paths to clean up + $paths_to_clean = []; + // get all pool-config directories configured + $sel_stmt = Database::prepare("SELECT DISTINCT `config_dir` FROM `" . TABLE_PANEL_FPMDAEMONS . "`"); + Database::pexecute($sel_stmt); + while ($fpmd = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) { + $poolfiles = glob(\Froxlor\FileDir::makeCorrectFile($fpmd['config_dir'] . '/*.conf')); + foreach ($poolfiles as $cf) { + $contents = file_get_contents($cf); + $pattern = preg_quote('session.save_path', '/'); + $pattern = "/" . $pattern . ".+?\=(.*)/"; + if (preg_match_all($pattern, $contents, $matches)) { + $paths_to_clean[] = \Froxlor\FileDir::makeCorrectDir(trim($matches[1][0])); + } + } + } + + // every path is just needed once + $paths_to_clean = array_unique($paths_to_clean); + + if (count($paths_to_clean) > 0) { + foreach ($paths_to_clean as $ptc) { + // find all files older then maxlifetime and delete them + \Froxlor\FileDir::safe_exec("find -O3 \"" . $ptc . "\" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin \"+" . $maxlifetime . "\" -delete"); + } + } + } + private function parseConfig() + { + define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']); + if (!class_exists('\\Froxlor\\Database\\Database')) { + throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?"); + } + if (!file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) { + throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system."); + } + } + + private function checkConfigParam($needed = false) + { + if ($needed) { + if (!isset($this->_args["froxlor-dir"])) { + $this->_args["froxlor-dir"] = \Froxlor\Froxlor::getInstallDir(); + } elseif (!is_dir($this->_args["froxlor-dir"])) { + throw new \Exception("Given --froxlor-dir parameter is not a directory"); + } elseif (!file_exists($this->_args["froxlor-dir"])) { + throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')"); + } elseif (!is_readable($this->_args["froxlor-dir"])) { + throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')"); + } + } + } +} diff --git a/lib/Froxlor/Cli/PhpSessioncleanCmd.php b/lib/Froxlor/Cli/PhpSessioncleanCmd.php new file mode 100644 index 00000000..4d83e7c3 --- /dev/null +++ b/lib/Froxlor/Cli/PhpSessioncleanCmd.php @@ -0,0 +1,64 @@ + (2018-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Cron + * + */ +class PhpSessioncleanCmd extends CmdLineHandler +{ + + /** + * list of valid switches + * + * @var array + */ + public static $switches = array( + 'h' + ); + + /** + * list of valid parameters + * + * @var array + */ + public static $params = array( + 'froxlor-dir', + 'max-lifetime', + 'help' + ); + + public static $action_class = '\\Froxlor\\Cli\\Action\\PhpSessioncleanAction'; + + public static function printHelp() + { + self::println(""); + self::println("Help / command line parameters:"); + self::println(""); + // commands + self::println("--froxlor-dir\t\tpath to froxlor installation"); + self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/"); + self::println(""); + self::println("--max-lifetime\t\tThe number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Defaults to '1440'"); + self::println("\t\t\tExample: --max-lifetime=2000"); + self::println(""); + self::println("--help\t\t\tshow help screen (this)"); + self::println(""); + // switches + self::println("-h\t\t\tsame as --help"); + self::println(""); + + die(); // end of execution + } +}