cacti-1.2.10/ 0000775 0001750 0001750 00000000000 13627045400 011703 5 ustar markv markv cacti-1.2.10/poller_automation.php 0000664 0001750 0001750 00000111623 13627045366 016170 0 ustar markv markv #!/usr/bin/php -q
1) {
if ($config['connection'] == 'online') {
db_force_remote_cnn();
} else {
cacti_log('WARNING: Main Cacti database offline. Can not run automation', false, 'AUTOM8');
exit(1);
}
}
/** sig_handler - provides a generic means to catch exceptions to the Cacti log.
* @arg $signo - (int) the signal that was thrown by the interface.
* @return - null */
function sig_handler($signo) {
global $network_id, $thread, $master, $poller_id;
switch ($signo) {
case SIGTERM:
case SIGINT:
if ($thread > 0) {
clearTask($network_id, getmypid());
exit;
} elseif($thread == 0 && !$master) {
$pids = array_rekey(db_fetch_assoc_prepared("SELECT pid
FROM automation_processes
WHERE network_id = ?
AND task!='tmaster'",
array($network_id)), 'pid', 'pid');
if (cacti_sizeof($pids)) {
foreach($pids as $pid) {
posix_kill($pid, SIGTERM);
}
}
clearTask($network_id, getmypid());
sleep(5);
db_execute_prepared('DELETE
FROM automation_ips
WHERE network_id = ?',
array($network_id));
} else {
$pids = array_rekey(db_fetch_assoc_prepared("SELECT pid
FROM automation_processes
WHERE poller_id = ?
AND task='tmaster'",
array($poller_id)), 'pid', 'pid');
if (cacti_sizeof($pids)) {
foreach($pids as $pid) {
posix_kill($pid, SIGTERM);
}
}
clearTask($network_id, getmypid());
}
exit;
break;
default:
/* ignore all other signals */
}
}
/* take time and log performance data */
$start = microtime(true);
// Unix Timestamp for Database
$startTime = time();
/* let PHP run just as long as it has to */
ini_set('max_execution_time', '0');
$dir = dirname(__FILE__);
chdir($dir);
/* process calling arguments */
$parms = $_SERVER['argv'];
array_shift($parms);
$debug = false;
$force = false;
$network_id = 0;
$poller_id = $config['poller_id'];
$thread = 0;
$master = false;
global $debug, $poller_id, $network_id, $thread, $master;
if (cacti_sizeof($parms)) {
foreach($parms as $parameter) {
if (strpos($parameter, '=')) {
list($arg, $value) = explode('=', $parameter);
} else {
$arg = $parameter;
$value = '';
}
switch ($arg) {
case '-d':
case '--debug':
$debug = true;
break;
case '-M':
case '--master':
$master = true;
break;
case '--poller':
$poller_id = $value;
break;
case '-f':
case '--force':
$force = true;
break;
case '--network':
$network_id = $value;
break;
case '--thread':
$thread = $value;
break;
case '-v':
case '--version':
display_version();
exit;
case '-h':
case '--help':
display_help();
exit;
default:
print 'ERROR: Invalid Parameter ' . $parameter . "\n\n";
display_help();
exit;
}
}
}
/* install signal handlers for UNIX only */
if (function_exists('pcntl_signal')) {
pcntl_signal(SIGTERM, 'sig_handler');
pcntl_signal(SIGINT, 'sig_handler');
}
// Let's ensure that we were called correctly
if (!$master && !$network_id) {
print "FATAL: You must specify -M to Start the Master Control Process, or the Network ID using --network\n";
exit;
}
// Simple check for a disabled network
if (!$master && $thread == 0) {
$status = db_fetch_cell_prepared('SELECT enabled
FROM automation_networks
WHERE id = ?
AND poller_id = ?',
array($network_id, $poller_id));
if ($status != 'on' && !$force) {
cacti_log(automation_get_pid() . " WARNING: The Network ID: $network_id is disabled. You must use the 'force' option to force it's execution.", true, 'AUTOM8');
exit;
}
}
if ($master) {
$networks = db_fetch_assoc_prepared('SELECT *
FROM automation_networks
WHERE poller_id = ?',
array($poller_id));
$launched = 0;
if (cacti_sizeof($networks)) {
foreach($networks as $network) {
if (api_automation_is_time_to_start($network['id']) || $force) {
automation_debug("Launching Network Master for '" . $network['name'] . "'\n");
exec_background(read_config_option('path_php_binary'), '-q ' . read_config_option('path_webroot') . '/poller_automation.php --poller=' . $poller_id . ' --network=' . $network['id'] . ($force ? ' --force':'') . ($debug ? ' --debug':''));
$launched++;
} else {
automation_debug("Not time to Run Discovery for '" . $network['name'] . "'\n");
}
}
}
exit;
}
// Check for Network Master
if (!$master && $thread == 0) {
automation_debug("Thread master about to launch collector threads\n");
// Remove any stale entries
$pids = array_rekey(
db_fetch_assoc_prepared('SELECT pid
FROM automation_processes
WHERE network_id = ?',
array($network_id)),
'pid', 'pid'
);
automation_debug("Killing any prior running threads\n");
if (cacti_sizeof($pids)) {
foreach($pids as $pid) {
if (isProcessRunning($pid)) {
killProcess($pid);
cacti_log("WARNING: Automation Process $pid is still running for Network ID: $network_id", true, 'AUTOM8');
} else {
cacti_log("WARNING: Process $pid claims to be running but not found for Network ID: $network_id", true, 'AUTOM8');
}
}
}
automation_debug("Removing any orphan entries\n");
db_execute_prepared('DELETE FROM automation_ips
WHERE network_id = ?',
array($network_id));
db_execute_prepared('DELETE FROM automation_processes
WHERE network_id = ?',
array($network_id));
registerTask($network_id, getmypid(), $poller_id, 'tmaster');
cacti_log(automation_get_pid() . " Network Discover is now running for Subnet Range '$network_id'", true, 'AUTOM8');
$preexisting_devices = getNetworkDevices($network_id);
automation_primeIPAddressTable($network_id);
$threads = db_fetch_cell_prepared('SELECT threads
FROM automation_networks
WHERE id = ?',
array($network_id));
if ($threads <= 0) {
$threads = 1;
}
automation_debug("Automation will use $threads Threads\n");
db_execute_prepared('UPDATE automation_networks
SET last_started = ?
WHERE id = ?',
array(date('Y-m-d H:i:s', $startTime), $network_id));
$curthread = 1;
while($curthread <= $threads) {
automation_debug("Launching Thread $curthread\n");
exec_background(read_config_option('path_php_binary'), '-q ' . read_config_option('path_webroot') . '/poller_automation.php --poller=' . $poller_id . " --thread=$curthread --network=$network_id" . ($force ? ' --force':'') . ($debug ? ' --debug':''));
$curthread++;
}
sleep(5);
automation_debug("Checking for Running Threads\n");
$failcount = 0;
while (true) {
$command = db_fetch_cell_prepared('SELECT command
FROM automation_processes
WHERE network_id = ?
AND task="tmaster"',
array($network_id));
if ($command == 'cancel') {
killProcess(getmypid());
}
$running = db_fetch_cell_prepared('SELECT count(*)
FROM automation_processes
WHERE network_id = ?
AND task!="tmaster"
AND status="running"',
array($network_id));
automation_debug("Found $running Threads\n");
// Are there no more running tasks? Wait up to 15 seconds to
// allow processes to start before checking for failures
if (($running == 0 && $failcount > 3) || $command == 'cancel') {
db_execute_prepared('DELETE FROM automation_ips
WHERE network_id = ?',
array($network_id));
$totals = db_fetch_row_prepared('SELECT SUM(up_hosts) AS up, SUM(snmp_hosts) AS snmp
FROM automation_processes
WHERE network_id = ?',
array($network_id));
/* take time and log performance data */
$end = microtime(true);
db_execute_prepared('UPDATE automation_networks
SET up_hosts = ?, snmp_hosts = ?,
last_started = ?, last_runtime = ?
WHERE id = ?',
array($totals['up'], $totals['snmp'], date('Y-m-d H:i:s', $startTime), ($end - $start), $network_id));
clearAllTasks($network_id);
reportNetworkStatus($network_id, $preexisting_devices);
exit;
} else {
$failcount++;
}
sleep(5);
}
} else {
registerTask($network_id, getmypid(), $poller_id);
discoverDevices($network_id, $thread);
endTask($network_id, getmypid());
}
exit;
function discoverDevices($network_id, $thread) {
$network = db_fetch_row_prepared('SELECT *
FROM automation_networks
WHERE id = ?',
array($network_id));
$temp = db_fetch_assoc('SELECT automation_templates.*, host_template.name
FROM automation_templates
LEFT JOIN host_template
ON (automation_templates.host_template=host_template.id)');
$dns = trim($network['dns_servers']);
/* Let's do some stats! */
$stats = array();
$stats['scanned'] = 0;
$stats['ping'] = 0;
$stats['snmp'] = 0;
$stats['added'] = 0;
$count_graph = 0;
$count = 0;
while(true) {
// Check for cancel
$command = db_fetch_cell_prepared('SELECT command
FROM automation_processes
WHERE network_id = ?
AND task = "tmaster"',
array($network_id));
if ($command == 'cancel' || empty($command)) {
removeMyProcess(getmypid(), $network_id);
killProcess(getmypid());
exit;
}
// set and ip to be scanned
db_execute_prepared('UPDATE automation_ips
SET pid = ?, thread = ?
WHERE network_id = ?
AND status = 0
AND pid = 0
LIMIT 1',
array(getmypid(), $thread, $network_id));
$device = db_fetch_row_prepared('SELECT *
FROM automation_ips
WHERE pid = ?
AND thread = ?
AND status=0',
array(getmypid(), $thread));
if (cacti_sizeof($device) && isset($device['ip_address'])) {
$count++;
cacti_log(automation_get_pid() . ' NOTE: Found device IP address \'' . $device['ip_address'] .'\' to check',false,'AUTOM8',POLLER_VERBOSITY_MEDIUM);
if ($dns != '') {
$dnsname = automation_get_dns_from_ip($device['ip_address'], $dns, 300);
if ($dnsname != $device['ip_address'] && $dnsname != 'timed_out') {
automation_debug("Device: " . $device['ip_address'] . ", Checking DNS: Found '" . $dnsname . "'");
db_execute_prepared('UPDATE automation_ips
SET hostname = ?
WHERE ip_address = ?',
array($dnsname, $device['ip_address']));
$device['hostname'] = $dnsname;
$device['dnsname'] = $dnsname;
$device['dnsname_short'] = preg_split('/[\.]+/', strtolower($dnsname), -1, PREG_SPLIT_NO_EMPTY);
} elseif ($network['enable_netbios'] == 'on') {
automation_debug("Device: " . $device['ip_address'] . ", Checking DNS: Not found, Checking NetBIOS:");
$netbios = ping_netbios_name($device['ip_address']);
if ($netbios === false) {
automation_debug(" Not found");
$device['hostname'] = $device['ip_address'];
$device['dnsname'] = '';
$device['dnsname_short'] = '';
} else {
automation_debug(" Found: '" . $netbios . "'");
db_execute_prepared('UPDATE automation_ips
SET hostname = ?
WHERE ip_address = ?',
array($device['hostname'], $device['ip_address']));
$device['dnsname'] = $netbios;
$device['dnsname_short'] = $netbios;
}
} else {
automation_debug("Device: " . $device['ip_address'] . ", Checking DNS: Not found");
$device['hostname'] = $device['ip_address'];
$device['dnsname'] = '';
$device['dnsname_short'] = '';
}
} else {
$dnsname = @gethostbyaddr($device['ip_address']);
$device['hostname'] = $dnsname;
if ($dnsname != $device['ip_address']) {
automation_debug("Device: " . $device['ip_address'] . ", Checking DNS: Found '" . $dnsname . "'");
db_execute_prepared('UPDATE automation_ips
SET hostname = ?
WHERE ip_address = ?',
array($dnsname, $device['ip_address']));
$device['dnsname'] = $dnsname;
$device['dnsname_short'] = preg_split('/[\.]+/', strtolower($dnsname), -1, PREG_SPLIT_NO_EMPTY);
} elseif ($network['enable_netbios'] == 'on') {
automation_debug("Device: " . $device['ip_address'] . ", Checking DNS: Not found, Checking NetBIOS:");
$netbios = ping_netbios_name($device['ip_address']);
if ($netbios === false) {
automation_debug(" Not found");
$device['hostname'] = $device['ip_address'];
$device['dnsname'] = '';
$device['dnsname_short'] = '';
} else {
automation_debug(" Found: '" . $netbios . "'");
db_execute_prepared('UPDATE automation_ips
SET hostname = ?
WHERE ip_address = ?',
array($device['hostname'], $device['ip_address']));
$device['dnsname'] = $netbios;
$device['dnsname_short'] = $netbios;
}
} else {
automation_debug("Device: " . $device['ip_address'] . ", Checking DNS: Not found");
$device['hostname'] = $device['ip_address'];
$device['dnsname'] = '';
$device['dnsname_short'] = '';
}
}
$exists = db_fetch_row_prepared('SELECT id, snmp_version, status, deleted
FROM host
WHERE hostname IN (?,?)',
array($device['ip_address'], $device['hostname']));
if (!cacti_sizeof($exists)) {
automation_debug(", Status: Not in Cacti");
if (substr($device['ip_address'], -3) < 255) {
automation_debug(', Ping: ');
// Set status to running
markIPRunning($device['ip_address'], $network_id);
$stats['scanned']++;
$device['snmp_status'] = 0;
$device['ping_status'] = 0;
$device['snmp_id'] = $network['snmp_id'];
$device['poller_id'] = $network['poller_id'];
$device['site_id'] = $network['site_id'];
$device['snmp_version'] = '';
$device['snmp_port'] = '';
$device['snmp_community'] = '';
$device['snmp_username'] = '';
$device['snmp_password'] = '';
$device['snmp_auth_protocol'] = '';
$device['snmp_auth_passphrase'] = '';
$device['snmp_auth_protocol'] = '';
$device['snmp_context'] = '';
$device['snmp_port'] = '';
$device['snmp_timeout'] = '';
$device['snmp_sysDescr'] = '';
$device['snmp_sysObjectID'] = '';
$device['snmp_sysUptime'] = 0;
$device['snmp_sysName'] = '';
$device['snmp_sysName_short'] = '';
$device['snmp_sysLocation'] = '';
$device['snmp_sysContact'] = '';
$device['os'] = '';
$device['snmp_priv_passphrase'] = '';
$device['snmp_priv_protocol'] = '';
/* create new ping socket for host pinging */
$ping = new Net_Ping;
$ping->host['hostname'] = $device['ip_address'];
$ping->retries = $network['ping_retries'];
$ping->port = $network['ping_port'];;
/* perform the appropriate ping check of the host */
$bypass_ping = false;
$result = false;
if ($network['ping_method'] == PING_SNMP) {
$bypass_ping = true;
}
if ($bypass_ping == false) {
$result = $ping->ping(AVAIL_PING, $network['ping_method'], $network['ping_timeout'], 1);
if (!$result) {
automation_debug(" No response");
updateDownDevice($network_id, $device['ip_address']);
} else {
automation_debug(" Responded");
$stats['ping']++;
addUpDevice($network_id, getmypid());
}
}
if (($result || $bypass_ping) && automation_valid_snmp_device($device)) {
$snmp_sysName = trim($device['snmp_sysName']);
$snmp_sysName_short = '';
if (!is_ipaddress($snmp_sysName)) {
$parts = explode('.', $snmp_sysName);
foreach($parts as $part) {
if (is_numeric($part)) {
$snmp_sysName_short = $snmp_sysName;
break;
}
}
if ($snmp_sysName_short == '') {
$snmp_sysName_short = $parts[0];
}
} else {
$snmp_sysName_short = $snmp_sysName;
}
$exists = db_fetch_row_prepared('SELECT id, status, snmp_version, deleted
FROM host
WHERE hostname IN (?,?)',
array($snmp_sysName_short, $snmp_sysName));
if (cacti_sizeof($exists)) {
if ($exists['deleted'] != 'on') {
if ($exists['status'] == 3 || $exists['status'] == 2) {
addUpDevice($network_id, getmypid());
if ($exists['snmp_version'] > 0) {
addSNMPDevice($network_id, getmypid());
}
// Rerun data queries if specified
rerunDataQueries($exists['id'], $network);
}
automation_debug(' Device is in Cacti!');
} else {
automation_debug(' Device is in Cacti but marked as deleted!');
}
markIPDone($device['ip_address'], $network_id);
} else {
$host_id = 0;
if ($snmp_sysName != '') {
$hostname = gethostbyaddr($device['ip_address']);
if ($hostname != $device['ip_address']) {
if (strpos($hostname, '.')) {
$hostname = substr($hostname, 0, strpos($hostname, '.') - 1);
}
}
$isCactiSysName = db_fetch_cell_prepared('SELECT COUNT(*)
FROM host
WHERE snmp_sysName = ?
AND (hostname = ? OR hostname LIKE "' . $hostname . '%")',
array($snmp_sysName, $device['ip_address']));
if ($isCactiSysName) {
automation_debug(", Skipping sysName '" . $snmp_sysName . "' already in Cacti!\n");
markIPDone($device['ip_address'], $network_id);
continue;
}
if ($network['same_sysname'] == '') {
$isDuplicateSysNameDiscovery = db_fetch_cell_prepared('SELECT COUNT(*)
FROM automation_devices
WHERE network_id = ?
AND sysName != ""
AND ip != ?
AND sysName = ?',
array($network_id, $device['ip_address'], $snmp_sysName));
$isDuplicateSysNameCacti = db_fetch_cell_prepared('SELECT COUNT(*)
FROM host
WHERE snmp_sysName = ?
AND hostname != ?',
array($snmp_sysName, $device['ip_address']));
if ($isDuplicateSysNameDiscovery || $isDuplicateSysNameCacti) {
automation_debug(", Skipping sysName '" . $snmp_sysName . "' already Discovered!\n");
markIPDone($device['ip_address'], $network_id);
continue;
}
}
$stats['snmp']++;
addSNMPDevice($network_id, getmypid());
automation_debug(" Responded");
$fos = automation_find_os($device['snmp_sysDescr'], $device['snmp_sysObjectID'], $device['snmp_sysName']);
if ($fos != false && $network['add_to_cacti'] == 'on') {
automation_debug(', Template: ' . $fos['name'] . "\n");
$device['os'] = $fos['name'];
$device['host_template'] = $fos['host_template'];
$device['availability_method'] = $fos['availability_method'];
$host_id = automation_add_device($device);
if (!empty($host_id)) {
if (isset($device['snmp_sysDescr']) && $device['snmp_sysDescr'] != '') {
db_execute_prepared('UPDATE host
SET snmp_sysDescr = ?
WHERE id = ?',
array($device['snmp_sysDescr'], $host_id));
}
if (isset($device['snmp_sysObjectID']) && $device['snmp_sysObjectID'] != '') {
db_execute_prepared('UPDATE host
SET snmp_sysObjectID = ?
WHERE id = ?',
array($device['snmp_sysObjectID'], $host_id));
}
if (isset($device['snmp_sysUptime']) && $device['snmp_sysUptime'] != '') {
db_execute_prepared('UPDATE host
SET snmp_sysUptimeInstance = ?
WHERE id = ?',
array($device['snmp_sysUptime'], $host_id));
}
if (isset($device['snmp_sysContact']) && $device['snmp_sysContact'] != '') {
db_execute_prepared('UPDATE host
SET snmp_sysContact = ?
WHERE id = ?',
array($device['snmp_sysContact'], $host_id));
}
if (isset($device['snmp_sysName']) && $device['snmp_sysName'] != '') {
db_execute_prepared('UPDATE host
SET snmp_sysName = ?
WHERE id = ?',
array($device['snmp_sysName'], $host_id));
}
if (isset($device['snmp_sysLocation']) && $device['snmp_sysLocation'] != '') {
db_execute_prepared('UPDATE host
SET snmp_sysLocation = ?
WHERE id = ?',
array($device['snmp_sysLocation'], $host_id));
}
automation_update_device($host_id);
}
$stats['added']++;
} elseif ($fos == false) {
automation_debug(", Template: Not found, Not adding to Cacti\n");
} else {
automation_debug(", Template: " . $fos['name']);
$device['os'] = $fos['name'];
automation_debug(", Skipped: Add to Cacti disabled\n");
}
}
// if the devices template is not discovered, add to found table
if ($host_id == 0) {
db_execute('REPLACE INTO automation_devices
(network_id, hostname, ip, snmp_community, snmp_version, snmp_port, snmp_username, snmp_password, snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, sysName, sysLocation, sysContact, sysDescr, sysUptime, os, snmp, up, time) VALUES ('
. $network_id . ', '
. db_qstr($device['dnsname']) . ', '
. db_qstr($device['ip_address']) . ', '
. db_qstr($device['snmp_community']) . ', '
. db_qstr($device['snmp_version']) . ', '
. db_qstr($device['snmp_port']) . ', '
. db_qstr($device['snmp_username']) . ', '
. db_qstr($device['snmp_password']) . ', '
. db_qstr($device['snmp_auth_protocol']) . ', '
. db_qstr($device['snmp_priv_passphrase']) . ', '
. db_qstr($device['snmp_priv_protocol']) . ', '
. db_qstr($device['snmp_context']) . ', '
. db_qstr($device['snmp_sysName']) . ', '
. db_qstr($device['snmp_sysLocation']) . ', '
. db_qstr($device['snmp_sysContact']) . ', '
. db_qstr($device['snmp_sysDescr']) . ', '
. db_qstr($device['snmp_sysUptime']) . ', '
. db_qstr($device['os']) . ', '
. '1, 1,' . time() . ')');
}
markIPDone($device['ip_address'], $network_id);
}
} elseif ($result) {
db_execute('REPLACE INTO automation_devices
(network_id, hostname, ip, snmp_community, snmp_version, snmp_port, snmp_username, snmp_password, snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, sysName, sysLocation, sysContact, sysDescr, sysUptime, os, snmp, up, time) VALUES ('
. $network_id . ', '
. db_qstr($device['dnsname']) . ', '
. db_qstr($device['ip_address']) . ', '
. db_qstr($device['snmp_community']) . ', '
. db_qstr($device['snmp_version']) . ', '
. db_qstr($device['snmp_port']) . ', '
. db_qstr($device['snmp_username']) . ', '
. db_qstr($device['snmp_password']) . ', '
. db_qstr($device['snmp_auth_protocol']) . ', '
. db_qstr($device['snmp_priv_passphrase']) . ', '
. db_qstr($device['snmp_priv_protocol']) . ', '
. db_qstr($device['snmp_context']) . ', '
. db_qstr($device['snmp_sysName']) . ', '
. db_qstr($device['snmp_sysLocation']) . ', '
. db_qstr($device['snmp_sysContact']) . ', '
. db_qstr($device['snmp_sysDescr']) . ', '
. db_qstr($device['snmp_sysUptime']) . ', '
. '"", 0, 1,' . time() . ')');
automation_debug(", Alive no SNMP!");
markIPDone($device['ip_address'], $network_id);
} else {
markIPDone($device['ip_address'], $network_id);
}
automation_debug("\n");
} else {
automation_debug(", Status: Ignoring Address (PHP Bug does not allow us to ping .255 as it thinks its a broadcast IP)!\n");
markIPDone($device['ip_address'], $network_id);
}
} else {
if ($exists['deleted'] != 'on') {
if ($exists['status'] == 3 || $exists['status'] == 2) {
addUpDevice($network_id, getmypid());
if ($exists['snmp_version'] > 0) {
addSNMPDevice($network_id, getmypid());
}
// Rerun data queries if specified
rerunDataQueries($exists['id'], $network);
}
automation_debug(", Status: Already in Cacti\n");
} else {
automation_debug(", Status: Already in Cacti but marked as deleted\n");
}
markIPDone($device['ip_address'], $network_id);
}
} else {
// no more ips to scan
break;
}
}
cacti_log(automation_get_pid() . ' Network ' . $network['name'] . " Thread $thread Finished, " . $stats['scanned'] . ' IPs Scanned, ' . $stats['ping'] . ' IPs Responded to Ping, ' . $stats['snmp'] . ' Responded to SNMP, ' . $stats['added'] . ' Device Added, ' . $count_graph . ' Graphs Added to Cacti', true, 'AUTOM8');
return true;
}
/* display_version - displays version information */
function display_version() {
$version = get_cacti_version();
print "Cacti Network Discovery Scanner, Version $version, " . COPYRIGHT_YEARS . "\n";
}
/* display_help - displays the usage of the function */
function display_help () {
display_version();
print "\nusage: poller_automation.php -M [--poller=ID] | --network=network_id [-T=thread_id]\n";
print " [--debug] [--force]\n\n";
print "Cacti's automation poller. This poller has two operating modes, Master and Slave.\n";
print "The Master process tracks and launches all Slaves based upon Cacti's automation\n";
print "settings. If you only want to force a network to be collected, you only need to\n";
print "specify the Network ID and the force options.\n\n";
print "Master Process:\n";
print " -M | --master - Master poller for all Automation\n";
print " --poller=ID - Master Poller ID, Defaults to 0 or WebServer\n\n";
print "Network Masters and Workers:\n";
print " --network=n - Network ID to discover\n";
print " --thread=n - Thread ID, Defaults to 0 or Network Master\n\n";
print "General Options:\n";
print " --force - Force the execution of a discovery process\n";
print " --debug - Display verbose output during execution\n\n";
}
function isProcessRunning($pid) {
return posix_kill($pid, 0);
}
function killProcess($pid) {
return posix_kill($pid, SIGTERM);
}
function removeMyProcess($pid, $network_id) {
db_execute_prepared('DELETE FROM automation_processes
WHERE pid = ?
AND network_id = ?',
array($pid, $network_id));
db_execute_prepared('DELETE FROM automation_ips
WHERE pid = ?
AND network_id = ?',
array($pid, $network_id));
}
function rerunDataQueries($host_id, &$network) {
if ($network['rerun_data_queries'] == 'on') {
$snmp_queries = db_fetch_assoc_prepared('SELECT snmp_query_id
FROM host_snmp_query
WHERE host_id = ?',
array($host_id));
if (cacti_sizeof($snmp_queries)) {
foreach($snmp_queries as $query) {
run_data_query($host_id, $query['snmp_query_id']);
}
}
}
}
function registerTask($network_id, $pid, $poller_id, $task = 'collector') {
db_execute_prepared("REPLACE INTO automation_processes
(pid, poller_id, network_id, task, status, heartbeat, command)
VALUES (?, ?, ?, ?, 'running', NOW(), 'start')",
array($pid, $poller_id, $network_id, $task));
}
function endTask($network_id, $pid) {
db_execute_prepared("UPDATE automation_processes
SET status='done', heartbeat=NOW()
WHERE pid = ?
AND network_id = ?",
array($pid, $network_id));
}
function addUpDevice($network_id, $pid) {
db_execute_prepared('UPDATE automation_processes
SET up_hosts=up_hosts+1, heartbeat=NOW()
WHERE pid = ?
AND network_id = ?',
array($pid, $network_id));
}
function addSNMPDevice($network_id, $pid) {
db_execute_prepared('UPDATE automation_processes
SET snmp_hosts=snmp_hosts+1, heartbeat=NOW()
WHERE pid = ?
AND network_id = ?',
array($pid, $network_id));
}
function reportNetworkStatus($network_id, $old_devices) {
$details = db_fetch_row_prepared('SELECT notification_enabled, notification_email,
notification_fromname, notification_fromemail
FROM automation_networks
WHERE id = ?',
array($network_id));
if (cacti_sizeof($details)) {
if ($details['notification_enabled'] == 'on') {
if ($details['notification_fromname'] == '') {
$fromname = read_config_option('automation_fromname');
if ($fromname == '') {
$fromname = read_config_option('settings_from_name');
if ($fromname == '') {
$fromname = __('Cacti Primary Admin');
}
}
} else {
$fromname = $details['notification_fromname'];
}
if ($details['notification_fromemail'] == '') {
$fromemail = read_config_option('automation_fromemail');
if ($fromemail == '') {
$fromemail = read_config_option('settings_from_email');
if ($fromemail == '') {
$fromemail = 'root@cacti.net';
}
}
} else {
$fromemail = $details['notification_fromemail'];
}
$from = $fromname . ' <' . $fromemail . '>';
if ($details['notification_email'] != '') {
$email = $details['notification_email'];
} else {
$email = read_config_option('automation_email');
if ($email == '') {
$admin_user = read_config_option('admin_user');
if ($admin_user == '') {
cacti_log('WARNING: Unable to send Automation Notification Email. No Primary Admin User Account specified.', false, 'POLLER');
return false;
}
$details = db_fetch_cell_prepared('SELECT email_address AS notification_email, full_name
FROM user_auth
WHERE id = ?',
array($admin_user));
if (!cacti_sizeof($details)) {
cacti_log('WARNING: Unable to send Automation Notification Email. The Primary Admin User Account does not exist.', false, 'POLLER');
return false;
}
if ($details['notification_email'] == '') {
cacti_log('WARNING: Unable to send Automation Notification Email. The Primary Admin User Account does not have an Email Address.', false, 'POLLER');
return false;
}
$email = ($details['full_name'] != '' ? $details['full_name']:__('Cacti Primary Admin')) . ' <' . $details['notification_email'] . '>';
}
}
$new_devices = getNetworkDevices($network_id);
$ids = array();
populateDeviceIndex($ids, 0, $old_devices);
populateDeviceIndex($ids, 1, $new_devices);
$table_head_style = 'style="border-bottom: 1px solid black"';
$table_head = '
' .
"Hostname " .
"IP Address " .
"SNMP Name " .
"Has SNMP? " .
"Responding? " .
' ';
$table_exist = '';
$table_new = '';
$count_exist = 0;
$count_new = 0;
$font_up = 'up ';
$font_down = 'down ';
foreach ($new_devices as $device) {
$id = $device['ip'];
$html_line = '' . $device['hostname'] .
' ' . $device['ip'] .
' ' . (empty($device['sysName']) ? 'None ' : $device['sysName']) .
' ' . ($device['snmp'] ? $font_up : $font_down) .
' ' . ($device['up'] ? $font_up : $font_down) .
' ';
if ($ids[$id]['old'] != '') {
$table_exist .= $html_line;
$count_exist++;
} else {
$table_new .= $html_line;
$count_new++;
}
}
if (strlen($table_exist) > 0) {
$table_exist .= ' ';
}
if (strlen($table_new) > 0) {
$table_new .= ' ';
}
$v = get_cacti_version();
$headers['User-Agent'] = 'Cacti-Automation-v' . $v;
$status = ($count_new + $count_exist) . ' devices discovered';
if ($count_new > 0) {
$status .= ', ' . $count_new . ' new!';
}
$network = db_fetch_row_prepared('SELECT id, name, subnet_range, last_started, last_runtime
FROM automation_networks
WHERE id = ?',
array($network_id));
$subject = 'Discovery of ' . $network['name'] . ' (' . $network['subnet_range'] . ') - ' . $status;
$output = 'Discovery of ' . $network['name'] . ' ' .
'Summary ' .
'Network: ' . $network['subnet_range'] . ' '.
'Started: ' . $network['last_started'] . ' ' .
'Duration: ' . intval($network['last_runtime']) . ' ' .
'Existing: ' . $count_exist . ' devices ' .
'New: ' . $count_new . ' devices ' .
'
';
if ($count_new > 0 || $count_exist > 0) {
$output .= '';
if ($count_new > 0) {
$output .= 'New Devices ' . $table_head . $table_new;
}
if ($count_exist > 0) {
$output .= 'Existing Devices ' . $table_head . $table_exist;
}
$output .= '
';
}
$error = mailer(
$from,
$email,
'',
'',
'',
$subject,
$output,
__('Cacti Automation Report requires an html based Email client'),
'',
$headers
);
if (strlen($error)) {
cacti_log("WARNING: Automation had problems sending to '$email' for $status. The error was '$error'", false, 'AUTOM8');
} else {
cacti_log("NOTICE: Email Notification Sent to '$email' for $status.", false, 'AUTOM8');
}
}
}
}
function populateDeviceIndex(&$ids, $is_new, $devices) {
$field = ($is_new ? 'new' : 'old');
foreach ($devices as $index => $device) {
$id = $device['ip'];
if (!isset($ids[$id])) {
$ids[$id] = array('old' => '', 'new' => '');
}
$ids[$id][$field] = $id;
}
}
function clearTask($network_id, $pid) {
db_execute_prepared('DELETE
FROM automation_processes
WHERE pid = ?
AND network_id = ?',
array($pid, $network_id));
db_execute_prepared('DELETE
FROM automation_ips
WHERE network_id = ?',
array($network_id));
}
function clearAllTasks($network_id) {
db_execute_prepared('DELETE FROM automation_processes
WHERE network_id = ?',
array($network_id));
}
function markIPRunning($ip_address, $network_id) {
db_execute_prepared('UPDATE automation_ips
SET status=1
WHERE ip_address = ?
AND network_id = ?',
array($ip_address, $network_id));
}
function markIPDone($ip_address, $network_id) {
db_execute_prepared('UPDATE automation_ips
SET status=2
WHERE ip_address = ?
AND network_id = ?',
array($ip_address, $network_id));
}
function getNetworkDevices($network_id) {
return db_fetch_assoc_prepared('SELECT id, hostname, ip, sysName, snmp, up, time
FROM automation_devices
WHERE network_id = ?
ORDER BY hostname',
array($network_id));
}
function updateDownDevice($network_id, $ip) {
$exists = db_fetch_cell_prepared('SELECT COUNT(*)
FROM automation_devices
WHERE ip = ?
AND network_id = ?',
array($ip, $network_id));
if ($exists) {
db_execute_prepared("UPDATE automation_devices
SET up='0'
WHERE ip = ?
AND network_id = ?",
array($ip, $network_id));
}
}
cacti-1.2.10/snmpagent_mibcache.php 0000664 0001750 0001750 00000004556 13627045365 016247 0 ustar markv markv /dev/null &');
}
sleep(30 - time() % 30);
}
cacti-1.2.10/data_debug.php 0000664 0001750 0001750 00000103132 13627045364 014504 0 ustar markv markv __('Run Check'),
2 => __('Delete Check')
);
ini_set('memory_limit', '-1');
set_default_action();
switch (get_request_var('action')) {
case 'actions':
form_actions();
break;
case 'run_debug':
$id = get_filter_request_var('id');
if ($id > 0) {
$selected_items = array($id);
debug_delete($selected_items);
debug_rerun($selected_items);
raise_message('rerun', __('Data Source debug started.'), MESSAGE_LEVEL_INFO);
header('Location: data_debug.php?action=view&id=' . get_filter_request_var('id'));
} else {
raise_message('repair_error', __('Data Source debug received an invalid Data Source ID.'), MESSAGE_LEVEL_ERROR);
}
break;
case 'run_repair':
$id = get_filter_request_var('id');
if ($id > 0) {
if (dsdebug_run_repair($id)) {
raise_message('repair', __('All RRDfile repairs succeeded.'), MESSAGE_LEVEL_INFO);
} else {
raise_message('repair', __('One or more RRDfile repairs failed. See Cacti log for errors.'), MESSAGE_LEVEL_ERROR);
}
$selected_items = array($id);
debug_delete($selected_items);
debug_rerun($selected_items);
raise_message('rerun', __('Automatic Data Source debug being rerun after repair.'), MESSAGE_LEVEL_INFO);
header('Location: data_debug.php?action=view&id=' . get_filter_request_var('id'));
} else {
raise_message('repair_error', __('Data Source repair received an invalid Data Source ID.'), MESSAGE_LEVEL_ERROR);
}
break;
case 'view':
$id = get_filter_request_var('id');
$debug_status = debug_process_status($id);
if ($debug_status == 'notset') {
$selected_items = array($id);
debug_delete($selected_items);
debug_rerun($selected_items);
$debug_status = 'waiting';
}
if ($debug_status == 'waiting' || $debug_status == 'analysis') {
$refresh = array(
'seconds' => 30,
'page' => 'data_debug.php?action=view&id=' . $id . '&header=false',
'logout' => 'false'
);
set_page_refresh($refresh);
}
top_header();
debug_view();
bottom_footer();
break;
case 'ajax_hosts':
$sql_where = '';
if (get_request_var('site_id') > 0) {
$sql_where = 'site_id = ' . get_request_var('site_id');
}
get_allowed_ajax_hosts(true, 'applyFilter', $sql_where);
break;
case 'ajax_hosts_noany':
$sql_where = '';
if (get_request_var('site_id') > 0) {
$sql_where = 'site_id = ' . get_request_var('site_id');
}
get_allowed_ajax_hosts(false, 'applyFilter', $sql_where);
break;
default:
validate_request_vars();
$refresh = array(
'seconds' => get_request_var('refresh'),
'page' => 'data_debug.php?header=false',
'logout' => 'false'
);
set_page_refresh($refresh);
top_header();
debug_wizard();
bottom_footer();
break;
}
function debug_process_status($id) {
$status = db_fetch_row_prepared('SELECT done, IFNULL(issue, "waiting") AS issue
FROM data_debug
WHERE datasource = ?',
array($id));
if (cacti_sizeof($status) == 0) {
return 'notset';
} elseif ($status['issue'] == 'waiting') {
return 'waiting';
} elseif ($status['done'] == 1) {
return 'complete';
} else {
return 'analysis';
}
}
function form_actions() {
global $actions, $assoc_actions;
/* ================= input validation ================= */
get_filter_request_var('id');
get_filter_request_var('drp_action', FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^([a-zA-Z0-9_]+)$/')));
/* ================= input validation ================= */
$selected_items = array();
if (isset_request_var('save_list')) {
/* loop through each of the lists selected on the previous page and get more info about them */
foreach ($_POST as $var=>$val) {
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
/* ================= input validation ================= */
input_validate_input_number($matches[1]);
/* ==================================================== */
$selected_items[] = $matches[1];
}
}
/* if we are to save this form, instead of display it */
if (isset_request_var('save_list')) {
if (get_request_var('drp_action') == '2') { /* delete */
debug_delete($selected_items);
header('Location: data_debug.php?header=false&debug=-1');
} elseif (get_request_var('drp_action') == '1') { /* Rerun */
debug_rerun($selected_items);
header('Location: data_debug.php?header=false&debug=1');
}
exit;
}
}
}
function debug_rerun($selected_items) {
$info = array(
'rrd_folder_writable' => '',
'rrd_exists' => '',
'rrd_writable' => '',
'active' => '',
'owner' => '',
'runas_poller' => '',
'runas_website' => get_running_user(),
'last_result' => '',
'valid_data' => '',
'rra_timestamp' => '',
'rra_timestamp2' => '',
'rrd_match' => ''
);
$info = serialize($info);
if (!empty($selected_items)) {
foreach($selected_items as $id) {
$exists = db_fetch_cell_prepared('SELECT id
FROM data_debug
WHERE datasource = ?',
array($id));
if (!$exists) {
$save = array();
$save['id'] = 0;
$save['datasource'] = $id;
$save['info'] = $info;
$save['started'] = time();
$save['user'] = intval($_SESSION['sess_user_id']);
$id = sql_save($save, 'data_debug');
} else {
$stime = time();
db_execute_prepared('UPDATE data_debug
SET started = ?,
done = 0,
info = ?,
issue = ""
WHERE id = ?',
array($stime, $info, $exists));
}
}
}
}
function debug_delete($selected_items) {
if (!empty($selected_items)) {
foreach($selected_items as $id) {
db_execute_prepared('DELETE
FROM data_debug
WHERE datasource = ?',
array($id));
}
}
}
function validate_request_vars() {
/* ================= input validation and session storage ================= */
$filters = array(
'rows' => array(
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
),
'refresh' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '60'
),
'page' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
),
'rfilter' => array(
'filter' => FILTER_VALIDATE_IS_REGEX,
'pageset' => true,
'default' => '',
'options' => array('options' => 'sanitize_search_string')
),
'sort_column' => array(
'filter' => FILTER_CALLBACK,
'default' => 'name_cache',
'options' => array('options' => 'sanitize_search_string')
),
'sort_direction' => array(
'filter' => FILTER_CALLBACK,
'default' => 'ASC',
'options' => array('options' => 'sanitize_search_string')
),
'site_id' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '-1',
'pageset' => true,
),
'host_id' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '-1',
'pageset' => true,
),
'template_id' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '-1',
'pageset' => true,
),
'status' => array(
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
),
'profile' => array(
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
),
'debug' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '-1',
'pageset' => true,
)
);
validate_store_request_vars($filters, 'sess_dd');
/* ================= input validation ================= */
}
function debug_wizard() {
global $actions;
$display_text = array(
'name_cache' => array(
'display' => __('Data Source'),
'sort' => 'ASC',
'tip' => __('The Data Source to Debug'),
),
'username' => array(
'display' => __('User'),
'sort' => 'ASC',
'tip' => __('The User who requested the Debug.'),
),
'started' => array(
'display' => __('Started'),
'sort' => 'DESC',
'align' => 'right',
'tip' => __('The Date that the Debug was Started.'),
),
'local_data_id' => array(
'display' => __('ID'),
'sort' => 'ASC',
'align' => 'right',
'tip' => __('The Data Source internal ID.'),
),
'nosort1' => array(
'display' => __('Status'),
'sort' => 'ASC',
'align' => 'center',
'tip' => __('The Status of the Data Source Debug Check.'),
),
'nosort2' => array(
'display' => __('Writable'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the Data Collector or the Web Site have Write access.'),
),
'nosort3' => array(
'display' => __('Exists'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the Data Source is located in the Poller Cache.'),
),
'nosort4' => array(
'display' => __('Active'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the Data Source is Enabled.'),
),
'nosort5' => array(
'display' => __('RRD Match'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the RRDfile matches the Data Source Template.'),
),
'nosort6' => array(
'display' => __('Valid Data'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the RRDfile has been getting good recent Data.'),
),
'nosort7' => array(
'display' => __('RRD Updated'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the RRDfile has been writted to properly.'),
),
'nosort8' => array(
'display' => __('Issues'),
'align' => 'right',
'sort' => '',
'tip' => __('Summary of issues found for the Data Source.'),
)
);
if (isset_request_var('purge')) {
db_execute('TRUNCATE TABLE data_debug');
}
/* fill in the current date for printing in the log */
if (defined('CACTI_DATE_TIME_FORMAT')) {
$datefmt = CACTI_DATE_TIME_FORMAT;
} else {
$datefmt = 'Y-m-d H:i:s';
}
data_debug_filter();
$total_rows = 0;
$checks = array();
if (get_request_var('rows') == '-1') {
$rows = read_config_option('num_rows_table');
} else {
$rows = get_request_var('rows');
}
/* form the 'where' clause for our main sql query */
if (get_request_var('rfilter') != '') {
$sql_where1 = "WHERE (dtd.name_cache RLIKE '" . get_request_var('rfilter') . "'" .
" OR dtd.local_data_id RLIKE '" . get_request_var('rfilter') . "'" .
" OR dt.name RLIKE '" . get_request_var('rfilter') . "')";
} else {
$sql_where1 = '';
}
if (get_request_var('host_id') == '-1') {
/* Show all items */
} elseif (isempty_request_var('host_id')) {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' (dl.host_id=0 OR dl.host_id IS NULL)';
} elseif (!isempty_request_var('host_id')) {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dl.host_id=' . get_request_var('host_id');
}
if (get_request_var('site_id') == '-1') {
/* Show all items */
} elseif (isempty_request_var('site_id')) {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' (h.site_id=0 OR h.site_id IS NULL)';
} elseif (!isempty_request_var('site_id')) {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' h.site_id=' . get_request_var('site_id');
}
if (get_request_var('template_id') == '-1') {
/* Show all items */
} elseif (get_request_var('template_id') == '0') {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dtd.data_template_id=0';
} elseif (!isempty_request_var('template_id')) {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dtd.data_template_id=' . get_request_var('template_id');
}
if (get_request_var('profile') == '-1') {
/* Show all items */
} else {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dtd.data_source_profile_id=' . get_request_var('profile');
}
if (get_request_var('status') == '-1') {
/* Show all items */
} elseif (get_request_var('status') == '0') {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dd.issue != ""';
} elseif (get_request_var('status') == '1') {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dtd.active="on"';
} else {
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dtd.active=""';
}
if (get_request_var('debug') == '-1') {
$dd_join = 'LEFT';
} elseif (get_request_var('debug') == 0) {
$dd_join = 'LEFT';
$sql_where1 .= ($sql_where1 != '' ? ' AND':'WHERE') . ' dd.datasource IS NULL';
} else {
$dd_join = 'INNER';
}
$total_rows = db_fetch_cell("SELECT COUNT(*)
FROM data_local AS dl
INNER JOIN data_template_data AS dtd
ON dl.id=dtd.local_data_id
INNER JOIN data_template AS dt
ON dt.id=dl.data_template_id
INNER JOIN host AS h
ON h.id = dl.host_id
$dd_join JOIN data_debug AS dd
ON dl.id = dd.datasource
$sql_where1");
$sql_order = get_order_string();
$sql_limit = ' LIMIT ' . ($rows*(get_request_var('page')-1)) . ',' . $rows;
$checks = db_fetch_assoc("SELECT dd.*, dtd.local_data_id, dtd.name_cache
FROM data_local AS dl
INNER JOIN data_template_data AS dtd
ON dl.id=dtd.local_data_id
INNER JOIN data_template AS dt
ON dt.id=dl.data_template_id
INNER JOIN host AS h
ON h.id = dl.host_id
$dd_join JOIN data_debug AS dd
ON dl.id = dd.datasource
$sql_where1
$sql_order
$sql_limit");
$nav = html_nav_bar('data_debug.php', MAX_DISPLAY_PAGES, get_request_var('page'), $rows, $total_rows, cacti_sizeof($display_text) + 1, __('Data Sources'), 'page', 'main');
form_start('data_debug.php', 'chk');
print $nav;
html_start_box('', '100%', '', '3', 'center', '');
html_header_sort_checkbox($display_text, get_request_var('sort_column'), get_request_var('sort_direction'), false);
if (cacti_sizeof($checks)) {
foreach ($checks as $check) {
$info = unserialize($check['info']);
$issues = explode("\n", $check['issue']);
$issue_line = '';
if (cacti_sizeof($issues)) {
$issue_line = $issues[0];
}
$issue_title = implode(' ',$issues);
$user = db_fetch_cell_prepared('SELECT username
FROM user_auth
WHERE id = ?',
array($check['user']), 'username');
form_alternate_row('line' . $check['local_data_id']);
form_selectable_cell(filter_value(title_trim($check['name_cache'], read_config_option('max_title_length')), get_request_var('rfilter'), 'data_debug.php?action=view&id=' . $check['local_data_id']), $check['local_data_id']);
if (!empty($check['datasource'])) {
form_selectable_ecell($user, $check['local_data_id']);
form_selectable_cell(date($datefmt, $check['started']), $check['local_data_id'], '', 'right');
form_selectable_cell($check['local_data_id'], $check['local_data_id'], '', 'right');
form_selectable_cell(debug_icon(($check['done'] ? (strlen($issue_line) ? 'off' : 'on'):'')), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['rrd_writable']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['rrd_exists']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['active']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['rrd_match']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['valid_data']), $check['local_data_id'], '', 'center');
if ($check['done'] && $info['rrd_writable'] == '') {
form_selectable_cell(debug_icon('blah'), $check['local_data_id'], '', 'center');
} else {
form_selectable_cell(debug_icon(($info['rra_timestamp2'] != '' ? 1 : '')), $check['local_data_id'], '', 'center');
}
form_selectable_cell('' . ($issue_line != '' ? __esc('Issues') : __esc('N/A')) . ' ', $check['local_data_id'], '', 'right');
} else {
form_selectable_cell('-', $check['local_data_id']);
form_selectable_cell(__('Not Debugging'), $check['local_data_id'], '', 'right');
form_selectable_cell($check['local_data_id'], $check['local_data_id'], '', 'right');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'right');
}
form_checkbox_cell($check['local_data_id'], $check['local_data_id']);
form_end_row();
}
} else {
print "" . __('No Checks') . " ";
}
html_end_box(false);
if (cacti_sizeof($checks)) {
print $nav;
}
form_hidden_box('save_list', '1', '');
/* draw the dropdown containing a list of available actions for this form */
draw_actions_dropdown($actions);
form_end();
}
function debug_view() {
global $config, $refresh;
$refresh = 60;
$id = get_filter_request_var('id');
$check = db_fetch_row_prepared('SELECT *
FROM data_debug
WHERE datasource = ?',
array($id));
$check_exists = cacti_sizeof($check);
if (isset($check) && is_array($check)) {
$check['info'] = unserialize($check['info']);
}
$dtd = db_fetch_row_prepared('SELECT *
FROM data_template_data
WHERE local_data_id = ?',
array($check['datasource']));
$real_pth = str_replace('', $config['rra_path'], $dtd['data_source_path']);
$poller_data = array();
if (!empty($check['info']['last_result'])) {
foreach ($check['info']['last_result'] as $a => $l) {
$poller_data[] = "$a = $l";
}
}
$poller_data = implode(' ', $poller_data);
$rra_updated = '';
if (isset($check['info']['rra_timestamp2'])) {
$rra_updated = $check['info']['rra_timestamp2'] != '' ? __('Yes') : '';
}
$rrd_exists = '';
if (isset($check['info']['rrd_exists'])) {
$rrd_exists = $check['info']['rrd_exists'] == '1' ? __('Yes') : __('Not Checked Yet');
}
$active = '';
if (isset($check['info']['active'])) {
$active = $check['info']['active'] == 'on' ? __('Yes') : __('Not Checked Yet');
}
$issue = '';
if (isset($check['issue'])) {
$issue = $check['issue'];
}
if ($check['done'] == 1) {
if ($issue != '') {
$issue_icon = debug_icon(0);
} else {
$issue_icon = debug_icon(1);
}
} else {
if (isset($check['info']['rrd_match_array']['ds'])) {
if ($check['info']['rrd_match'] == 0) {
$issue_icon = debug_icon('blah');
$issue = __('Issues found! Waiting on RRDfile update');
} else {
$issue_icon = debug_icon('');
$issue = __('No Initial found! Waiting on RRDfile update');
}
} else {
$issue_icon = debug_icon('');
$issue = __('Waiting on analysis and RRDfile update');
}
}
$fields = array(
array(
'name' => 'owner',
'title' => __('RRDfile Owner'),
'icon' => '-'
),
array(
'name' => 'runas_website',
'title' => __('Website runs as'),
'icon' => '-'
),
array(
'name' => 'runas_poller',
'title' => __('Poller runs as'),
'icon' => '-'
),
array(
'name' => 'rrd_folder_writable',
'title' => __('Is RRA Folder writeable by poller?'),
'value' => dirname($real_pth)
),
array(
'name' => 'rrd_writable',
'title' => __('Is RRDfile writeable by poller?'),
'value' => $real_pth
),
array(
'name' => 'rrd_exists',
'title' => __('Does the RRDfile Exist?'),
'value' => $rrd_exists
),
array(
'name' => 'active',
'title' => __('Is the Data Source set as Active?'),
'value' => $active
),
array(
'name' => 'last_result',
'title' => __('Did the poller receive valid data?'),
'value' => $poller_data
),
array(
'name' => 'rra_updated',
'title' => __('Was the RRDfile updated?'),
'value' => '',
'icon' => $rra_updated
),
array(
'name' => 'rra_timestamp',
'title' => __('First Check TimeStamp'),
'icon' => '-'
),
array(
'name' => 'rra_timestamp2',
'title' => __('Second Check TimeStamp'),
'icon' => '-'
),
array(
'name' => 'convert_name',
'title' => __('Were we able to convert the title?'),
'value' => get_data_source_title($check['datasource'])
),
array(
'name' => 'rrd_match',
'title' => __('Data Source matches the RRDfile?'),
'value' => ''
),
array(
'name' => 'issue',
'title' => __('Issues'),
'value' => $issue,
'icon' => $issue_icon
),
);
$debug_status = debug_process_status($id);
if ($debug_status == 'waiting') {
html_start_box(__('Data Source Troubleshooter [ Auto Refreshing till Complete ] %s', ' '), '100%', '', '3', 'center', '');
} elseif ($debug_status == 'analysis') {
html_start_box(__('Data Source Troubleshooter [ Auto Refreshing till RRDfile Update ] %s', ' '), '100%', '', '3', 'center', '');
} else {
html_start_box(__('Data Source Troubleshooter [ Analysis Complete! %s ]', '' . __('Rerun Analysis') . ' '), '100%', '', '3', 'center', '');
}
html_header(
array(
__('Check'),
__('Value'),
__('Results')
)
);
$i = 1;
foreach ($fields as $field) {
$field_name = $field['name'];
form_alternate_row('line' . $i);
form_selectable_ecell($field['title'], $i);
$value = __('');
$icon = '';
if (array_key_exists($field_name, $check['info'])) {
$value = $check['info'][$field_name];
if ($field_name == 'last_result') {
$icon = debug_icon_valid_result($value);
} else {
$icon = debug_icon($value);
}
}
if (array_key_exists('value', $field)) {
$value = $field['value'];
}
if (array_key_exists('icon', $field)) {
$icon = $field['icon'];
}
$value_title = $value;
if (strlen($value) > 100) {
$value = substr($value, 0, 100);
}
form_selectable_cell($value, $i, '', '', $value_title);
form_selectable_cell($icon, $i);
form_end_row();
$i++;
}
html_end_box();
if ($check_exists > 0 && isset($check['info']['rrd_match_array']['ds']) && $check['info']['rrd_match'] == 0) {
html_start_box(__('Data Source Repair Recommendations'), '', '', '2', 'center', '');
html_header(
array(
__('Data Source'),
__('Issue')
)
);
if (isset($check['info']['rrd_match_array']['ds'])) {
$i = 0;
foreach($check['info']['rrd_match_array']['ds'] AS $data_source => $details) {
form_alternate_row('line2_' . $i, true);
form_selectable_cell($data_source, $i);
$output = '';
foreach($details as $attribute => $recommendation) {
$output .= __('For attrbitute \'%s\', issue found \'%s\'', $attribute, $recommendation);
}
form_selectable_cell($output, 'line_2' . $i);
form_end_row();
$i++;
}
}
html_end_box();
if (isset($check['info']['rrd_match_array']['tune'])) {
$path = get_data_source_path($id, true);
if (is_writeable($path)) {
html_start_box(__('Repair Steps [ %s ]', '' . __('Apply Suggested Fixes') . ' '), '', '', '2', 'center', '');
} else {
html_start_box(__('Repair Steps [ Run Fix from Command Line ]', $path), '', '', '2', 'center', '');
}
html_header(array(__('Command')));
$rrdtool_path = read_config_option('path_rrdtool');
$i = 0;
foreach($check['info']['rrd_match_array']['tune'] AS $options) {
form_alternate_row('line3_' . $i, true);
form_selectable_cell($rrdtool_path . ' tune ' . $options, 'line3_' . $i);
form_end_row();
$i++;
}
html_end_box();
}
} else {
html_start_box(__('Data Source Repair Recommendations'), '', '', '2', 'center', '');
form_alternate_row('line3_0', true);
form_selectable_cell(__('Waiting on Data Source Check to Complete'), 'line3_0');
form_end_row();
html_end_box();
}
?>
';
}
if ($result === '-') {
return ' ';
}
if (is_array($result)) {
foreach($result as $variable => $value) {
if (!prepare_validate_result($value)) {
return ' ';
}
}
return ' ';
} elseif (prepare_validate_result($result)) {
return ' ';
} else {
return ' ';
}
}
function debug_icon($result) {
if ($result === '' || $result === false) {
return ' ';
}
if ($result === '-') {
return ' ';
}
if ($result === 1 || $result === 'on') {
return ' ';
}
if ($result === 0 || $result === 'off') {
return ' ';
}
return ' ';
}
function data_debug_filter() {
global $item_rows, $page_refresh_interval;
if (get_request_var('site_id') > 0) {
$host_where = 'site_id = ' . get_request_var('site_id');
} else {
$host_where = '';
}
if (get_request_var('host_id') > 0) {
$hostname = db_fetch_cell_prepared('SELECT CONCAT(description, " ( ", hostname, " )") FROM host WHERE id = ?', array(get_request_var('host_id')));
} else {
$hostname = '';
}
html_start_box(__('Data Source Troubleshooter [ %s ]', (empty($hostname) ? (get_request_var('host_id') == -1 ? __('All Devices') :__('No Device')) : html_escape($hostname))), '100%', '', '3', 'center', '');
?>
array(
'color_id' => '0',
'graph_type_id' => '9',
'consolidation_function_id' => '4',
'text_format' => 'Cur:',
'hard_return' => ''
),
1 => array(
'color_id' => '0',
'graph_type_id' => '9',
'consolidation_function_id' => '1',
'text_format' => 'Avg:',
'hard_return' => ''
),
2 => array(
'color_id' => '0',
'graph_type_id' => '9',
'consolidation_function_id' => '3',
'text_format' => 'Max:',
'hard_return' => 'on'
));
} elseif ($graph_item_types[get_nfilter_request_var('graph_type_id')] == 'LEGEND_CAMM') {
/* this can be a major time saver when creating lots of graphs with the typical
GPRINT LAST/AVERAGE/MAX legends */
$items = array(
0 => array(
'color_id' => '0',
'graph_type_id' => '9',
'consolidation_function_id' => '4',
'text_format' => __('Cur:'),
'hard_return' => ''
),
1 => array(
'color_id' => '0',
'graph_type_id' => '9',
'consolidation_function_id' => '1',
'text_format' => __('Avg:'),
'hard_return' => ''
),
2 => array(
'color_id' => '0',
'graph_type_id' => '9',
'consolidation_function_id' => '2',
'text_format' => __('Min:'),
'hard_return' => ''
),
3 => array(
'color_id' => '0',
'graph_type_id' => '9',
'consolidation_function_id' => '3',
'text_format' => __('Max:'),
'hard_return' => 'on'
)
);
}
$sequence = get_nfilter_request_var('sequence');
foreach ($items as $item) {
/* generate a new sequence if needed */
if (empty($sequence)) {
$sequence = get_sequence($sequence, 'sequence', 'graph_templates_item', 'local_graph_id=' . get_nfilter_request_var('local_graph_id'));
}
$save['id'] = get_nfilter_request_var('graph_template_item_id');
$save['graph_template_id'] = get_nfilter_request_var('graph_template_id');
$save['local_graph_template_item_id'] = get_nfilter_request_var('local_graph_template_item_id');
$save['local_graph_id'] = get_nfilter_request_var('local_graph_id');
$save['task_item_id'] = form_input_validate(get_nfilter_request_var('task_item_id'), 'task_item_id', '^[0-9]+$', true, 3);
$save['color_id'] = form_input_validate((isset($item['color_id']) ? $item['color_id'] : get_nfilter_request_var('color_id')), 'color_id', '^[0-9]+$', true, 3);
/* if alpha is disabled, use invisible_alpha instead */
if (!isset_request_var('alpha')) {
set_request_var('alpha', get_nfilter_request_var('invisible_alpha'));
}
$save['alpha'] = form_input_validate((isset($item['alpha']) ? $item['alpha'] : get_nfilter_request_var('alpha')), 'alpha', '', true, 3);
$save['graph_type_id'] = form_input_validate((isset($item['graph_type_id']) ? $item['graph_type_id'] : get_nfilter_request_var('graph_type_id')), 'graph_type_id', '^[0-9]+$', true, 3);
if (isset_request_var('line_width') || isset($item['line_width'])) {
$save['line_width'] = form_input_validate((isset($item['line_width']) ? $item['line_width'] : get_nfilter_request_var('line_width')), 'line_width', '(^[0-9]+[\.,0-9]+$|^[0-9]+$)', true, 3);
}else { # make sure to transfer old LINEx style into line_width on save
switch ($save['graph_type_id']) {
case GRAPH_ITEM_TYPE_LINE1:
$save['line_width'] = 1;
break;
case GRAPH_ITEM_TYPE_LINE2:
$save['line_width'] = 2;
break;
case GRAPH_ITEM_TYPE_LINE3:
$save['line_width'] = 3;
break;
default:
$save['line_width'] = 0;
}
}
$save['dashes'] = form_input_validate((isset_request_var('dashes') ? get_nfilter_request_var('dashes') : ''), 'dashes', '', true, 3);
$save['dash_offset'] = form_input_validate((isset_request_var('dash_offset') ? get_nfilter_request_var('dash_offset') : ''), 'dash_offset', '^[0-9]+$', true, 3);
$save['cdef_id'] = form_input_validate(get_nfilter_request_var('cdef_id'), 'cdef_id', '^[0-9]+$', true, 3);
$save['vdef_id'] = form_input_validate(get_nfilter_request_var('vdef_id'), 'vdef_id', '^[0-9]+$', true, 3);
$save['shift'] = form_input_validate((isset_request_var('shift') ? get_nfilter_request_var('shift') : ''), 'shift', '^((on)|)$', true, 3);
$save['consolidation_function_id'] = form_input_validate((isset($item['consolidation_function_id']) ? $item['consolidation_function_id'] : get_nfilter_request_var('consolidation_function_id')), 'consolidation_function_id', '^[0-9]+$', true, 3);
$save['textalign'] = form_input_validate((isset_request_var('textalign') ? get_nfilter_request_var('textalign') : ''), 'textalign', '^[a-z]+$', true, 3);
$save['text_format'] = form_input_validate((isset($item['text_format']) ? $item['text_format'] : get_nfilter_request_var('text_format')), 'text_format', '', true, 3);
$save['value'] = form_input_validate(get_nfilter_request_var('value'), 'value', '', true, 3);
$save['hard_return'] = form_input_validate(((isset($item['hard_return']) ? $item['hard_return'] : (isset_request_var('hard_return') ? get_nfilter_request_var('hard_return') : ''))), 'hard_return', '', true, 3);
$save['gprint_id'] = form_input_validate(get_nfilter_request_var('gprint_id'), 'gprint_id', '^[0-9]+$', true, 3);
$save['sequence'] = $sequence;
if (!is_error_message()) {
$graph_template_item_id = sql_save($save, 'graph_templates_item');
if ($graph_template_item_id) {
raise_message(1);
} else {
raise_message(2);
}
}
$sequence = 0;
}
if (is_error_message()) {
header('Location: graphs.php?header=false&action=item_edit&graph_template_item_id=' . (empty($graph_template_item_id) ? get_nfilter_request_var('graph_template_item_id') : $graph_template_item_id) . '&id=' . get_nfilter_request_var('local_graph_id'));
exit;
} else {
header('Location: graphs.php?header=false&action=graph_edit&id=' . get_nfilter_request_var('local_graph_id'));
exit;
}
}
}
/* -----------------------
item - Graph Items
----------------------- */
function item_movedown() {
global $graph_item_types;
/* ================= input validation ================= */
get_filter_request_var('id');
get_filter_request_var('local_graph_id');
/* ==================================================== */
$arr = get_graph_group(get_request_var('id'));
$next_id = get_graph_parent(get_request_var('id'), 'next');
if ((!empty($next_id)) && (isset($arr{get_request_var('id')}))) {
move_graph_group(get_request_var('id'), $arr, $next_id, 'next');
} elseif (preg_match('/(GPRINT|VRULE|HRULE|COMMENT)/', $graph_item_types{db_fetch_cell_prepared('SELECT graph_type_id FROM graph_templates_item WHERE id = ?', array(get_request_var('id')))})) {
move_item_down('graph_templates_item', get_request_var('id'), 'local_graph_id=' . get_request_var('local_graph_id'));
}
}
function item_moveup() {
global $graph_item_types;
/* ================= input validation ================= */
get_filter_request_var('id');
get_filter_request_var('local_graph_id');
/* ==================================================== */
$arr = get_graph_group(get_request_var('id'));
$previous_id = get_graph_parent(get_request_var('id'), 'previous');
if ((!empty($previous_id)) && (isset($arr{get_request_var('id')}))) {
move_graph_group(get_request_var('id'), $arr, $previous_id, 'previous');
} elseif (preg_match('/(GPRINT|VRULE|HRULE|COMMENT)/', $graph_item_types{db_fetch_cell_prepared('SELECT graph_type_id FROM graph_templates_item WHERE id = ?', array(get_request_var('id')))})) {
move_item_up('graph_templates_item', get_request_var('id'), 'local_graph_id=' . get_request_var('local_graph_id'));
}
}
function item_remove() {
/* ================= input validation ================= */
get_filter_request_var('id');
/* ==================================================== */
db_execute_prepared('DELETE FROM graph_templates_item WHERE id = ?', array(get_request_var('id')));
}
function validate_item_vars() {
/* ================= input validation and session storage ================= */
$filters = array(
'host_id' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '0'
),
'local_graph_id' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '0'
),
'data_template_id' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '0'
)
);
validate_store_request_vars($filters, 'sess_gitems');
/* ================= input validation ================= */
}
function item_edit() {
global $struct_graph_item, $graph_item_types, $consolidation_functions;
/* ================= input validation ================= */
get_filter_request_var('id');
get_filter_request_var('host_id');
get_filter_request_var('local_graph_id');
get_filter_request_var('data_template_id');
/* ==================================================== */
validate_item_vars();
$id = (!isempty_request_var('id') ? '&id=' . get_request_var('id') : '');
$host = db_fetch_row_prepared('SELECT hostname
FROM host
WHERE id = ?',
array(get_request_var('host_id')));
if (empty($host['hostname'])) {
$header = __('Data Sources [No Device]');
} else {
$header = __esc('Data Sources [%s]', $host['hostname']);
}
html_start_box($header, '100%', '', '3', 'center', '');
?>
0) {
$sql_where = 'h.id=' . get_request_var('host_id');
} elseif (get_request_var('host_id') == 0) {
$sql_where = 'h.id IS NULL';
} else {
$sql_where = '';
}
if (get_request_var('data_template_id') == '-1') {
$sql_where .= '';
} elseif (get_request_var('data_template_id') == '0') {
$sql_where .= ($sql_where != '' ? ' AND ':'') . 'dl.data_template_id=0';
} elseif (!isempty_request_var('data_template_id')) {
$sql_where .= ($sql_where != '' ? ' AND ':'') . 'dl.data_template_id=' . get_request_var('data_template_id');
}
if (!isempty_request_var('id')) {
$template_item = db_fetch_row_prepared('SELECT *
FROM graph_templates_item
WHERE id = ?',
array(get_request_var('id')));
} else {
$template_item = array();
kill_session_var('sess_graph_items_dti');
}
$title = db_fetch_cell_prepared('SELECT title_cache
FROM graph_templates_graph
WHERE local_graph_id = ?',
array(get_request_var('local_graph_id')));
$header_label = __esc('Graph Items [graph: %s]', $title);
form_start('graphs_items.php', 'greph_edit');
html_start_box($header_label, '100%', true, '3', 'center', '');
/* by default, select the LAST DS chosen to make everyone's lives easier */
if (!isempty_request_var('local_graph_id')) {
$struct_graph_item['task_item_id']['default'] = 0;
if (isset($template_item['task_item_id'])) {
$task_item_id = $template_item['task_item_id'];
$value = db_fetch_cell_prepared("SELECT
CONCAT_WS('', dtd.name_cache,' (', dtr.data_source_name, ')') as name
FROM data_local AS dl
INNER JOIN data_template_data AS dtd
ON dtd.local_data_id=dl.id
INNER JOIN data_template_rrd AS dtr
ON dtr.local_data_id=dl.id
LEFT JOIN host AS h
ON dl.host_id=h.id
WHERE dtr.id = ?",
array($task_item_id));
} else {
$task_item_id = 0;
$value = '';
}
if (get_selected_theme() != 'classic' && read_config_option('autocomplete_enabled') > 0) {
$action = 'ajax_graph_items';
if (get_request_var('host_id') > 0) {
$action .= '&host_id=' . get_filter_request_var('host_id');
}
if (get_request_var('data_template_id') > 0) {
$action .= '&data_template_id=' . get_filter_request_var('data_template_id');
}
$struct_graph_item['task_item_id'] = array(
'method' => 'drop_callback',
'friendly_name' => __('Data Source'),
'description' => __('Choose the Data Source to associate with this Graph Item.'),
'sql' => '',
'action' => $action,
'none_value' => __('None'),
'id' => $task_item_id,
'value' => $value
);
}
/* modifications to the default graph items array */
$struct_graph_item['task_item_id']['sql'] = "SELECT
CONCAT_WS('', dtd.name_cache,' (', dtr.data_source_name, ')') as name, dtr.id
FROM data_local AS dl
INNER JOIN data_template_data AS dtd
ON dtd.local_data_id=dl.id
INNER JOIN data_template_rrd AS dtr
ON dtr.local_data_id=dl.id
LEFT JOIN host AS h
ON dl.host_id=h.id";
/* Make sure we don't limit the list so that the selected DS isn't in the list in edit mode */
if ($sql_where != '') {
if (!isempty_request_var('id')) {
$struct_graph_item['task_item_id']['sql'] .= " WHERE ($sql_where) OR (dtr.id=" . $template_item['task_item_id'] . ")";
} else {
$struct_graph_item['task_item_id']['sql'] .= " WHERE $sql_where";
}
}
$struct_graph_item['task_item_id']['sql'] .= ' ORDER BY name';
}
$form_array = array();
foreach ($struct_graph_item as $field_name => $field_array) {
$form_array += array($field_name => $struct_graph_item[$field_name]);
if (get_selected_theme() != 'classic' && read_config_option('autocomplete_enabled')) {
if ($field_name != 'task_item_id') {
$form_array[$field_name]['value'] = (isset($template_item[$field_name]) ? $template_item[$field_name] : '');
}
}else{
$form_array[$field_name]['value'] = (isset($template_item[$field_name]) ? $template_item[$field_name] : '');
}
$form_array[$field_name]['form_id'] = (isset($template_item['id']) ? $template_item['id'] : '0');
}
draw_edit_form(
array(
'config' => array('no_form_tag' => true),
'fields' => $form_array
)
);
form_hidden_box('local_graph_id', get_request_var('local_graph_id'), '0');
form_hidden_box('graph_template_item_id', (!empty($template_item) ? $template_item['id'] : '0'), '');
form_hidden_box('local_graph_template_item_id', (!empty($template_item) ? $template_item['local_graph_template_item_id'] : '0'), '');
form_hidden_box('graph_template_id', (!empty($template_item) ? $template_item['graph_template_id'] : '0'), '');
form_hidden_box('_graph_type_id', (!empty($template_item) ? $template_item['graph_type_id'] : '0'), '');
form_hidden_box('save_component_item', '1', '');
form_hidden_box('invisible_alpha', $form_array['alpha']['value'], 'FF');
form_hidden_box('rrdtool_version', get_rrdtool_version(), '');
html_end_box(true, true);
form_save_button('graphs.php?action=graph_edit&id=' . get_request_var('local_graph_id'));
?>
__('Delete'),
2 => __('Disable'),
3 => __('Enable'),
);
if ($config['poller_id'] == 1) {
$poller_actions += array(4 =>__('Full Sync'));
}
$poller_status = array(
0 => '' . __('New/Idle') . '
',
1 => '' . __('Running') . '
',
2 => '' . __('Idle') . '
',
3 => '' . __('Down') . '
',
4 => '' . __('Disabled') . '
',
5 => '' . __('Recovering') . '
',
6 => '' . __('Heartbeat') . '
',
);
/* file: pollers.php, action: edit */
$fields_poller_edit = array(
'spacer0' => array(
'method' => 'spacer',
'friendly_name' => __('Data Collector Information'),
),
'name' => array(
'method' => 'textbox',
'friendly_name' => __('Name'),
'description' => __('The primary name for this Data Collector.'),
'value' => '|arg1:name|',
'size' => '50',
'default' => __('New Data Collector'),
'max_length' => '100'
),
'hostname' => array(
'method' => 'textbox',
'friendly_name' => __('Data Collector Hostname'),
'description' => __('The hostname for Data Collector. It may have to be a Fully Qualified Domain name for the remote Pollers to contact it for activities such as re-indexing, Real-time graphing, etc.'),
'value' => '|arg1:hostname|',
'size' => '50',
'default' => '',
'max_length' => '100'
),
'timezone' => array(
'method' => 'drop_callback',
'friendly_name' => __('TimeZone'),
'description' => __('The TimeZone for the Data Collector.'),
'sql' => 'SELECT Name AS id, Name AS name FROM mysql.time_zone_name ORDER BY name',
'action' => 'ajax_tz',
'id' => '|arg1:timezone|',
'value' => '|arg1:timezone|'
),
'notes' => array(
'method' => 'textarea',
'friendly_name' => __('Notes'),
'description' => __('Notes for this Data Collectors Database.'),
'value' => '|arg1:notes|',
'textarea_rows' => 4,
'textarea_cols' => 50
),
'spacer_collection' => array(
'method' => 'spacer',
'friendly_name' => __('Collection Settings'),
),
'processes' => array(
'method' => 'textbox',
'friendly_name' => __('Processes'),
'description' => __('The number of Data Collector processes to use to spawn.'),
'value' => '|arg1:processes|',
'size' => '10',
'default' => read_config_option('concurrent_processes'),
'max_length' => '4'
),
'threads' => array(
'method' => 'textbox',
'friendly_name' => __('Threads'),
'description' => __('The number of Spine Threads to use per Data Collector process.'),
'value' => '|arg1:threads|',
'size' => '10',
'default' => read_config_option('max_threads'),
'max_length' => '4'
),
'sync_interval' => array(
'method' => 'drop_array',
'friendly_name' => __('Sync Interval'),
'description' => __('The polling sync interval in use. This setting will affect how often this poller is checked and updated.'),
'value' => '|arg1:sync_interval|',
'default' => read_config_option('poller_sync_interval'),
'array' => $poller_sync_intervals,
),
'spacer_remotedb' => array(
'method' => 'spacer',
'friendly_name' => __('Remote Database Connection'),
),
'dbhost' => array(
'method' => 'textbox',
'friendly_name' => __('Hostname'),
'description' => __('The hostname for the remote database server.'),
'value' => '|arg1:dbhost|',
'size' => '50',
'default' => '',
'max_length' => '100'
),
'dbdefault' => array(
'method' => 'textbox',
'friendly_name' => __('Remote Database Name'),
'description' => __('The name of the remote database.'),
'value' => '|arg1:dbdefault|',
'size' => '20',
'default' => $database_default,
'max_length' => '20'
),
'dbuser' => array(
'method' => 'textbox',
'friendly_name' => __('Remote Database User'),
'description' => __('The user name to use to connect to the remote database.'),
'value' => '|arg1:dbuser|',
'size' => '20',
'default' => $database_username,
'max_length' => '20'
),
'dbpass' => array(
'method' => 'textbox_password',
'friendly_name' => __('Remote Database Password'),
'description' => __('The user password to use to connect to the remote database.'),
'value' => '|arg1:dbpass|',
'size' => '40',
'default' => $database_password,
'max_length' => '64'
),
'dbport' => array(
'method' => 'textbox',
'friendly_name' => __('Remote Database Port'),
'description' => __('The TCP port to use to connect to the remote database.'),
'value' => '|arg1:dbport|',
'size' => '5',
'default' => $database_port,
'max_length' => '5'
),
'dbssl' => array(
'method' => 'checkbox',
'friendly_name' => __('Remote Database SSL'),
'description' => __('If the remote database uses SSL to connect, check the checkbox below.'),
'value' => '|arg1:dbssl|',
'default' => $database_ssl ? 'on':''
),
'dbsslkey' => array(
'method' => 'textbox',
'friendly_name' => __('Remote Database SSL Key'),
'description' => __('The file holding the SSL Key to use to connect to the remote database.'),
'value' => '|arg1:dbsslkey|',
'size' => '50',
'default' => $database_ssl_key,
'max_length' => '255'
),
'dbsslcert' => array(
'method' => 'textbox',
'friendly_name' => __('Remote Database SSL Certificate'),
'description' => __('The file holding the SSL Certificate to use to connect to the remote database.'),
'value' => '|arg1:dbsslcert|',
'size' => '50',
'default' => $database_ssl_cert,
'max_length' => '255'
),
'dbsslca' => array(
'method' => 'textbox',
'friendly_name' => __('Remote Database SSL Authority'),
'description' => __('The file holding the SSL Certificate Authority to use to connect to the remote database.'),
'value' => '|arg1:dbsslca|',
'size' => '50',
'default' => $database_ssl_ca,
'max_length' => '255'
),
'id' => array(
'method' => 'hidden',
'value' => '|arg1:id|',
),
'save_component_poller' => array(
'method' => 'hidden',
'value' => '1'
)
);
/* set default action */
set_default_action();
switch (get_request_var('action')) {
case 'save':
form_save();
break;
case 'actions':
form_actions();
break;
case 'ajax_tz':
print json_encode(db_fetch_assoc_prepared('SELECT Name AS label, Name AS `value`
FROM mysql.time_zone_name
WHERE Name LIKE ?
ORDER BY Name
LIMIT ' . read_config_option('autocomplete_rows'),
array('%' . get_nfilter_request_var('term') . '%')));
break;
case 'ping':
test_database_connection();
break;
case 'edit':
top_header();
poller_edit();
bottom_footer();
break;
default:
top_header();
pollers();
bottom_footer();
break;
}
/* --------------------------
Global Form Functions
-------------------------- */
/* --------------------------
The Save Function
-------------------------- */
function form_save() {
if (isset_request_var('save_component_poller')) {
// Common data
$save['id'] = get_filter_request_var('id');
$save['name'] = form_input_validate(get_nfilter_request_var('name'), 'name', '', false, 3);
$save['hostname'] = form_input_validate(get_nfilter_request_var('hostname'), 'hostname', '', false, 3);
$save['timezone'] = form_input_validate(get_nfilter_request_var('timezone'), 'timezone', '', false, 3);
$save['notes'] = form_input_validate(get_nfilter_request_var('notes'), 'notes', '', true, 3);
// Process settings
$save['processes'] = form_input_validate(get_nfilter_request_var('processes'), 'processes', '^[0-9]+$', false, 3);
$save['threads'] = form_input_validate(get_nfilter_request_var('threads'), 'threads', '^[0-9]+$', false, 3);
if ($save['id'] != 1) {
$save['sync_interval'] = form_input_validate(get_nfilter_request_var('sync_interval'), 'sync_interval', '^[0-9]+$', false, 3);
// Database settings
$save['dbdefault'] = form_input_validate(get_nfilter_request_var('dbdefault'), 'dbdefault', '', true, 3);
$save['dbhost'] = form_input_validate(get_nfilter_request_var('dbhost'), 'dbhost', '', true, 3);
$save['dbuser'] = form_input_validate(get_nfilter_request_var('dbuser'), 'dbuser', '', true, 3);
$save['dbpass'] = form_input_validate(get_nfilter_request_var('dbpass'), 'dbpass', '', true, 3);
$save['dbport'] = form_input_validate(get_nfilter_request_var('dbport'), 'dbport', '', true, 3);
$save['dbssl'] = isset_request_var('dbssl') ? 'on':'';
$save['dbsslkey'] = form_input_validate(get_nfilter_request_var('dbsslkey'), 'dbsslkey', '', true, 3);
$save['dbsslcert'] = form_input_validate(get_nfilter_request_var('dbsslcert'), 'dbsslcert', '', true, 3);
$save['dbsslca'] = form_input_validate(get_nfilter_request_var('dbsslca'), 'dbsslca', '', true, 3);
}
// Check for duplicate hostname
$error = false;
if (poller_check_duplicate_poller_id($save['id'], $save['hostname'], 'hostname')) {
raise_message('dupe_hostname', __('You have already used this hostname \'%s\'. Please enter a non-duplicate hostname.', $save['hostname']), MESSAGE_LEVEL_ERROR);
$error = true;
}
if (isset($save['dbhost'])) {
if (poller_check_duplicate_poller_id($save['id'], $save['dbhost'], 'dbhost')) {
raise_message('dupe_dbhost', __('You have already used this database hostname \'%s\'. Please enter a non-duplicate database hostname.', $save['hostname']), MESSAGE_LEVEL_ERROR);
$error = true;
}
}
if (isset($save['dbhost']) && $save['dbhost'] == 'localhost' && $save['id'] > 1) {
raise_message('poller_dbhost');
} elseif ($save['id'] > 1 && poller_host_duplicate($save['id'], $save['dbhost'])) {
raise_message('poller_nodupe');
} elseif (!is_error_message() && $error == false) {
$poller_id = sql_save($save, 'poller');
if ($poller_id) {
raise_message(1);
} else {
raise_message(2);
}
}
header('Location: pollers.php?header=false&action=edit&id=' . (empty($poller_id) ? get_nfilter_request_var('id') : $poller_id));
}
}
function poller_check_duplicate_poller_id($poller_id, $hostname, $column) {
$ip_addresses = array();
$ip_hostnames = array();
if (is_ipaddress($hostname)) {
$address = gethostbyaddr($hostname);
if ($address != $hostname) {
$ip_hostnames[$address] = $address;
} else {
$ip_addresses[$address] = $address;
}
$ip_addresses[$hostname] = $hostname;
} else {
$addresses = dns_get_record($hostname);
$ip = gethostbyname($hostname);
if ($ip != $hostname) {
$ip_addresses[$ip] = $ip;
}
$ip_hostnames[$hostname] = $hostname;
if (sizeof($addresses)) {
foreach($addresses as $address) {
if (isset($address['target'])) {
$ip_hostnames[$address['host']] = $address['host'];
}
if (isset($address['host'])) {
$ip_hostnames[$address['host']] = $address['host'];
}
if (isset($address['ip'])) {
$ip_addresses[$address['ip']] = $address['ip'];
}
}
}
}
$sql_where1 = '';
if (sizeof($ip_addresses)) {
$sql_where1 = "$column IN ('" . implode("','", $ip_addresses) . "')";
}
$sql_where2 = '';
if (sizeof($ip_hostnames)) {
foreach($ip_hostnames as $host) {
$parts = explode('.', $host);
$sql_where2 .= ($sql_where2 != '' ? ' OR ':' OR (') . "($column = '$parts[0]' OR $column LIKE '$parts[0].%' OR $column = '$host')";
}
$sql_where2 .= ')';
}
$duplicate = db_fetch_cell_prepared("SELECT id
FROM poller
WHERE id != ?
AND ($sql_where1 $sql_where2)",
array($poller_id));
if (empty($duplicate)) {
return false;
} else {
return true;
}
}
function poller_host_duplicate($poller_id, $host) {
if ($host == 'localhost') {
return true;
} else {
return db_fetch_cell_prepared('SELECT COUNT(*)
FROM poller
WHERE dbhost LIKE "' . $host . '%"
AND id != ?',
array($poller_id));
}
}
function form_actions() {
global $poller_actions;
/* ================= input validation ================= */
get_filter_request_var('drp_action', FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^([a-zA-Z0-9_]+)$/')));
/* ==================================================== */
/* if we are to save this form, instead of display it */
if (isset_request_var('selected_items')) {
$selected_items = sanitize_unserialize_selected_items(get_nfilter_request_var('selected_items'));
if ($selected_items != false) {
if (get_nfilter_request_var('drp_action') == '1') { // delete
db_execute('DELETE FROM poller WHERE ' . array_to_sql_or($selected_items, 'id'));
db_execute('UPDATE host SET poller_id=1 WHERE deleted="" AND ' . array_to_sql_or($selected_items, 'poller_id'));
db_execute('UPDATE automation_networks SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
db_execute('UPDATE automation_processes SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
db_execute('UPDATE poller_command SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
db_execute('UPDATE poller_item SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
db_execute('UPDATE poller_output_realtime SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
db_execute('UPDATE poller_time SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',', $selected_items) . ' deleted by user ' . $_SESSION['sess_user_id'], false, 'WEBUI');
} elseif (get_request_var('drp_action') == '2') { // disable
db_execute('UPDATE poller SET disabled="on" WHERE ' . array_to_sql_or($selected_items, 'id'));
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',', $selected_items) . ' disabled by user ' . $_SESSION['sess_user_id'], false, 'WEBUI');
} elseif (get_request_var('drp_action') == '3') { // enable
db_execute('UPDATE poller SET disabled="" WHERE ' . array_to_sql_or($selected_items, 'id'));
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',', $selected_items) . ' enabled by user ' . $_SESSION['sess_user_id'], false, 'WEBUI');
} elseif (get_request_var('drp_action') == '4') { // full sync
session_write_close(); // Save&Close the session so the Interface is still responsive
$success = array();
$failed = array();
$ids = array();
foreach($selected_items as $item) {
// Operation not allowed on the main poller
if ($item == 1) {
continue;
}
$ids[] = $item;
$poller = db_fetch_row_prepared('SELECT *
FROM poller
WHERE id = ?',
array($item));
if ($poller['dbhost'] == 'localhost') {
raise_message('poller_dbhost');
continue;
} elseif ($item == 1) {
raise_message('poller_nomain');
continue;
} else {
if (replicate_out($item)) {
$success[] = $item;
db_execute_prepared('UPDATE poller
SET last_sync = NOW()
WHERE id = ?',
array($item));
} else {
$failed[] = $item;
}
}
}
session_start(); // Start the session again
if (sizeof($failed)) {
cacti_log('WARNING: Some selected Remote Data Collectors in [' . implode(', ', $ids) . '] failed synchronization by user ' . get_username($_SESSION['sess_user_id']) . ', Successful/Failed[' . sizeof($success) . '/' . sizeof($failed) . ']. See log for details.', false, 'WEBUI');
} else {
cacti_log('NOTE: All selected Remote Data Collectors in [' . implode(', ', $ids) . '] synchronized correctly by user ' . get_username($_SESSION['sess_user_id']), false, 'WEBUI');
}
}
}
header('Location: pollers.php?header=false');
exit;
}
/* setup some variables */
$pollers = ''; $i = 0;
/* loop through each of the graphs selected on the previous page and get more info about them */
foreach ($_POST as $var => $val) {
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
/* ================= input validation ================= */
input_validate_input_number($matches[1]);
/* ==================================================== */
$pollers .= '' . html_escape(db_fetch_cell_prepared('SELECT name FROM poller WHERE id = ?', array($matches[1]))) . ' ';
$poller_array[$i] = $matches[1];
$i++;
}
}
top_header();
form_start('pollers.php');
html_start_box($poller_actions[get_nfilter_request_var('drp_action')], '60%', '', '3', 'center', '');
if (isset($poller_array) && cacti_sizeof($poller_array)) {
if (get_nfilter_request_var('drp_action') == '1') { // delete
print "
" . __n('Click \'Continue\' to delete the following Data Collector. Note, all devices will be disassociated from this Data Collector and mapped back to the Main Cacti Data Collector.', 'Click \'Continue\' to delete all following Data Collectors. Note, all devices will be disassociated from these Data Collectors and mapped back to the Main Cacti Data Collector.', cacti_sizeof($poller_array)) . "
\n";
$save_html = " ";
} elseif (get_request_var('drp_action') == '2') { // disable
print "
" . __n('Click \'Continue\' to disable the following Data Collector.', 'Click \'Continue\' to disable the following Data Collectors.', cacti_sizeof($poller_array)) . "
\n";
$save_html = " ";
} elseif (get_request_var('drp_action') == '3') { // enable
print "
" . __n('Click \'Continue\' to enable the following Data Collector.', 'Click \'Continue\' to enable the following Data Collectors.', cacti_sizeof($poller_array)) . "
\n";
$save_html = " ";
} elseif (get_request_var('drp_action') == '4') { // full sync
print "
" . __n('Click \'Continue\' to Synchronize the Remote Data Collector for Offline Operation.', 'Click \'Continue\' to Synchronize the Remote Data Collectors for Offline Operation.', cacti_sizeof($poller_array)) . "
\n";
$save_html = " ";
}
} else {
raise_message(40);
header('Location: pollers.php?header=false');
exit;
}
print "
$save_html
\n";
html_end_box();
form_end();
bottom_footer();
}
/* ---------------------
Site Functions
--------------------- */
function poller_edit() {
global $fields_poller_edit;
/* ================= input validation ================= */
get_filter_request_var('id');
/* ==================================================== */
if (!isempty_request_var('id')) {
$poller = db_fetch_row_prepared('SELECT *
FROM poller
WHERE id = ?',
array(get_request_var('id')));
$header_label = __esc('Site [edit: %s]', $poller['name']);
} else {
$poller = array();
$header_label = __('Site [new]');
}
form_start('pollers.php', 'poller');
html_start_box($header_label, '100%', true, '3', 'center', '');
if (cacti_sizeof($poller)) {
if ($poller['id'] == 1) {
unset($fields_poller_edit['sync_interval']);
unset($fields_poller_edit['spacer_remotedb']);
unset($fields_poller_edit['dbdefault']);
unset($fields_poller_edit['dbhost']);
unset($fields_poller_edit['dbuser']);
unset($fields_poller_edit['dbpass']);
unset($fields_poller_edit['dbport']);
unset($fields_poller_edit['dbssl']);
unset($fields_poller_edit['dbsslkey']);
unset($fields_poller_edit['dbsslcert']);
unset($fields_poller_edit['dbsslca']);
}
if ($poller['timezone'] == '') {
$poller['timezone'] = ini_get('date.timezone');
}
}
draw_edit_form(
array(
'config' => array('no_form_tag' => true),
'fields' => inject_form_variables($fields_poller_edit, (isset($poller) ? $poller : array()))
)
);
$tip_text = __('Remote Data Collectors must be able to communicate to the Main Data Collector, and vice versa. Use this button to verify that the Main Data Collector can communicate to this Remote Data Collector.');
if (read_config_option('hide_form_description') == 'on') {
$tooltip = '' . $tip_text . ' ';
} else {
$tooltip = '' . str_replace("\n", '', display_tooltip($tip_text)) . '
';
}
$row_html = '';
$pt = read_config_option('poller_type');
if (isset($poller) && cacti_sizeof($poller)) {
if ($poller['id'] > 1) {
?>
array(
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
),
'page' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
),
'filter' => array(
'filter' => FILTER_DEFAULT,
'pageset' => true,
'default' => ''
),
'sort_column' => array(
'filter' => FILTER_CALLBACK,
'default' => 'name',
'options' => array('options' => 'sanitize_search_string')
),
'sort_direction' => array(
'filter' => FILTER_CALLBACK,
'default' => 'ASC',
'options' => array('options' => 'sanitize_search_string')
)
);
validate_store_request_vars($filters, 'sess_pollers');
/* ================= input validation ================= */
if (get_request_var('rows') == '-1') {
$rows = read_config_option('num_rows_table');
} else {
$rows = get_request_var('rows');
}
html_start_box( __('Data Collectors'), '100%', '', '3', 'center', '');
?>
array('display' => __('Collector Name'), 'align' => 'left', 'sort' => 'ASC', 'tip' => __('The Name of this Data Collector.')),
'id' => array('display' => __('ID'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The unique id associated with this Data Collector.')),
'hostname' => array('display' => __('Hostname'), 'align' => 'right', 'sort' => 'ASC', 'tip' => __('The Hostname where the Data Collector is running.')),
'status' => array('display' => __('Status'), 'align' => 'center', 'sort' => 'DESC', 'tip' => __('The Status of this Data Collector.')),
'nosort0' => array('display' => __('Proc/Threads'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The Number of Poller Processes and Threads for this Data Collector.')),
'total_time' => array('display' => __('Polling Time'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The last data collection time for this Data Collector.')),
'nosort1' => array('display' => __('Avg/Max'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The Average and Maximum Collector timings for this Data Collector.')),
'hosts' => array('display' => __('Devices'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The number of Devices associated with this Data Collector.')),
'snmp' => array('display' => __('SNMP Gets'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The number of SNMP gets associated with this Collector.')),
'script' => array('display' => __('Scripts'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The number of script calls associated with this Data Collector.')),
'server' => array('display' => __('Servers'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The number of script server calls associated with this Data Collector.')),
'last_update' => array('display' => __('Last Finished'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The last time this Data Collector completed.')),
'last_status' => array('display' => __('Last Update'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The last time this Data Collector checked in with the main Cacti site.')),
'last_sync' => array('display' => __('Last Sync'), 'align' => 'right', 'sort' => 'DESC', 'tip' => __('The last time this Data Collector was full synced with main Cacti site.')));
html_header_sort_checkbox($display_text, get_request_var('sort_column'), get_request_var('sort_direction'), false);
$i = 0;
if (cacti_sizeof($pollers)) {
foreach ($pollers as $poller) {
if ($poller['id'] == 1) {
$disabled = true;
} else {
$disabled = false;
}
if ($poller['disabled'] == 'on') {
$poller['status'] = 4;
}else if ($poller['heartbeat'] > 310) {
$poller['status'] = 6;
}
$mma = round($poller['avg_time'], 2) . '/' . round($poller['max_time'], 2);
if (empty($poller['name'])) {
$poller['name'] = '<no name>';
}
$pt = read_config_option('poller_type');
form_alternate_row('line' . $poller['id'], true, $disabled);
form_selectable_cell(filter_value($poller['name'], get_request_var('filter'), 'pollers.php?action=edit&id=' . $poller['id']), $poller['id']);
form_selectable_cell($poller['id'], $poller['id'], '', 'right');
form_selectable_ecell($poller['hostname'], $poller['id'], '', 'right');
form_selectable_cell($poller_status[$poller['status']], $poller['id'], '', 'center');
form_selectable_cell($poller['processes'] . '/' . ($pt == 2 ? $poller['threads']:'-'), $poller['id'], '', 'right');
form_selectable_cell(number_format_i18n($poller['total_time'], 2), $poller['id'], '', 'right');
form_selectable_cell($mma, $poller['id'], '', 'right');
form_selectable_cell(number_format_i18n($poller['hosts'], '-1'), $poller['id'], '', 'right');
form_selectable_cell(number_format_i18n($poller['snmp'], '-1'), $poller['id'], '', 'right');
form_selectable_cell(number_format_i18n($poller['script'], '-1'), $poller['id'], '', 'right');
form_selectable_cell(number_format_i18n($poller['server'], '-1'), $poller['id'], '', 'right');
form_selectable_cell(substr($poller['last_update'], 5), $poller['id'], '', 'right');
form_selectable_cell(substr($poller['last_status'], 5), $poller['id'], '', 'right');
if ($poller['id'] == 1) {
form_selectable_cell(__('N/A'), $poller['id'], '', 'right');
} else {
form_selectable_cell(substr($poller['last_sync'], 5), $poller['id'], '', 'right');
}
form_checkbox_cell($poller['name'], $poller['id'], $disabled);
form_end_row();
}
} else {
print "" . __('No Data Collectors Found') . " \n";
}
html_end_box(false);
if (cacti_sizeof($pollers)) {
print $nav;
}
/* draw the dropdown containing a list of available actions for this form */
draw_actions_dropdown($poller_actions);
form_end();
}
cacti-1.2.10/script_server.php 0000664 0001750 0001750 00000027064 13627045365 015331 0 ustar markv markv = 2) {
if ($_SERVER['argv'][1] == 'spine')
$environ = 'spine';
else
if (($_SERVER['argv'][1] == 'cmd.php') || ($_SERVER['argv'][1] == 'cmd'))
$environ = 'cmd';
elseif ($_SERVER['argv'][1] == 'realtime')
$environ = 'realtime';
else
$environ = 'other';
if ($_SERVER['argc'] == 3)
$poller_id = $_SERVER['argv'][2];
else
$poller_id = 1;
} else {
$environ = 'cmd';
$poller_id = 1;
}
cacti_log('DEBUG: SERVER: ' . $environ . ' PARENT: ' . $parent_pid, false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
if ($config['cacti_server_os'] == 'win32') {
cacti_log('DEBUG: GETCWD: ' . strtolower(strtr(getcwd(),"\\",'/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
cacti_log('DEBUG: DIRNAM: ' . strtolower(strtr(dirname(__FILE__),"\\",'/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
} else {
cacti_log('DEBUG: GETCWD: ' . strtr(getcwd(),"\\",'/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
cacti_log('DEBUG: DIRNAM: ' . strtr(dirname(__FILE__),"\\",'/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
}
cacti_log('DEBUG: FILENM: ' . __FILE__, false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
/* send status back to the server */
cacti_log('PHP Script Server has Started - Parent is ' . $environ, false, 'PHPSVR', POLLER_VERBOSITY_HIGH);
fputs(STDOUT, 'PHP Script Server has Started - Parent is ' . $environ . "\n");
fflush(STDOUT);
$log_file = '/usr/share/cacti/site/log/script_server_' . getmypid() . '.out';
$log_keep = false;
/* process waits for input and then calls functions as required */
while (1) {
$result = '';
$input_string = fgets(STDIN, 1024);
$function = '';
$parameters = '';
$parameter_array = array();
$isParentRunning = true;
if (empty($input_string)) {
if (!empty($parent_pid)) {
if(strncasecmp(PHP_OS, "win", 3) == 0) {
$out = [];
exec("TASKLIST /FO LIST /FI \"PID eq $parent_pid\"", $out);
$isParentRunning = (count($out) > 1);
} elseif (function_exists('posix_kill')) {
$isParentRunning = posix_kill(intval($parent_pid), 0);
}
}
if ($isParentRunning) {
if (!empty($parent_pid)) {
cacti_log('WARNING: Input Expected, parent process ' . $parent_pid . ' should have sent non-blank line', false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
} else {
cacti_log('WARNING: Input Expected, unable to check parent process', false, 'PHPSVR', POLLER_VERBOSITY_MEDIUM);
}
} else {
cacti_log('WARNING: Parent (' . $parent_pid . ') of Script Server (' . getmypid() . ') has been lost, forcing exit', false, 'PHPSVR', POLLER_VERBOSITY_HIGH);
$input_string = 'quit';
}
$log_keep = true;
}
if (!empty($input_string)) {
$input_string = trim($input_string);
if (substr($input_string,0,4) == 'quit') {
fputs(STDOUT, 'PHP Script Server Shutdown request received, exiting' . PHP_EOL);
fflush(STDOUT);
cacti_log('DEBUG: PHP Script Server Shutdown request received, exiting', false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
if (!$log_keep) {
unlink($log_file);
}
db_close();
exit(0);
}
if ($input_string != '') {
/* pull off the parameters */
$i = 0;
while ( true ) {
$pos = strpos($input_string, ' ');
if ($pos > 0) {
switch ($i) {
case 0:
/* cut off include file as first part of input string and keep rest for further parsing */
$include_file = trim(substr($input_string,0,$pos));
$input_string = trim(strchr($input_string, ' ')) . ' ';
break;
case 1:
/* cut off function as second part of input string and keep rest for further parsing */
$function = trim(substr($input_string,0,$pos), "' ");
$input_string = trim(strchr($input_string, ' ')) . ' ';
break;
case 2:
/* take the rest as parameter(s) to the function stripped off previously */
$parameters = trim($input_string);
break 2;
}
} else {
break;
}
$i++;
}
if (!parseArgs($parameters, $parameter_array)) {
cacti_log("WARNING: Script Server count not parse '$parameters' for $function", false, 'PHPSVR');
fputs(STDOUT, "U\n");
fflush(STDOUT);
continue;
}
cacti_log("DEBUG: PID[$pid] CTR[$ctr] INC: '". basename($include_file) .
"' FUNC: '$function' PARMS: '" . implode('\', \'',$parameter_array) .
"'", false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
/* validate the existance of the function, and include if applicable */
if (!function_exists($function)) {
if (file_exists($include_file)) {
/* quirk in php on Windows, believe it or not.... */
/* path must be lower case */
if ($config['cacti_server_os'] == 'win32') {
$include_file = strtolower($include_file);
}
/* set this variable so the calling script can determine if it was called
* by the script server or stand-alone */
$called_by_script_server = true;
/* turn on output buffering to avoid problems with nasty scripts */
ob_start();
include_once($include_file);
ob_end_clean();
} else {
cacti_log('WARNING: PHP Script File to be included, does not exist', false, 'PHPSVR');
}
}
if (function_exists($function)) {
if ($parameters == '') {
$result = call_user_func($function);
} else {
$result = call_user_func_array($function, $parameter_array);
}
fputs(STDOUT, trim($result) . "\n");
fflush(STDOUT);
cacti_log("DEBUG: PID[$pid] CTR[$ctr] RESPONSE:'$result'", false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
$ctr++;
} else {
cacti_log("WARNING: Function does not exist INC: '". basename($include_file) . "' FUNC: '" .$function . "' PARMS: '" . $parameters . "'", false, 'PHPSVR');
fputs(STDOUT, "U\n");
fflush(STDOUT);
}
}
}
/* end the process if the runtime exceeds MAX_POLLER_RUNTIME */
if (($start + MAX_POLLER_RUNTIME) < time()) {
cacti_log('Maximum runtime of ' . MAX_POLLER_RUNTIME . ' seconds exceeded for the Script Server. Exiting.', true, 'PHPSVR');
exit (-1);
}
}
function parseArgs($string, &$str_list, $debug = false) {
$delimiters = array("'",'"');
$delimited = false;
$str_list = array();
if ($debug) echo "String: '" . $string . "'\n";
foreach($delimiters as $delimiter) {
if (strpos($string, $delimiter) !== false) {
$delimited = true;
break;
}
}
/* process the simple case */
if (!$delimited) {
$str_list = explode(' ', $string);
if ($debug) echo "Output: '" . implode(",", $str_list) . "'\n";
return true;
}
/* Break str down into an array of characters and process */
$char_array = str_split($string);
$escaping = false;
$indelim = false;
$parse_ok = true;
$curstr = '';
foreach($char_array as $char) {
switch ($char) {
case '\'':
case '"':
if (!$indelim) {
if (!$escaping) {
$indelim = true;
} else {
$curstr .= $char;
$escaping = false;
}
} elseif (!$escaping) {
$str_list[] = $curstr;
$curstr = '';
$indelim = false;
} elseif ($escaping) {
$curstr .= $char;
$escaping = false;
}
break;
case '\\':
if ($escaping) {
$curstr .= $char;
$escaping = false;
} else {
$escaping = true;
}
break;
case ' ':
if ($escaping) {
$parse_ok = false;
$msg = 'Parse error attempting to parse string';
} elseif ($indelim) {
$curstr .= $char;
} elseif ($curstr != '') {
$str_list[] = $curstr;
$curstr = '';
}
break;
case '`':
$parse_ok = false;
$msg = 'Backtic (`) characters not allowed';
break;
default:
if ($escaping) {
$parse_ok = false;
$msg = 'Parse error attempting to parse string';
} else {
$curstr .= $char;
}
break;
}
if (!$parse_ok) {
break;
}
}
/* Add the last str to the string array */
if ($indelim || $escaping) {
$parse_ok = false;
$msg = 'Parse error attempting to parse string';
}
if (!$parse_ok) {
echo 'ERROR: ' . $msg . " '" . $string . "'\n";
} elseif ($curstr != '') {
$str_list[] = $curstr;
}
if ($debug) echo "Output: '" . implode(",", $str_list) . "'\n";
return $parse_ok;
}
cacti-1.2.10/poller_realtime.php 0000664 0001750 0001750 00000023072 13627045366 015612 0 ustar markv markv #!/usr/bin/php -q
0) {
/* create an array keyed off of each .rrd file */
foreach ($results as $item) {
$rt_graph_path = read_config_option('realtime_cache_path') . '/user_' . $poller_id . '_' . $item['local_data_id'] . '.rrd';
$data_source_path = get_data_source_path($item['local_data_id'], true);
/* create rt rrd */
if (!file_exists($rt_graph_path)) {
/* get the syntax */
$command = @rrdtool_function_create($item['local_data_id'], '-60', true);
/* replace path */
$command = str_replace($data_source_path, $rt_graph_path, $command);
/* replace step */
$command = preg_replace('/--step\s(\d+)/', '--step 1', $command);
/* WIN32: before sending this command off to rrdtool, get rid
of all of the '\' characters. Unix does not care; win32 does.
Also make sure to replace all of the fancy "\"s at the end of the line,
but make sure not to get rid of the "\n"s that are supposed to be
in there (text format) */
$command = str_replace("\\\n", " ", $command);
/* create the rrdfile */
shell_exec($command);
/* change permissions so that the poller can clear */
@chmod($rt_graph_path, 0644);
} else {
/* change permissions so that the poller can clear */
@chmod($rt_graph_path, 0644);
}
/* now, let's update the path to keep the RRDs updated */
$item['rrd_path'] = $rt_graph_path;
/* cleanup the value */
$value = trim($item['output']);
$unix_time = strtotime($item['time']);
$rrd_update_array[$item['rrd_path']]['local_data_id'] = $item['local_data_id'];
/* single one value output */
if ((is_numeric($value)) || ($value == 'U')) {
$rrd_update_array[$item['rrd_path']]['times'][$unix_time][$item['rrd_name']] = $value;
/* multiple value output */
} else {
$values = explode(' ', $value);
$rrd_field_names = array_rekey(db_fetch_assoc_prepared('SELECT
data_template_rrd.data_source_name,
data_input_fields.data_name
FROM (data_template_rrd,data_input_fields)
WHERE data_template_rrd.data_input_field_id=data_input_fields.id
AND data_template_rrd.local_data_id = ?', array($item['local_data_id'])), 'data_name', 'data_source_name');
for ($i=0; $i