Edit file File name : check Content :#!/usr/bin/php <?php global $processlist, $pids; $logging = false; if ($logging) { $my_file = '/root/cron.log'; $handle = fopen($my_file, 'a') or die('Cannot open file: ' . $my_file); $data = date('Y-m-d H:i:s') . " Starting cron \n"; fwrite($handle, $data); } $processlist = []; $pids = []; /* Plesk Memcache Options, cpanel options are handled on a per-user basis */ $memory_per_instance = 16; $mem_a = 770; // Specify the access mask to be used for the Unix socket, in octal $mem_t = 1; //Specify the number of threads to use when processing incoming requests $max_connection = 1024; $mem_R = 20; //Sets the maximum number of requests per event process $ps = shell_exec("/usr/bin/ps -Ao user:40,pid,start_time,command --sort=user,command,-start_time | grep [m]emcached[^\/] "); $ps = explode("\n", $ps); foreach ($ps as $i => $process) { //create a hash by user of all running memcached instances $process_arr = explode(' ', preg_replace("/[\s]+/", ' ', $process)); if (!isset($processlist[$process_arr[0]])) { $processlist[$process_arr[0]] = []; } if ($process_arr[0] != '') { $processlist[$process_arr[0]][$process_arr[1]] = ['time' => $process_arr[2], 'command' => implode(array_slice($process_arr, 3), ' ')]; if($process_arr[0] != 'memcached'){ // We don't want to add the system memcached to our list so it stays running $pids[$process_arr[1]] = 1;//create hash of just pids running memcached echo 'found memcache: ' . $process_arr[1] . "\n"; } } } if (file_exists('/usr/local/cpanel/cpanel')) { // We're on cpanel // Check if this is a litespeed server, if so let softaculous know if(file_exists('/usr/local/lsws/conf/httpd_config.xml')){ touch('/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/hooks/is-turbo-server'); } // get a list of all cpanel users and save it to a file, read the file and cycle through each user shell_exec('/usr/bin/ls -1 /var/cpanel/users > /opt/memcached/etc/memcached_users'); $users = file('/opt/memcached/etc/memcached_users'); foreach ($users as $num => $username) { if(trim($username) == "system"){ continue; } echo "$username\n"; $username = trim($username); /* We check to see if the user has a directory on the system * Then we check if there is a folder to hold the memcache socket, creating it with proper permissions if not * Next we create a .memcached folder in the user's home dir to store config data * If the user has a file name ".memcached.on" in their home dir, they are flagged to be able to use memcached. * This file is setup by A2 Optimized cpanel * We read through the config file and setup X number of memcached instances for the user * */ if (file_exists("/var/cpanel/users/{$username}")) { if (!is_dir("/opt/memcached/run/{$username}")) { echo "\tmaking directory /opt/memcached/run/{$username}\n"; mkdir("/opt/memcached/run/{$username}"); } chown("/opt/memcached/run/{$username}", $username); chgrp("/opt/memcached/run/{$username}", $username); if (!is_dir("/home/{$username}/.memcached")) { mkdir("/home/{$username}/.memcached"); chown("/home/{$username}/.memcached", $username); chgrp("/home/{$username}/.memcached", $username); } $memcached_file = "/home/{$username}/.memcached/memcached.json"; if (file_exists($memcached_file)) { $instances = (array)json_decode(file_get_contents($memcached_file)); } else { $instances = []; } $ids = []; foreach ($instances as $i => $instance) { $ids[$i] = true; } $conf_file = "/opt/memcached/etc/conf/{$username}.conf"; //make sure there is at least a default .conf for the user if (!file_exists($conf_file)) { if (file_exists($memcached_file)) { $fh = fopen($conf_file, 'w+'); fwrite($fh, "1,{$username},770,16,1,1024,20"); fclose($fh); } } if (file_exists($conf_file) && file_exists("/home/{$username}/.memcached.on")) { echo "\nfound $conf_file\n"; $configs = file($conf_file); foreach ($configs as $confignum => $config) { echo "\tfound config $config"; $config = explode(',', trim($config)); //config file contains 0->unique_id,1->username,2->a,3->m,4->t,5->c,6->R $command = "/usr/bin/memcached -P /opt/memcached/run/{$config[1]}/memcached-{$config[0]}.pid -u {$config[1]} -a {$config[2]} -m {$config[3]} -t {$config[4]} -c {$config[5]} -R {$config[6]} -s /opt/memcached/run/{$config[1]}/memcached-{$config[0]}.sock -d"; //echo "\t\t$command\n"; $running = false; if (file_exists("/opt/memcached/run/{$config[1]}/memcached-{$config[0]}.pid")) { $socket = "/opt/memcached/run/{$config[1]}/memcached-{$config[0]}.sock"; if (!isset($instances[$config[0]])) { $instances[$config[0]] = []; } else { $instances[$config[0]] = json_decode(json_encode($instances[$config[0]]),true); } $instances[$config[0]]['socket'] = "unix://{$socket}"; $instances[$config[0]]['socket_path'] = $socket; $instances[$config[0]]['id'] = $config[0]; $instances[$config[0]]['user'] = $config[1]; $instances[$config[0]]['perms'] = $config[2]; $instances[$config[0]]['size'] = $config[3]; $instances[$config[0]]['threads'] = $config[4]; $instances[$config[0]]['max_connections'] = $config[5]; $instances[$config[0]]['sequential_requests'] = $config[6]; $instances[$config[0]]['pidfile'] = "/opt/memcached/run/{$config[1]}/memcached-{$config[0]}.pid"; unset($ids[$config[0]]); $memcache = new MemcacheLite(); if ($memcache->connect($socket) ) { $stats = $memcache->get_stats(); if (isset($stats['pid'])) { if (isset($pids[$stats['pid']]) && isset($processlist[$config[1]][$stats['pid']])) { //echo "\t\t{$processlist[$config[1]][$stats['pid']]["command"]}\n"; if (strpos($processlist[$config[1]][$stats['pid']]['command'], $command) === 0) { // trim($processlist[$config[1]][$stats['pid']]["command"]) == trim($command)){ echo "\t\t{$stats['pid']} Running\n"; $running = true; unset($pids[$stats['pid']]); } else { echo "\t\tcommands did not match - starting a new memcached instance\n"; } } else { echo "\t\tpid returned by memcached did not match a known pid - starting a new memcached instance\n"; } } else { echo "\t\tno pid was returned by memcached - starting a new memcached instance\n"; } } } if (!$running) { echo "starting {$command}"; $res = shell_exec($command); } } } } foreach ($ids as $id => $val) { unset($instances[$id]); } $fp = fopen($memcached_file, 'w+'); fwrite($fp, json_encode($instances)); fclose($fp); } } if (file_exists('/usr/sbin/plesk')) { // We're on Plesk // get a list of all plesk users and save it to a file, read the file and cycle through each user shell_exec('/usr/sbin/plesk bin client --list > /opt/memcached/etc/memcached_users'); $users = file('/opt/memcached/etc/memcached_users'); foreach ($users as $num => $username) { echo "$username\n"; $username = trim($username); /* We check to see if the user has a folder to hold the memcache socket, creating it with proper permissions if not * All users have memcached access so we don't need to set flags. * Also all users only have a single instance so no need to read / write individual configs, just spin up an memcached instance */ if (posix_getpwnam($username)) { if (!is_dir("/opt/memcached/run/{$username}")) { echo "\tmaking directory /opt/memcached/run/{$username}\n"; mkdir("/opt/memcached/run/{$username}"); } chown("/opt/memcached/run/{$username}", $username); chgrp("/opt/memcached/run/{$username}", 'psaserv'); /* Possible to get instances from wp-toolkit sqlite db? Currently we have a single memcache instance per account as per Andy Melichar */ $instance = 1; $command = "/usr/bin/memcached -P /opt/memcached/run/{$username}/memcached-{$instance}.pid -u {$username} -a {$mem_a} -m {$memory_per_instance} -t {$mem_t} -c {$max_connection} -R {$mem_R} -s /opt/memcached/run/{$username}/memcached-{$instance}.sock -d"; //echo "\t\t$command\n"; $running = false; if (file_exists("/opt/memcached/run/{$username}/memcached-{$instance}.pid")) { $socket = "/opt/memcached/run/{$username}/memcached-{$instance}.sock"; if (!isset($instances[$username])) { $instances[$username] = []; } $instances[$username]['socket'] = "unix://{$socket}"; $instances[$username]['socket_path'] = $socket; $instances[$username]['id'] = $username; $instances[$username]['user'] = $username; $instances[$username]['perms'] = $mem_a; $instances[$username]['size'] = $memory_per_instance; $instances[$username]['threads'] = $mem_t; $instances[$username]['max_connections'] = $max_connection; $instances[$username]['sequential_requests'] = $mem_R; $instances[$username]['pidfile'] = "/opt/memcached/run/{$username}/memcached-{$instance}.pid"; $memcache = new MemcacheLite(); if ($memcache->connect($socket) ) { $stats = $memcache->get_stats(); if (isset($stats['pid'])) { if (isset($pids[$stats['pid']]) && isset($processlist[$username][$stats['pid']])) { //echo "\t\t{$processlist[$config[1]][$stats['pid']]["command"]}\n"; if (strpos($processlist[$username][$stats['pid']]['command'], $command) === 0) { // trim($processlist[$config[1]][$stats['pid']]["command"]) == trim($command)){ echo "\t\t{$stats['pid']} Running\n"; $running = true; unset($pids[$stats['pid']]); } else { echo "\t\tcommands did not match - starting a new memcached instance\n"; } } else { echo "\t\tpid returned by memcached did not match a known pid - starting a new memcached instance\n"; } } else { echo "\t\tno pid was returned by memcached - starting a new memcached instance\n"; } } } if (!$running) { echo "starting {$command}"; $res = shell_exec($command); } } } /* Check instances for WP Login change */ $instances = getAllInstances(); echo "Checking for login url changes\n"; foreach ($instances as $instance) { /* Go into each sites directory to check if change files exist */ $site_path = wpcli("eval 'echo ABSPATH;'", $instance['id']); echo "Checking $site_path \n"; $new_login = null; if (file_exists($site_path . '.rwl_setdefault')) { echo "Found setdefault for $site_path \n"; $new_login = 'wp-login.php'; unlink($site_path . '.rwl_setdefault'); } if(file_exists($site_path . 'wp-config.bak.a2')){ // Move readable wp-config file to un-readable rename($site_path . 'wp-config.bak.a2', $site_path . 'wp-config.bak-a2.php'); } $plugin_status_output = wpcli("plugin status easy-hide-login", $instance['id']); if (strpos($plugin_status_output, 'Active') == false) { // Old hide login plugin is active if (file_exists($site_path . '.rwl_update')) { echo "Found update for $site_path \n"; $new_login = wpcli('option get a2_login_page', $instance['id']); unlink($site_path . '.rwl_update'); } if ($new_login) { $message = "Setting new login for $site_path \n"; if ($logging) { $data = date('Y-m-d H:i:s') . ' ' . $message; fwrite($handle, $data); } echo $message; setInstanceLogin($instance['id'], 'wp-login.php?' . $new_login . '&redirect=false'); } } } } /* If there are any memcached pids that aren't assigned to a valid user, we kill them */ foreach ($pids as $pid => $running) { echo "kill {$pid}\n"; $res = shell_exec("/usr/bin/kill {$pid}"); } if ($logging) { $new_data = date('Y-m-d H:i:s') . " Finished cron \n"; fwrite($handle, $new_data); } echo "\n\nComplete\n\n"; class MemcacheLite { protected $connection; protected $socket; public function connect($socket = '') { socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 1, 'usec' => 0]); socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, ['sec' => 1, 'usec' => 0]); if ($socket != '') { $this->socket = $socket; } if ($this->connection = socket_create(AF_UNIX, SOCK_STREAM, 0)) { if (!socket_connect($this->connection, $socket)) { echo "\t\tcould not connect to {$socket}\n"; return false; } } else { echo "\t\tphp could not create a socket connector\n"; return false; } return true; } public function close() { socket_close($this->connection); } public function get_stats() { $stats = []; socket_write($this->connection, "stats\n"); $data = socket_read($this->connection, 2048, PHP_BINARY_READ); $lines = explode("\n", $data); foreach ($lines as $linenum => $line) { if (trim($line) != '') { $line_arr = explode(' ', $line); if (count($line_arr) == 3) { $stats[$line_arr[1]] = trim($line_arr[2]); } } } return $stats; } } /** * Gets all WP instances from Plesk sqlite db * * @return array of instance objects */ function getAllInstances() { try { /* Get all instances */ $myPDO = new PDO('sqlite:/usr/local/psa/var/modules/wp-toolkit/wp-toolkit.sqlite3'); $statement = $myPDO->prepare(' SELECT * FROM Instances '); $statement->execute(); return $statement->fetchall(PDO::FETCH_ASSOC); } catch (PDOException $e) { echo 'PDOException with getAllInstances ' . $e->getMessage() . "\n"; return false; } } /** * Sets Instance Login * * @param int $instance_id for instance being updated * @param string $new_login new string being used for login, either random or default * * @return bool true if successfully updated login, false if PDO exception */ function setInstanceLogin($instance_id, $new_login) { try { $new_login = $new_login . '/'; echo "updating sqlite: $instance_id $new_login \n"; $myPDO = new PDO('sqlite:/usr/local/psa/var/modules/wp-toolkit/wp-toolkit.sqlite3'); /* $statement = $myPDO->prepare(' INSERT into InstanceProperties (instanceID, name, value) VALUES (:instanceId, \'customLoginPostfix\', :value) ON DUPLICATE KEY UPDATE value=:new_login '); $statement->bindParam(':value', $new_login, PDO::PARAM_STR); $statement->bindParam(':new_login', $new_login, PDO::PARAM_STR); $statement->bindParam(':instanceId', $instance_id, PDO::PARAM_INT); $statement->execute(); */ $existing_record = $myPDO->prepare(' SELECT * FROM InstanceProperties WHERE instanceId = :instanceId AND name = \'customLoginPostfix\' '); $existing_record->bindParam(':instanceId', $instance_id, PDO::PARAM_INT); $existing_record->execute(); $row = $existing_record->fetch(PDO::FETCH_ASSOC); if ($row) { // Update $statement = $myPDO->prepare(' UPDATE InstanceProperties SET value = :new_login WHERE instanceId = :instanceId AND name = \'customLoginPostfix\' '); } else { // Insert $statement = $myPDO->prepare(' INSERT INTO InstanceProperties ( value, instanceId, name ) VALUES ( :new_login, :instanceId, \'customLoginPostfix\' ) '); } $statement->bindParam(':new_login', $new_login, PDO::PARAM_STR); $statement->bindParam(':instanceId', $instance_id, PDO::PARAM_INT); $statement->execute(); } catch (PDOException $e) { echo "PDOException with setInstanceLogin $instance_id " . $e->getMessage() . "\n"; return false; } return true; } /** * Basic method for using wordpress comandline commands * * @param string $do this command * @param int $instance_id of instance command is being done on * * @return string of what wpcli returned after attempting action. */ function wpcli($do, $instance_id) { $cmd = '/usr/sbin/plesk ext wp-toolkit --wp-cli -instance-id ' . $instance_id . ' -- ' . $do; $wpcli_returned = trim(shell_exec($cmd)); return $wpcli_returned; } ?>Save