- Implemented: New cron class and split up cron_daily
- Implemented: FS#3110 - Turn monitoring module into cron jobs
2 files deleted
3 files modified
34 files added
| | |
| | | `value` varchar(255) NOT NULL |
| | | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
| | | |
| | | |
| | | -- -------------------------------------------------------- |
| | | |
| | | -- |
| | | -- Table structure for table `sys_cron` |
| | | -- |
| | | |
| | | CREATE TABLE IF NOT EXISTS `sys_cron` ( |
| | | `name` varchar(50) NOT NULL, |
| | | `last_run` datetime NULL DEFAULT NULL, |
| | | `next_run` datetime NULL DEFAULT NULL, |
| | | `running` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', |
| | | PRIMARY KEY (`name`) |
| | | ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
| | | |
| | | |
| | | -- -------------------------------------------------------- |
| | | |
| | | -- |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2007-2012, Till Brehm, projektfarm Gmbh |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | define('SCRIPT_PATH', dirname($_SERVER["SCRIPT_FILENAME"])); |
| | | require(SCRIPT_PATH."/lib/config.inc.php"); |
| | | require(SCRIPT_PATH."/lib/app.inc.php"); |
| | | |
| | | set_time_limit(0); |
| | | ini_set('error_reporting', E_ALL & ~E_NOTICE); |
| | | |
| | | // make sure server_id is always an int |
| | | $conf['server_id'] = intval($conf['server_id']); |
| | | |
| | | |
| | | // Load required base-classes |
| | | $app->uses('ini_parser,file,services,getconf,system,cron,functions'); |
| | | $app->load('libdatetime,cronjob'); |
| | | |
| | | |
| | | // read all cron jobs |
| | | $path = SCRIPT_PATH . '/lib/classes/cron.d'; |
| | | if(!is_dir($path)) die('Cron path missing!'); |
| | | $files = array(); |
| | | $d = opendir($path); |
| | | while($f = readdir($d)) { |
| | | $file_path = $path . '/' . $f; |
| | | if($f === '.' || $f === '..' || !is_file($file_path)) continue; |
| | | if(substr($f, strrpos($f, '.')) !== '.php') continue; |
| | | $files[] = $f; |
| | | } |
| | | closedir($d); |
| | | |
| | | // sort in alphabetical order, so we can use prefixes like 000-xxx |
| | | sort($files); |
| | | |
| | | foreach($files as $f) { |
| | | $name = substr($f, 0, strpos($f, '.')); |
| | | if(preg_match('/^\d+\-(.*)$/', $name, $match)) $name = $match[1]; // strip numerical prefix from file name |
| | | |
| | | include($path . '/' . $f); |
| | | $class_name = 'cronjob_' . $name; |
| | | |
| | | if(class_exists($class_name, false)) { |
| | | $cronjob = new $class_name(); |
| | | if(get_parent_class($cronjob) !== 'cronjob') { |
| | | print 'Invalid class ' . $class_name . ' not extending class cronjob (' . get_parent_class($cronjob) . ')!' . "\n"; |
| | | unset($cronjob); |
| | | continue; |
| | | } |
| | | print 'Included ' . $class_name . ' from ' . $file_path . ' -> will now run job.' . "\n"; |
| | | |
| | | $cronjob->run(); |
| | | |
| | | print 'run job (' . $class_name . ') done.' . "\n"; |
| | | |
| | | unset($cronjob); |
| | | } |
| | | } |
| | | unset($files); |
| | | |
| | | die("finished.\n"); |
| | | |
| | | ?> |
New file |
| | |
| | | #!/bin/sh |
| | | |
| | | PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin |
| | | |
| | | if [ -f /usr/local/ispconfig/server/lib/php.ini ]; then |
| | | PHPINIOWNER=`stat -c %U /usr/local/ispconfig/server/lib/php.ini` |
| | | if [ $PHPINIOWNER == 'root' ] || [ $PHPINIOWNER == 'ispconfig' ]; then |
| | | export PHPRC=/usr/local/ispconfig/server/lib |
| | | fi |
| | | fi |
| | | |
| | | /usr/bin/php -q /usr/local/ispconfig/server/cron.php |
old mode 100644
new mode 100755
| | |
| | | #!/bin/sh |
| | | |
| | | PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin |
| | | |
| | | if [ -f /usr/local/ispconfig/server/lib/php.ini ]; then |
| | | PHPINIOWNER=`stat -c %U /usr/local/ispconfig/server/lib/php.ini` |
| | | if [ $PHPINIOWNER == 'root' ] || [ $PHPINIOWNER == 'ispconfig' ]; then |
| | | export PHPRC=/usr/local/ispconfig/server/lib |
| | | fi |
| | | fi |
| | | |
| | | /usr/bin/php -q /usr/local/ispconfig/server/cron_daily.php |
| | | |
| | | if [ -f /usr/local/ispconfig/server/cron_daily_billing.sh ]; then |
| | | /usr/local/ispconfig/server/cron_daily_billing.sh |
| | | fi |
| | | echo "This script is no longer used. Use the cron.sh instead." |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_mailbox_stats extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | // cronjob code here |
| | | |
| | | ####################################################################################################### |
| | | // store the mailbox statistics in the database |
| | | ####################################################################################################### |
| | | |
| | | $parse_mail_log = false; |
| | | $sql = "SELECT mailuser_id,maildir FROM mail_user WHERE server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | if(count($records) > 0) $parse_mail_log = true; |
| | | |
| | | foreach($records as $rec) { |
| | | if(@is_file($rec['maildir'].'/ispconfig_mailsize')) { |
| | | $parse_mail_log = false; |
| | | |
| | | // rename file |
| | | rename($rec['maildir'].'/ispconfig_mailsize',$rec['maildir'].'/ispconfig_mailsize_save'); |
| | | |
| | | // Read the file |
| | | $lines = file($rec['maildir'].'/ispconfig_mailsize_save'); |
| | | $mail_traffic = 0; |
| | | foreach($lines as $line) { |
| | | $mail_traffic += intval($line); |
| | | } |
| | | unset($lines); |
| | | |
| | | // Delete backup file |
| | | if(@is_file($rec['maildir'].'/ispconfig_mailsize_save')) unlink($rec['maildir'].'/ispconfig_mailsize_save'); |
| | | |
| | | // Save the traffic stats in the sql database |
| | | $tstamp = date('Y-m'); |
| | | |
| | | $sql = "SELECT * FROM mail_traffic WHERE month = '$tstamp' AND mailuser_id = ".$rec['mailuser_id']; |
| | | $tr = $app->dbmaster->queryOneRecord($sql); |
| | | |
| | | $mail_traffic += $tr['traffic']; |
| | | if($tr['traffic_id'] > 0) { |
| | | $sql = "UPDATE mail_traffic SET traffic = $mail_traffic WHERE traffic_id = ".$tr['traffic_id']; |
| | | } else { |
| | | $sql = "INSERT INTO mail_traffic (month,mailuser_id,traffic) VALUES ('$tstamp',".$rec['mailuser_id'].",$mail_traffic)"; |
| | | } |
| | | $app->dbmaster->query($sql); |
| | | //echo $sql; |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | if($parse_mail_log == true) { |
| | | $mailbox_traffic = array(); |
| | | $mail_boxes = array(); |
| | | $mail_rewrites = array(); // we need to read all mail aliases and forwards because the address in amavis is not always the mailbox address |
| | | |
| | | function parse_mail_log_line($line) { |
| | | //Oct 31 17:35:48 mx01 amavis[32014]: (32014-05) Passed CLEAN, [IPv6:xxxxx] [IPv6:xxxxx] <xxx@yyyy> -> <aaaa@bbbb>, Message-ID: <xxxx@yyyyy>, mail_id: xxxxxx, Hits: -1.89, size: 1591, queued_as: xxxxxxx, 946 ms |
| | | |
| | | if(preg_match('/^(\w+\s+\d+\s+\d+:\d+:\d+)\s+[^ ]+\s+amavis.* <([^>]+)>\s+->\s+((<[^>]+>,)+) .*Message-ID:\s+<([^>]+)>.* size:\s+(\d+),.*$/', $line, $matches) == false) return false; |
| | | |
| | | $timestamp = strtotime($matches[1]); |
| | | if(!$timestamp) return false; |
| | | |
| | | $to = array(); |
| | | $recipients = explode(',', $matches[3]); |
| | | foreach($recipients as $recipient) { |
| | | $recipient = substr($recipient, 1, -1); |
| | | if(!$recipient || $recipient == $matches[2]) continue; |
| | | $to[] = $recipient; |
| | | } |
| | | |
| | | return array('line' => $line, 'timestamp' => $timestamp, 'size' => $matches[6], 'from' => $matches[2], 'to' => $to, 'message-id' => $matches[5]); |
| | | } |
| | | |
| | | function add_mailbox_traffic(&$traffic_array, $address, $traffic) { |
| | | global $mail_boxes, $mail_rewrites; |
| | | |
| | | $address = strtolower($address); |
| | | |
| | | if(in_array($address, $mail_boxes) == true) { |
| | | if(!isset($traffic_array[$address])) $traffic_array[$address] = 0; |
| | | $traffic_array[$address] += $traffic; |
| | | } elseif(array_key_exists($address, $mail_rewrites)) { |
| | | foreach($mail_rewrites[$address] as $address) { |
| | | if(!isset($traffic_array[$address])) $traffic_array[$address] = 0; |
| | | $traffic_array[$address] += $traffic; |
| | | } |
| | | } else { |
| | | // this is not a local address - skip it |
| | | } |
| | | } |
| | | |
| | | $sql = "SELECT email FROM mail_user WHERE server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | foreach($records as $record) { |
| | | $mail_boxes[] = $record['email']; |
| | | } |
| | | $sql = "SELECT source, destination FROM mail_forwarding WHERE server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | foreach($records as $record) { |
| | | $targets = preg_split('/[\n,]+/', $record['destination']); |
| | | foreach($targets as $target) { |
| | | if(in_array($target, $mail_boxes)) { |
| | | if(isset($mail_rewrites[$record['source']])) $mail_rewrites[$record['source']][] = $target; |
| | | else $mail_rewrites[$record['source']] = array($target); |
| | | } |
| | | } |
| | | } |
| | | |
| | | $state_file = dirname(__FILE__) . '/mail_log_parser.state'; |
| | | $prev_line = false; |
| | | $last_line = false; |
| | | $cur_line = false; |
| | | |
| | | if(file_exists($state_file)) { |
| | | $prev_line = parse_mail_log_line(trim(file_get_contents($state_file))); |
| | | //if($prev_line) echo "continuing from previous run, log position: " . $prev_line['message-id'] . " at " . strftime('%d.%m.%Y %H:%M:%S', $prev_line['timestamp']) . "\n"; |
| | | } |
| | | |
| | | if(file_exists('/var/log/mail.log')) { |
| | | $fp = fopen('/var/log/mail.log', 'r'); |
| | | //echo "Parsing mail.log...\n"; |
| | | $l = 0; |
| | | while($line = fgets($fp, 8192)) { |
| | | $l++; |
| | | //if($l % 1000 == 0) echo "\rline $l"; |
| | | $cur_line = parse_mail_log_line($line); |
| | | if(!$cur_line) continue; |
| | | |
| | | if($prev_line) { |
| | | // check if this line has to be processed |
| | | if($cur_line['timestamp'] < $prev_line['timestamp']) { |
| | | $parse_mail_log = false; // we do not need to parse the second file! |
| | | continue; // already processed |
| | | } elseif($cur_line['timestamp'] == $prev_line['timestamp'] && $cur_line['message-id'] == $prev_line['message-id']) { |
| | | $parse_mail_log = false; // we do not need to parse the second file! |
| | | $prev_line = false; // this line has already been processed but the next one has to be! |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | add_mailbox_traffic($mailbox_traffic, $cur_line['from'], $cur_line['size']); |
| | | foreach($cur_line['to'] as $to) { |
| | | add_mailbox_traffic($mailbox_traffic, $to, $cur_line['size']); |
| | | } |
| | | $last_line = $line; // store for the state file |
| | | } |
| | | fclose($fp); |
| | | //echo "\n"; |
| | | } |
| | | |
| | | if($parse_mail_log == true && file_exists('/var/log/mail.log.1')) { |
| | | $fp = fopen('/var/log/mail.log.1', 'r'); |
| | | //echo "Parsing mail.log.1...\n"; |
| | | $l = 0; |
| | | while($line = fgets($fp, 8192)) { |
| | | $l++; |
| | | //if($l % 1000 == 0) echo "\rline $l"; |
| | | $cur_line = parse_mail_log_line($line); |
| | | if(!$cur_line) continue; |
| | | |
| | | if($prev_line) { |
| | | // check if this line has to be processed |
| | | if($cur_line['timestamp'] < $prev_line['timestamp']) continue; // already processed |
| | | if($cur_line['timestamp'] == $prev_line['timestamp'] && $cur_line['message-id'] == $prev_line['message-id']) { |
| | | $prev_line = false; // this line has already been processed but the next one has to be! |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | add_mailbox_traffic($mailbox_traffic, $cur_line['from'], $cur_line['size']); |
| | | foreach($cur_line['to'] as $to) { |
| | | add_mailbox_traffic($mailbox_traffic, $to, $cur_line['size']); |
| | | } |
| | | } |
| | | fclose($fp); |
| | | //echo "\n"; |
| | | } |
| | | unset($mail_rewrites); |
| | | unset($mail_boxes); |
| | | |
| | | // Save the traffic stats in the sql database |
| | | $tstamp = date('Y-m'); |
| | | $sql = "SELECT mailuser_id,email FROM mail_user WHERE server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | foreach($records as $rec) { |
| | | if(array_key_exists($rec['email'], $mailbox_traffic)) { |
| | | $sql = "SELECT * FROM mail_traffic WHERE month = '$tstamp' AND mailuser_id = ".$rec['mailuser_id']; |
| | | $tr = $app->dbmaster->queryOneRecord($sql); |
| | | |
| | | $mail_traffic = $tr['traffic'] + $mailbox_traffic[$rec['email']]; |
| | | if($tr['traffic_id'] > 0) { |
| | | $sql = "UPDATE mail_traffic SET traffic = $mail_traffic WHERE traffic_id = ".$tr['traffic_id']; |
| | | } else { |
| | | $sql = "INSERT INTO mail_traffic (month,mailuser_id,traffic) VALUES ('$tstamp',".$rec['mailuser_id'].",$mail_traffic)"; |
| | | } |
| | | $app->dbmaster->query($sql); |
| | | //echo $sql; |
| | | } |
| | | } |
| | | |
| | | unset($mailbox_traffic); |
| | | if($last_line) file_put_contents($state_file, $last_line); |
| | | } |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_clamav_log extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_clamav'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | // Todo: the state should be calculated. |
| | | $state = 'ok'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_freshclam'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* Get the data from the LAST log-Entry. |
| | | * if there can be found: |
| | | * WARNING: Your ClamAV installation is OUTDATED! |
| | | * then the clamav is outdated. This is a warning! |
| | | */ |
| | | $state = 'ok'; |
| | | |
| | | $tmp = explode("\n", $data); |
| | | $lastLog = array(); |
| | | if ($tmp[sizeof($tmp) - 1] == '') { |
| | | /* the log ends with an empty line remove this */ |
| | | array_pop($tmp); |
| | | } |
| | | if (strpos($tmp[sizeof($tmp) - 1], '-------------') !== false) { |
| | | /* the log ends with "-----..." remove this */ |
| | | array_pop($tmp); |
| | | } |
| | | for ($i = sizeof($tmp) - 1; $i > 0; $i--) { |
| | | if (strpos($tmp[$i], '---------') === false) { |
| | | /* no delimiter found, so add this to the last-log */ |
| | | $lastLog[] = $tmp[$i]; |
| | | } else { |
| | | /* delimiter found, so there is no more line left! */ |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Now we have the last log in the array. |
| | | * Check if the outdated-string is found... |
| | | */ |
| | | foreach ($lastLog as $line) { |
| | | if (strpos(strtolower($line), 'outdated') !== false) { |
| | | /* |
| | | * Outdatet is only info, because if we set this to warning, the server is |
| | | * as long in state warning, as there is a new version of ClamAv which takes |
| | | * sometimes weeks! |
| | | */ |
| | | $state = $this->_tools->_setState($state, 'info'); |
| | | } |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_cpu extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'cpu_info'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | if (file_exists('/proc/cpuinfo')) { |
| | | $cpuData = shell_exec('cat /proc/cpuinfo'); |
| | | $cpuInfo = explode("\n", $cpuData); |
| | | $processor = 0; |
| | | |
| | | foreach ($cpuInfo as $line) { |
| | | |
| | | $part = preg_split('/:/', $line); |
| | | $key = trim($part[0]); |
| | | $value = trim($part[1]); |
| | | if ($key == 'processor') |
| | | $processor = intval($value); |
| | | if ($key != '') |
| | | $data[$key . ' ' . $processor] = $value; |
| | | } |
| | | |
| | | /* the cpu has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * It is not Linux, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_disk_usage extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'disk_usage'; |
| | | |
| | | /** The state of the disk-usage */ |
| | | $state = 'ok'; |
| | | |
| | | /** Fetch the data of ALL devices into a array (needed for monitoring!) */ |
| | | //$dfData = shell_exec('df -hT 2>/dev/null'); |
| | | $app->uses('getconf'); |
| | | $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); |
| | | $dfData = shell_exec('df -hT|grep -v "'.$web_config['website_basedir'].'/" 2>/dev/null'); |
| | | |
| | | // split into array |
| | | $df = explode("\n", $dfData); |
| | | |
| | | /* |
| | | * ignore the first line, process the rest |
| | | */ |
| | | for ($i = 1; $i <= sizeof($df); $i++) { |
| | | if ($df[$i] != '') { |
| | | /* |
| | | * Make an array of the data |
| | | */ |
| | | $s = preg_split('/[\s]+/', $df[$i]); |
| | | $data[$i]['fs'] = $s[0]; |
| | | $data[$i]['type'] = $s[1]; |
| | | $data[$i]['size'] = $s[2]; |
| | | $data[$i]['used'] = $s[3]; |
| | | $data[$i]['available'] = $s[4]; |
| | | $data[$i]['percent'] = $s[5]; |
| | | $data[$i]['mounted'] = $s[6]; |
| | | /* |
| | | * calculate the state |
| | | */ |
| | | $usePercent = floatval($data[$i]['percent']); |
| | | |
| | | //* get the free memsize |
| | | if(substr($data[$i]['available'],-1) == 'G') { |
| | | $freesize = floatval($data[$i]['available'])*1024; |
| | | } elseif(substr($data[$i]['available'],-1) == 'T') { |
| | | $freesize = floatval($data[$i]['available'])*1024*1024; |
| | | } else { |
| | | $freesize = floatval($data[$i]['available']); |
| | | } |
| | | |
| | | //* We don't want to check some filesystem which have no sensible filling levels |
| | | switch ($data[$i]['type']) { |
| | | case 'iso9660': |
| | | case 'cramfs': |
| | | case 'udf': |
| | | case 'tmpfs': |
| | | case 'devtmpfs': |
| | | case 'udev': |
| | | break; |
| | | default: |
| | | if ($usePercent > 75 && $freesize < 2000) |
| | | $state = $this->_tools->_setState($state, 'info'); |
| | | if ($usePercent > 80 && $freesize < 1000) |
| | | $state = $this->_tools->_setState($state, 'warning'); |
| | | if ($usePercent > 90 && $freesize < 500) |
| | | $state = $this->_tools->_setState($state, 'critical'); |
| | | if ($usePercent > 95 && $freesize < 100) |
| | | $state = $this->_tools->_setState($state, 'error'); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_email_quota extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/15 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | $app->uses('getconf'); |
| | | $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); |
| | | if($mail_config['mailbox_quota_stats'] == 'n') return; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | |
| | | //* Initialize data array |
| | | $data = array(); |
| | | |
| | | //* the id of the server as int |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | //* The type of the data |
| | | $type = 'email_quota'; |
| | | |
| | | //* The state of the email_quota. |
| | | $state = 'ok'; |
| | | |
| | | $mailboxes = $app->db->queryAllRecords("SELECT email,maildir FROM mail_user WHERE server_id = $server_id"); |
| | | if(is_array($mailboxes)) { |
| | | foreach($mailboxes as $mb) { |
| | | $email = $mb['email']; |
| | | $email_parts = explode('@',$mb['email']); |
| | | $filename = $mb['maildir'].'/.quotausage'; |
| | | if(file_exists($filename) && !is_link($filename)) { |
| | | $quotafile = file($filename); |
| | | $data[$email]['used'] = trim($quotafile['1']); |
| | | unset($quotafile); |
| | | } else { |
| | | exec('du -s '.escapeshellcmd($mb['maildir']),$out); |
| | | $parts = explode(' ',$out[0]); |
| | | $data[$email]['used'] = intval($parts[0])*1024; |
| | | unset($out); |
| | | unset($parts); |
| | | } |
| | | } |
| | | } |
| | | |
| | | unset($mailboxes); |
| | | |
| | | //* Dovecot quota check Courier in progress lathama@gmail.com |
| | | /* |
| | | if($dir = opendir("/var/vmail")){ |
| | | while (($quotafiles = readdir($dir)) !== false){ |
| | | if(preg_match('/.\_quota$/', $quotafiles)){ |
| | | $quotafile = (file("/var/vmail/" . $quotafiles)); |
| | | $emailaddress = preg_replace('/_quota/',"", $quotafiles); |
| | | $emailaddress = preg_replace('/_/',"@", $emailaddress); |
| | | $data[$emailaddress]['used'] = trim($quotafile['1']); |
| | | } |
| | | } |
| | | closedir($dir); |
| | | } |
| | | */ |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_fail2ban extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_fail2ban'; |
| | | |
| | | /* This monitoring is only available if fail2ban is installed */ |
| | | system('which fail2ban-client', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval !== 0) |
| | | system('which fail2ban', $retval); // CentOS |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * fail2ban is not installed, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_hd_quota extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | //* Initialize data array |
| | | $data = array(); |
| | | |
| | | //* the id of the server as int |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | //* The type of the data |
| | | $type = 'harddisk_quota'; |
| | | |
| | | //* The state of the harddisk_quota. |
| | | $state = 'ok'; |
| | | |
| | | //* Fetch the data for all users |
| | | $dfData = shell_exec('repquota -au 2>/dev/null'); |
| | | |
| | | //* Split into array |
| | | $df = explode("\n", $dfData); |
| | | |
| | | //* ignore the first 5 lines, process the rest |
| | | for ($i = 5; $i <= sizeof($df); $i++) { |
| | | if ($df[$i] != '') { |
| | | //* Make a array of the data |
| | | $s = preg_split('/[\s]+/', $df[$i]); |
| | | $username = $s[0]; |
| | | if (substr($username, 0, 3) == 'web') { |
| | | if (isset($data['user'][$username])) { |
| | | $data['user'][$username]['used'] += $s[2]; |
| | | $data['user'][$username]['soft'] += $s[3]; |
| | | $data['user'][$username]['hard'] += $s[4]; |
| | | $data['user'][$username]['files'] += $s[5]; |
| | | } else { |
| | | $data['user'][$username]['used'] = $s[2]; |
| | | $data['user'][$username]['soft'] = $s[3]; |
| | | $data['user'][$username]['hard'] = $s[4]; |
| | | $data['user'][$username]['files'] = $s[5]; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //** Fetch the data for all users |
| | | $dfData = shell_exec('repquota -ag 2>/dev/null'); |
| | | |
| | | //* split into array |
| | | $df = explode("\n", $dfData); |
| | | |
| | | //* ignore the first 5 lines, process the rest |
| | | for ($i = 5; $i <= sizeof($df); $i++) { |
| | | if ($df[$i] != '') { |
| | | //* Make a array of the data |
| | | $s = preg_split('/[\s]+/', $df[$i]); |
| | | $groupname = $s[0]; |
| | | if (substr($groupname, 0, 6) == 'client') { |
| | | if (isset($data['group'][$groupname])) { |
| | | $data['group'][$groupname]['used'] += $s[1]; |
| | | $data['group'][$groupname]['soft'] += $s[2]; |
| | | $data['group'][$groupname]['hard'] += $s[3]; |
| | | } else { |
| | | $data['group'][$groupname]['used'] = $s[1]; |
| | | $data['group'][$groupname]['soft'] = $s[2]; |
| | | $data['group'][$groupname]['hard'] = $s[3]; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_iptables extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'iptables_rules'; |
| | | |
| | | /* This monitoring is only available if fail2ban is installed */ |
| | | system('which iptables', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data['output'] = '<h2>iptables -S (ipv4)</h2>'.shell_exec('iptables -S 2>/dev/null'); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | |
| | | /* This monitoring is only available if fail2ban is installed */ |
| | | system('which ip6tables', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data['output'] .= '<br><h2>ip6tables -S (ipv6)</h2>'.shell_exec('ip6tables -S 2>/dev/null'); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_ispconfig_log extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_ispconfig'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | // Todo: the state should be calculated. |
| | | $state = 'ok'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_ispc_cron'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | //* Ensure that output is encoded so that it does not break the serialize |
| | | if(is_array($res) && isset($res['data'])) $res['data'] = htmlentities($res['data']); |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_ispconfig_version extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'ispc_info'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $data['name'] = ISPC_APP_TITLE; |
| | | $data['version'] = ISPC_APP_VERSION; |
| | | |
| | | /* the ISPC-Version has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_mail_log extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mail'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mail_warn'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mail_err'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_mail_queue extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | private function _getIntArray($line) { |
| | | /** The array of float found */ |
| | | $res = array(); |
| | | /* First build a array from the line */ |
| | | $data = explode(' ', $line); |
| | | /* then check if any item is a float */ |
| | | foreach ($data as $item) { |
| | | if ($item . '' == (int) $item . '') { |
| | | $res[] = $item; |
| | | } |
| | | } |
| | | return $res; |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'mailq'; |
| | | |
| | | /* Get the data from the mailq */ |
| | | $data['output'] = shell_exec('mailq'); |
| | | |
| | | /* |
| | | * The last line has more informations |
| | | */ |
| | | $tmp = explode("\n", $data['output']); |
| | | $more = $tmp[sizeof($tmp) - 1]; |
| | | $res = $this->_getIntArray($more); |
| | | $data['bytes'] = $res[0]; |
| | | $data['requests'] = $res[1]; |
| | | |
| | | /** The state of the mailq. */ |
| | | $state = 'ok'; |
| | | if ($data['requests'] > 2000) |
| | | $state = 'info'; |
| | | if ($data['requests'] > 5000) |
| | | $state = 'warning'; |
| | | if ($data['requests'] > 8000) |
| | | $state = 'critical'; |
| | | if ($data['requests'] > 10000) |
| | | $state = 'error'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_mem_usage extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'mem_usage'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $miData = shell_exec('cat /proc/meminfo'); |
| | | |
| | | $memInfo = explode("\n", $miData); |
| | | |
| | | foreach ($memInfo as $line) { |
| | | $part = preg_split('/:/', $line); |
| | | $key = trim($part[0]); |
| | | $tmp = explode(' ', trim($part[1])); |
| | | $value = 0; |
| | | if ($tmp[1] == 'kB') |
| | | $value = $tmp[0] * 1024; |
| | | $data[$key] = $value; |
| | | } |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_mongodb extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mongodb'; |
| | | |
| | | /* This monitoring is only available if MongoDB is installed */ |
| | | system('which mongod', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval !== 0) |
| | | system('which mongod', $retval); // CentOS |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * MongoDB is not installed, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_openvz extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'openvz_veinfo'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $app->load(openvz_tools); |
| | | $openVzTools = new openvz_tools(); |
| | | $data = $openVzTools->getOpenVzVeInfo(); |
| | | |
| | | /* the VE-Info has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'openvz_beancounter'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $app->load(openvz_tools); |
| | | $openVzTools = new openvz_tools(); |
| | | $data = $openVzTools->getOpenVzVeBeanCounter(); |
| | | |
| | | /* calculate the state of the beancounter */ |
| | | if ($data == '') { |
| | | $state = 'no_state'; |
| | | } else { |
| | | $state = 'ok'; |
| | | |
| | | /* transfer this output-string into a array */ |
| | | $test = explode("\n", $data); |
| | | |
| | | /* the first list of the output is not needed */ |
| | | array_shift($test); |
| | | |
| | | /* now process all items of the rest */ |
| | | foreach ($test as $item) { |
| | | /* |
| | | * eliminate all doubled spaces and spaces at the beginning and end |
| | | */ |
| | | while (strpos($item, ' ') !== false) { |
| | | $item = str_replace(' ', ' ', $item); |
| | | } |
| | | $item = trim($item); |
| | | |
| | | /* |
| | | * The failcounter is the LAST |
| | | */ |
| | | if ($item != '') { |
| | | $tmp = explode(' ', $item); |
| | | $failCounter = $tmp[sizeof($tmp) - 1]; |
| | | if ($failCounter > 0) |
| | | $state = 'info'; |
| | | if ($failCounter > 50) |
| | | $state = 'warning'; |
| | | if ($failCounter > 200) |
| | | $state = 'critical'; |
| | | if ($failCounter > 10000) |
| | | $state = 'error'; |
| | | } |
| | | } |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_os_version extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = $app->functions->intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'os_info'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $dist = $this->_tools->get_distname(); |
| | | |
| | | $data['name'] = $dist['name']; |
| | | $data['version'] = $dist['version']; |
| | | |
| | | /* the OS has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_raid extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'raid_state'; |
| | | |
| | | /* |
| | | * We support several RAID types, but if we can't find any of them, we have no data |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | |
| | | /* |
| | | * Check, if Software-RAID is enabled |
| | | */ |
| | | if (file_exists('/proc/mdstat')) { |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('cat /proc/mdstat'); |
| | | |
| | | /* |
| | | * Then calc the state. |
| | | */ |
| | | $tmp = explode("\n", $data['output']); |
| | | $state = 'ok'; |
| | | for ($i = 0; $i < sizeof($tmp); $i++) { |
| | | /* fetch the next line */ |
| | | $line = $tmp[$i]; |
| | | |
| | | if ((strpos($line, '[U_]') !== false) || (strpos($line, '[_U]') !== false)) { |
| | | /* One Disk is not working. |
| | | * if the next line starts with "[>" or "[=" then |
| | | * recovery (resync) is in state and the state is |
| | | * information instead of critical |
| | | */ |
| | | $nextLine = $tmp[$i + 1]; |
| | | if ((strpos($nextLine, '[>') === false) && (strpos($nextLine, '[=') === false)) { |
| | | $state = $this->_tools->_setState($state, 'critical'); |
| | | } else { |
| | | $state = $this->_tools->_setState($state, 'info'); |
| | | } |
| | | } |
| | | if (strpos($line, '[__]') !== false) { |
| | | /* both Disk are not working */ |
| | | $state = $this->_tools->_setState($state, 'error'); |
| | | } |
| | | if (strpos($line, '[UU]') !== false) { |
| | | /* The disks are OK. |
| | | * if the next line starts with "[>" or "[=" then |
| | | * recovery (resync) is in state and the state is |
| | | * information instead of ok |
| | | */ |
| | | $nextLine = $tmp[$i + 1]; |
| | | if ((strpos($nextLine, '[>') === false) && (strpos($nextLine, '[=') === false)) { |
| | | $state = $this->_tools->_setState($state, 'ok'); |
| | | } else { |
| | | $state = $this->_tools->_setState($state, 'info'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | /* |
| | | * Check, if we have mpt-status installed (LSIsoftware-raid) |
| | | */ |
| | | if (file_exists('/proc/mpt/summary')) { |
| | | system('which mpt-status', $retval); |
| | | if ($retval === 0) { |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('mpt-status --autoload'); |
| | | |
| | | /* |
| | | * Then calc the state. |
| | | */ |
| | | $state = 'ok'; |
| | | if(is_array($data['output'])) { |
| | | foreach ($data['output'] as $item) { |
| | | /* |
| | | * The output contains information for every RAID and every HDD. |
| | | * We only need the state of the RAID |
| | | */ |
| | | if (strpos($item, 'state ') !== false) { |
| | | /* |
| | | * We found a raid, process the state of it |
| | | */ |
| | | if (strpos($item, ' ONLINE ') !== false) { |
| | | $this->_tools->_setState($state, 'ok'); |
| | | } elseif (strpos($item, ' OPTIMAL ') !== false) { |
| | | $this->_tools->_setState($state, 'ok'); |
| | | } elseif (strpos($item, ' INITIAL ') !== false) { |
| | | $this->_tools->_setState($state, 'info'); |
| | | } elseif (strpos($item, ' INACTIVE ') !== false) { |
| | | $this->_tools->_setState($state, 'critical'); |
| | | } elseif (strpos($item, ' RESYNC ') !== false) { |
| | | $this->_tools->_setState($state, 'info'); |
| | | } elseif (strpos($item, ' DEGRADED ') !== false) { |
| | | $this->_tools->_setState($state, 'critical'); |
| | | } else { |
| | | /* we don't know the state. so we set the state to critical, that the |
| | | * admin is warned, that something is wrong |
| | | */ |
| | | $this->_tools->_setState($state, 'critical'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * 3ware Controller |
| | | */ |
| | | system('which tw_cli', $retval); |
| | | if($retval === 0) { |
| | | |
| | | $data['output'] = shell_exec('tw_cli info c0'); |
| | | |
| | | $state = 'ok'; |
| | | if(is_array($data['output'])) { |
| | | foreach ($data['output'] as $item) { |
| | | if (strpos($item, 'RAID') !== false) { |
| | | if (strpos($item, ' VERIFYING ') !== false) { |
| | | $this->_tools->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' MIGRATE-PAUSED ') !== false) { |
| | | $this->_tools->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' MIGRATING ') !== false) { |
| | | $this->_tools->_setState($state, 'ok'); |
| | | } |
| | | else if (strpos($item, ' INITIALIZING ') !== false) { |
| | | $this->_tools->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' INIT-PAUSED ') !== false) { |
| | | $this->_tools->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' REBUILDING ') !== false) { |
| | | $this->_tools->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' REBUILD-PAUSED ') !== false) { |
| | | $this->_tools->_setState($state, 'warning'); |
| | | } |
| | | else if (strpos($item, ' RECOVERY ') !== false) { |
| | | $this->_tools->_setState($state, 'warning'); |
| | | } |
| | | else if (strpos($item, ' DEGRADED ') !== false) { |
| | | $this->_tools->_setState($state, 'critical'); |
| | | } |
| | | else if (strpos($item, ' UNKNOWN ') !== false) { |
| | | $this->_tools->_setState($state, 'critical'); |
| | | } |
| | | else if (strpos($item, ' OK ') !== false) { |
| | | $this->_tools->_setState($state, 'ok'); |
| | | } |
| | | else if (strpos($item, ' OPTIMAL ') !== false) { |
| | | $this->_tools->_setState($state, 'ok'); |
| | | } |
| | | else { |
| | | $this->_tools->_setState($state, 'critical'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_rkhunter extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'rkhunter'; |
| | | |
| | | /* This monitoring is only available if rkhunter is installed */ |
| | | system('which rkhunter', $retval); |
| | | if ($retval === 0) { |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('rkhunter --update --checkall --nocolors --skip-keypress'); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * rkhunter is not installed, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_server extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'server_load'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $procUptime = shell_exec("cat /proc/uptime | cut -f1 -d' '"); |
| | | $data['up_days'] = floor($procUptime / 86400); |
| | | $data['up_hours'] = floor(($procUptime - $data['up_days'] * 86400) / 3600); |
| | | $data['up_minutes'] = floor(($procUptime - $data['up_days'] * 86400 - $data['up_hours'] * 3600) / 60); |
| | | |
| | | $data['uptime'] = shell_exec('uptime'); |
| | | |
| | | $tmp = explode(',', $data['uptime'], 4); |
| | | $tmpUser = explode(' ', trim($tmp[2])); |
| | | $data['user_online'] = intval($tmpUser[0]); |
| | | |
| | | //* New Load Average code to fix "always zero" bug in non-english distros. NEEDS TESTING |
| | | $loadTmp = shell_exec("cat /proc/loadavg | cut -f1-3 -d' '"); |
| | | $load = explode(' ', $loadTmp); |
| | | $data['load_1'] = floatval(str_replace(',', '.', $load[0])); |
| | | $data['load_5'] = floatval(str_replace(',', '.', $load[1])); |
| | | $data['load_15'] = floatval(str_replace(',', '.', $load[2])); |
| | | |
| | | /** The state of the server-load. */ |
| | | $state = 'ok'; |
| | | if ($data['load_1'] > 20) |
| | | $state = 'info'; |
| | | if ($data['load_1'] > 50) |
| | | $state = 'warning'; |
| | | if ($data['load_1'] > 100) |
| | | $state = 'critical'; |
| | | if ($data['load_1'] > 150) |
| | | $state = 'error'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_services extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* |
| | | * First we get the Monitoring-data from the tools |
| | | */ |
| | | $res = $this->_tools->monitorServices(); |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_syslog extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '*/5 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'sys_log'; |
| | | |
| | | /* |
| | | * is there any warning or error for this server? |
| | | */ |
| | | $state = 'ok'; |
| | | $dbData = $app->dbmaster->queryAllRecords('SELECT loglevel FROM sys_log WHERE server_id = ' . $server_id . ' AND loglevel > 0'); |
| | | if (is_array($dbData)) { |
| | | foreach ($dbData as $item) { |
| | | if ($item['loglevel'] == 1) |
| | | $state = $this->_tools->_setState($state, 'warning'); |
| | | if ($item['loglevel'] == 2) |
| | | $state = $this->_tools->_setState($state, 'error'); |
| | | } |
| | | } |
| | | |
| | | /** There is no monitor-data because the data is in the sys_log table */ |
| | | $data['output'] = ''; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_messages'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_tools->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_monitor_system_update extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 * * * *'; |
| | | protected $_run_at_new = true; |
| | | |
| | | private $_tools = null; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | /* used for all monitor cronjobs */ |
| | | $app->load('monitor_tools'); |
| | | $this->_tools = new monitor_tools(); |
| | | /* end global section for monitor cronjobs */ |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'system_update'; |
| | | |
| | | /* This monitoring is only available on Debian or Ubuntu */ |
| | | if (file_exists('/etc/debian_version')) { |
| | | |
| | | /* |
| | | * first update the "apt database" |
| | | */ |
| | | shell_exec('apt-get update'); |
| | | |
| | | /* |
| | | * Then test the upgrade. |
| | | * if there is any output, then there is a needed update |
| | | */ |
| | | $aptData = shell_exec('apt-get -s -qq dist-upgrade'); |
| | | if ($aptData == '') { |
| | | /* There is nothing to update! */ |
| | | $state = 'ok'; |
| | | } else { |
| | | /* |
| | | * There is something to update! this is in most cases not critical, so we can |
| | | * do a system-update once a month or so... |
| | | */ |
| | | $state = 'info'; |
| | | } |
| | | |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = $aptData; |
| | | } elseif (file_exists('/etc/gentoo-release')) { |
| | | |
| | | /* |
| | | * first update the portage tree |
| | | */ |
| | | |
| | | // In keeping with gentoo's rsync policy, don't update to frequently (every four hours - taken from http://www.gentoo.org/doc/en/source_mirrors.xml) |
| | | $do_update = true; |
| | | if (file_exists('/usr/portage/metadata/timestamp.chk')) { |
| | | $datetime = file_get_contents('/usr/portage/metadata/timestamp.chk'); |
| | | $datetime = trim($datetime); |
| | | |
| | | $dstamp = strtotime($datetime); |
| | | if ($dstamp) { |
| | | $checkat = $dstamp + 14400; // + 4hours |
| | | if (mktime() < $checkat) { |
| | | $do_update = false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if ($do_update) { |
| | | shell_exec('emerge --sync --quiet'); |
| | | } |
| | | |
| | | /* |
| | | * Then test the upgrade. |
| | | * if there is any output, then there is a needed update |
| | | */ |
| | | $emergeData = shell_exec('glsa-check -t affected'); |
| | | if ($emergeData == '') { |
| | | /* There is nothing to update! */ |
| | | $state = 'ok'; |
| | | $data['output'] = 'No unapplied GLSA\'s found on the system.'; |
| | | } else { |
| | | /* There is something to update! */ |
| | | $state = 'info'; |
| | | $data['output'] = shell_exec('glsa-check -pv --nocolor affected 2>/dev/null'); |
| | | } |
| | | } elseif (file_exists('/etc/SuSE-release')) { |
| | | |
| | | /* |
| | | * update and find the upgrade. |
| | | * if there is any output, then there is a needed update |
| | | */ |
| | | $aptData = shell_exec('zypper -q lu'); |
| | | if ($aptData == '') { |
| | | /* There is nothing to update! */ |
| | | $state = 'ok'; |
| | | } else { |
| | | /* |
| | | * There is something to update! this is in most cases not critical, so we can |
| | | * do a system-update once a month or so... |
| | | */ |
| | | $state = 'info'; |
| | | } |
| | | |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('zypper lu'); |
| | | } else { |
| | | /* |
| | | * It is not Debian/Ubuntu, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | } |
| | | |
| | | $res = array(); |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | |
| | | //* Ensure that output is encoded so that it does not break the serialize |
| | | //$res['data']['output'] = htmlentities($res['data']['output']); |
| | | $res['data']['output'] = htmlentities($res['data']['output'],ENT_QUOTES,'UTF-8'); |
| | | |
| | | /* |
| | | * Insert the data into the database |
| | | */ |
| | | $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . |
| | | 'VALUES (' . |
| | | $res['server_id'] . ', ' . |
| | | "'" . $app->dbmaster->quote($res['type']) . "', " . |
| | | 'UNIX_TIMESTAMP(), ' . |
| | | "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " . |
| | | "'" . $res['state'] . "'" . |
| | | ')'; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* The new data is written, now we can delete the old one */ |
| | | $this->_tools->delOldRecords($res['type'], $res['server_id']); |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_awstats extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | ####################################################################################################### |
| | | // Create awstats statistics |
| | | ####################################################################################################### |
| | | |
| | | $sql = "SELECT domain_id, domain, document_root, web_folder, type, system_user, system_group, parent_domain_id FROM web_domain WHERE (type = 'vhost' or type = 'vhostsubdomain') and stats_type = 'awstats' AND server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | |
| | | $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); |
| | | |
| | | foreach($records as $rec) { |
| | | //$yesterday = date('Ymd',time() - 86400); |
| | | $yesterday = date('Ymd',strtotime("-1 day", time())); |
| | | |
| | | $log_folder = 'log'; |
| | | if($rec['type'] == 'vhostsubdomain') { |
| | | $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($rec['parent_domain_id'])); |
| | | $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $rec['domain']); |
| | | if($subdomain_host == '') $subdomain_host = 'web'.$rec['domain_id']; |
| | | $log_folder .= '/' . $subdomain_host; |
| | | unset($tmp); |
| | | } |
| | | $logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log'); |
| | | if(!@is_file($logfile)) { |
| | | $logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log.gz'); |
| | | if(!@is_file($logfile)) { |
| | | continue; |
| | | } |
| | | } |
| | | $web_folder = ($rec['type'] == 'vhostsubdomain' ? $rec['web_folder'] : 'web'); |
| | | $domain = escapeshellcmd($rec['domain']); |
| | | $statsdir = escapeshellcmd($rec['document_root'].'/'.$web_folder.'/stats'); |
| | | $awstats_pl = $web_config['awstats_pl']; |
| | | $awstats_buildstaticpages_pl = $web_config['awstats_buildstaticpages_pl']; |
| | | |
| | | $awstats_conf_dir = $web_config['awstats_conf_dir']; |
| | | $awstats_website_conf_file = $web_config['awstats_conf_dir'].'/awstats.'.$domain.'.conf'; |
| | | |
| | | if(is_file($awstats_website_conf_file)) unlink($awstats_website_conf_file); |
| | | |
| | | $sql = "SELECT domain FROM web_domain WHERE (type = 'alias' OR type = 'subdomain') AND parent_domain_id = ".$rec['domain_id']; |
| | | $aliases = $app->db->queryAllRecords($sql); |
| | | $aliasdomain = ''; |
| | | |
| | | if(is_array($aliases)) { |
| | | foreach ($aliases as $alias) { |
| | | $aliasdomain.= ' '.$alias['domain']. ' www.'.$alias['domain']; |
| | | } |
| | | } |
| | | |
| | | if(!is_file($awstats_website_conf_file)) { |
| | | $awstats_conf_file_content = 'Include "'.$awstats_conf_dir.'/awstats.conf" |
| | | LogFile="/var/log/ispconfig/httpd/'.$domain.'/yesterday-access.log" |
| | | SiteDomain="'.$domain.'" |
| | | HostAliases="www.'.$domain.' localhost 127.0.0.1'.$aliasdomain.'"'; |
| | | file_put_contents($awstats_website_conf_file,$awstats_conf_file_content); |
| | | } |
| | | |
| | | if(!@is_dir($statsdir)) mkdir($statsdir); |
| | | if(is_link('/var/log/ispconfig/httpd/'.$domain.'/yesterday-access.log')) unlink('/var/log/ispconfig/httpd/'.$domain.'/yesterday-access.log'); |
| | | symlink($logfile,'/var/log/ispconfig/httpd/'.$domain.'/yesterday-access.log'); |
| | | |
| | | $awmonth = date("n"); |
| | | $awyear = date("Y"); |
| | | |
| | | if (date("d") == 1) { |
| | | $awmonth = date("m")-1; |
| | | if (date("m") == 1) { |
| | | $awyear = date("Y")-1; |
| | | $awmonth = "12"; |
| | | } |
| | | } |
| | | |
| | | // awstats_buildstaticpages.pl -update -config=mydomain.com -lang=en -dir=/var/www/domain.com/'.$web_folder.'/stats -awstatsprog=/path/to/awstats.pl |
| | | // $command = "$awstats_buildstaticpages_pl -update -config='$domain' -lang=".$conf['language']." -dir='$statsdir' -awstatsprog='$awstats_pl'"; |
| | | |
| | | $command = "$awstats_buildstaticpages_pl -month='$awmonth' -year='$awyear' -update -config='$domain' -lang=".$conf['language']." -dir='$statsdir' -awstatsprog='$awstats_pl'"; |
| | | |
| | | if (date("d") == 2) { |
| | | $awmonth = date("m")-1; |
| | | if (date("m") == 1) { |
| | | $awyear = date("Y")-1; |
| | | $awmonth = "12"; |
| | | } |
| | | |
| | | $statsdirold = $statsdir."/".$awyear."-".$awmonth."/"; |
| | | mkdir($statsdirold); |
| | | $files = scandir($statsdir); |
| | | foreach ($files as $file) { |
| | | if (substr($file,0,1) != "." && !is_dir("$statsdir"."/"."$file") && substr($file,0,1) != "w" && substr($file,0,1) != "i") copy("$statsdir"."/"."$file","$statsdirold"."$file"); |
| | | } |
| | | } |
| | | |
| | | |
| | | if($awstats_pl != '' && $awstats_buildstaticpages_pl != '' && fileowner($awstats_pl) == 0 && fileowner($awstats_buildstaticpages_pl) == 0) { |
| | | exec($command); |
| | | if(is_file($rec['document_root'].'/'.$web_folder.'/stats/index.html')) unlink($rec['document_root'].'/'.$web_folder.'/stats/index.html'); |
| | | rename($rec['document_root'].'/'.$web_folder.'/stats/awstats.'.$domain.'.html',$rec['document_root'].'/'.$web_folder.'/stats/awsindex.html'); |
| | | if(!is_file($rec['document_root']."/".$web_folder."/stats/index.php")) { |
| | | if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { |
| | | copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master",$rec['document_root']."/".$web_folder."/stats/index.php"); |
| | | } else { |
| | | copy("/usr/local/ispconfig/server/conf/awstats_index.php.master",$rec['document_root']."/".$web_folder."/stats/index.php"); |
| | | } |
| | | } |
| | | |
| | | $app->log('Created awstats statistics with command: '.$command,LOGLEVEL_DEBUG); |
| | | } else { |
| | | $app->log("No awstats statistics created. Either $awstats_pl or $awstats_buildstaticpages_pl is not owned by root user.",LOGLEVEL_WARN); |
| | | } |
| | | |
| | | if(is_file($rec['document_root']."/".$web_folder."/stats/index.php")) { |
| | | chown($rec['document_root']."/".$web_folder."/stats/index.php",$rec['system_user']); |
| | | chgrp($rec['document_root']."/".$web_folder."/stats/index.php",$rec['system_group']); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_webalizer extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | ####################################################################################################### |
| | | // Create webalizer statistics |
| | | ####################################################################################################### |
| | | |
| | | function setConfigVar( $filename, $varName, $varValue, $append = 0 ) { |
| | | if($lines = @file($filename)) { |
| | | $out = ''; |
| | | $found = 0; |
| | | foreach($lines as $line) { |
| | | @list($key, $value) = preg_split('/[\t= ]+/', $line, 2); |
| | | if($key == $varName) { |
| | | $out .= $varName.' '.$varValue."\n"; |
| | | $found = 1; |
| | | } else { |
| | | $out .= $line; |
| | | } |
| | | } |
| | | if($found == 0) { |
| | | //* add \n if the last line does not end with \n or \r |
| | | if(substr($out,-1) != "\n" && substr($out,-1) != "\r") $out .= "\n"; |
| | | //* add the new line at the end of the file |
| | | if($append == 1) $out .= $varName.' '.$varValue."\n"; |
| | | } |
| | | |
| | | file_put_contents($filename,$out); |
| | | } |
| | | } |
| | | |
| | | |
| | | $sql = "SELECT domain_id, domain, document_root, web_folder, type, parent_domain_id FROM web_domain WHERE (type = 'vhost' or type = 'vhostsubdomain') and stats_type = 'webalizer' AND server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | |
| | | foreach($records as $rec) { |
| | | //$yesterday = date('Ymd',time() - 86400); |
| | | $yesterday = date('Ymd',strtotime("-1 day", time())); |
| | | |
| | | $log_folder = 'log'; |
| | | if($rec['type'] == 'vhostsubdomain') { |
| | | $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($rec['parent_domain_id'])); |
| | | $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $rec['domain']); |
| | | if($subdomain_host == '') $subdomain_host = 'web'.$rec['domain_id']; |
| | | $log_folder .= '/' . $subdomain_host; |
| | | unset($tmp); |
| | | } |
| | | $logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log'); |
| | | if(!@is_file($logfile)) { |
| | | $logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log.gz'); |
| | | if(!@is_file($logfile)) { |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | $domain = escapeshellcmd($rec['domain']); |
| | | $statsdir = escapeshellcmd($rec['document_root'].'/'.($rec['type'] == 'vhostsubdomain' ? $rec['web_folder'] : 'web').'/stats'); |
| | | $webalizer = '/usr/bin/webalizer'; |
| | | $webalizer_conf_main = '/etc/webalizer/webalizer.conf'; |
| | | $webalizer_conf = escapeshellcmd($rec['document_root'].'/log/webalizer.conf'); |
| | | |
| | | if(is_file($statsdir.'/index.php')) unlink($statsdir.'/index.php'); |
| | | |
| | | if(!@is_file($webalizer_conf)) { |
| | | copy($webalizer_conf_main,$webalizer_conf); |
| | | } |
| | | |
| | | if(@is_file($webalizer_conf)) { |
| | | setConfigVar($webalizer_conf, 'Incremental', 'yes'); |
| | | setConfigVar($webalizer_conf, 'IncrementalName', $statsdir.'/webalizer.current'); |
| | | setConfigVar($webalizer_conf, 'HistoryName', $statsdir.'/webalizer.hist'); |
| | | } |
| | | |
| | | |
| | | if(!@is_dir($statsdir)) mkdir($statsdir); |
| | | exec("$webalizer -c $webalizer_conf -n $domain -s $domain -r $domain -q -T -p -o $statsdir $logfile"); |
| | | } |
| | | |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_logfiles extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | ####################################################################################################### |
| | | // Make the web logfiles directories world readable to enable ftp access |
| | | ####################################################################################################### |
| | | |
| | | if(is_dir('/var/log/ispconfig/httpd')) exec('chmod +r /var/log/ispconfig/httpd/*'); |
| | | |
| | | ####################################################################################################### |
| | | // Manage and compress web logfiles and create traffic statistics |
| | | ####################################################################################################### |
| | | |
| | | $sql = "SELECT domain_id, domain, type, document_root, web_folder, parent_domain_id FROM web_domain WHERE (type = 'vhost' or type = 'vhostsubdomain') AND server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | foreach($records as $rec) { |
| | | |
| | | //* create traffic statistics based on yesterdays access log file |
| | | $yesterday = date('Ymd',time() - 86400); |
| | | |
| | | $log_folder = 'log'; |
| | | if($rec['type'] == 'vhostsubdomain') { |
| | | $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($rec['parent_domain_id'])); |
| | | $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $rec['domain']); |
| | | if($subdomain_host == '') $subdomain_host = 'web'.$rec['domain_id']; |
| | | $log_folder .= '/' . $subdomain_host; |
| | | unset($tmp); |
| | | } |
| | | |
| | | $logfile = $rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log'; |
| | | $total_bytes = 0; |
| | | |
| | | $handle = @fopen($logfile, "r"); |
| | | if ($handle) { |
| | | while (($line = fgets($handle, 4096)) !== false) { |
| | | if (preg_match('/^\S+ \S+ \S+ \[.*?\] "\S+.*?" \d+ (\d+) ".*?" ".*?"/', $line, $m)) { |
| | | $total_bytes += intval($m[1]); |
| | | } |
| | | } |
| | | |
| | | //* Insert / update traffic in master database |
| | | $traffic_date = date('Y-m-d',time() - 86400); |
| | | $tmp = $app->dbmaster->queryOneRecord("select hostname from web_traffic where hostname='".$rec['domain']."' and traffic_date='".$traffic_date."'"); |
| | | if(is_array($tmp) && count($tmp) > 0) { |
| | | $sql = "update web_traffic set traffic_bytes=traffic_bytes+" |
| | | . $total_bytes |
| | | . " where hostname='" . $rec['domain'] |
| | | . "' and traffic_date='" . $traffic_date . "'"; |
| | | } else { |
| | | $sql = "insert into web_traffic (hostname, traffic_date, traffic_bytes) values ('".$rec['domain']."', '".$traffic_date."', '".$total_bytes."')"; |
| | | } |
| | | $app->dbmaster->query($sql); |
| | | |
| | | fclose($handle); |
| | | } |
| | | |
| | | $yesterday2 = date('Ymd',time() - 86400*2); |
| | | $logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$yesterday2.'-access.log'); |
| | | |
| | | //* Compress logfile |
| | | if(@is_file($logfile)) { |
| | | // Compress yesterdays logfile |
| | | exec("gzip -c $logfile > $logfile.gz"); |
| | | unlink($logfile); |
| | | } |
| | | |
| | | // rotate and compress the error.log when it exceeds a size of 10 MB |
| | | $logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/error.log'); |
| | | if(is_file($logfile) && filesize($logfile) > 10000000) { |
| | | exec("gzip -c $logfile > $logfile.1.gz"); |
| | | exec("cat /dev/null > $logfile"); |
| | | } |
| | | |
| | | // delete logfiles after 30 days |
| | | $month_ago = date('Ymd',time() - 86400 * 30); |
| | | $logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$month_ago.'-access.log.gz'); |
| | | if(@is_file($logfile)) { |
| | | unlink($logfile); |
| | | } |
| | | |
| | | //* Delete older Log files, in case that we missed them before due to serverdowntimes. |
| | | $datepart = date('Ym',time() - 86400 * 31 * 2); |
| | | |
| | | $logfile = escapeshellcmd($rec['document_root']).'/' . $log_folder . '/'.$datepart.'*-access.log.gz'; |
| | | exec('rm -f '.$logfile); |
| | | |
| | | $logfile = escapeshellcmd($rec['document_root']).'/' . $log_folder . '/'.$datepart.'*-access.log'; |
| | | exec('rm -f '.$logfile); |
| | | } |
| | | |
| | | //* Delete old logfiles in /var/log/ispconfig/httpd/ that were created by vlogger for the hostname of the server |
| | | exec('hostname -f', $tmp_hostname); |
| | | if($tmp_hostname[0] != '' && is_dir('/var/log/ispconfig/httpd/'.$tmp_hostname[0])) { |
| | | exec('cd /var/log/ispconfig/httpd/'.$tmp_hostname[0]."; find . -mtime +30 -name '*.log' | xargs rm > /dev/null 2> /dev/null"); |
| | | } |
| | | unset($tmp_hostname); |
| | | |
| | | ####################################################################################################### |
| | | // Rotate the ispconfig.log file |
| | | ####################################################################################################### |
| | | |
| | | // rotate the ispconfig.log when it exceeds a size of 10 MB |
| | | $logfile = $conf['ispconfig_log_dir'].'/ispconfig.log'; |
| | | if(is_file($logfile) && filesize($logfile) > 10000000) { |
| | | exec("gzip -c $logfile > $logfile.1.gz"); |
| | | exec("cat /dev/null > $logfile"); |
| | | } |
| | | |
| | | // rotate the cron.log when it exceeds a size of 10 MB |
| | | $logfile = $conf['ispconfig_log_dir'].'/cron.log'; |
| | | if(is_file($logfile) && filesize($logfile) > 10000000) { |
| | | exec("gzip -c $logfile > $logfile.1.gz"); |
| | | exec("cat /dev/null > $logfile"); |
| | | } |
| | | |
| | | // rotate the auth.log when it exceeds a size of 10 MB |
| | | $logfile = $conf['ispconfig_log_dir'].'/auth.log'; |
| | | if(is_file($logfile) && filesize($logfile) > 10000000) { |
| | | exec("gzip -c $logfile > $logfile.1.gz"); |
| | | exec("cat /dev/null > $logfile"); |
| | | } |
| | | |
| | | ####################################################################################################### |
| | | // Cleanup website tmp directories |
| | | ####################################################################################################### |
| | | |
| | | $sql = "SELECT domain_id, domain, document_root, system_user FROM web_domain WHERE server_id = ".$conf['server_id']; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | $app->uses('system'); |
| | | if(is_array($records)) { |
| | | foreach($records as $rec){ |
| | | $tmp_path = realpath(escapeshellcmd($rec['document_root'].'/tmp')); |
| | | if($tmp_path != '' && strlen($tmp_path) > 10 && is_dir($tmp_path) && $app->system->is_user($rec['system_user'])){ |
| | | exec('cd '.$tmp_path."; find . -mtime +1 -name 'sess_*' | grep -v -w .no_delete | xargs rm > /dev/null 2> /dev/null"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | ####################################################################################################### |
| | | // Cleanup logs in master database (only the "master-server") |
| | | ####################################################################################################### |
| | | |
| | | if ($app->dbmaster == $app->db) { |
| | | /** 7 days */ |
| | | $tstamp = time() - (60*60*24*7); |
| | | |
| | | /* |
| | | * Keep 7 days in sys_log |
| | | * (we can delete the old items, because if they are OK, they don't interrest anymore |
| | | * if they are NOT ok, the server will try to process them in 1 minute and so the |
| | | * error appears again after 1 minute. So it is no problem to delete the old one! |
| | | */ |
| | | $sql = "DELETE FROM sys_log WHERE tstamp < " . $tstamp . " AND server_id != 0"; |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* |
| | | * Delete all remote-actions "done" and older than 7 days |
| | | * ATTENTION: We have the same problem as described in cleaning the datalog. We must not |
| | | * delete the last entry |
| | | */ |
| | | $sql = "SELECT max(action_id) FROM sys_remoteaction"; |
| | | $res = $app->dbmaster->queryOneRecord($sql); |
| | | $maxId = $res['max(action_id)']; |
| | | $sql = "DELETE FROM sys_remoteaction " . |
| | | "WHERE tstamp < " . $tstamp . " " . |
| | | " AND action_state = 'ok' " . |
| | | " AND action_id <" . intval($maxId); |
| | | $app->dbmaster->query($sql); |
| | | |
| | | /* |
| | | * The sys_datalog is more difficult. |
| | | * 1) We have to keet ALL entries with |
| | | * server_id=0, because they depend on ALL servers (even if they are not |
| | | * actually in the system (and will be insered in 3 days or so). |
| | | * 2) We have to keey ALL entries which are not actually precessed by the |
| | | * server never mind how old they are! |
| | | * 3) We have to keep the entry with the highest autoinc-id, because mysql calculates the |
| | | * autoinc-id as "new value = max(row) +1" and does not store this in a separate table. |
| | | * This means, if we delete to entry with the highest autoinc-value then this value is |
| | | * reused as autoinc and so there are more than one entries with the same value (over |
| | | * for example 4 Weeks). This is confusing for our system. |
| | | * ATTENTION 2) and 3) is in some case NOT the same! so we have to check both! |
| | | */ |
| | | |
| | | /* First we need all servers and the last sys_datalog-id they processed */ |
| | | $sql = "SELECT server_id, updated FROM server ORDER BY server_id"; |
| | | $records = $app->dbmaster->queryAllRecords($sql); |
| | | |
| | | /* Then we need the highest value ever */ |
| | | $sql = "SELECT max(datalog_id) FROM sys_datalog"; |
| | | $res = $app->dbmaster->queryOneRecord($sql); |
| | | $maxId = $res['max(datalog_id)']; |
| | | |
| | | /* Then delete server by server */ |
| | | foreach($records as $server) { |
| | | $tmp_server_id = intval($server['server_id']); |
| | | if($tmp_server_id > 0) { |
| | | $sql = "DELETE FROM sys_datalog " . |
| | | "WHERE tstamp < " . $tstamp . |
| | | " AND server_id = " . intval($server['server_id']) . |
| | | " AND datalog_id < " . intval($server['updated']) . |
| | | " AND datalog_id < " . intval($maxId); |
| | | } |
| | | // echo $sql . "\n"; |
| | | $app->dbmaster->query($sql); |
| | | } |
| | | } |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_quota_notify extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | ######### |
| | | // function for sending notification emails |
| | | ######### |
| | | function send_notification_email($template, $placeholders, $recipients) { |
| | | global $conf; |
| | | |
| | | if(!is_array($recipients) || count($recipients) < 1) return false; |
| | | if(!is_array($placeholders)) $placeholders = array(); |
| | | |
| | | if(file_exists($conf['rootpath'].'/conf-custom/mail/' . $template . '_'.$conf['language'].'.txt')) { |
| | | $lines = file($conf['rootpath'].'/conf-custom/mail/' . $template . '_'.$conf['language'].'.txt'); |
| | | } elseif(file_exists($conf['rootpath'].'/conf-custom/mail/' . $template . '_en.txt')) { |
| | | $lines = file($conf['rootpath'].'/conf-custom/mail/' . $template . '_en.txt'); |
| | | } elseif(file_exists($conf['rootpath'].'/conf/mail/' . $template . '_'.$conf['language'].'.txt')) { |
| | | $lines = file($conf['rootpath'].'/conf/mail/' . $template . '_'.$conf['language'].'.txt'); |
| | | } else { |
| | | $lines = file($conf['rootpath'].'/conf/mail/' . $template . '_en.txt'); |
| | | } |
| | | |
| | | //* get mail headers, subject and body |
| | | $mailHeaders = ''; |
| | | $mailBody = ''; |
| | | $mailSubject = ''; |
| | | $inHeader = true; |
| | | for($l = 0; $l < count($lines); $l++) { |
| | | if($lines[$l] == '') { |
| | | $inHeader = false; |
| | | continue; |
| | | } |
| | | if($inHeader == true) { |
| | | $parts = explode(':', $lines[$l], 2); |
| | | if(strtolower($parts[0]) == 'subject') $mailSubject = trim($parts[1]); |
| | | unset($parts); |
| | | $mailHeaders .= trim($lines[$l]) . "\n"; |
| | | } else { |
| | | $mailBody .= trim($lines[$l]) . "\n"; |
| | | } |
| | | } |
| | | $mailBody = trim($mailBody); |
| | | |
| | | //* Replace placeholders |
| | | $mailHeaders = strtr($mailHeaders, $placeholders); |
| | | $mailSubject = strtr($mailSubject, $placeholders); |
| | | $mailBody = strtr($mailBody, $placeholders); |
| | | |
| | | for($r = 0; $r < count($recipients); $r++) { |
| | | mail($recipients[$r], $mailSubject, $mailBody, $mailHeaders); |
| | | } |
| | | |
| | | unset($mailSubject); |
| | | unset($mailHeaders); |
| | | unset($mailBody); |
| | | unset($lines); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | ####################################################################################################### |
| | | // enforce traffic quota (run only on the "master-server") |
| | | ####################################################################################################### |
| | | |
| | | if ($app->dbmaster == $app->db) { |
| | | |
| | | $global_config = $app->getconf->get_global_config('mail'); |
| | | |
| | | $current_month = date('Y-m'); |
| | | |
| | | //* Check website traffic quota |
| | | $sql = "SELECT sys_groupid,domain_id,domain,traffic_quota,traffic_quota_lock FROM web_domain WHERE (traffic_quota > 0 or traffic_quota_lock = 'y') and (type = 'vhost' OR type = 'vhostsubdomain')"; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | if(is_array($records)) { |
| | | foreach($records as $rec) { |
| | | |
| | | $web_traffic_quota = $rec['traffic_quota']; |
| | | $domain = $rec['domain']; |
| | | |
| | | // get the client |
| | | /* |
| | | $client_group_id = $rec["sys_groupid"]; |
| | | $client = $app->db->queryOneRecord("SELECT limit_traffic_quota,parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); |
| | | $reseller = $app->db->queryOneRecord("SELECT limit_traffic_quota FROM client WHERE client_id = ".intval($client['parent_client_id'])); |
| | | |
| | | $client_traffic_quota = intval($client['limit_traffic_quota']); |
| | | $reseller_traffic_quota = intval($reseller['limit_traffic_quota']); |
| | | */ |
| | | |
| | | //* get the traffic |
| | | $tmp = $app->db->queryOneRecord("SELECT SUM(traffic_bytes) As total_traffic_bytes FROM web_traffic WHERE traffic_date like '$current_month%' AND hostname = '$domain'"); |
| | | $web_traffic = round($tmp['total_traffic_bytes']/1024/1024); |
| | | |
| | | //* Website is over quota, we will disable it |
| | | /*if( ($web_traffic_quota > 0 && $web_traffic > $web_traffic_quota) || |
| | | ($client_traffic_quota > 0 && $web_traffic > $client_traffic_quota) || |
| | | ($reseller_traffic_quota > 0 && $web_traffic > $reseller_traffic_quota)) {*/ |
| | | if($web_traffic_quota > 0 && $web_traffic > $web_traffic_quota) { |
| | | $app->dbmaster->datalogUpdate('web_domain', "traffic_quota_lock = 'y',active = 'n'", 'domain_id', $rec['domain_id']); |
| | | $app->log('Traffic quota for '.$rec['domain'].' exceeded. Disabling website.',LOGLEVEL_DEBUG); |
| | | |
| | | //* Send traffic notifications |
| | | if($rec['traffic_quota_lock'] != 'y' && ($web_config['overtraffic_notify_admin'] == 'y' || $web_config['overtraffic_notify_client'] == 'y')) { |
| | | |
| | | $placeholders = array('{domain}' => $rec['domain'], |
| | | '{admin_mail}' => ($global_config['admin_mail'] != ''? $global_config['admin_mail'] : 'root')); |
| | | |
| | | $recipients = array(); |
| | | //* send email to admin |
| | | if($global_config['admin_mail'] != '' && $web_config['overtraffic_notify_admin'] == 'y') { |
| | | $recipients[] = $global_config['admin_mail']; |
| | | } |
| | | |
| | | //* Send email to client |
| | | if($web_config['overtraffic_notify_client'] == 'y') { |
| | | $client_group_id = $rec["sys_groupid"]; |
| | | $client = $app->db->queryOneRecord("SELECT client.email FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); |
| | | if($client['email'] != '') { |
| | | $recipients[] = $client['email']; |
| | | } |
| | | } |
| | | |
| | | send_notification_email('web_traffic_notification', $placeholders, $recipients); |
| | | } |
| | | |
| | | } else { |
| | | //* unlock the website, if traffic is lower then quota |
| | | if($rec['traffic_quota_lock'] == 'y') { |
| | | $app->dbmaster->datalogUpdate('web_domain', "traffic_quota_lock = 'n',active = 'y'", 'domain_id', $rec['domain_id']); |
| | | $app->log('Traffic quota for '.$rec['domain'].' ok again. Re-enabling website.',LOGLEVEL_DEBUG); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | ####################################################################################################### |
| | | // send website quota warnings by email |
| | | ####################################################################################################### |
| | | |
| | | if ($app->dbmaster == $app->db) { |
| | | |
| | | $global_config = $app->getconf->get_global_config('mail'); |
| | | |
| | | //* Check website disk quota |
| | | $sql = "SELECT domain_id,sys_groupid,domain,system_user,last_quota_notification,DATEDIFF(CURDATE(), last_quota_notification) as `notified_before` FROM web_domain WHERE (type = 'vhost' OR type = 'vhostsubdomain')"; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | if(is_array($records) && !empty($records)) { |
| | | |
| | | $tmp_rec = $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'harddisk_quota' ORDER BY created DESC"); |
| | | $monitor_data = array(); |
| | | if(is_array($tmp_rec)) { |
| | | foreach ($tmp_rec as $tmp_mon) { |
| | | $monitor_data = array_merge_recursive($monitor_data,unserialize($app->db->unquote($tmp_mon['data']))); |
| | | } |
| | | } |
| | | |
| | | foreach($records as $rec) { |
| | | |
| | | //$web_hd_quota = $rec['hd_quota']; |
| | | $domain = $rec['domain']; |
| | | |
| | | $username = $rec['system_user']; |
| | | $rec['used'] = $monitor_data['user'][$username]['used']; |
| | | $rec['soft'] = $monitor_data['user'][$username]['soft']; |
| | | $rec['hard'] = $monitor_data['user'][$username]['hard']; |
| | | $rec['files'] = $monitor_data['user'][$username]['files']; |
| | | |
| | | if (!is_numeric($rec['used'])){ |
| | | if ($rec['used'][0] > $rec['used'][1]){ |
| | | $rec['used'] = $rec['used'][0]; |
| | | } else { |
| | | $rec['used'] = $rec['used'][1]; |
| | | } |
| | | } |
| | | if (!is_numeric($rec['soft'])) $rec['soft']=$rec['soft'][1]; |
| | | if (!is_numeric($rec['hard'])) $rec['hard']=$rec['hard'][1]; |
| | | if (!is_numeric($rec['files'])) $rec['files']=$rec['files'][1]; |
| | | |
| | | // used space ratio |
| | | if($rec['soft'] > 0){ |
| | | $used_ratio = $rec['used']/$rec['soft']; |
| | | } else { |
| | | $used_ratio = 0; |
| | | } |
| | | |
| | | $rec['ratio'] = number_format($used_ratio * 100, 2, '.', '').'%'; |
| | | |
| | | if($rec['used'] > 1024) { |
| | | $rec['used'] = round($rec['used'] / 1024,2).' MB'; |
| | | } else { |
| | | if ($rec['used'] != '') $rec['used'] .= ' KB'; |
| | | } |
| | | |
| | | if($rec['soft'] > 1024) { |
| | | $rec['soft'] = round($rec['soft'] / 1024,2).' MB'; |
| | | } elseif($rec['soft'] == 0){ |
| | | $rec['soft'] = '----'; |
| | | } else { |
| | | $rec['soft'] .= ' KB'; |
| | | } |
| | | |
| | | if($rec['hard'] > 1024) { |
| | | $rec['hard'] = round($rec['hard'] / 1024,2).' MB'; |
| | | } elseif($rec['hard'] == 0){ |
| | | $rec['hard'] = '----'; |
| | | } else { |
| | | $rec['hard'] .= ' KB'; |
| | | } |
| | | |
| | | // send notifications only if 90% or more of the quota are used |
| | | if($used_ratio < 0.9) { |
| | | // reset notification date |
| | | if($rec['last_quota_notification']) $app->dbmaster->datalogUpdate('web_domain', "last_quota_notification = NULL", 'domain_id', $rec['domain_id']); |
| | | |
| | | // send notification - everything ok again |
| | | if($rec['last_quota_notification'] && $web_config['overquota_notify_onok'] == 'y' && ($web_config['overquota_notify_admin'] == 'y' || $web_config['overquota_notify_client'] == 'y')) { |
| | | $placeholders = array('{domain}' => $rec['domain'], |
| | | '{admin_mail}' => ($global_config['admin_mail'] != ''? $global_config['admin_mail'] : 'root'), |
| | | '{used}' => $rec['used'], |
| | | '{soft}' => $rec['soft'], |
| | | '{hard}' => $rec['hard'], |
| | | '{ratio}' => $rec['ratio']); |
| | | |
| | | $recipients = array(); |
| | | |
| | | //* send email to admin |
| | | if($global_config['admin_mail'] != '' && $web_config['overquota_notify_admin'] == 'y') { |
| | | $recipients[] = $global_config['admin_mail']; |
| | | } |
| | | |
| | | //* Send email to client |
| | | if($web_config['overquota_notify_client'] == 'y') { |
| | | $client_group_id = $rec["sys_groupid"]; |
| | | $client = $app->db->queryOneRecord("SELECT client.email FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); |
| | | if($client['email'] != '') { |
| | | $recipients[] = $client['email']; |
| | | } |
| | | } |
| | | send_notification_email('web_quota_ok_notification', $placeholders, $recipients); |
| | | } |
| | | |
| | | continue; |
| | | } |
| | | |
| | | // could a notification be sent? |
| | | $send_notification = false; |
| | | if(!$rec['last_quota_notification']) $send_notification = true; // not yet notified |
| | | elseif($web_config['overquota_notify_freq'] > 0 && $rec['notified_before'] >= $web_config['overquota_notify_freq']) $send_notification = true; |
| | | |
| | | //* Send quota notifications |
| | | if(($web_config['overquota_notify_admin'] == 'y' || $web_config['overquota_notify_client'] == 'y') && $send_notification == true) { |
| | | $app->dbmaster->datalogUpdate('web_domain', "last_quota_notification = CURDATE()", 'domain_id', $rec['domain_id']); |
| | | |
| | | $placeholders = array('{domain}' => $rec['domain'], |
| | | '{admin_mail}' => ($global_config['admin_mail'] != ''? $global_config['admin_mail'] : 'root'), |
| | | '{used}' => $rec['used'], |
| | | '{soft}' => $rec['soft'], |
| | | '{hard}' => $rec['hard'], |
| | | '{ratio}' => $rec['ratio']); |
| | | |
| | | $recipients = array(); |
| | | |
| | | //* send email to admin |
| | | if($global_config['admin_mail'] != '' && $web_config['overquota_notify_admin'] == 'y') { |
| | | $recipients[] = $global_config['admin_mail']; |
| | | } |
| | | |
| | | //* Send email to client |
| | | if($web_config['overquota_notify_client'] == 'y') { |
| | | $client_group_id = $rec["sys_groupid"]; |
| | | $client = $app->db->queryOneRecord("SELECT client.email FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); |
| | | if($client['email'] != '') { |
| | | $recipients[] = $client['email']; |
| | | } |
| | | } |
| | | send_notification_email('web_quota_notification', $placeholders, $recipients); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | ####################################################################################################### |
| | | // send mail quota warnings by email |
| | | ####################################################################################################### |
| | | |
| | | if ($app->dbmaster == $app->db) { |
| | | |
| | | $global_config = $app->getconf->get_global_config('mail'); |
| | | $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); |
| | | |
| | | //* Check email quota |
| | | $sql = "SELECT mailuser_id,sys_groupid,email,name,quota,last_quota_notification,DATEDIFF(CURDATE(), last_quota_notification) as `notified_before` FROM mail_user"; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | if(is_array($records) && !empty($records)) { |
| | | |
| | | $tmp_rec = $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'email_quota' ORDER BY created DESC"); |
| | | $monitor_data = array(); |
| | | if(is_array($tmp_rec)) { |
| | | foreach ($tmp_rec as $tmp_mon) { |
| | | //$monitor_data = array_merge_recursive($monitor_data,unserialize($app->db->unquote($tmp_mon['data']))); |
| | | $tmp_array = unserialize($app->db->unquote($tmp_mon['data'])); |
| | | if(is_array($tmp_array)) { |
| | | foreach($tmp_array as $username => $data) { |
| | | if(@!$monitor_data[$username]['used']) $monitor_data[$username]['used'] = $data['used']; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | foreach($records as $rec) { |
| | | |
| | | $email = $rec['email']; |
| | | |
| | | $rec['used'] = isset($monitor_data[$email]['used']) ? $monitor_data[$email]['used'] : array(1 => 0); |
| | | |
| | | if (!is_numeric($rec['used'])) $rec['used']=$rec['used'][1]; |
| | | |
| | | // used space ratio |
| | | if($rec['quota'] > 0){ |
| | | $used_ratio = $rec['used']/$rec['quota']; |
| | | } else { |
| | | $used_ratio = 0; |
| | | } |
| | | |
| | | $rec['ratio'] = number_format($used_ratio * 100, 2, '.', '').'%'; |
| | | |
| | | if($rec['quota'] > 0){ |
| | | $rec['quota'] = round($rec['quota'] / 1048576,4).' MB'; |
| | | } else { |
| | | $rec['quota'] = '----'; |
| | | } |
| | | |
| | | if($rec['used'] < 1544000) { |
| | | $rec['used'] = round($rec['used'] / 1024,4).' KB'; |
| | | } else { |
| | | $rec['used'] = round($rec['used'] / 1048576,4).' MB'; |
| | | } |
| | | |
| | | // send notifications only if 90% or more of the quota are used |
| | | if($used_ratio < 0.9) { |
| | | // reset notification date |
| | | if($rec['last_quota_notification']) $app->dbmaster->datalogUpdate('mail_user', "last_quota_notification = NULL", 'mailuser_id', $rec['mailuser_id']); |
| | | |
| | | // send notification - everything ok again |
| | | if($rec['last_quota_notification'] && $mail_config['overquota_notify_onok'] == 'y' && ($mail_config['overquota_notify_admin'] == 'y' || $mail_config['overquota_notify_client'] == 'y')) { |
| | | $placeholders = array('{email}' => $rec['email'], |
| | | '{admin_mail}' => ($global_config['admin_mail'] != ''? $global_config['admin_mail'] : 'root'), |
| | | '{used}' => $rec['used'], |
| | | '{name}' => $rec['name'], |
| | | '{quota}' => $rec['quota'], |
| | | '{ratio}' => $rec['ratio']); |
| | | |
| | | $recipients = array(); |
| | | //* send email to admin |
| | | if($global_config['admin_mail'] != '' && $mail_config['overquota_notify_admin'] == 'y') { |
| | | $recipients[] = $global_config['admin_mail']; |
| | | } |
| | | |
| | | //* Send email to client |
| | | if($mail_config['overquota_notify_client'] == 'y') { |
| | | $client_group_id = $rec["sys_groupid"]; |
| | | $client = $app->db->queryOneRecord("SELECT client.email FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); |
| | | if($client['email'] != '') { |
| | | $recipients[] = $client['email']; |
| | | } |
| | | } |
| | | |
| | | send_notification_email('mail_quota_ok_notification', $placeholders, $recipients); |
| | | } |
| | | |
| | | continue; |
| | | } |
| | | |
| | | //* Send quota notifications |
| | | // could a notification be sent? |
| | | $send_notification = false; |
| | | if(!$rec['last_quota_notification']) $send_notification = true; // not yet notified |
| | | elseif($mail_config['overquota_notify_freq'] > 0 && $rec['notified_before'] >= $mail_config['overquota_notify_freq']) $send_notification = true; |
| | | |
| | | if(($mail_config['overquota_notify_admin'] == 'y' || $mail_config['overquota_notify_client'] == 'y') && $send_notification == true) { |
| | | $app->dbmaster->datalogUpdate('mail_user', "last_quota_notification = CURDATE()", 'mailuser_id', $rec['mailuser_id']); |
| | | |
| | | $placeholders = array('{email}' => $rec['email'], |
| | | '{admin_mail}' => ($global_config['admin_mail'] != ''? $global_config['admin_mail'] : 'root'), |
| | | '{used}' => $rec['used'], |
| | | '{name}' => $rec['name'], |
| | | '{quota}' => $rec['quota'], |
| | | '{ratio}' => $rec['ratio']); |
| | | |
| | | $recipients = array(); |
| | | //* send email to admin |
| | | if($global_config['admin_mail'] != '' && $mail_config['overquota_notify_admin'] == 'y') { |
| | | $recipients[] = $global_config['admin_mail']; |
| | | } |
| | | |
| | | //* Send email to client |
| | | if($mail_config['overquota_notify_client'] == 'y') { |
| | | $client_group_id = $rec["sys_groupid"]; |
| | | $client = $app->db->queryOneRecord("SELECT client.email FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); |
| | | if($client['email'] != '') { |
| | | $recipients[] = $client['email']; |
| | | } |
| | | } |
| | | |
| | | send_notification_email('mail_quota_notification', $placeholders, $recipients); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_openvz extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | ####################################################################################################### |
| | | // deactivate virtual servers (run only on the "master-server") |
| | | ####################################################################################################### |
| | | |
| | | if ($app->dbmaster == $app->db) { |
| | | $current_date = date('Y-m-d'); |
| | | |
| | | //* Check which virtual machines have to be deactivated |
| | | $sql = "SELECT * FROM openvz_vm WHERE active = 'y' AND active_until_date != '0000-00-00' AND active_until_date < '$current_date'"; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | if(is_array($records)) { |
| | | foreach($records as $rec) { |
| | | $app->dbmaster->datalogUpdate('openvz_vm', "active = 'n'", 'vm_id', $rec['vm_id']); |
| | | $app->log('Virtual machine active date expired. Disabling VM '.$rec['veid'],LOGLEVEL_DEBUG); |
| | | } |
| | | } |
| | | } |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob_backup extends cronjob { |
| | | |
| | | // job schedule |
| | | protected $_schedule = '0 0 * * *'; |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onPrepare() { |
| | | global $app; |
| | | |
| | | parent::onPrepare(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onBeforeRun() { |
| | | global $app; |
| | | |
| | | return parent::onBeforeRun(); |
| | | } |
| | | |
| | | public function onRunJob() { |
| | | global $app, $conf; |
| | | |
| | | ####################################################################################################### |
| | | // Create website backups |
| | | ####################################################################################################### |
| | | function formatBytes($size, $precision = 2) { |
| | | $base=log($size)/log(1024); |
| | | $suffixes=array('','k','M','G','T'); |
| | | return round(pow(1024,$base-floor($base)),$precision).$suffixes[floor($base)]; |
| | | } |
| | | |
| | | $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); |
| | | $backup_dir = $server_config['backup_dir']; |
| | | $backup_mode = $server_config['backup_mode']; |
| | | if($backup_mode == '') $backup_mode = 'userzip'; |
| | | |
| | | $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); |
| | | $http_server_user = $web_config['user']; |
| | | |
| | | if($backup_dir != '') { |
| | | |
| | | if(isset($server_config['backup_dir_ftpread']) && $server_config['backup_dir_ftpread'] == 'y') { |
| | | $backup_dir_permissions = 0755; |
| | | } else { |
| | | $backup_dir_permissions = 0750; |
| | | } |
| | | |
| | | if(!is_dir($backup_dir)) { |
| | | mkdir(escapeshellcmd($backup_dir), $backup_dir_permissions, true); |
| | | } else { |
| | | chmod(escapeshellcmd($backup_dir), $backup_dir_permissions); |
| | | } |
| | | |
| | | $sql = "SELECT * FROM web_domain WHERE server_id = '".$conf['server_id']."' AND (type = 'vhost' OR type = 'vhostsubdomain') AND backup_interval != 'none'"; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | if(is_array($records)) { |
| | | foreach($records as $rec) { |
| | | |
| | | //* Do the website backup |
| | | if($rec['backup_interval'] == 'daily' or ($rec['backup_interval'] == 'weekly' && date('w') == 0) or ($rec['backup_interval'] == 'monthly' && date('d') == '01')) { |
| | | |
| | | $web_path = $rec['document_root']; |
| | | $web_user = $rec['system_user']; |
| | | $web_group = $rec['system_group']; |
| | | $web_id = $rec['domain_id']; |
| | | $web_backup_dir = $backup_dir.'/web'.$web_id; |
| | | if(!is_dir($web_backup_dir)) mkdir($web_backup_dir, 0750); |
| | | chmod($web_backup_dir, 0750); |
| | | //if(isset($server_config['backup_dir_ftpread']) && $server_config['backup_dir_ftpread'] == 'y') { |
| | | chown($web_backup_dir, $rec['system_user']); |
| | | chgrp($web_backup_dir, $rec['system_group']); |
| | | /*} else { |
| | | chown($web_backup_dir, 'root'); |
| | | chgrp($web_backup_dir, 'root'); |
| | | }*/ |
| | | if($backup_mode == 'userzip') { |
| | | //* Create a .zip backup as web user and include also files owned by apache / nginx user |
| | | $web_backup_file = 'web'.$web_id.'_'.date('Y-m-d_H-i').'.zip'; |
| | | exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -group '.escapeshellarg($web_group).' -print 2> /dev/null | zip -b /tmp --exclude=backup\* --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@', $tmp_output, $retval); |
| | | if($retval == 0) exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -user '.escapeshellarg($http_server_user).' -print 2> /dev/null | zip -b /tmp --exclude=backup\* --update --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@', $tmp_output, $retval); |
| | | } else { |
| | | //* Create a tar.gz backup as root user |
| | | $web_backup_file = 'web'.$web_id.'_'.date('Y-m-d_H-i').'.tar.gz'; |
| | | exec('tar pczf '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' --exclude=backup\* --directory '.escapeshellarg($web_path).' .', $tmp_output, $retval); |
| | | } |
| | | if($retval == 0){ |
| | | chown($web_backup_dir.'/'.$web_backup_file, 'root'); |
| | | chgrp($web_backup_dir.'/'.$web_backup_file, 'root'); |
| | | chmod($web_backup_dir.'/'.$web_backup_file, 0750); |
| | | |
| | | //* Insert web backup record in database |
| | | //$insert_data = "(server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",".$web_id.",'web','".$backup_mode."',".time().",'".$app->db->quote($web_backup_file)."')"; |
| | | //$app->dbmaster->datalogInsert('web_backup', $insert_data, 'backup_id'); |
| | | $sql = "INSERT INTO web_backup (server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",".$web_id.",'web','".$backup_mode."',".time().",'".$app->db->quote($web_backup_file)."')"; |
| | | $app->db->query($sql); |
| | | if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql); |
| | | } else { |
| | | if(is_file($web_backup_dir.'/'.$web_backup_file)) unlink($web_backup_dir.'/'.$web_backup_file); |
| | | } |
| | | |
| | | //* Remove old backups |
| | | $backup_copies = intval($rec['backup_copies']); |
| | | |
| | | $dir_handle = dir($web_backup_dir); |
| | | $files = array(); |
| | | while (false !== ($entry = $dir_handle->read())) { |
| | | if($entry != '.' && $entry != '..' && substr($entry,0,3) == 'web' && is_file($web_backup_dir.'/'.$entry)) { |
| | | $files[] = $entry; |
| | | } |
| | | } |
| | | $dir_handle->close(); |
| | | |
| | | rsort($files); |
| | | |
| | | for ($n = $backup_copies; $n <= 10; $n++) { |
| | | if(isset($files[$n]) && is_file($web_backup_dir.'/'.$files[$n])) { |
| | | unlink($web_backup_dir.'/'.$files[$n]); |
| | | //$sql = "SELECT backup_id FROM web_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = $web_id AND filename = '".$app->db->quote($files[$n])."'"; |
| | | //$tmp = $app->dbmaster->queryOneRecord($sql); |
| | | //$app->dbmaster->datalogDelete('web_backup', 'backup_id', $tmp['backup_id']); |
| | | //$sql = "DELETE FROM web_backup WHERE backup_id = ".intval($tmp['backup_id']); |
| | | $sql = "DELETE FROM web_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = $web_id AND filename = '".$app->db->quote($files[$n])."'"; |
| | | $app->db->query($sql); |
| | | if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql); |
| | | } |
| | | } |
| | | |
| | | unset($files); |
| | | unset($dir_handle); |
| | | |
| | | //* Remove backupdir symlink and create as directory instead |
| | | $app->uses('system'); |
| | | $app->system->web_folder_protection($web_path,false); |
| | | |
| | | if(is_link($web_path.'/backup')) { |
| | | unlink($web_path.'/backup'); |
| | | } |
| | | if(!is_dir($web_path.'/backup')) { |
| | | mkdir($web_path.'/backup'); |
| | | chown($web_path.'/backup', $rec['system_user']); |
| | | chgrp($web_path.'/backup', $rec['system_group']); |
| | | } |
| | | |
| | | $app->system->web_folder_protection($web_path,true); |
| | | |
| | | } |
| | | |
| | | /* If backup_interval is set to none and we have a |
| | | backup directory for the website, then remove the backups */ |
| | | if($rec['backup_interval'] == 'none') { |
| | | $web_id = $rec['domain_id']; |
| | | $web_user = $rec['system_user']; |
| | | $web_backup_dir = realpath($backup_dir.'/web'.$web_id); |
| | | if(is_dir($web_backup_dir)) { |
| | | exec('sudo -u '.escapeshellarg($web_user).' rm -f '.escapeshellarg($web_backup_dir.'/*')); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | $sql = "SELECT * FROM web_database WHERE server_id = '".$conf['server_id']."' AND backup_interval != 'none'"; |
| | | $records = $app->db->queryAllRecords($sql); |
| | | if(is_array($records)) { |
| | | |
| | | include('lib/mysql_clientdb.conf'); |
| | | |
| | | foreach($records as $rec) { |
| | | |
| | | //* Do the database backup |
| | | if($rec['backup_interval'] == 'daily' or ($rec['backup_interval'] == 'weekly' && date('w') == 0) or ($rec['backup_interval'] == 'monthly' && date('d') == '01')) { |
| | | |
| | | $web_id = $rec['parent_domain_id']; |
| | | $db_backup_dir = $backup_dir.'/web'.$web_id; |
| | | if(!is_dir($db_backup_dir)) mkdir($db_backup_dir, 0750); |
| | | chmod($db_backup_dir, 0750); |
| | | chown($db_backup_dir, 'root'); |
| | | chgrp($db_backup_dir, 'root'); |
| | | |
| | | //* Do the mysql database backup with mysqldump or mongodump |
| | | $db_id = $rec['database_id']; |
| | | $db_name = $rec['database_name']; |
| | | |
| | | if ($rec['type'] == 'mysql') { |
| | | $db_backup_file = 'db_'.$db_name.'_'.date('Y-m-d_H-i').'.sql'; |
| | | //$command = "mysqldump -h '".escapeshellcmd($clientdb_host)."' -u '".escapeshellcmd($clientdb_user)."' -p'".escapeshellcmd($clientdb_password)."' -c --add-drop-table --create-options --quick --result-file='".$db_backup_dir.'/'.$db_backup_file."' '".$db_name."'"; |
| | | $command = "mysqldump -h ".escapeshellarg($clientdb_host)." -u ".escapeshellarg($clientdb_user)." -p".escapeshellarg($clientdb_password)." -c --add-drop-table --quote-names --routines --events --triggers --hex-blob --create-options --quick --result-file='".$db_backup_dir.'/'.$db_backup_file."' '".$db_name."'"; |
| | | exec($command, $tmp_output, $retval); |
| | | |
| | | //* Compress the backup with gzip |
| | | if($retval == 0) exec("gzip -c '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file)."' > '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".gz'", $tmp_output, $retval); |
| | | |
| | | if($retval == 0){ |
| | | chmod($db_backup_dir.'/'.$db_backup_file.'.gz', 0750); |
| | | chown($db_backup_dir.'/'.$db_backup_file.'.gz', fileowner($db_backup_dir)); |
| | | chgrp($db_backup_dir.'/'.$db_backup_file.'.gz', filegroup($db_backup_dir)); |
| | | |
| | | //* Insert web backup record in database |
| | | //$insert_data = "(server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mysql','sqlgz',".time().",'".$app->db->quote($db_backup_file).".gz')"; |
| | | //$app->dbmaster->datalogInsert('web_backup', $insert_data, 'backup_id'); |
| | | $sql = "INSERT INTO web_backup (server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mysql','sqlgz',".time().",'".$app->db->quote($db_backup_file).".gz')"; |
| | | $app->db->query($sql); |
| | | if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql); |
| | | |
| | | } else { |
| | | if(is_file($db_backup_dir.'/'.$db_backup_file.'.gz')) unlink($db_backup_dir.'/'.$db_backup_file.'.gz'); |
| | | } |
| | | //* Remove the uncompressed file |
| | | if(is_file($db_backup_dir.'/'.$db_backup_file)) unlink($db_backup_dir.'/'.$db_backup_file); |
| | | } else if ($rec['type'] == 'mongo') { |
| | | $db_backup_file = 'db_'.$db_name.'_'.date('Y-m-d_H-i'); |
| | | |
| | | try { |
| | | $connection = new MongoClient("mongodb://root:123456@127.0.0.1:27017/admin"); |
| | | $db = $connection->selectDB($db_name); |
| | | // exclude not supported by mongodump, only get user collections |
| | | $collections = $db->getCollectionNames(false); |
| | | |
| | | foreach ($collections as $collection) { |
| | | // mongodump -h 127.0.0.1 --port 27017 -u root -p 123456 --authenticationDatabase admin -d <db> -c <table> -o /tmp/test |
| | | $command = "mongodump -h 127.0.0.1 --port 27017 -u root -p 123456 --authenticationDatabase admin -d ".escapeshellcmd($db_name)." -c ".escapeshellcmd($collection)." -o ".escapeshellcmd($db_backup_dir.'/'.$db_backup_file); |
| | | exec($command); |
| | | } |
| | | |
| | | if (is_dir(escapeshellcmd($db_backup_dir.'/'.$db_backup_file))) { |
| | | //* Compress the backup with gzip |
| | | exec("cd ".escapeshellcmd($db_backup_dir)." && tar -pczf ".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".tar.gz ".escapeshellcmd($db_backup_file)); |
| | | chmod($db_backup_dir.'/'.$db_backup_file.'.tar.gz', 0750); |
| | | chown($db_backup_dir.'/'.$db_backup_file.'.tar.gz', fileowner($db_backup_dir)); |
| | | chgrp($db_backup_dir.'/'.$db_backup_file.'.tar.gz', filegroup($db_backup_dir)); |
| | | |
| | | //* Insert web backup record in database |
| | | $sql = "INSERT INTO web_backup (server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mongodb','rootgz',".time().",'".$app->db->quote($db_backup_file).".tar.gz')"; |
| | | $app->db->query($sql); |
| | | |
| | | if ($app->db->dbHost != $app->dbmaster->dbHost) { |
| | | $app->dbmaster->query($sql); |
| | | } |
| | | |
| | | //* Remove the uncompressed file |
| | | exec("rm -rf ".escapeshellcmd($db_backup_dir.'/'.$db_backup_file)); |
| | | } |
| | | } catch (MongoConnnectionException $e) { |
| | | // connecting to MongoDB failed - cannot create backup |
| | | } |
| | | } |
| | | |
| | | //* Remove old backups |
| | | $backup_copies = intval($rec['backup_copies']); |
| | | |
| | | $dir_handle = dir($db_backup_dir); |
| | | $files = array(); |
| | | while (false !== ($entry = $dir_handle->read())) { |
| | | if($entry != '.' && $entry != '..' && (preg_match('/^db_(.*?)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.sql.gz$/', $entry, $matches) || preg_match('/^db_(.*?)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.tar.gz$/', $entry, $matches)) && is_file($db_backup_dir.'/'.$entry)) { |
| | | if(array_key_exists($matches[1], $files) == false) $files[$matches[1]] = array(); |
| | | $files[$matches[1]][] = $entry; |
| | | } |
| | | } |
| | | $dir_handle->close(); |
| | | |
| | | reset($files); |
| | | foreach($files as $db_name => $filelist) { |
| | | rsort($filelist); |
| | | for ($n = $backup_copies; $n <= 10; $n++) { |
| | | if(isset($filelist[$n]) && is_file($db_backup_dir.'/'.$filelist[$n])) { |
| | | unlink($db_backup_dir.'/'.$filelist[$n]); |
| | | //$sql = "SELECT backup_id FROM web_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = $web_id AND filename = '".$app->db->quote($filelist[$n])."'"; |
| | | //$tmp = $app->dbmaster->queryOneRecord($sql); |
| | | //$sql = "DELETE FROM web_backup WHERE backup_id = ".intval($tmp['backup_id']); |
| | | $sql = "DELETE FROM web_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = $web_id AND filename = '".$app->db->quote($filelist[$n])."'"; |
| | | $app->db->query($sql); |
| | | if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql); |
| | | } |
| | | } |
| | | } |
| | | |
| | | unset($files); |
| | | unset($dir_handle); |
| | | } |
| | | } |
| | | |
| | | unset($clientdb_host); |
| | | unset($clientdb_user); |
| | | unset($clientdb_password); |
| | | |
| | | } |
| | | } |
| | | |
| | | parent::onRunJob(); |
| | | } |
| | | |
| | | /* this function is optional if it contains no custom code */ |
| | | public function onAfterRun() { |
| | | global $app; |
| | | |
| | | parent::onAfterRun(); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cron { |
| | | |
| | | /**#@+ |
| | | * @access private |
| | | */ |
| | | private $_sMinute = ''; |
| | | private $_sHour = ''; |
| | | private $_sDay = ''; |
| | | private $_sMonth = ''; |
| | | private $_sWDay = ''; |
| | | private $_bParsed = false; |
| | | private $_iNextRun = null; |
| | | private $_aValidValues; |
| | | |
| | | public function __construct() { |
| | | // empty |
| | | $this->_sMinute = ''; |
| | | $this->_sHour = ''; |
| | | $this->_sDay = ''; |
| | | $this->_sMonth = ''; |
| | | $this->_sWDay = ''; |
| | | $this->_bParsed = false; |
| | | $this->_aValidValues = array('minute' => array(), |
| | | 'hour' => array(), |
| | | 'day' => array(), |
| | | 'month' => array(), |
| | | 'weekday' => array()); |
| | | } |
| | | |
| | | private function _calcValidValues() { |
| | | // minute field |
| | | $this->_aValidValues['minute'] = $this->_calcFieldValues('minute', $this->_sMinute); |
| | | $this->_aValidValues['hour'] = $this->_calcFieldValues('hour', $this->_sHour); |
| | | $this->_aValidValues['day'] = $this->_calcFieldValues('day', $this->_sDay); |
| | | $this->_aValidValues['month'] = $this->_calcFieldValues('month', $this->_sMonth); |
| | | $this->_aValidValues['weekday'] = $this->_calcFieldValues('weekday', $this->_sWDay); |
| | | $this->_bParsed = true; |
| | | } |
| | | |
| | | private function _calcFieldValues($sField, $sValue) { |
| | | global $app; |
| | | |
| | | $aValidValues = array(); |
| | | |
| | | // global checks |
| | | $iFrom = 0; |
| | | $iTo = 0; |
| | | switch($sField) { |
| | | case 'minute': |
| | | $iTo = 59; |
| | | break; |
| | | case 'hour': |
| | | $iTo = 23; |
| | | break; |
| | | case 'day': |
| | | $iFrom = 1; |
| | | $iTo = 31; |
| | | break; |
| | | case 'month': |
| | | $sValue = strtr($sValue, array('JAN' => 1, |
| | | 'FEB' => 2, |
| | | 'MAR' => 3, |
| | | 'APR' => 4, |
| | | 'MAY' => 5, |
| | | 'JUN' => 6, |
| | | 'JUL' => 7, |
| | | 'AUG' => 8, |
| | | 'SEP' => 9, |
| | | 'OCT' => 10, |
| | | 'NOV' => 11, |
| | | 'DEC' => 12) |
| | | ); |
| | | $iFrom = 1; |
| | | $iTo = 12; |
| | | break; |
| | | case 'weekday': |
| | | $sValue = strtr($sValue, array('SUN' => 0, |
| | | 'MON' => 1, |
| | | 'TUE' => 2, |
| | | 'WED' => 3, |
| | | 'THU' => 4, |
| | | 'FRI' => 5, |
| | | 'SAT' => 6, |
| | | '7' => 0) |
| | | ); |
| | | $iTo = 6; |
| | | break; |
| | | } |
| | | $aParts = explode(',', $sValue); |
| | | for($a = 0; $a < count($aParts); $a++) { |
| | | $sValue = $aParts[$a]; |
| | | $iValue = $app->functions->intval($sValue); |
| | | |
| | | if($sValue === '*') { |
| | | // everything is valid |
| | | for($i = $iFrom; $i <= $iTo; $i++) { |
| | | $aValidValues[] = $i; |
| | | } |
| | | break; // no need to go any further |
| | | } elseif((string)$iValue == $sValue) { |
| | | if($iValue >= $iFrom && $iValue <= $iTo) $aValidValues[] = $iValue; |
| | | } elseif(preg_match('/^([0-9]+)-([0-9]+)(\/([1-9][0-9]*))?$/', $sValue, $aMatch)) { |
| | | if($aMatch[1] < $iFrom) $aMatch[1] = $iFrom; |
| | | if($aMatch[2] > $iTo) $aMatch[2] = $iTo; |
| | | if(isset($aMatch[3])) { |
| | | for($i = $aMatch[1]; $i <= $aMatch[2]; $i++) { |
| | | if(($i - $aMatch[1]) % $aMatch[4] == 0) $aValidValues[] = $i; |
| | | } |
| | | } else { |
| | | for($i = $aMatch[1]; $i <= $aMatch[2]; $i++) $aValidValues[] = $i; |
| | | } |
| | | } elseif(preg_match('/^\*\/([1-9][0-9]*)$/', $sValue, $aMatch)) { |
| | | for($i = $iFrom; $i <= $iTo; $i++) { |
| | | if($i % $aMatch[1] == 0) $aValidValues[] = $i; |
| | | } |
| | | } |
| | | } |
| | | |
| | | $aValidValues = array_unique($aValidValues); |
| | | sort($aValidValues); |
| | | |
| | | return $aValidValues; |
| | | } |
| | | |
| | | /**#@-*/ |
| | | |
| | | /** |
| | | * Set the cron field values |
| | | * |
| | | * @param string $sMinute the minute field value |
| | | * @param string $sHour the hour field value |
| | | * @param string $sDay the day field value |
| | | * @param string $sWDay the weekday field value |
| | | * @param string $sMonth the month field value |
| | | */ |
| | | public function setCronFields($sMinute = '*', $sHour = '*', $sDay = '*', $sMonth = '*', $sWDay = '*') { |
| | | $this->_sMinute = $sMinute; |
| | | $this->_sHour = $sHour; |
| | | $this->_sDay = $sDay; |
| | | $this->_sMonth = $sMonth; |
| | | $this->_sWDay = $sWDay; |
| | | $this->_bParsed = false; |
| | | } |
| | | |
| | | /** |
| | | * Parse a line of a cron and set the internal field values |
| | | * |
| | | * @param string $sLine cron line |
| | | */ |
| | | public function parseCronLine($sLine) { |
| | | $aFields = preg_split('/[ \t]+/', trim($sLine)); |
| | | for($i = 0; $i < 5; $i++) { |
| | | if(!isset($aFields[$i])) $aFields[$i] = '*'; |
| | | } |
| | | if($aFields[0] == '@yearly' || $aFields[0] == '@annually') $aFields = array(0, 0, 1, 1, '*'); |
| | | elseif($aFields[0] == '@monthly') $aFields = array(0, 0, 1, '*', '*'); |
| | | elseif($aFields[0] == '@weekly') $aFields = array(0, 0, '*', '*', 0); |
| | | elseif($aFields[0] == '@daily' || $aFields[0] == '@midnight') $aFields = array(0, 0, '*', '*', '*'); |
| | | elseif($aFields[0] == '@hourly') $aFields = array(0, '*', '*', '*', '*'); |
| | | |
| | | $this->setCronFields($aFields[0], $aFields[1], $aFields[2], $aFields[3], $aFields[4]); |
| | | } |
| | | |
| | | public function getNextRun($vDate) { |
| | | global $app; |
| | | |
| | | $iTimestamp = ISPConfigDatetime::to_timestamp($vDate); |
| | | if($iTimestamp === false) return $iTimestamp; |
| | | |
| | | if($this->_bParsed == false) $this->_calcValidValues(); |
| | | |
| | | // get the field values for the given Date. |
| | | list($iMinute, $iHour, $iDay, $iWDay, $iMonth, $iYear) = explode(':', ISPConfigDateTime::to_string($vDate, 'custom:%M:%H:%d:%w:%m:%Y')); |
| | | |
| | | $bValid = false; |
| | | $iStartYear = $iYear; |
| | | while($bValid == false) { |
| | | $iCurMinute = $this->_getNextValue('minute', $iMinute, true); |
| | | $iCurHour = $this->_getNextValue('hour', $iHour, true); |
| | | $iCurDay = $this->_getNextValue('day', $iDay, true); |
| | | $iCurMonth = $this->_getNextValue('month', $iMonth, true); |
| | | $iCurWDay = $this->_getNextValue('weekday', $iWDay, true); |
| | | |
| | | $iNextMinute = $this->_getNextValue('minute', $iMinute); |
| | | $iNextHour = $this->_getNextValue('hour', $iHour); |
| | | $iNextDay = $this->_getNextValue('day', $iDay); |
| | | $iNextMonth = $this->_getNextValue('month', $iMonth); |
| | | $iNextWDay = $this->_getNextValue('weekday', $iWDay); |
| | | |
| | | if($iNextMinute > $iMinute && $iHour == $iCurHour && $iDay == $iCurDay && $iWDay == $iCurWDay && $iMonth == $iCurMonth) { |
| | | $iMinute = $iNextMinute; |
| | | } elseif($iNextHour > $iHour && $iDay == $iCurDay && $iWDay == $iCurWDay && $iMonth == $iCurMonth) { |
| | | $iMinute = reset($this->_aValidValues['minute']); |
| | | $iHour = $iNextHour; |
| | | } elseif($iNextDay > $iDay && ISPConfigDateTime::last_day($iMonth) >= $iNextDay && $iMonth == $iCurMonth) { |
| | | $iMinute = reset($this->_aValidValues['minute']); |
| | | $iHour = reset($this->_aValidValues['hour']); |
| | | $iDay = $iNextDay; |
| | | } elseif($iNextMonth > $iMonth) { |
| | | $iMinute = reset($this->_aValidValues['minute']); |
| | | $iHour = reset($this->_aValidValues['hour']); |
| | | $iDay = reset($this->_aValidValues['day']); |
| | | $iMonth = $iNextMonth; |
| | | } else { |
| | | $iMinute = reset($this->_aValidValues['minute']); |
| | | $iHour = reset($this->_aValidValues['hour']); |
| | | $iDay = reset($this->_aValidValues['day']); |
| | | $iMonth = reset($this->_aValidValues['month']); |
| | | $iYear++; |
| | | } |
| | | |
| | | $ts = mktime($iHour, $iMinute, 0, $iMonth, $iDay, $iYear); |
| | | //print strftime('%d.%m.%Y (%A) %H:%M', $ts) . "\n"; |
| | | //var_dump($iCurMinute, $iCurHour, $iCurDay, $iCurMonth, $iCurWDay, '--', $iNextMinute, $iNextHour, $iNextDay, $iNextMonth, $iNextWDay); |
| | | if(ISPConfigDateTime::last_day($iMonth, $iYear) >= $iDay && in_array($app->functions->intval(strftime('%w', $ts)), $this->_aValidValues['weekday'], true) === true) { |
| | | $bValid = true; |
| | | } else { |
| | | if($iYear - $iStartYear > 5) { |
| | | if(LOG_PRIORITY <= PRIO_ERROR) $portal->log('No valid run dates for schedule ' . $this->_sMinute . ' ' . $this->_sHour . ' ' . $this->_sDay . ' ' . $this->_sMonth . ' ' . $this->_sWDay . ' in the next 5 years!', PRIO_ERROR, __FILE__, __LINE__); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | //var_dump($vDate, implode('-', array($iYear, $iMonth, $iDay, $iHour, $iNextMinute, 0)), $this->_sMinute, $this->_sHour, $this->_sDay, $this->_sWDay, $this->_sMonth, $this->_aValidValues); |
| | | return $iYear . '-' . $iMonth . '-' . $iDay . ' ' . $iHour . ':' . $iNextMinute . ':0'; |
| | | } |
| | | |
| | | private function _getNextValue($sField, $iValue, $bIncludeCurrent = false) { |
| | | if(!array_key_exists($sField, $this->_aValidValues)) return false; |
| | | |
| | | reset($this->_aValidValues[$sField]); |
| | | while(($cur = each($this->_aValidValues[$sField])) !== false) { |
| | | if($bIncludeCurrent == true && $cur['value'] >= $iValue) return $cur['value']; |
| | | elseif($cur['value'] > $iValue) return $cur['value']; |
| | | } |
| | | return reset($this->_aValidValues[$sField]); |
| | | } |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | class cronjob { |
| | | |
| | | // default is every 5 minutes |
| | | protected $_schedule = '*/5 * * * *'; |
| | | |
| | | // may a run be skipped? |
| | | protected $_no_skip = false; |
| | | |
| | | // if true, this job is run when it is first recognized. If false, the next run is calculated from schedule on first run. |
| | | protected $_run_at_new = false; |
| | | |
| | | protected $_last_run = null; |
| | | protected $_next_run = null; |
| | | private $_running = false; |
| | | |
| | | /** return schedule */ |
| | | public function getSchedule() { |
| | | return $this->_schedule; |
| | | } |
| | | |
| | | /** run through cronjob sequence **/ |
| | | public function run() { |
| | | |
| | | print "Called run() for class " . get_class($this) . "\n"; |
| | | print "Job has schedule: " . $this->_schedule . "\n"; |
| | | $this->onPrepare(); |
| | | $run_it = $this->onBeforeRun(); |
| | | if($run_it == true) { |
| | | $this->onRunJob(); |
| | | $this->onAfterRun(); |
| | | } |
| | | $this->onCompleted(); |
| | | |
| | | return; |
| | | } |
| | | |
| | | /* this function prepares some data for the job and sets next run time if first executed */ |
| | | protected function onPrepare() { |
| | | global $app; |
| | | |
| | | print "Called onPrepare() for class " . get_class($this) . "\n"; |
| | | // check the run time and values for this job |
| | | |
| | | // get previous run data |
| | | $data = $app->db->queryOneRecord("SELECT `last_run`, `next_run`, `running` FROM `sys_cron` WHERE `name` = '" . $app->db->quote(get_class($this)) . "'"); |
| | | if($data) { |
| | | if($data['last_run']) $this->_last_run = $data['last_run']; |
| | | if($data['next_run']) $this->_next_run = $data['next_run']; |
| | | if($data['running'] == 1) $this->_running = true; |
| | | } |
| | | if(!$this->_next_run) { |
| | | if($this->_run_at_new == true) { |
| | | $this->_next_run = ISPConfigDateTime::dbtime(); // run now. |
| | | } else { |
| | | $app->cron->parseCronLine($this->_schedule); |
| | | $next_run = $app->cron->getNextRun(ISPConfigDateTime::dbtime()); |
| | | $this->_next_run = $next_run; |
| | | |
| | | $app->db->query("REPLACE INTO `sys_cron` (`name`, `last_run`, `next_run`, `running`) VALUES ('" . $app->db->quote(get_class($this)) . "', " . ($this->_last_run ? "'" . $app->db->quote($this->_last_run) . "'" : "NULL") . ", " . ($next_run === false ? "NULL" : "'" . $app->db->quote($next_run) . "'") . ", " . ($this->_running == true ? "1" : "0") . ")"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* this function checks if a cron job's next runtime is reached and returns true or false */ |
| | | protected function onBeforeRun() { |
| | | global $app; |
| | | |
| | | print "Called onBeforeRun() for class " . get_class($this) . "\n"; |
| | | |
| | | if($this->_running == true) return false; // job is still marked as running! |
| | | |
| | | print "Jobs next run is " . $this->_next_run . "\n"; |
| | | $reached = ISPConfigDateTime::compare($this->_next_run, ISPConfigDateTime::dbtime()); |
| | | print "Date compare of " . ISPConfigDateTime::to_timestamp($this->_next_run) . " and " . ISPConfigDateTime::dbtime() . " is " . $reached . "\n"; |
| | | if($reached === false) return false; // error! |
| | | |
| | | if($reached === -1) { |
| | | // next_run time not reached |
| | | return false; |
| | | } |
| | | |
| | | // next_run time reached (reached === 0 or -1) |
| | | |
| | | // calculare next run time based on last_run or current time |
| | | $app->cron->parseCronLine($this->_schedule); |
| | | if($this->_no_skip == true) { |
| | | // we need to calculare the next run based on the previous next_run, as we may not skip one. |
| | | $next_run = $app->cron->getNextRun($this->_next_run); |
| | | if($next_run === false) { |
| | | // we could not calculate next run, try it with current time |
| | | $next_run = $app->cron->getNextRun(ISPConfigDateTime::dbtime()); |
| | | } |
| | | } else { |
| | | // calculate next run based on current time |
| | | $next_run = $app->cron->getNextRun(ISPConfigDateTime::dbtime()); |
| | | } |
| | | |
| | | print "Jobs next run is now " . $next_run . "\n"; |
| | | |
| | | $app->db->query("REPLACE INTO `sys_cron` (`name`, `last_run`, `next_run`, `running`) VALUES ('" . $app->db->quote(get_class($this)) . "', NOW(), " . ($next_run === false ? "NULL" : "'" . $app->db->quote($next_run) . "'") . ", 1)"); |
| | | return true; |
| | | } |
| | | |
| | | // child classes should override this! |
| | | protected function onRunJob() { |
| | | global $app; |
| | | |
| | | print "Called onRun() for class " . get_class($this) . "\n"; |
| | | } |
| | | |
| | | // child classes may override this! |
| | | protected function onAfterRun() { |
| | | global $app; |
| | | |
| | | print "Called onAfterRun() for class " . get_class($this) . "\n"; |
| | | } |
| | | |
| | | // child classes may NOT override this! |
| | | private function onCompleted() { |
| | | global $app; |
| | | |
| | | print "Called onCompleted() for class " . get_class($this) . "\n"; |
| | | $app->db->query("UPDATE `sys_cron` SET `running` = 0 WHERE `name` = '" . $app->db->quote(get_class($this)) . "'"); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2010, Till Brehm, projektfarm Gmbh |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | //* The purpose of this library is to provide some general functions. |
| | | //* This class is loaded automatically by the ispconfig framework. |
| | | |
| | | class functions { |
| | | var $idn_converter = null; |
| | | var $idn_converter_name = ''; |
| | | |
| | | public function mail($to, $subject, $text, $from, $filepath = '', $filetype = 'application/pdf', $filename = '', $cc = '', $bcc = '', $from_name = '') { |
| | | global $app,$conf; |
| | | |
| | | if($conf['demo_mode'] == true) $app->error("Mail sending disabled in demo mode."); |
| | | |
| | | $app->uses('getconf,ispcmail'); |
| | | $mail_config = $app->getconf->get_global_config('mail'); |
| | | if($mail_config['smtp_enabled'] == 'y') { |
| | | $mail_config['use_smtp'] = true; |
| | | $app->ispcmail->setOptions($mail_config); |
| | | } |
| | | $app->ispcmail->setSender($from, $from_name); |
| | | $app->ispcmail->setSubject($subject); |
| | | $app->ispcmail->setMailText($text); |
| | | |
| | | if($filepath != '') { |
| | | if(!file_exists($filepath)) $app->error("Mail attachement does not exist ".$filepath); |
| | | $app->ispcmail->readAttachFile($filepath); |
| | | } |
| | | |
| | | if($cc != '') $app->ispcmail->setHeader('Cc', $cc); |
| | | if($bcc != '') $app->ispcmail->setHeader('Bcc', $bcc); |
| | | |
| | | $app->ispcmail->send($to); |
| | | $app->ispcmail->finish(); |
| | | |
| | | /* left in here just for the case... |
| | | if($filepath != '') { |
| | | if(!file_exists($filepath)) $app->error("Mail attachement does not exist ".$filepath); |
| | | |
| | | $content = file_get_contents($filepath); |
| | | $content = chunk_split(base64_encode($content)); |
| | | $uid = strtoupper(md5(uniqid(time()))); |
| | | $subject = "=?utf-8?B?".base64_encode($subject)."?="; |
| | | |
| | | if($filename == '') { |
| | | $path_parts = pathinfo($filepath); |
| | | $filename = $path_parts["basename"]; |
| | | unset($path_parts); |
| | | } |
| | | |
| | | $header = "Return-Path: $from\nFrom: $from\nReply-To: $from\n"; |
| | | if($cc != '') $header .= "Cc: $cc\n"; |
| | | if($bcc != '') $header .= "Bcc: $bcc\n"; |
| | | $header .= "MIME-Version: 1.0\n"; |
| | | $header .= "Content-Type: multipart/mixed; boundary=$uid\n"; |
| | | |
| | | $header .= "--$uid\n"; |
| | | $header .= "Content-Type: text/plain;\n\tcharset=\"UTF-8\"\n"; |
| | | $header .= "Content-Transfer-Encoding: 8bit\n\n"; |
| | | $header .= "$text\n"; |
| | | |
| | | $header .= "--$uid\n"; |
| | | $header .= "Content-Type: $filetype; name=\"$filename\"\n"; |
| | | |
| | | $header .= "Content-Transfer-Encoding: base64\n"; |
| | | $header .= "Content-Disposition: attachment; filename=\"$filename\"\n\n"; |
| | | $header .= "$content\n"; |
| | | |
| | | $header .= "--$uid--"; |
| | | |
| | | mail($to, $subject, "", $header); |
| | | } else { |
| | | $header = "From: $from\nReply-To: $from\n"; |
| | | if($cc != '') $header .= "Cc: $cc\n"; |
| | | if($bcc != '') $header .= "Bcc: $bcc\n"; |
| | | $header .= "Content-Type: text/plain;\n\tcharset=\"UTF-8\"\n"; |
| | | $header .= "Content-Transfer-Encoding: 8bit\n\n"; |
| | | $subject = "=?utf-8?B?".base64_encode($subject)."?="; |
| | | mail($to, $subject, $text, $header); |
| | | } |
| | | */ |
| | | return true; |
| | | } |
| | | |
| | | public function array_merge($array1,$array2) { |
| | | $out = $array1; |
| | | foreach($array2 as $key => $val) { |
| | | $out[$key] = $val; |
| | | } |
| | | return $out; |
| | | } |
| | | |
| | | public function currency_format($number, $view = '') { |
| | | global $app; |
| | | if($view != '') $number_format_decimals = (int)$app->lng('number_format_decimals_'.$view); |
| | | if(!$number_format_decimals) $number_format_decimals = (int)$app->lng('number_format_decimals'); |
| | | |
| | | $number_format_dec_point = $app->lng('number_format_dec_point'); |
| | | $number_format_thousands_sep = $app->lng('number_format_thousands_sep'); |
| | | if($number_format_thousands_sep == 'number_format_thousands_sep') $number_format_thousands_sep = ''; |
| | | return number_format((double)$number, $number_format_decimals, $number_format_dec_point, $number_format_thousands_sep); |
| | | } |
| | | |
| | | public function get_ispconfig_url() { |
| | | global $app; |
| | | |
| | | $url = (stristr($_SERVER['SERVER_PROTOCOL'],'HTTPS') || stristr($_SERVER['HTTPS'],'on'))?'https':'http'; |
| | | if($_SERVER['SERVER_NAME'] != '_') { |
| | | $url .= '://'.$_SERVER['SERVER_NAME']; |
| | | if($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) { |
| | | $url .= ':'.$_SERVER['SERVER_PORT']; |
| | | } |
| | | } else { |
| | | $app->uses("getconf"); |
| | | $server_config = $app->getconf->get_server_config(1,'server'); |
| | | $url .= '://'.$server_config['hostname']; |
| | | if($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) { |
| | | $url .= ':'.$_SERVER['SERVER_PORT']; |
| | | } |
| | | } |
| | | return $url; |
| | | } |
| | | |
| | | public function json_encode($data) { |
| | | if(!function_exists('json_encode')){ |
| | | if(is_array($data) || is_object($data)){ |
| | | $islist = is_array($data) && (empty($data) || array_keys($data) === range(0,count($data)-1)); |
| | | |
| | | if($islist){ |
| | | $json = '[' . implode(',', array_map(array($this, "json_encode"), $data) ) . ']'; |
| | | } else { |
| | | $items = Array(); |
| | | foreach( $data as $key => $value ) { |
| | | $items[] = $this->json_encode("$key") . ':' . $this->json_encode($value); |
| | | } |
| | | $json = '{' . implode(',', $items) . '}'; |
| | | } |
| | | } elseif(is_string($data)){ |
| | | # Escape non-printable or Non-ASCII characters. |
| | | # I also put the \\ character first, as suggested in comments on the 'addclashes' page. |
| | | $string = '"'.addcslashes($data, "\\\"\n\r\t/".chr(8).chr(12)).'"'; |
| | | $json = ''; |
| | | $len = strlen($string); |
| | | # Convert UTF-8 to Hexadecimal Codepoints. |
| | | for($i = 0; $i < $len; $i++){ |
| | | $char = $string[$i]; |
| | | $c1 = ord($char); |
| | | |
| | | # Single byte; |
| | | if($c1 <128){ |
| | | $json .= ($c1 > 31) ? $char : sprintf("\\u%04x", $c1); |
| | | continue; |
| | | } |
| | | |
| | | # Double byte |
| | | $c2 = ord($string[++$i]); |
| | | if(($c1 & 32) === 0){ |
| | | $json .= sprintf("\\u%04x", ($c1 - 192) * 64 + $c2 - 128); |
| | | continue; |
| | | } |
| | | |
| | | # Triple |
| | | $c3 = ord($string[++$i]); |
| | | if(($c1 & 16) === 0){ |
| | | $json .= sprintf("\\u%04x", (($c1 - 224) <<12) + (($c2 - 128) << 6) + ($c3 - 128)); |
| | | continue; |
| | | } |
| | | |
| | | # Quadruple |
| | | $c4 = ord($string[++$i]); |
| | | if(($c1 & 8) === 0){ |
| | | $u = (($c1 & 15) << 2) + (($c2>>4) & 3) - 1; |
| | | |
| | | $w1 = (54<<10) + ($u<<6) + (($c2 & 15) << 2) + (($c3>>4) & 3); |
| | | $w2 = (55<<10) + (($c3 & 15)<<6) + ($c4-128); |
| | | $json .= sprintf("\\u%04x\\u%04x", $w1, $w2); |
| | | } |
| | | } |
| | | } else { |
| | | # int, floats, bools, null |
| | | $json = strtolower(var_export($data, true)); |
| | | } |
| | | return $json; |
| | | } else { |
| | | return json_encode($data); |
| | | } |
| | | } |
| | | |
| | | public function suggest_ips($type = 'IPv4'){ |
| | | global $app; |
| | | |
| | | if($type == 'IPv4'){ |
| | | $regex = "/^[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}$/"; |
| | | } else { |
| | | // IPv6 |
| | | $regex = "/^(\:\:([a-f0-9]{1,4}\:){0,6}?[a-f0-9]{0,4}|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){0,6}?\:\:|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){1,6}?\:\:([a-f0-9]{1,4}\:){1,6}?[a-f0-9]{1,4})(\/\d{1,3})?$/i"; |
| | | } |
| | | |
| | | $ips = array(); |
| | | $results = $app->db->queryAllRecords("SELECT ip_address AS ip FROM server_ip WHERE ip_type = '".$type."'"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | if(preg_match($regex, $result['ip'])) $ips[] = $result['ip']; |
| | | } |
| | | } |
| | | $results = $app->db->queryAllRecords("SELECT ip_address AS ip FROM openvz_ip"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | if(preg_match($regex, $result['ip'])) $ips[] = $result['ip']; |
| | | } |
| | | } |
| | | $results = $app->db->queryAllRecords("SELECT data AS ip FROM dns_rr WHERE type = 'A' OR type = 'AAAA'"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | if(preg_match($regex, $result['ip'])) $ips[] = $result['ip']; |
| | | } |
| | | } |
| | | $results = $app->db->queryAllRecords("SELECT ns AS ip FROM dns_slave"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | if(preg_match($regex, $result['ip'])) $ips[] = $result['ip']; |
| | | } |
| | | } |
| | | |
| | | $results = $app->db->queryAllRecords("SELECT xfer FROM dns_slave WHERE xfer != ''"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | $tmp_ips = explode(',', $result['xfer']); |
| | | foreach($tmp_ips as $tmp_ip){ |
| | | $tmp_ip = trim($tmp_ip); |
| | | if(preg_match($regex, $tmp_ip)) $ips[] = $tmp_ip; |
| | | } |
| | | } |
| | | } |
| | | $results = $app->db->queryAllRecords("SELECT xfer FROM dns_soa WHERE xfer != ''"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | $tmp_ips = explode(',', $result['xfer']); |
| | | foreach($tmp_ips as $tmp_ip){ |
| | | $tmp_ip = trim($tmp_ip); |
| | | if(preg_match($regex, $tmp_ip)) $ips[] = $tmp_ip; |
| | | } |
| | | } |
| | | } |
| | | $results = $app->db->queryAllRecords("SELECT also_notify FROM dns_soa WHERE also_notify != ''"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | $tmp_ips = explode(',', $result['also_notify']); |
| | | foreach($tmp_ips as $tmp_ip){ |
| | | $tmp_ip = trim($tmp_ip); |
| | | if(preg_match($regex, $tmp_ip)) $ips[] = $tmp_ip; |
| | | } |
| | | } |
| | | } |
| | | $results = $app->db->queryAllRecords("SELECT remote_ips FROM web_database WHERE remote_ips != ''"); |
| | | if(!empty($results) && is_array($results)){ |
| | | foreach($results as $result){ |
| | | $tmp_ips = explode(',', $result['remote_ips']); |
| | | foreach($tmp_ips as $tmp_ip){ |
| | | $tmp_ip = trim($tmp_ip); |
| | | if(preg_match($regex, $tmp_ip)) $ips[] = $tmp_ip; |
| | | } |
| | | } |
| | | } |
| | | $ips = array_unique($ips); |
| | | sort($ips, SORT_NUMERIC); |
| | | |
| | | $result_array = array('cheader' => array(), 'cdata' => array()); |
| | | |
| | | if(!empty($ips)){ |
| | | $result_array['cheader'] = array('title' => 'IPs', |
| | | 'total' => count($ips), |
| | | 'limit' => count($ips) |
| | | ); |
| | | |
| | | foreach($ips as $ip){ |
| | | $result_array['cdata'][] = array( 'title' => $ip, |
| | | 'description' => $type, |
| | | 'onclick' => '', |
| | | 'fill_text' => $ip |
| | | ); |
| | | } |
| | | } |
| | | |
| | | return $result_array; |
| | | } |
| | | |
| | | public function intval($string, $force_numeric = false) { |
| | | if(intval($string) == 2147483647 || ($string > 0 && intval($string) < 0)) { |
| | | if($force_numeric == true) return floatval($string); |
| | | elseif(preg_match('/^([-]?)[0]*([1-9][0-9]*)([^0-9].*)*$/', $string, $match)) return $match[1].$match[2]; |
| | | else return 0; |
| | | } else { |
| | | return intval($string); |
| | | } |
| | | } |
| | | |
| | | /** IDN converter wrapper. |
| | | * all converter classes should be placed in ISPC_CLASS_PATH.'/idn/' |
| | | */ |
| | | private function _idn_encode_decode($domain, $encode = true) { |
| | | if($domain == '') return ''; |
| | | if(preg_match('/^[0-9\.]+$/', $domain)) return $domain; // may be an ip address - anyway does not need to bee encoded |
| | | |
| | | // get domain and user part if it is an email |
| | | $user_part = false; |
| | | if(strpos($domain, '@') !== false) { |
| | | $user_part = substr($domain, 0, strrpos($domain, '@')); |
| | | $domain = substr($domain, strrpos($domain, '@') + 1); |
| | | } |
| | | |
| | | if($encode == true) { |
| | | if(function_exists('idn_to_ascii')) { |
| | | $domain = idn_to_ascii($domain); |
| | | } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) { |
| | | /* use idna class: |
| | | * @author Matthias Sommerfeld <mso@phlylabs.de> |
| | | * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de |
| | | * @version 0.8.0 2011-03-11 |
| | | */ |
| | | |
| | | if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') { |
| | | include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php'); |
| | | $this->idn_converter = new idna_convert(array('idn_version' => 2008)); |
| | | $this->idn_converter_name = 'idna_convert.class'; |
| | | } |
| | | $domain = $this->idn_converter->encode($domain); |
| | | } |
| | | } else { |
| | | if(function_exists('idn_to_utf8')) { |
| | | $domain = idn_to_utf8($domain); |
| | | } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) { |
| | | /* use idna class: |
| | | * @author Matthias Sommerfeld <mso@phlylabs.de> |
| | | * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de |
| | | * @version 0.8.0 2011-03-11 |
| | | */ |
| | | |
| | | if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') { |
| | | include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php'); |
| | | $this->idn_converter = new idna_convert(array('idn_version' => 2008)); |
| | | $this->idn_converter_name = 'idna_convert.class'; |
| | | } |
| | | $domain = $this->idn_converter->decode($domain); |
| | | } |
| | | } |
| | | |
| | | if($user_part !== false) return $user_part . '@' . $domain; |
| | | else return $domain; |
| | | } |
| | | |
| | | public function idn_encode($domain) { |
| | | $domains = explode("\n", $domain); |
| | | for($d = 0; $d < count($domains); $d++) { |
| | | $domains[$d] = $this->_idn_encode_decode($domains[$d], true); |
| | | } |
| | | return implode("\n", $domains); |
| | | } |
| | | |
| | | public function idn_decode($domain) { |
| | | $domains = explode("\n", $domain); |
| | | for($d = 0; $d < count($domains); $d++) { |
| | | $domains[$d] = $this->_idn_encode_decode($domains[$d], false); |
| | | } |
| | | return implode("\n", $domains); |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | Copyright (c) 2013, Marius Cramer, pixcept KG |
| | | All rights reserved. |
| | | |
| | | Redistribution and use in source and binary forms, with or without modification, |
| | | are permitted provided that the following conditions are met: |
| | | |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright notice, |
| | | this list of conditions and the following disclaimer in the documentation |
| | | and/or other materials provided with the distribution. |
| | | * Neither the name of ISPConfig nor the names of its contributors |
| | | may be used to endorse or promote products derived from this software without |
| | | specific prior written permission. |
| | | |
| | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| | | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| | | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| | | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| | | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| | | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| | | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | /** |
| | | * Date and Time class |
| | | * |
| | | * provides functions related to date and time operations |
| | | */ |
| | | abstract class ISPConfigDateTime { |
| | | |
| | | /** |
| | | * Get days, hours, minutes and seconds |
| | | * |
| | | * Returns an array with days, hours, minutes and seconds from a given amount of seconds |
| | | * |
| | | * @access public |
| | | * @param int $seconds amount of seconds |
| | | * @param bool $get_days if true get the days, too |
| | | * @return array data (0 => days, 1 => hours, 2 => minutes, 3 => seconds) |
| | | */ |
| | | public static function get_parts($seconds, $get_days = false) { |
| | | $days = 0; |
| | | if($get_days == true) { |
| | | $days = floor($seconds / (3600 * 24)); |
| | | $seconds = $seconds % (3600 * 24); |
| | | } |
| | | $hours = floor($seconds / 3600); |
| | | $seconds = $seconds % 3600; |
| | | $minutes = floor($seconds / 60); |
| | | $seconds = $seconds % 60; |
| | | |
| | | return array($days, $hours, $minutes, $seconds); |
| | | } |
| | | |
| | | public static function dbtime() { |
| | | global $app; |
| | | |
| | | $time = $app->db->queryOneRecord('SELECT UNIX_TIMESTAMP() as `time`'); |
| | | return $time['time']; |
| | | } |
| | | |
| | | /** |
| | | * Get a unix timestamp for a date |
| | | * |
| | | * @access public |
| | | * @param mixed $date the date to convert. Can be |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @return int the unix timestamp |
| | | */ |
| | | public static function to_timestamp($date) { |
| | | if(!is_string($date) && !is_numeric($date)) return false; |
| | | $date = trim($date); |
| | | |
| | | if(is_numeric($date)) return $date; |
| | | |
| | | if(strpos($date, '-') !== false) { |
| | | $regex = "(\d{2,4})-(\d{1,2})-(\d{1,2})(\s+(\d{1,2}):(\d{1,2})(:(\d{1,2}))?)?"; |
| | | $ok = preg_match("'$regex'", $date, $matches); |
| | | if($ok) { |
| | | $year = $matches[1]; |
| | | $month = $matches[2]; |
| | | $day = $matches[3]; |
| | | $hour = isset($matches[5]) ? $matches[5] : 0; |
| | | $minute = isset($matches[6]) ? $matches[6] : 0; |
| | | $second = isset($matches[8]) ? $matches[8] : 0; |
| | | } |
| | | } else { |
| | | $regex = "(\d{1,2})[/.](\d{1,2})[/.](\d{2,4})(\s+(\d{1,2}):(\d{1,2})(:(\d{1,2}))?)?"; |
| | | $ok = preg_match("'$regex'", $date, $matches); |
| | | if($ok) { |
| | | $year = $matches[3]; |
| | | $month = $matches[2]; |
| | | $day = $matches[1]; |
| | | $hour = isset($matches[5]) ? $matches[5] : 0; |
| | | $minute = isset($matches[6]) ? $matches[6] : 0; |
| | | $second = isset($matches[8]) ? $matches[8] : 0; |
| | | } |
| | | } |
| | | |
| | | if(!$ok) return false; |
| | | |
| | | if(!$day || !$month || !$year) return false; |
| | | if(!$hour) $hour = 0; |
| | | if(!$minute) $minute = 0; |
| | | if(!$second) $second = 0; |
| | | if($year < 1900) $year += 1900; |
| | | |
| | | if(!checkdate($month, $day, $year)) return false; |
| | | |
| | | $date = mktime($hour, $minute, $second, $month, $day, $year); |
| | | |
| | | return $date; |
| | | } |
| | | |
| | | /** |
| | | * Get a date string |
| | | * |
| | | * Returns a formatted date string |
| | | * |
| | | * @access public |
| | | * @param mixed $date the date to convert. Can be |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @param string $format the format to get the date string in. |
| | | * - short: dd.mm.yy |
| | | * - veryshort: dd.mm. |
| | | * - medium: dd.mm.yyyy |
| | | * - long: dd. Month yyyy |
| | | * - extra: Day, dd. Month yyyy |
| | | * - day: dd |
| | | * - monthnum: mm |
| | | * - shortmonth: Short month name like Mar for March |
| | | * - month: Month name |
| | | * - shortyear: yy |
| | | * - year: yyyy |
| | | * - onlydate: dd.mm |
| | | * - onlydatelong: dd. Month |
| | | * - onlytime: HH:MM |
| | | * - rss: Rss time format for XML |
| | | * - nice: if you prepend a nice: (like nice:long) you will get results like "today" or "yesterday" if applicable |
| | | * - custom: you can give a strftime format like %d.%m.%Y %H:%M if you prepend custom: to it |
| | | * @param bool $time if true apped the time to the date string |
| | | * @param bool $seconds if true append the seconds to the time |
| | | * @return string date string |
| | | */ |
| | | public static function to_string($date, $format = 'short', $time = false, $seconds = false) { |
| | | global $portal; |
| | | |
| | | if(!$date) return ''; |
| | | |
| | | setlocale(LC_TIME, array('de_DE.UTF-8', 'de_DE', 'de_DE.ISO-8859-1', 'de_DE.ISO-8859-15')); |
| | | |
| | | if(!is_numeric($date)) { |
| | | $date = self::to_timestamp($date); |
| | | if($date === false) return $date; |
| | | } |
| | | |
| | | if($format == 'timestamp') return $date; |
| | | |
| | | $fmt = ''; |
| | | $prepend = ''; |
| | | if(substr($format, 0, 5) == 'nice:') { |
| | | if(strftime('%d.%m.%Y', $date) == strftime('%d.%m.%Y', $portal->getTime())) { |
| | | if($time == true) $format = 'onlytime'; |
| | | else $format = ''; |
| | | $prepend = 'Heute'; |
| | | } elseif(strftime('%d.%m.%Y', $date) == strftime('%d.%m.%Y', $portal->getTime() - 86400)) { |
| | | if($time == true) $format = 'onlytime'; |
| | | else $format = ''; |
| | | $prepend = 'Gestern'; |
| | | } elseif(strftime('%d.%m.%Y', $date) == strftime('%d.%m.%Y', $portal->getTime() + 86400)) { |
| | | if($time == true) $format = 'onlytime'; |
| | | else $format = ''; |
| | | $prepend = 'Morgen'; |
| | | } else { |
| | | $format = substr($format, 5); |
| | | } |
| | | } elseif(substr($format, 0, 7) == 'custom:') { |
| | | $fmt = substr($format, 7); |
| | | $format = ''; |
| | | $time = false; |
| | | } |
| | | |
| | | if($format == 'short') $fmt = '%d.%m.%y'; |
| | | elseif($format == 'veryshort') $fmt = '%d.%m.'; |
| | | elseif($format == 'medium') $fmt = '%d.%m.%Y'; |
| | | elseif($format == 'long') $fmt = '%d. %B %Y'; |
| | | elseif($format == 'extra') $fmt = '%A, %d. %B %Y'; |
| | | elseif($format == 'day') $fmt = '%d'; |
| | | elseif($format == 'monthnum') $fmt = '%m'; |
| | | elseif($format == 'shortmonth') $fmt = '%b'; |
| | | elseif($format == 'month') $fmt = '%B'; |
| | | elseif($format == 'shortyear') $fmt = '%y'; |
| | | elseif($format == 'year') $fmt = '%Y'; |
| | | elseif($format == 'onlydate') $fmt = '%d.%m.'; |
| | | elseif($format == 'onlydatelong') $fmt = '%d. %B'; |
| | | elseif($format == 'onlytime') { |
| | | $fmt = '%H:%M'; |
| | | $time = false; |
| | | } elseif($format == 'rss') { |
| | | $ret = date(DATE_RSS, $date); |
| | | if($prepend != '') $ret = $prepend . ' ' . $ret; |
| | | return $ret; |
| | | } elseif($format == 'sitemap') { |
| | | $ret = date(DATE_ATOM, $date); |
| | | if($prepend != '') $ret = $prepend . ' ' . $ret; |
| | | return $ret; |
| | | } |
| | | if($time == true) $fmt .= ' %H:%M' . ($seconds == true ? ':%S' : ''); |
| | | |
| | | if($fmt != '') $ret = strftime($fmt, $date); |
| | | else $ret = ''; |
| | | |
| | | if($prepend != '') $ret = trim($prepend . ' ' . $ret); |
| | | return $ret; |
| | | } |
| | | |
| | | /** |
| | | * Get the month difference of two dates |
| | | * |
| | | * Gets the difference in months of two given dates. |
| | | * The days are ignored, so the difference between 2010-01-21 and 2010-05-01 is 4! |
| | | * |
| | | * @access public |
| | | * @param mixed $date_from the beginning date, either |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @param mixed $date_to the ending date, either |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @param bool $return_years if set to true, the function returns an array of years and months instead of months |
| | | * @param bool $include_both if set to true, the starting AND ending month is included, so the month count is +1 |
| | | * @return mixed either int (months) or array of int (0 => years, 1 => months) or FALSE on invalid dates |
| | | */ |
| | | public static function months_between($date_from, $date_to, $return_years = false, $include_both = false) { |
| | | $date_from = self::to_string($date_from, 'custom:%Y%m'); |
| | | if($date_from === false) return $date_from; |
| | | |
| | | $date_to = self::to_string($date_to, 'custom:%Y%m'); |
| | | if($date_to === false) return $date_to; |
| | | |
| | | $date_from = intval($date_from); |
| | | $date_to = intval($date_to); |
| | | |
| | | if($date_to < $date_from) return false; |
| | | |
| | | $result = $date_to - $date_from; |
| | | if($include_both == true) $result++; |
| | | |
| | | $years = floor($result / 100); |
| | | $months = $result % 100; |
| | | if($months > 12) $months -= 88; |
| | | elseif($months == 12) { |
| | | $months = 0; |
| | | $years++; |
| | | } |
| | | if($return_years == true) return array($years, $months); |
| | | |
| | | $months += ($years * 12); |
| | | return $months; |
| | | } |
| | | |
| | | /** |
| | | * Get the day difference of two dates |
| | | * |
| | | * Gets the difference in days of two given dates. |
| | | * |
| | | * @access public |
| | | * @param mixed $date_from the beginning date, either |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @param mixed $date_to the ending date, either |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @param bool $include_both if set to true, the starting AND ending day is included, so the day count is +1 |
| | | * @return mixed either int (days) or FALSE on invalid dates |
| | | */ |
| | | public static function days_between($date_from, $date_to, $include_both = false) { |
| | | $date_from = self::to_string($date_from, 'custom:%Y-%m-%d'); |
| | | if($date_from === false) return $date_from; |
| | | list($y, $m, $d) = explode('-', $date_from); |
| | | $ts_from = mktime(0, 0, 0, $m, $d, $y); |
| | | |
| | | $date_to = self::to_string($date_to, 'custom:%Y-%m-%d'); |
| | | if($date_to === false) return $date_to; |
| | | list($y, $m, $d) = explode('-', $date_to); |
| | | $ts_to = mktime(0, 0, 0, $m, $d, $y); |
| | | |
| | | $result = $ts_to - $ts_from; |
| | | if($include_both == true) $result++; |
| | | |
| | | $days = floor($result / (3600 * 24)); |
| | | |
| | | return $days; |
| | | } |
| | | |
| | | /** |
| | | * Check if one date is before another |
| | | * |
| | | * @access public |
| | | * @param mixed $date_1 the first date, either |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @param mixed $date_2 the second date, either |
| | | * - int (unix timestamp) |
| | | * - date string yyyy-mm-dd[ hh:mm:ss] |
| | | * - date string dd.mm.yyyy[ hh:mm:ss] |
| | | * @return mixed either int (1 if the first date is earlier, -1 if the second date is earlier, 0 if both are the same) or FALSE on invalid dates |
| | | */ |
| | | public static function compare($date_1, $date_2) { |
| | | $ts_1 = self::to_timestamp($date_1); |
| | | if($ts_1 === false) return false; |
| | | $ts_2 = self::to_timestamp($date_2); |
| | | if($ts_2 === false) return false; |
| | | |
| | | if($ts_1 < $ts_2) return 1; |
| | | elseif($ts_1 > $ts_2) return -1; |
| | | else return 0; |
| | | } |
| | | |
| | | /** |
| | | * Convert date to sql format |
| | | * |
| | | * Converts a date from different formats to the sql format if possible |
| | | * |
| | | * @access public |
| | | * @param string $date date string in forms |
| | | * - dd.mm.yy |
| | | * - yyyy-mm-dd |
| | | * - yy-mm-dd |
| | | * - yyyy/mm/dd |
| | | * - dd.mm.yy |
| | | * - all formats can have time information HH:MM:SS appended |
| | | * @param bool $no_time if true, the resulting sql date is without time part even if time was part of the input |
| | | * @return mixed sql date string on success, error object otherwise |
| | | */ |
| | | public static function sql_date($date = false, $no_time = false) { |
| | | global $portal; |
| | | |
| | | $result = ''; |
| | | $time = ''; |
| | | |
| | | if($date === false) $date = $portal->getTime(true); |
| | | |
| | | if(is_numeric($date)) { |
| | | return ($no_time ? strftime('%Y-%m-%d', $date) : strftime('%Y-%m-%d %H:%M:%S', $date)); |
| | | } |
| | | |
| | | if(preg_match('/^(.*)(\d{1,2}:\d{1,2}(:\d{1,2})?)(\D|$)/', $date, $matches)) { |
| | | $date = $matches[1]; |
| | | $time = ' ' . $matches[2]; |
| | | } |
| | | if(preg_match('/(^|\D)(\d{4,4})-(\d{1,2})-(\d{1,2})(\D|$)/', $date, $result)) { |
| | | $day = $result[4]; |
| | | $month = $result[3]; |
| | | $year = $result[2]; |
| | | } elseif(preg_match('/(^|\D)(\d{4,4})\/(\d{1,2})\/(\d{1,2})(\D|$)/', $date, $result)) { |
| | | $day = $result[4]; |
| | | $month = $result[3]; |
| | | $year = $result[2]; |
| | | } elseif(preg_match('/(^|\D)(\d{2,2})-(\d{1,2})-(\d{1,2})(\D|$)/', $date, $result)) { |
| | | $day = $result[4]; |
| | | $month = $result[3]; |
| | | $year = $result[2]; |
| | | } elseif(preg_match('/(^|\D)(\d{1,2})\.(\d{1,2})\.(\d{4,4})(\D|$)/', $date, $result)) { |
| | | $day = $result[2]; |
| | | $month = $result[3]; |
| | | $year = $result[4]; |
| | | } elseif(preg_match('/(^|\D)(\d{1,2})\.(\d{1,2})\.(\d{2,2})(\D|$)/', $date, $result)) { |
| | | $day = $result[2]; |
| | | $month = $result[3]; |
| | | $year = $result[4]; |
| | | } else { |
| | | return false; |
| | | } |
| | | if($no_time == true) $time = ''; |
| | | |
| | | $day = str_pad(intval($day), 2, '0', STR_PAD_LEFT); |
| | | $month = str_pad(intval($month), 2, '0', STR_PAD_LEFT); |
| | | $year = intval($year); |
| | | |
| | | $valid = checkdate($month, $day, $year); |
| | | if(!$valid) return false; |
| | | |
| | | return $year . '-' . $month . '-' . $day . $time; |
| | | } |
| | | |
| | | /** |
| | | * Get information if given date is leap year |
| | | * |
| | | * @access public |
| | | * @param mixed $date Date to check |
| | | * @return bool true if leap year, false otherwise |
| | | */ |
| | | public static function is_leap_year($date) { |
| | | // check if only year was given |
| | | if(is_numeric($date) && $date < 10000) $date .= '-01-01'; |
| | | |
| | | $ts = self::to_timestamp($date); |
| | | if($ts === false) return false; |
| | | |
| | | if(date('L', $ts) == 1) return true; |
| | | else return false; |
| | | } |
| | | |
| | | /** |
| | | * Get the last day of the month |
| | | * |
| | | * @access public |
| | | * @param int $month the month to get the last day for |
| | | * @param int $year the corresponding year (for february in leap years) |
| | | * @return bool true if leap year, false otherwise |
| | | */ |
| | | public static function last_day($month, $year = false) { |
| | | switch($month) { |
| | | case 1: |
| | | case 3: |
| | | case 5: |
| | | case 7: |
| | | case 8: |
| | | case 10: |
| | | case 12: |
| | | return 31; |
| | | break; |
| | | case 2: |
| | | return ($year !== false && self::is_leap_year($year) ? 29 : 28); |
| | | break; |
| | | default: |
| | | return 30; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get age for given date |
| | | * |
| | | * Returns the age for a given date if possible |
| | | * |
| | | * @access public |
| | | * @param string $date see ISPConfigDateTime::sql_date() for possible values |
| | | * @return mixed int of age if successful, error object otherwise |
| | | * @see ISPConfigDateTime::sql_date |
| | | */ |
| | | public static function calc_age($date) { |
| | | global $portal; |
| | | |
| | | $date = self::sql_date($date); |
| | | if($date === false) return $date; |
| | | |
| | | list($year, $month, $day) = explode('-', $date); |
| | | list($curyear, $curmonth, $curday) = explode('-', strftime('%Y-%m-%d', $portal->getTime())); |
| | | |
| | | $year_diff = $curyear - $year; |
| | | $month_diff = $curmonth - $month; |
| | | $day_diff = $curday - $day; |
| | | |
| | | if($day_diff < 0) $month_diff--; |
| | | if($month_diff < 0) $year_diff--; |
| | | if($year_diff < 0) $year_diff = 0; |
| | | |
| | | return $year_diff; |
| | | } |
| | | } |
| | | |
| | |
| | | return array('name' => $distname, 'version' => $distver, 'id' => $distid, 'baseid' => $distbaseid); |
| | | } |
| | | |
| | | //** Email Quota |
| | | public function monitorEmailQuota() { |
| | | global $conf, $app; |
| | | |
| | | //* Initialize data array |
| | | $data = array(); |
| | | |
| | | //* the id of the server as int |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | //* The type of the data |
| | | $type = 'email_quota'; |
| | | |
| | | //* The state of the email_quota. |
| | | $state = 'ok'; |
| | | |
| | | $mailboxes = $app->db->queryAllRecords("SELECT email,maildir FROM mail_user WHERE server_id = $server_id"); |
| | | if(is_array($mailboxes)) { |
| | | foreach($mailboxes as $mb) { |
| | | $email = $mb['email']; |
| | | $email_parts = explode('@',$mb['email']); |
| | | $filename = $mb['maildir'].'/.quotausage'; |
| | | if(file_exists($filename) && !is_link($filename)) { |
| | | $quotafile = file($filename); |
| | | $data[$email]['used'] = trim($quotafile['1']); |
| | | unset($quotafile); |
| | | } else { |
| | | exec('du -s '.escapeshellcmd($mb['maildir']),$out); |
| | | $parts = explode(' ',$out[0]); |
| | | $data[$email]['used'] = intval($parts[0])*1024; |
| | | unset($out); |
| | | unset($parts); |
| | | } |
| | | } |
| | | } |
| | | |
| | | unset($mailboxes); |
| | | |
| | | //* Dovecot quota check Courier in progress lathama@gmail.com |
| | | /* |
| | | if($dir = opendir("/var/vmail")){ |
| | | while (($quotafiles = readdir($dir)) !== false){ |
| | | if(preg_match('/.\_quota$/', $quotafiles)){ |
| | | $quotafile = (file("/var/vmail/" . $quotafiles)); |
| | | $emailaddress = preg_replace('/_quota/',"", $quotafiles); |
| | | $emailaddress = preg_replace('/_/',"@", $emailaddress); |
| | | $data[$emailaddress]['used'] = trim($quotafile['1']); |
| | | } |
| | | } |
| | | closedir($dir); |
| | | } |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | //** Filesystem Quota |
| | | public function monitorHDQuota() { |
| | | global $conf; |
| | | |
| | | //* Initialize data array |
| | | $data = array(); |
| | | |
| | | //* the id of the server as int |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | //* The type of the data |
| | | $type = 'harddisk_quota'; |
| | | |
| | | //* The state of the harddisk_quota. |
| | | $state = 'ok'; |
| | | |
| | | //* Fetch the data for all users |
| | | $dfData = shell_exec('repquota -au 2>/dev/null'); |
| | | |
| | | //* Split into array |
| | | $df = explode("\n", $dfData); |
| | | |
| | | //* ignore the first 5 lines, process the rest |
| | | for ($i = 5; $i <= sizeof($df); $i++) { |
| | | if ($df[$i] != '') { |
| | | //* Make a array of the data |
| | | $s = preg_split('/[\s]+/', $df[$i]); |
| | | $username = $s[0]; |
| | | if (substr($username, 0, 3) == 'web') { |
| | | if (isset($data['user'][$username])) { |
| | | $data['user'][$username]['used'] += $s[2]; |
| | | $data['user'][$username]['soft'] += $s[3]; |
| | | $data['user'][$username]['hard'] += $s[4]; |
| | | $data['user'][$username]['files'] += $s[5]; |
| | | } else { |
| | | $data['user'][$username]['used'] = $s[2]; |
| | | $data['user'][$username]['soft'] = $s[3]; |
| | | $data['user'][$username]['hard'] = $s[4]; |
| | | $data['user'][$username]['files'] = $s[5]; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //** Fetch the data for all users |
| | | $dfData = shell_exec('repquota -ag 2>/dev/null'); |
| | | |
| | | //* split into array |
| | | $df = explode("\n", $dfData); |
| | | |
| | | //* ignore the first 5 lines, process the rest |
| | | for ($i = 5; $i <= sizeof($df); $i++) { |
| | | if ($df[$i] != '') { |
| | | //* Make a array of the data |
| | | $s = preg_split('/[\s]+/', $df[$i]); |
| | | $groupname = $s[0]; |
| | | if (substr($groupname, 0, 6) == 'client') { |
| | | if (isset($data['group'][$groupname])) { |
| | | $data['group'][$groupname]['used'] += $s[1]; |
| | | $data['group'][$groupname]['soft'] += $s[2]; |
| | | $data['group'][$groupname]['hard'] += $s[3]; |
| | | } else { |
| | | $data['group'][$groupname]['used'] = $s[1]; |
| | | $data['group'][$groupname]['soft'] = $s[2]; |
| | | $data['group'][$groupname]['hard'] = $s[3]; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //* Return the Result |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorServer() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'server_load'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $procUptime = shell_exec("cat /proc/uptime | cut -f1 -d' '"); |
| | | $data['up_days'] = floor($procUptime / 86400); |
| | | $data['up_hours'] = floor(($procUptime - $data['up_days'] * 86400) / 3600); |
| | | $data['up_minutes'] = floor(($procUptime - $data['up_days'] * 86400 - $data['up_hours'] * 3600) / 60); |
| | | |
| | | $data['uptime'] = shell_exec('uptime'); |
| | | |
| | | $tmp = explode(',', $data['uptime'], 4); |
| | | $tmpUser = explode(' ', trim($tmp[2])); |
| | | $data['user_online'] = intval($tmpUser[0]); |
| | | |
| | | //* New Load Average code to fix "always zero" bug in non-english distros. NEEDS TESTING |
| | | $loadTmp = shell_exec("cat /proc/loadavg | cut -f1-3 -d' '"); |
| | | $load = explode(' ', $loadTmp); |
| | | $data['load_1'] = floatval(str_replace(',', '.', $load[0])); |
| | | $data['load_5'] = floatval(str_replace(',', '.', $load[1])); |
| | | $data['load_15'] = floatval(str_replace(',', '.', $load[2])); |
| | | |
| | | /** The state of the server-load. */ |
| | | $state = 'ok'; |
| | | if ($data['load_1'] > 20) |
| | | $state = 'info'; |
| | | if ($data['load_1'] > 50) |
| | | $state = 'warning'; |
| | | if ($data['load_1'] > 100) |
| | | $state = 'critical'; |
| | | if ($data['load_1'] > 150) |
| | | $state = 'error'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorOsVer() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'os_info'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $dist = $this->get_distname(); |
| | | |
| | | $data['name'] = $dist['name']; |
| | | $data['version'] = $dist['version']; |
| | | |
| | | /* the OS has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorIspcVer() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'ispc_info'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $data['name'] = ISPC_APP_TITLE; |
| | | $data['version'] = ISPC_APP_VERSION; |
| | | |
| | | /* the ISPC-Version has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorDiskUsage() { |
| | | global $app,$conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'disk_usage'; |
| | | |
| | | /** The state of the disk-usage */ |
| | | $state = 'ok'; |
| | | |
| | | /** Fetch the data of ALL devices into a array (needed for monitoring!) */ |
| | | //$dfData = shell_exec('df -hT 2>/dev/null'); |
| | | $app->uses('getconf'); |
| | | $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); |
| | | $dfData = shell_exec('df -hT|grep -v "'.$web_config['website_basedir'].'/" 2>/dev/null'); |
| | | |
| | | // split into array |
| | | $df = explode("\n", $dfData); |
| | | |
| | | /* |
| | | * ignore the first line, process the rest |
| | | */ |
| | | for ($i = 1; $i <= sizeof($df); $i++) { |
| | | if ($df[$i] != '') { |
| | | /* |
| | | * Make an array of the data |
| | | */ |
| | | $s = preg_split('/[\s]+/', $df[$i]); |
| | | $data[$i]['fs'] = $s[0]; |
| | | $data[$i]['type'] = $s[1]; |
| | | $data[$i]['size'] = $s[2]; |
| | | $data[$i]['used'] = $s[3]; |
| | | $data[$i]['available'] = $s[4]; |
| | | $data[$i]['percent'] = $s[5]; |
| | | $data[$i]['mounted'] = $s[6]; |
| | | /* |
| | | * calculate the state |
| | | */ |
| | | $usePercent = floatval($data[$i]['percent']); |
| | | |
| | | //* get the free memsize |
| | | if(substr($data[$i]['available'],-1) == 'G') { |
| | | $freesize = floatval($data[$i]['available'])*1024; |
| | | } elseif(substr($data[$i]['available'],-1) == 'T') { |
| | | $freesize = floatval($data[$i]['available'])*1024*1024; |
| | | } else { |
| | | $freesize = floatval($data[$i]['available']); |
| | | } |
| | | |
| | | //* We don't want to check some filesystem which have no sensible filling levels |
| | | switch ($data[$i]['type']) { |
| | | case 'iso9660': |
| | | case 'cramfs': |
| | | case 'udf': |
| | | case 'tmpfs': |
| | | case 'devtmpfs': |
| | | case 'udev': |
| | | break; |
| | | default: |
| | | if ($usePercent > 75 && $freesize < 2000) |
| | | $state = $this->_setState($state, 'info'); |
| | | if ($usePercent > 80 && $freesize < 1000) |
| | | $state = $this->_setState($state, 'warning'); |
| | | if ($usePercent > 90 && $freesize < 500) |
| | | $state = $this->_setState($state, 'critical'); |
| | | if ($usePercent > 95 && $freesize < 100) |
| | | $state = $this->_setState($state, 'error'); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorMemUsage() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'mem_usage'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $miData = shell_exec('cat /proc/meminfo'); |
| | | |
| | | $memInfo = explode("\n", $miData); |
| | | |
| | | foreach ($memInfo as $line) { |
| | | $part = preg_split('/:/', $line); |
| | | $key = trim($part[0]); |
| | | $tmp = explode(' ', trim($part[1])); |
| | | $value = 0; |
| | | if ($tmp[1] == 'kB') |
| | | $value = $tmp[0] * 1024; |
| | | $data[$key] = $value; |
| | | } |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorCpu() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'cpu_info'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | if (file_exists('/proc/cpuinfo')) { |
| | | $cpuData = shell_exec('cat /proc/cpuinfo'); |
| | | $cpuInfo = explode("\n", $cpuData); |
| | | $processor = 0; |
| | | |
| | | foreach ($cpuInfo as $line) { |
| | | |
| | | $part = preg_split('/:/', $line); |
| | | $key = trim($part[0]); |
| | | $value = trim($part[1]); |
| | | if ($key == 'processor') |
| | | $processor = intval($value); |
| | | if ($key != '') |
| | | $data[$key . ' ' . $processor] = $value; |
| | | } |
| | | |
| | | /* the cpu has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * It is not Linux, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | // this function remains in the tools class, because it is used by cron AND rescue |
| | | public function monitorServices() { |
| | | global $app; |
| | | global $conf; |
| | |
| | | $data['mysqlserver'] = 0; |
| | | $state = 'error'; // because service is down |
| | | } |
| | | |
| | | if ($this->_checkTcp('localhost', 27017)) { |
| | | $data['mongodbserver'] = 1; |
| | | } else { |
| | | $data['mongodbserver'] = 0; |
| | | $state = 'error'; // because service is down |
| | | } |
| | | } |
| | | $data['mongodbserver'] = -1; |
| | | if ($this->_checkTcp('localhost', 27017)) { |
| | | $data['mongodbserver'] = 1; |
| | | } else { |
| | | $data['mongodbserver'] = 0; |
| | | //$state = 'error'; // because service is down |
| | | /* TODO!!! check if this is a mongodbserver at all, otherwise it will always throw an error state!!! */ |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorOpenVzHost() { |
| | | global $app; |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'openvz_veinfo'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $app->load(openvz_tools); |
| | | $openVzTools = new openvz_tools(); |
| | | $data = $openVzTools->getOpenVzVeInfo(); |
| | | |
| | | /* the VE-Info has no state. It is, what it is */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorOpenVzUserBeancounter() { |
| | | global $app; |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'openvz_beancounter'; |
| | | |
| | | /* |
| | | Fetch the data into a array |
| | | */ |
| | | $app->load(openvz_tools); |
| | | $openVzTools = new openvz_tools(); |
| | | $data = $openVzTools->getOpenVzVeBeanCounter(); |
| | | |
| | | /* calculate the state of the beancounter */ |
| | | if ($data == '') { |
| | | $state = 'no_state'; |
| | | } else { |
| | | $state = 'ok'; |
| | | |
| | | /* transfer this output-string into a array */ |
| | | $test = explode("\n", $data); |
| | | |
| | | /* the first list of the output is not needed */ |
| | | array_shift($test); |
| | | |
| | | /* now process all items of the rest */ |
| | | foreach ($test as $item) { |
| | | /* |
| | | * eliminate all doubled spaces and spaces at the beginning and end |
| | | */ |
| | | while (strpos($item, ' ') !== false) { |
| | | $item = str_replace(' ', ' ', $item); |
| | | } |
| | | $item = trim($item); |
| | | |
| | | /* |
| | | * The failcounter is the LAST |
| | | */ |
| | | if ($item != '') { |
| | | $tmp = explode(' ', $item); |
| | | $failCounter = $tmp[sizeof($tmp) - 1]; |
| | | if ($failCounter > 0) |
| | | $state = 'info'; |
| | | if ($failCounter > 50) |
| | | $state = 'warning'; |
| | | if ($failCounter > 200) |
| | | $state = 'critical'; |
| | | if ($failCounter > 10000) |
| | | $state = 'error'; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorSystemUpdate() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'system_update'; |
| | | |
| | | /* This monitoring is only available on Debian or Ubuntu */ |
| | | if (file_exists('/etc/debian_version')) { |
| | | |
| | | /* |
| | | * first update the "apt database" |
| | | */ |
| | | shell_exec('apt-get update'); |
| | | |
| | | /* |
| | | * Then test the upgrade. |
| | | * if there is any output, then there is a needed update |
| | | */ |
| | | $aptData = shell_exec('apt-get -s -qq dist-upgrade'); |
| | | if ($aptData == '') { |
| | | /* There is nothing to update! */ |
| | | $state = 'ok'; |
| | | } else { |
| | | /* |
| | | * There is something to update! this is in most cases not critical, so we can |
| | | * do a system-update once a month or so... |
| | | */ |
| | | $state = 'info'; |
| | | } |
| | | |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = $aptData; |
| | | } elseif (file_exists('/etc/gentoo-release')) { |
| | | |
| | | /* |
| | | * first update the portage tree |
| | | */ |
| | | |
| | | // In keeping with gentoo's rsync policy, don't update to frequently (every four hours - taken from http://www.gentoo.org/doc/en/source_mirrors.xml) |
| | | $do_update = true; |
| | | if (file_exists('/usr/portage/metadata/timestamp.chk')) { |
| | | $datetime = file_get_contents('/usr/portage/metadata/timestamp.chk'); |
| | | $datetime = trim($datetime); |
| | | |
| | | $dstamp = strtotime($datetime); |
| | | if ($dstamp) { |
| | | $checkat = $dstamp + 14400; // + 4hours |
| | | if (mktime() < $checkat) { |
| | | $do_update = false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if ($do_update) { |
| | | shell_exec('emerge --sync --quiet'); |
| | | } |
| | | |
| | | /* |
| | | * Then test the upgrade. |
| | | * if there is any output, then there is a needed update |
| | | */ |
| | | $emergeData = shell_exec('glsa-check -t affected'); |
| | | if ($emergeData == '') { |
| | | /* There is nothing to update! */ |
| | | $state = 'ok'; |
| | | $data['output'] = 'No unapplied GLSA\'s found on the system.'; |
| | | } else { |
| | | /* There is something to update! */ |
| | | $state = 'info'; |
| | | $data['output'] = shell_exec('glsa-check -pv --nocolor affected 2>/dev/null'); |
| | | } |
| | | } elseif (file_exists('/etc/SuSE-release')) { |
| | | |
| | | /* |
| | | * update and find the upgrade. |
| | | * if there is any output, then there is a needed update |
| | | */ |
| | | $aptData = shell_exec('zypper -q lu'); |
| | | if ($aptData == '') { |
| | | /* There is nothing to update! */ |
| | | $state = 'ok'; |
| | | } else { |
| | | /* |
| | | * There is something to update! this is in most cases not critical, so we can |
| | | * do a system-update once a month or so... |
| | | */ |
| | | $state = 'info'; |
| | | } |
| | | |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('zypper lu'); |
| | | } else { |
| | | /* |
| | | * It is not Debian/Ubuntu, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorMailQueue() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'mailq'; |
| | | |
| | | /* Get the data from the mailq */ |
| | | $data['output'] = shell_exec('mailq'); |
| | | |
| | | /* |
| | | * The last line has more informations |
| | | */ |
| | | $tmp = explode("\n", $data['output']); |
| | | $more = $tmp[sizeof($tmp) - 1]; |
| | | $res = $this->_getIntArray($more); |
| | | $data['bytes'] = $res[0]; |
| | | $data['requests'] = $res[1]; |
| | | |
| | | /** The state of the mailq. */ |
| | | $state = 'ok'; |
| | | if ($data['requests'] > 2000) |
| | | $state = 'info'; |
| | | if ($data['requests'] > 5000) |
| | | $state = 'warning'; |
| | | if ($data['requests'] > 8000) |
| | | $state = 'critical'; |
| | | if ($data['requests'] > 10000) |
| | | $state = 'error'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorRaid() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'raid_state'; |
| | | |
| | | /* |
| | | * We support several RAID types, but if we can't find any of them, we have no data |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | |
| | | /* |
| | | * Check, if Software-RAID is enabled |
| | | */ |
| | | if (file_exists('/proc/mdstat')) { |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('cat /proc/mdstat'); |
| | | |
| | | /* |
| | | * Then calc the state. |
| | | */ |
| | | $tmp = explode("\n", $data['output']); |
| | | $state = 'ok'; |
| | | for ($i = 0; $i < sizeof($tmp); $i++) { |
| | | /* fetch the next line */ |
| | | $line = $tmp[$i]; |
| | | |
| | | if ((strpos($line, '[U_]') !== false) || (strpos($line, '[_U]') !== false)) { |
| | | /* One Disk is not working. |
| | | * if the next line starts with "[>" or "[=" then |
| | | * recovery (resync) is in state and the state is |
| | | * information instead of critical |
| | | */ |
| | | $nextLine = $tmp[$i + 1]; |
| | | if ((strpos($nextLine, '[>') === false) && (strpos($nextLine, '[=') === false)) { |
| | | $state = $this->_setState($state, 'critical'); |
| | | } else { |
| | | $state = $this->_setState($state, 'info'); |
| | | } |
| | | } |
| | | if (strpos($line, '[__]') !== false) { |
| | | /* both Disk are not working */ |
| | | $state = $this->_setState($state, 'error'); |
| | | } |
| | | if (strpos($line, '[UU]') !== false) { |
| | | /* The disks are OK. |
| | | * if the next line starts with "[>" or "[=" then |
| | | * recovery (resync) is in state and the state is |
| | | * information instead of ok |
| | | */ |
| | | $nextLine = $tmp[$i + 1]; |
| | | if ((strpos($nextLine, '[>') === false) && (strpos($nextLine, '[=') === false)) { |
| | | $state = $this->_setState($state, 'ok'); |
| | | } else { |
| | | $state = $this->_setState($state, 'info'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | /* |
| | | * Check, if we have mpt-status installed (LSIsoftware-raid) |
| | | */ |
| | | if (file_exists('/proc/mpt/summary')) { |
| | | system('which mpt-status', $retval); |
| | | if ($retval === 0) { |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('mpt-status --autoload'); |
| | | |
| | | /* |
| | | * Then calc the state. |
| | | */ |
| | | $state = 'ok'; |
| | | if(is_array($data['output'])) { |
| | | foreach ($data['output'] as $item) { |
| | | /* |
| | | * The output contains information for every RAID and every HDD. |
| | | * We only need the state of the RAID |
| | | */ |
| | | if (strpos($item, 'state ') !== false) { |
| | | /* |
| | | * We found a raid, process the state of it |
| | | */ |
| | | if (strpos($item, ' ONLINE ') !== false) { |
| | | $this->_setState($state, 'ok'); |
| | | } elseif (strpos($item, ' OPTIMAL ') !== false) { |
| | | $this->_setState($state, 'ok'); |
| | | } elseif (strpos($item, ' INITIAL ') !== false) { |
| | | $this->_setState($state, 'info'); |
| | | } elseif (strpos($item, ' INACTIVE ') !== false) { |
| | | $this->_setState($state, 'critical'); |
| | | } elseif (strpos($item, ' RESYNC ') !== false) { |
| | | $this->_setState($state, 'info'); |
| | | } elseif (strpos($item, ' DEGRADED ') !== false) { |
| | | $this->_setState($state, 'critical'); |
| | | } else { |
| | | /* we don't know the state. so we set the state to critical, that the |
| | | * admin is warned, that something is wrong |
| | | */ |
| | | $this->_setState($state, 'critical'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * 3ware Controller |
| | | */ |
| | | system('which tw_cli', $retval); |
| | | if($retval === 0) { |
| | | |
| | | $data['output'] = shell_exec('tw_cli info c0'); |
| | | |
| | | $state = 'ok'; |
| | | if(is_array($data['output'])) { |
| | | foreach ($data['output'] as $item) { |
| | | if (strpos($item, 'RAID') !== false) { |
| | | if (strpos($item, ' VERIFYING ') !== false) { |
| | | $this->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' MIGRATE-PAUSED ') !== false) { |
| | | $this->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' MIGRATING ') !== false) { |
| | | $this->_setState($state, 'ok'); |
| | | } |
| | | else if (strpos($item, ' INITIALIZING ') !== false) { |
| | | $this->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' INIT-PAUSED ') !== false) { |
| | | $this->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' REBUILDING ') !== false) { |
| | | $this->_setState($state, 'info'); |
| | | } |
| | | else if (strpos($item, ' REBUILD-PAUSED ') !== false) { |
| | | $this->_setState($state, 'warning'); |
| | | } |
| | | else if (strpos($item, ' RECOVERY ') !== false) { |
| | | $this->_setState($state, 'warning'); |
| | | } |
| | | else if (strpos($item, ' DEGRADED ') !== false) { |
| | | $this->_setState($state, 'critical'); |
| | | } |
| | | else if (strpos($item, ' UNKNOWN ') !== false) { |
| | | $this->_setState($state, 'critical'); |
| | | } |
| | | else if (strpos($item, ' OK ') !== false) { |
| | | $this->_setState($state, 'ok'); |
| | | } |
| | | else if (strpos($item, ' OPTIMAL ') !== false) { |
| | | $this->_setState($state, 'ok'); |
| | | } |
| | | else { |
| | | $this->_setState($state, 'critical'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorRkHunter() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'rkhunter'; |
| | | |
| | | /* This monitoring is only available if rkhunter is installed */ |
| | | system('which rkhunter', $retval); |
| | | if ($retval === 0) { |
| | | /* |
| | | * Fetch the output |
| | | */ |
| | | $data['output'] = shell_exec('rkhunter --update --checkall --nocolors --skip-keypress'); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * rkhunter is not installed, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data['output'] = ''; |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorFail2ban() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_fail2ban'; |
| | | |
| | | /* This monitoring is only available if fail2ban is installed */ |
| | | system('which fail2ban-client', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval !== 0) |
| | | system('which fail2ban', $retval); // CentOS |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * fail2ban is not installed, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorMongoDB() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mongodb'; |
| | | |
| | | /* This monitoring is only available if MongoDB is installed */ |
| | | system('which mongod', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval !== 0) |
| | | system('which mongod', $retval); // CentOS |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | /* |
| | | * MongoDB is not installed, so there is no data and no state |
| | | * |
| | | * no_state, NOT unknown, because "unknown" is shown as state |
| | | * inside the GUI. no_state is hidden. |
| | | * |
| | | * We have to write NO DATA inside the DB, because the GUI |
| | | * could not know, if there is any dat, or not... |
| | | */ |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorIPTables() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'iptables_rules'; |
| | | |
| | | /* This monitoring is only available if fail2ban is installed */ |
| | | system('which iptables', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data['output'] = '<h2>iptables -S (ipv4)</h2>'.shell_exec('iptables -S 2>/dev/null'); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | |
| | | /* This monitoring is only available if fail2ban is installed */ |
| | | system('which ip6tables', $retval); // Debian, Ubuntu, Fedora |
| | | if ($retval === 0) { |
| | | /* Get the data of the log */ |
| | | $data['output'] .= '<br><h2>ip6tables -S (ipv6)</h2>'.shell_exec('ip6tables -S 2>/dev/null'); |
| | | |
| | | /* |
| | | * At this moment, there is no state (maybe later) |
| | | */ |
| | | $state = 'no_state'; |
| | | } else { |
| | | $state = 'no_state'; |
| | | $data = ''; |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorSysLog() { |
| | | global $app; |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'sys_log'; |
| | | |
| | | /* |
| | | * is there any warning or error for this server? |
| | | */ |
| | | $state = 'ok'; |
| | | $dbData = $app->dbmaster->queryAllRecords('SELECT loglevel FROM sys_log WHERE server_id = ' . $server_id . ' AND loglevel > 0'); |
| | | if (is_array($dbData)) { |
| | | foreach ($dbData as $item) { |
| | | if ($item['loglevel'] == 1) |
| | | $state = $this->_setState($state, 'warning'); |
| | | if ($item['loglevel'] == 2) |
| | | $state = $this->_setState($state, 'error'); |
| | | } |
| | | } |
| | | |
| | | /** There is no monitor-data because the data is in the sys_log table */ |
| | | $data['output'] = ''; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorMailLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mail'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorMailWarnLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mail_warn'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorMailErrLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_mail_err'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorMessagesLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_messages'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorISPCCronLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_ispc_cron'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* |
| | | * actually this info has no state. |
| | | * maybe someone knows better...???... |
| | | */ |
| | | $state = 'no_state'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorFreshClamLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_freshclam'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | /* Get the data from the LAST log-Entry. |
| | | * if there can be found: |
| | | * WARNING: Your ClamAV installation is OUTDATED! |
| | | * then the clamav is outdated. This is a warning! |
| | | */ |
| | | $state = 'ok'; |
| | | |
| | | $tmp = explode("\n", $data); |
| | | $lastLog = array(); |
| | | if ($tmp[sizeof($tmp) - 1] == '') { |
| | | /* the log ends with an empty line remove this */ |
| | | array_pop($tmp); |
| | | } |
| | | if (strpos($tmp[sizeof($tmp) - 1], '-------------') !== false) { |
| | | /* the log ends with "-----..." remove this */ |
| | | array_pop($tmp); |
| | | } |
| | | for ($i = sizeof($tmp) - 1; $i > 0; $i--) { |
| | | if (strpos($tmp[$i], '---------') === false) { |
| | | /* no delimiter found, so add this to the last-log */ |
| | | $lastLog[] = $tmp[$i]; |
| | | } else { |
| | | /* delimiter found, so there is no more line left! */ |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Now we have the last log in the array. |
| | | * Check if the outdated-string is found... |
| | | */ |
| | | foreach ($lastLog as $line) { |
| | | if (strpos(strtolower($line), 'outdated') !== false) { |
| | | /* |
| | | * Outdatet is only info, because if we set this to warning, the server is |
| | | * as long in state warning, as there is a new version of ClamAv which takes |
| | | * sometimes weeks! |
| | | */ |
| | | $state = $this->_setState($state, 'info'); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorClamAvLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_clamav'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | // Todo: the state should be calculated. |
| | | $state = 'ok'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | public function monitorIspConfigLog() { |
| | | global $conf; |
| | | |
| | | /* the id of the server as int */ |
| | | $server_id = intval($conf['server_id']); |
| | | |
| | | /** The type of the data */ |
| | | $type = 'log_ispconfig'; |
| | | |
| | | /* Get the data of the log */ |
| | | $data = $this->_getLogData($type); |
| | | |
| | | // Todo: the state should be calculated. |
| | | $state = 'ok'; |
| | | |
| | | /* |
| | | * Return the Result |
| | | */ |
| | | $res['server_id'] = $server_id; |
| | | $res['type'] = $type; |
| | | $res['data'] = $data; |
| | | $res['state'] = $state; |
| | | return $res; |
| | | } |
| | | |
| | | |
| | | public function _getLogData($log) { |
| | | global $conf; |
| | | |
| | |
| | | * * If the actual state is critical and you call the method with error, |
| | | * then the state is error. |
| | | */ |
| | | private function _setState($oldState, $newState) { |
| | | public function _setState($oldState, $newState) { |
| | | /* |
| | | * Calculate the weight of the old state |
| | | */ |
| | |
| | | } |
| | | } |
| | | |
| | | private function _getIntArray($line) { |
| | | /** The array of float found */ |
| | | $res = array(); |
| | | /* First build a array from the line */ |
| | | $data = explode(' ', $line); |
| | | /* then check if any item is a float */ |
| | | foreach ($data as $item) { |
| | | if ($item . '' == (int) $item . '') { |
| | | $res[] = $item; |
| | | } |
| | | } |
| | | return $res; |
| | | /** |
| | | * Deletes Records older than 4 minutes. |
| | | * The monitor writes new data every 5 minutes or longer (4 hour, 1 day). |
| | | * So if i delete all Date older than 4 minutes i can be sure, that all old data |
| | | * are deleted... |
| | | */ |
| | | public function delOldRecords($type, $serverId) { |
| | | global $app; |
| | | |
| | | // $now = time(); |
| | | // $old = $now - (4 * 60); // 4 minutes |
| | | $old = 'UNIX_TIMESTAMP() - 240'; |
| | | |
| | | /* |
| | | * ATTENTION if i do NOT pay attention of the server id, i delete all data (of the type) |
| | | * of ALL servers. This means, if i have a multiserver-environment and a server has a |
| | | * time not synced with the others (for example, all server has 11:00 and ONE server has |
| | | * 10:45) then the actual data of this server (with the time-stamp 10:45) get lost |
| | | * even though it is the NEWEST data of this server. To avoid this i HAVE to include |
| | | * the server-id! |
| | | */ |
| | | $sql = 'DELETE FROM monitor_data ' . |
| | | 'WHERE ' . |
| | | ' type =' . "'" . $app->dbmaster->quote($type) . "' " . |
| | | 'AND ' . |
| | | ' created < ' . $old . ' ' . |
| | | 'AND ' . |
| | | ' server_id = ' . $serverId; |
| | | $app->dbmaster->query($sql); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | ?> |