@@ -572,7 +572,7 @@ function upgrade_to_1_0_0() {
} else {
db_install_rename_table('plugin_nectar', 'reports');
db_install_rename_table('plugin_nectar_items', 'reports_items');
db_install_execute("UPDATE settings SET name=REPLACE(name, 'nectar','reports') WHERE name LIKE '%nectar%'");
db_install_execute("UPDATE IGNORE settings SET name=REPLACE(name, 'nectar','reports') WHERE name LIKE '%nectar%'");

db_install_add_column('reports', array('name' => 'bcc', 'type' => 'TEXT', 'after' => 'email'));
db_install_add_column('reports', array('name' => 'from_name', 'type' => 'VARCHAR(40)', 'NULL' => false, 'default' => '', 'after' => 'mailtime'));
@@ -1027,7 +1027,7 @@ function upgrade_to_1_0_0() {
db_install_execute("DELETE FROM plugin_db_changes WHERE plugin='autom8'");
db_install_execute("DELETE FROM plugin_hooks WHERE name='autom8'");

db_install_execute("UPDATE settings SET name=REPLACE(name, 'autom8', 'automation') WHERE name LIKE 'autom8%'");
db_install_execute("UPDATE IGNORE settings SET name = REPLACE(name, 'autom8', 'automation') WHERE name LIKE 'autom8%'");

// migrate discovery to Core if exists
if (db_table_exists('plugin_discover_hosts', false)) {
@@ -1237,13 +1237,13 @@ function upgrade_to_1_0_0() {
array($keephex, $hex['id']));

if (db_table_exists('color_template_items')) {
db_install_execute('UPDATE color_template_item
db_install_execute('UPDATE color_template_items
SET color_id = ?
WHERE color_id = ?',
array($keephex, $hex['id']));
}

db_install_execute('DELECT FROM colors WHERE id = ?', array($hex['id']));
db_install_execute('DELETE FROM colors WHERE id = ?', array($hex['id']));
}
}
}
@@ -1500,7 +1500,7 @@ function upgrade_to_1_0_0() {
db_install_add_column('aggregate_graph_templates_graph', array('name' => 't_legend_direction', 'type' => 'char(2)', 'default' => '0', 'after' => 'legend_position'));
db_install_add_column('aggregate_graph_templates_graph', array('name' => 'legend_direction', 'type' => 'varchar(10)', 'NULL' => true, 'after' => 't_legend_direction'));

// Update Aggregate CDEF's to become system level
// Update Aggregate CDEFs to become system level
db_install_add_column('cdef', array('name' => 'system', 'type' => 'mediumint(8) unsigned', 'NULL' => false, 'default' => '0', 'after' => 'hash'));
db_install_execute("UPDATE cdef SET system=1 WHERE name LIKE '\_%'");

@@ -1746,4 +1746,3 @@ function upgrade_to_1_0_0() {
}
}
}

@@ -244,7 +244,7 @@ function upgrade_to_1_1_34() {
db_install_execute('ALTER TABLE `version`
MODIFY COLUMN `cacti` char(20) NOT NULL DEFAULT ""');

db_install_execute('ALTER IGNORE TABLE version DROP PRIMARY KEY');
db_install_drop_key('version', 'key', 'PRIMARY');

db_install_add_key('version', 'key', 'PRIMARY', array('cacti'), 'BTREE');
}
@@ -0,0 +1,41 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2019 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/

function upgrade_to_1_2_3() {
// Correct max values in templates and data sources: GAUGE/ABSOLUTE (1,4)
db_install_execute("UPDATE data_template_rrd
SET rrd_maximum='U'
WHERE rrd_maximum = '0'
AND rrd_minimum = '0'
AND data_source_type_id IN(1,4)");

// Correct min/max values in templates and data sources: DERIVE/DDERIVE (3,7)
db_install_execute("UPDATE data_template_rrd
SET rrd_maximum='U', rrd_minimum='U'
WHERE (rrd_maximum = '0' OR rrd_minimum = '0')
AND data_source_type_id IN(3,7)");

// Speed up Data Sources page
db_install_add_key('data_template_data', 'key', 'name_cache', array('name_cache(191)'));
}
@@ -662,7 +662,7 @@ function display_new_graphs($rule, $url) {
<script type='text/javascript'>
function applyObjectFilter() {
strURL = '<?php print $url;?>';
strURL += '&rows=' + $('#rows').val();
strURL += '&rows=' + $('#orows').val();
strURL += '&filter=' + $('#filter').val();
strURL += '&header=false';
loadPageNoHeader(strURL);
@@ -682,6 +682,10 @@ function clearObjectFilter() {
clearObjectFilter();
});

$('#orows').change(function() {
applyObjectFilter();
});

$('#form_automation_objects').submit(function(event) {
event.preventDefault();
applyObjectFilter();
@@ -708,7 +712,7 @@ function clearObjectFilter() {
<?php print __('Objects');?>
</td>
<td>
<select id='rows' onChange='applyFilter()'>
<select id='orows'>
<option value='-1'<?php if (get_request_var('rows') == '-1') {?> selected<?php }?>><?php print __('Default');?></option>
<?php
if (cacti_sizeof($item_rows)) {
@@ -552,8 +552,12 @@ function api_reapply_suggested_data_source_data($local_data_id) {
ORDER BY sequence",
array($snmp_query_graph_id, $data_local['data_template_id']));

$matches = array();

if (cacti_sizeof($svs)) {
foreach ($svs as $sv) {
$sv['text'] = trim($sv['text']);

if (($sv['text'] == '|query_ifSpeed|' || $sv['text'] == '|query_ifHighSpeed|') && $sv['field_name'] == 'rrd_maximum') {
$subs_string = api_data_source_get_interface_speed($data_local);
$sv['text'] = $subs_string;
@@ -564,23 +568,26 @@ function api_reapply_suggested_data_source_data($local_data_id) {
}

/* if there are no '|query' characters, all of the substitutions were successful */
if (!substr_count($subs_string, '|query')) {
if (strpos($subs_string, '|query') === false) {
if (in_array($sv['field_name'], $matches)) {
continue;
}

if (db_column_exists('data_template_data', $sv['field_name'])) {
$matches[] = $sv['field_name'];
db_execute_prepared('UPDATE data_template_data
SET ' . $sv['field_name'] . ' = ?
WHERE local_data_id = ?',
array($sv['text'], $local_data_id));
} elseif (db_column_exists('data_template_rrd', $sv['field_name'])) {
$matches[] = $sv['field_name'];
db_execute_prepared('UPDATE data_template_rrd
SET ' . $sv['field_name'] . ' = ?
WHERE local_data_id = ?',
array($sv['text'], $local_data_id));
} else {
cacti_log('ERROR: Suggested value column error. Column ' . $sv['field_name'] . ' for Data Template ID ' . $data_local['data_template_id'] . ' is not a compatible field name for tables data_template_data and data_template_rrd. Please correct this suggested value mapping', false);
}

/* once we find a working value for that very field, stop */
break;
}
}
}
@@ -234,6 +234,8 @@ function api_reapply_suggested_graph_title($local_graph_id) {
ORDER BY sequence",
array($graph_local['snmp_query_graph_id']));

$matches = array();

$suggested_values_graph = array();
if (cacti_sizeof($suggested_values)) {
foreach ($suggested_values as $suggested_value) {
@@ -243,19 +245,29 @@ function api_reapply_suggested_graph_title($local_graph_id) {

/* if there are no '|' characters, all of the substitutions were successful */
if (!substr_count($subs_string, '|query')) {
if (in_array($suggested_value['field_name'], $matches)) {
continue;
}

$matches[] = $suggested_value['field_name'];

db_execute_prepared('UPDATE graph_templates_graph
SET ' . $suggested_value['field_name'] . ' = ?
WHERE local_graph_id = ?',
array($suggested_value['text'], $local_graph_id));

/* once we find a working value for this very field, stop */
$suggested_values_graph[$suggested_value['field_name']] = true;

return true;
}
}
}

if (sizeof($matches)) {
return true;
}
}

return false;
}

/* api_get_graphs_from_datasource - get's all graphs related to a data source
@@ -620,8 +620,35 @@ function is_tree_branch_empty($tree_id, $parent = 0) {
), 'host_id', 'host_id'
);

if (cacti_sizeof($hosts) && cacti_sizeof(get_allowed_devices('h.id IN(' . implode(',', $hosts) . ')'), 'description', '', -1) > 0) {
return false;
$sites = array_rekey(
db_fetch_assoc_prepared('SELECT site_id
FROM graph_tree_items
WHERE graph_tree_id = ?
AND site_id > 0
AND parent = ?',
array($tree_id, $parent)
), 'site_id', 'site_id'
);

if (!cacti_sizeof($sites)) {
if (cacti_sizeof($hosts) && cacti_sizeof(get_allowed_devices('h.id IN(' . implode(',', $hosts) . ')'), 'description', '', -1) > 0) {
return false;
}
} else {
$site_hosts = array();
foreach($sites as $site) {
$site_hosts += array_rekey(
db_fetch_assoc_prepared('SELECT id
FROM host
WHERE site_id = ?',
array($site)
), 'id', 'id'
);
}

if (cacti_sizeof($site_hosts) && cacti_sizeof(get_allowed_devices('h.id IN(' . implode(',', $site_hosts) . ')'), 'description', '', -1) > 0) {
return false;
}
}

$branches = db_fetch_assoc_prepared('SELECT id, graph_tree_id
@@ -652,7 +679,7 @@ function is_realm_allowed($realm) {
return false;
}

if (!user_perms_valid($_SESSION['sess_user_id'])) {
if (!is_user_perms_valid($_SESSION['sess_user_id'])) {
kill_session_var('sess_user_realms');
kill_session_var('sess_user_config_array');
kill_session_var('sess_config_array');
@@ -1093,6 +1120,7 @@ function get_allowed_graphs($sql_where = '', $order_by = 'gtg.title_cache', $lim

$graphs_sql = "SELECT gtg.local_graph_id, h.description, gt.name AS template_name,
gtg.title_cache, gtg.width, gtg.height, gl.snmp_index, gl.snmp_query_id,
IF(gl.graph_template_id=0, 0, IF(gl.snmp_query_id=0, 2, 1)) AS graph_source,
$sql_select
FROM graph_templates_graph AS gtg
INNER JOIN graph_local AS gl
@@ -1115,7 +1143,8 @@ function get_allowed_graphs($sql_where = '', $order_by = 'gtg.title_cache', $lim
) AS rower");
} else {
$graphs = db_fetch_assoc("SELECT gtg.local_graph_id, h.description, gt.name AS template_name,
gtg.title_cache, gtg.width, gtg.height, gl.snmp_index, gl.snmp_query_id
gtg.title_cache, gtg.width, gtg.height, gl.snmp_index, gl.snmp_query_id,
IF(gl.graph_template_id=0, 0, IF(gl.snmp_query_id=0, 2, 1)) AS graph_source
FROM graph_templates_graph AS gtg
INNER JOIN graph_local AS gl
ON gl.id=gtg.local_graph_id
@@ -1349,6 +1378,9 @@ function set_cached_allowed_type($type, &$items, $hash, $init_rows) {

if ($type == 'devices') {
$_SESSION['sess_allowed_templates'][$hash] = array_rekey($items, 'id', 'id');

// Handle special case of host_id 0
$_SESSION['sess_allowed_templates'][$hash][0] = '0';
} else {
$_SESSION['sess_allowed_templates'][$hash] = $items;
}
@@ -2537,38 +2569,33 @@ function reset_user_perms($user_id) {
array($user_id));
}

/* user_perms_valid - checks to see if the admin has changed users permissions
/* is_user_perms_valid - checks to see if the admin has changed users permissions
@arg $user_id - (int) the id of the current user
@returns - true if still valid, false otherwise */
function user_perms_valid($user_id) {
function is_user_perms_valid($user_id) {
global $config;

static $valid = 'null';
static $valid = NULL;
static $key = NULL;

if ($valid === 'null') {
$valid = true;
if (isset($_SESSION['sess_user_perms_key'])) {
$key = $_SESSION['sess_user_perms_key'];
} else {
$_SESSION['sess_user_perms_key'] = false;
}

if ($valid === NULL) {
if (cacti_version_compare($config['cacti_db_version'], '1.0.0', '>=')) {
$key = db_fetch_cell_prepared('SELECT reset_perms
FROM user_auth
WHERE id = ?',
array($user_id));

if (isset($_SESSION['sess_user_perms_key'])) {
if ($key != $_SESSION['sess_user_perms_key']) {
$valid = false;
}
}

$_SESSION['sess_user_perms_key'] = $key;
} else {
$_SESSION['sess_user_perms_key'] = $valid;
}
} else {
$valid = true;
$_SESSION['sess_user_perms_key'] = $valid;
}

$valid = ($_SESSION['sess_user_perms_key'] === $key);
$_SESSION['sess_user_perms_key'] = $key;

return $valid;
}

@@ -244,7 +244,7 @@ function boost_fetch_cache_check($local_data_id) {
/* include poller processing routinges */
include_once($config['library_path'] . '/poller.php');

/* check to see if boost can do it's job */
/* check to see if boost can do its job */
if (!boost_poller_id_check()) {
return false;
}
@@ -305,7 +305,7 @@ function boost_graph_cache_check($local_graph_id, $rra_id, $rrdtool_pipe, &$grap
/* install the boost error handler */
set_error_handler('boost_error_handler');

/* check to see if boost can do it's job */
/* check to see if boost can do its job */
if (!boost_poller_id_check()) {
return false;
}
@@ -1060,7 +1060,7 @@ function boost_determine_caching_state() {

/* boost_get_rrd_filename_and_template - pulls
1) the rrd_update template from the database in form of
update decisions for multi-output RRD's
update decisions for multi-output RRDs
2) rrd filename
@arg $local_data_id - the data source to obtain information from */
function boost_get_rrd_filename_and_template($local_data_id) {
@@ -1091,12 +1091,6 @@ function query_snmp_host($host_id, $snmp_query_id) {
$snmp_index = $value;
}

/* correct bogus index value */
/* found in some devices such as an EMC Cellera */
if ($snmp_index == 0) {
$snmp_index = 1;
}

$oid = $field_array['oid'] . '.' . $parse_value;

/* rewrite octet strings */
@@ -1140,12 +1134,6 @@ function query_snmp_host($host_id, $snmp_query_id) {
$snmp_index = $value;
}

/* correct bogus index value */
/* found in some devices such as an EMC Cellera */
if ($snmp_index == 0) {
$snmp_index = 1;
}

$oid = $field_array['oid'];

debug_log_insert('data_query', __('Found item [%s=\'%s\'] index: %s [from regexp oid value parse]', $field_name, $parse_value, $snmp_index));
@@ -100,7 +100,7 @@ function db_connect_real($device, $user, $pass, $db_name, $db_type = 'mysql', $p

$ver = db_get_global_variable('version', $cnn_id);

if (strpos($ver, 'MariaDB') !== false) {
if (strpos($ver, 'MariaDB') !== false) {
$srv = 'MariaDB';
$ver = str_replace('-MariaDB', '', $ver);
} else {
@@ -124,15 +124,13 @@ function db_connect_real($device, $user, $pass, $db_name, $db_type = 'mysql', $p

db_execute_prepared('SET SESSION sql_mode = ?', array($sql_mode), false);

if ($config['poller_id'] > 1) {
$timezone = db_fetch_cell_prepared('SELECT timezone
FROM poller
WHERE id = ?',
array($config['poller_id']), false);
$timezone = db_fetch_cell_prepared('SELECT timezone
FROM poller
WHERE id = ?',
array($config['poller_id']), false);

if ($timezone != '') {
db_execute_prepared('SET SESSION time_zone = ?', array($timezone), false);
}
if ($timezone != '') {
db_execute_prepared('SET SESSION time_zone = ?', array($timezone), false);
}

if (!empty($config['DEBUG_READ_CONFIG_OPTION'])) {
@@ -143,8 +143,8 @@ function dsdebug_poller_bottom() {
/* take time and log performance data */
$start = microtime(true);

$checks = db_fetch_assoc('SELECT *
FROM data_debug
$checks = db_fetch_assoc('SELECT *
FROM data_debug
WHERE `done` = 0');

if (!empty($checks)) {
@@ -155,9 +155,9 @@ function dsdebug_poller_bottom() {
$c['issue'] = array();
$info = unserialize($c['info']);

$dtd = db_fetch_row_prepared('SELECT *
FROM data_template_data
WHERE local_data_id = ?',
$dtd = db_fetch_row_prepared('SELECT *
FROM data_template_data
WHERE local_data_id = ?',
array($c['datasource']));

if (!isset($dtd['local_data_id'])) {
@@ -222,8 +222,8 @@ function dsdebug_poller_bottom() {
$info['rrd_info'] = $rrdinfo;

// rra_timestamp
if ($info['rra_timestamp'] != ''
&& isset($rrdinfo['last_update'])
if ($info['rra_timestamp'] != ''
&& isset($rrdinfo['last_update'])
&& $info['rra_timestamp'] != $rrdinfo['last_update']) {

$info['rra_timestamp2'] = $rrdinfo['last_update'];
@@ -276,7 +276,7 @@ function dsdebug_poller_bottom() {
// For errors that only appear after so many errors next
if ($c['done'] == 1) {
if ($info['rrd_match'] == 0) {
$c['issue'][] = __('RRDfile does not match Data Profile');
$c['issue'][] = __('RRDfile does not match Data Source');
$total_issues++;
}

@@ -305,9 +305,9 @@ function dsdebug_poller_bottom() {

$info = serialize($info);

db_execute_prepared('UPDATE data_debug
SET `done` = ?, `info` = ?, `issue` = ?
WHERE id = ?',
db_execute_prepared('UPDATE data_debug
SET `done` = ?, `info` = ?, `issue` = ?
WHERE id = ?',
array($c['done'], $info, trim(implode("\n", $c['issue'])), $c['id']));
}

@@ -317,3 +317,49 @@ function dsdebug_poller_bottom() {
restore_error_handler();
}

function dsdebug_run_repair($id) {
$check = db_fetch_row_prepared('SELECT *
FROM data_debug
WHERE datasource = ?',
array($id));

if (cacti_sizeof($check)) {
$check['info'] = unserialize($check['info']);

if (isset($check['info']['rrd_match_array']['tune'])) {
$path = get_data_source_path($id, true);

if (is_writeable($path)) {
$rrdtool_path = read_config_option('path_rrdtool');
$failures = 0;
$failure_data = '';

foreach($check['info']['rrd_match_array']['tune'] AS $options) {
$command = $rrdtool_path . ' tune ' . $options;

$output = rrdtool_execute('tune ' . $options, false, RRDTOOL_OUTPUT_RETURN_STDERR);

if ($output == '') {
cacti_log("RRDfile repair command succeeded for DS[$id] Command[$command]", false, 'DSDEBUG');
} else {
cacti_log("ERROR: RRDfile repair command failed for DS[$id] Command[$command] Output[$output]", false, 'DSDEBUG');
$failures++;
}
}

if ($failures == 0) {
return true;
}
} else {
cacti_log("ERROR: RRDfile Repair Command Failed for DS[$id] Output[Unable to write RRDfile]", false, 'DSDEBUG');
}
} else {
cacti_log("ERROR: RRDfile Repair Command Could not be run for DS[$id] Output[No tune recommendation found]", false, 'DSDEBUG');
}
} else {
cacti_log("ERROR: RRDfile Repair Command Could not be run for DS[$id] Output[No Data Source debug information found]", false, 'DSDEBUG');
}

return false;
}

@@ -27,10 +27,15 @@
average and peak calculations.
@returns - (mixed) The RRDfile names */
function get_rrdfile_names() {
return db_fetch_assoc('SELECT data_template_data.local_data_id, data_source_path FROM data_template_data LEFT JOIN poller_item ON poller_item.local_data_id = data_template_data.local_data_id WHERE poller_item.local_data_id IS NOT NULL AND data_template_data.local_data_id != 0');
return db_fetch_assoc('SELECT data_template_data.local_data_id, data_source_path
FROM data_template_data
LEFT JOIN poller_item
ON poller_item.local_data_id = data_template_data.local_data_id
WHERE poller_item.local_data_id IS NOT NULL
AND data_template_data.local_data_id != 0');
}

/* dsstats_debug - this simple routine print's a standard message to the console
/* dsstats_debug - this simple routine prints a standard message to the console
when running in debug mode.
@returns - NULL */
function dsstats_debug($message) {
@@ -48,10 +53,16 @@ function dsstats_debug($message) {
@returns - NULL */
function dsstats_get_and_store_ds_avgpeak_values($interval) {
global $config;
global $user_time, $system_time, $real_time;
global $total_user_time, $total_system_time, $total_real_time;

$rrdfiles = get_rrdfile_names();
$stats = array();

$user_time = 0;
$system_time = 0;
$real_time = 0;

$use_proxy = (read_config_option('storage_location') ? true:false);

/* open a pipe to rrdtool for writing and reading */
@@ -63,6 +74,10 @@ function dsstats_get_and_store_ds_avgpeak_values($interval) {
$rrdtool_pipe = $process_pipes[1];
}

$system_time = 0;
$user_time = 0;
$real_time = 0;

if (cacti_sizeof($rrdfiles)) {
foreach ($rrdfiles as $file) {
if ($file['data_source_path'] != '') {
@@ -86,6 +101,10 @@ function dsstats_get_and_store_ds_avgpeak_values($interval) {
dsstats_rrdtool_close($process);
}

$total_system_time += $system_time;
$total_user_time += $user_time;
$total_real_time += $real_time;

dsstats_write_buffer($stats, $interval);
}

@@ -149,12 +168,12 @@ function dsstats_write_buffer(&$stats_array, $interval) {
gather data from the RRDfile for the time period in question. It allows RRDtool to select the RRA to
use by simply limiting the number of rows to be returned to the default.
Once it has all of the information from the RRDfile. It then decomposes the resulting XML file to it's
Once it has all of the information from the RRDfile. It then decomposes the resulting XML file to its
components and then calculates the AVERAGE and MAX values from that data and returns an array to the calling
function for storage into the respective database table.
@returns - (mixed) An array of AVERAGE, and MAX values in an RRDfile by Data Source name */
function dsstats_obtain_data_source_avgpeak_values($rrdfile, $interval, $rrdtool_pipe) {
global $config;
global $config, $user_time, $system_time, $real_time;

$use_proxy = (read_config_option('storage_location') ? true:false);

@@ -211,27 +230,26 @@ function dsstats_obtain_data_source_avgpeak_values($rrdfile, $interval, $rrdtool
$i = 0;
$j = 0;
$def = '';
$xport = '';
$command = '';
$dsvalues = array();


/* escape the file name if on Windows */
if ($config['cacti_server_os'] != 'unix') {
$rrdfile = str_replace(':', "\\:", $rrdfile);
}

/* setup the export command by parsing throught the internal data source names */
/* setup the graph command by parsing throught the internal data source names */
if (cacti_sizeof($dsnames)) {
foreach ($dsnames as $dsname => $present) {
if ($average) {
$def .= 'DEF:' . $defs[$j] . $defs[$i] . "=\"" . $rrdfile . "\":" . $dsname . ':AVERAGE ';
$xport .= ' XPORT:' . $defs[$j] . $defs[$i];
$command .= ' VDEF:' . $defs[$j] . $defs[$i] . '_out=' . $defs[$j] . $defs[$i] . ',AVERAGE PRINT:' . $defs[$j] . $defs[$i] . '_out:%lf';
$i++;
}

if ($max) {
$def .= 'DEF:' . $defs[$j] . $defs[$i] . "=\"" . $rrdfile . "\":" . $dsname . ':MAX ';
$xport .= ' XPORT:' . $defs[$j] . $defs[$i];
$command .= ' VDEF:' . $defs[$j] . $defs[$i] . '_out=' . $defs[$j] . $defs[$i] . ',MAXIMUM PRINT:' . $defs[$j] . $defs[$i] . '_out:%lf';
$i++;
}

@@ -258,76 +276,74 @@ function dsstats_obtain_data_source_avgpeak_values($rrdfile, $interval, $rrdtool
break;
}

/* now execute the xport command */
$xport_cmd = 'xport --start now-1' . $interval . ' --end now ' . trim($def) . ' ' . trim($xport) . ' --maxrows 10000';
/* now execute the graph command */
$stats_cmd = 'graph x --start now-1' . $interval . ' --end now ' . trim($def) . ' ' . trim($command);

//print $stats_cmd . PHP_EOL;

if ($use_proxy) {
$xport_data = rrdtool_execute($xport_cmd, false, RRDTOOL_OUTPUT_STDOUT, $rrdtool_pipe, 'DSSTATS');
$xport_data = rrdtool_execute($stats_cmd, false, RRDTOOL_OUTPUT_STDOUT, $rrdtool_pipe, 'DSSTATS');
} else {
$xport_data = dsstats_rrdtool_execute($xport_cmd, $rrdtool_pipe);
$xport_data = dsstats_rrdtool_execute($stats_cmd, $rrdtool_pipe);
}

$position = array();
$position[] = array('RETURN' => 'RETURN');

/* initialize the array of return values */
foreach($dsnames as $dsname => $present) {
$dsvalues[$dsname]['AVG'] = 0;
$dsvalues[$dsname]['AVGCNT'] = 0;
$dsvalues[$dsname]['MAX'] = 0;

if ($average) {
$position[] = array($dsname => 'AVG');
}

if ($max) {
$position[] = array($dsname => 'MAX');
}
}

/* process the xport array and return average and peak values */
if ($xport_data != '') {
$xport_array = explode("\n", $xport_data);
//print_r($xport_array);

if (cacti_sizeof($xport_array)) {
foreach($xport_array as $line) {
/* we've found an output value, let's cut it to pieces */
if (substr_count($line, '<v>')) {
$line = str_replace('<row><t>', '', $line);
$line = str_replace('</t>', '', $line);
$line = str_replace('</v>', '', $line);
$line = str_replace('</row>', '', $line);

$values = explode('<v>', $line);
array_shift($values);

$i = 0;
/* sum and/or store values for later processing */
foreach($dsnames as $dsname => $present) {
if ($average) {
/* ignore 'NaN' values */
if (strtolower($values[$i]) != 'nan') {
$dsvalues[$dsname]['AVG'] += $values[$i];
$dsvalues[$dsname]['AVGCNT'] += 1;

if (!$max) {
if ($values[$i] > $dsvalues[$dsname]['MAX']) {
$dsvalues[$dsname]['MAX'] = $values[$i];
}
}
$i++;
foreach($xport_array as $index => $line) {
if ($line == '') continue;

if ($index > 0) {
// Catch the last line
if (substr($line, 0, 2) == 'OK') {
$line = trim($line, ' OK');
$parts = explode(' ', $line);
//print $line . PHP_EOL;

foreach($parts as $line) {
$sparts = explode(':', $line);
switch($sparts[0]) {
case 'u':
$user_time = $sparts[1];
break;
case 's':
$system_time = $sparts[1];
break;
case 'r':
$real_time = $sparts[1];
break;
}
}

if ($max) {
/* ignore 'NaN' values */
if (strtolower($values[$i]) != 'nan') {
if ($values[$i] > $dsvalues[$dsname]['MAX']) {
$dsvalues[$dsname]['MAX'] = $values[$i];
}
$i++;
}
break;
} else {
foreach($position[$index] as $dsname => $stat) {
$dsvalues[$dsname][$stat] = trim($line);
}
}
}
}

/* calculate the average */
foreach($dsnames as $dsname => $present) {
if ($dsvalues[$dsname]['AVGCNT'] > 0) {
$dsvalues[$dsname]['AVG'] = $dsvalues[$dsname]['AVG'] / $dsvalues[$dsname]['AVGCNT'];
}
}

return $dsvalues;
}
}
@@ -345,12 +361,16 @@ function dsstats_obtain_data_source_avgpeak_values($rrdfile, $interval, $rrdtool
@arg $type - (string) the type of statistics to log, either 'HOURLY', 'DAILY' or 'MAJOR'.
@returns - null */
function log_dsstats_statistics($type) {
global $start;
global $start, $total_user_time, $total_system_time, $total_real_time;;

/* take time and log performance data */
$end = microtime(true);

$cacti_stats = sprintf('Time:%01.4f ', round($end-$start,4));
$cacti_stats = sprintf('Time:%01.4f RRDUser:%01.4f RRDSystem:%01.4f RRDReal:%01.4f', round($end-$start,4), $total_user_time, $total_system_time, $total_real_time);

$total_user_time = 0;
$total_system_time = 0;
$total_real_time = 0;

/* take time and log performance data */
$start = microtime(true);
@@ -463,7 +483,7 @@ function dsstats_poller_output(&$rrd_update_array) {
$overhead = strlen($sql_cache_prefix) + strlen($sql_suffix);
$overhead_last = strlen($sql_last_prefix) + strlen($sql_last_suffix);

/* determine the keyvalue pair's to decide on how to store data */
/* determine the keyvalue pairs to decide on how to store data */
$ds_types = array_rekey(
db_fetch_assoc('SELECT DISTINCT data_source_name, data_source_type_id, rrd_step
FROM data_template_rrd
@@ -635,7 +635,7 @@ function get_format_message_instance($current_message) {
return $message;
}

/* get_message_max_type - finds the message and returns it's type
/* get_message_max_type - finds the message and returns its type
@returns - (string) the message type 'info', 'warn', 'error' or 'csrf' */
function get_message_max_type() {
global $messages;
@@ -2507,7 +2507,7 @@ function draw_navigation_text($type = 'url') {
}
}

$tree_title = $tree_name . ($leaf_name != '' ? ' (' . $leaf_name:'') . ($leaf_sub != '' ? ':' . $leaf_sub . ')':($leaf_name != '' ? ')':''));
$tree_title = $tree_name . ($leaf_name != '' ? ' (' . trim($leaf_name):'') . ($leaf_sub != '' ? ':' . trim($leaf_sub) . ')':($leaf_name != '' ? ')':''));

if ($tree_title != '') {
$current_nav .= "<li><a id='nav_title' href=#>" . html_escape($tree_title) . '</a></li>';
@@ -2534,11 +2534,28 @@ function draw_navigation_text($type = 'url') {
}

// keep a cache for each level we encounter
$nav_level_cache[$current_array['level']] = array(
'id' => $current_page . ':' . $current_action,
'url' => get_browser_query_string()
);
$hasNavError = false;
if (is_array($current_page)) {
cacti_log('WARNING: Navigation item suppressed - current page is not a string: ' . var_export($current_page,true));
$hasNavError = true;
}

if (is_array($current_action)) {
cacti_log('WARNING: Navigation item suppressed - current action is not a string: '. var_export($current_action,true));
$hasNavError = true;
}

if (is_array($current_array['level'])) {
cacti_log('WARNING: Navigation item suppressed - current level is not a string: ' . var_export($current_array['level'],true));
$hasNavError = true;
}

if (!$hasNavError) {
$nav_level_cache[$current_array['level']] = array(
'id' => $current_page . ':' . $current_action,
'url' => get_browser_query_string()
);
}
$current_nav .= '</ul>';

$_SESSION['sess_nav_level_cache'] = $nav_level_cache;
@@ -5018,10 +5035,18 @@ function get_rrdtool_version() {
}

function get_installed_rrdtool_version() {
$shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool') . ' -v 2>&1'));
global $config;

if ($config['cacti_server_os'] == 'win32') {
$shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v');
} else {
$shell = shell_exec(cacti_escapeshellcmd(read_config_option('path_rrdtool')) . ' -v 2>&1');
}

if (preg_match('/^RRDtool ([0-9.]+)$/', $shell, $matches)) {
return $matches[1];
}

return false;
}

@@ -237,18 +237,23 @@ function cacti_stats_calc($array, $ptile = 95) {
$average = $sum/$elements;
$var = 'p' . $ptile . 'n';

if ($var == 'p95n') {
$var = '';
}

foreach ($array as $number) {
$variance += pow(abs($number - $average), 2);
}

$ptile_index = floor($elements * (1 - ($ptile/100)));
$p95n_index = floor($elements * 0.05);
$p90n_index = floor($elements * 0.1);
$p75n_index = floor($elements * 0.25);
$p50n_index = floor($elements * 0.50);
$p25n_index = floor($elements * 0.75);

return array(
$var => $array[$ptile_index],
$results = array(
'p95n' => $array[$p95n_index],
'p90n' => $array[$p90n_index],
'p75n' => $array[$p75n_index],
'p50n' => $array[$p50n_index],
@@ -259,6 +264,12 @@ function cacti_stats_calc($array, $ptile = 95) {
'variance' => $variance,
'stddev' => sqrt($variance/$elements)
);

if ($var != '') {
$results[$var] = $array[$ptile_index];
}

return $results;
}

/* bandwidth_summation - given a data source, sums all data in the rrd for a given
@@ -0,0 +1,93 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2007-2019 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/

function get_graph_template_details($local_graph_id) {
global $config;
$graph_local = db_fetch_row_prepared('SELECT id, graph_template_id, snmp_query_id
FROM graph_local
WHERE id = ?',
array($local_graph_id));

$aggregate = db_fetch_row_prepared('SELECT agt.id, agt.name
FROM aggregate_graphs AS ag
LEFT JOIN aggregate_graph_templates AS agt
ON ag.aggregate_template_id=agt.id
WHERE local_graph_id = ?',
array($local_graph_id));

if (!empty($aggregate)) {
$url = $config['url_path'] . 'aggregate_graphs.php?action=edit&id=';

$hasDetail = !empty($aggregate['id']);
return array(
'id' => $local_graph_id,
'name' => $hasDetail ? $aggregate['name'] : __('Not Templated'),
'graph_description' => $hasDetail ? __('Aggregated Device') : __('Not Applicable'),
'url' => $url . $local_graph_id,
'source' => GRAPH_SOURCE_AGGREGATE,
);
} elseif (!cacti_sizeof($graph_local) || $graph_local['graph_template_id'] == 0) {
return array(
'id' => 0,
'name' => __('Not Templated'),
'url' => '',
'source' => GRAPH_SOURCE_PLAIN,
);
} elseif ($graph_local['snmp_query_id'] > 0) {
$url = $config['url_path'] . 'data_queries.php?action=item_edit&id=';

$detail = db_fetch_row_prepared('SELECT sqg.id, sqg.name
FROM snmp_query_graph AS sqg
INNER JOIN graph_local AS gl
ON gl.snmp_query_graph_id=sqg.id
AND gl.snmp_query_id=sqg.snmp_query_id
WHERE gl.id = ?',
array($local_graph_id));

$hasDetail = (cacti_sizeof($detail));
return array(
'id' => $hasDetail ? $detail['id'] : 0,
'name' => $hasDetail ? $detail['name'] : __('Not Found'),
'url' => $hasDetail ? ($url . $detail['id']) : '',
'source' => GRAPH_SOURCE_DATA_QUERY
);
} else {
$url = $config['url_path'] . 'graph_templates.php?action=template_edit&id=';

$detail = db_fetch_row_prepared('SELECT gt.id, gt.name
FROM graph_templates AS gt
INNER JOIN graph_local AS gl
ON gl.graph_template_id=gt.id
WHERE gl.id = ?',
array($local_graph_id));

$hasDetail = (cacti_sizeof($detail));
return array(
'id' => $hasDetail ? $detail['id'] :0,
'name' => $hasDetail ? $detail['name'] : __('Not Found'),
'url' => $hasDetail ? ($url . $detail['id']) : '',
'source' => GRAPH_SOURCE_TEMPLATE,
);
}
}

Large diffs are not rendered by default.

@@ -806,7 +806,6 @@ function reports_item_edit() {
useCss=<?php print ($report['cformat'] == 'on' ? 'true':'false');?>;

function toggle_item_type() {
//console.log($('#item_type').val());
// right bracket ')' does not come with a field
if ($('#item_type').val() == '<?php print REPORTS_ITEM_GRAPH;?>') {
$('#row_align').show();
@@ -95,34 +95,32 @@ function grow_dhtml_trees() {
$default_tree_id = read_user_setting('default_tree_id');

if (empty($default_tree_id)) {
if (read_config_option('auth_method') != 0) {
$user = db_fetch_row_prepared('SELECT policy_trees
FROM user_auth
WHERE id = ?',
$user = db_fetch_row_prepared('SELECT policy_trees
FROM user_auth
WHERE id = ?',
array($_SESSION['sess_user_id']));

if ($user['policy_trees'] == 1) {
$default_tree_id = db_fetch_cell_prepared('SELECT graph_tree.id
FROM graph_tree
LEFT JOIN user_auth_perms ON user_auth_perms.item_id = graph_tree.id
AND user_auth_perms.type = 2
AND user_auth_perms.user_id = ?
WHERE user_auth_perms.item_id IS NULL
AND graph_tree.enabled = "on"
ORDER BY graph_tree.id
LIMIT 1',
array($_SESSION['sess_user_id']));
} else {
$default_tree_id = db_fetch_cell('SELECT graph_tree.id
FROM graph_tree
INNER JOIN user_auth_perms ON user_auth_perms.item_id = graph_tree.id
AND user_auth_perms.type = 2
AND user_auth_perms.user_id = ?
WHERE graph_tree.enabled = "on"
ORDER BY graph_tree.id
LIMIT 1',
array($_SESSION['sess_user_id']));

if ($user['policy_trees'] == 1) {
$default_tree_id = db_fetch_cell_prepared('SELECT graph_tree.id
FROM graph_tree
LEFT JOIN user_auth_perms ON user_auth_perms.item_id = graph_tree.id
AND user_auth_perms.type = 2
AND user_auth_perms.user_id = ?
WHERE user_auth_perms.item_id IS NULL
AND graph_tree.enabled = "on"
ORDER BY graph_tree.id
LIMIT 1',
array($_SESSION['sess_user_id']));
} else {
$default_tree_id = db_fetch_cell('SELECT graph_tree.id
FROM graph_tree
INNER JOIN user_auth_perms ON user_auth_perms.item_id = graph_tree.id
AND user_auth_perms.type = 2
AND user_auth_perms.user_id = ?
WHERE graph_tree.enabled = "on"
ORDER BY graph_tree.id
LIMIT 1',
array($_SESSION['sess_user_id']));
}
}
} else {
$default_tree_id = db_fetch_cell('SELECT id FROM graph_tree ORDER BY sequence LIMIT 1');
@@ -148,13 +146,24 @@ function grow_dhtml_trees() {

var search_to = false;

function resizeGraphContent() {
docHeight = parseInt($('body').height());
navigation = $('.cactiTreeNavigationArea').offset();
navHeight = docHeight - navigation.top + 15;
visWidth = Math.max.apply(Math, $('.jstree').children(':visible').map(function() { return $(this).width(); }).get());
$('.cactiTreeNavigationArea').height(navHeight).width(visWidth);
$('.cactiGraphContentArea').css('margin-left', visWidth+10);
function resizeTreePanel() {
if (theme != 'classic') {
docHeight = parseInt($('body').height());
navigation = $('.cactiTreeNavigationArea').offset();
navWidth = $('.cactiTreeNavigationArea').outerWidth();
navHeight = docHeight - navigation.top + 15;
visWidth = Math.max.apply(Math, $('.jstree').children(':visible').map(function() {
return $(this).width();
}).get());

if (visWidth > navWidth) {
$('.cactiTreeNavigationArea').height(navHeight).width(visWidth);
$('.cactiGraphContentArea').css('margin-left', visWidth+5);
} else {
$('.cactiTreeNavigationArea').height(navHeight).width(navWidth);
$('.cactiGraphContentArea').css('margin-left', navWidth+5);
}
}
}

function checkTreeForLogout() {
@@ -176,15 +185,13 @@ function openNodes() {
return $.Deferred(function(def) {
id = $('a[id^='+name+']').first().attr('id');

//console.log('lastNode:'+lastNode+', Node:'+name);
if (lastNode == name) {
//console.log('lastNode:'+lastNode+', Node:'+name+', Id:'+id+', Select Node');
$('#jstree').jstree('select_node', id, function() {
def.resolve();
});
} else {
//console.log('lastNode:'+lastNode+', Node:'+name+', Id:'+id+', Open Node');
$('#jstree').jstree('open_node', id, function() {
$('.cactiConsoleNavigationArea').css('overflow-y', 'auto');
def.resolve();
});
}
@@ -207,63 +214,47 @@ function openNodes() {
})
.on('loaded.jstree', function() {
openNodes();
resizeTreePanel();
})
.on('ready.jstree', function() {
resizeGraphContent();
resizeTreePanel();
})
.on('changed.jstree', function() {
resizeGraphContent();
resizeTreePanel();
})
.on('before_open.jstree', function() {
checkTreeForLogout();
})
.on('open_node.jstree', function() {
resizeGraphContent();
$(window).trigger('resize');
resizeTreePanel();
responsiveResizeGraphs();
})
.on('close_node.jstree', function() {
resizeGraphContent();
$(window).trigger('resize');
resizeTreePanel();
responsiveResizeGraphs();
})
.on('select_node.jstree', function(e, data) {
if (data.node.id) {
if (data.node.id.search('tree_anchor') >= 0) {
href=$('#'+data.node.id).find('a:first').attr('href');
//href=$('#'+data.node.id).find('a:first').attr('href')+"&node=0";
} else {
//href=$('#'+data.node.id).find('a:first').attr('href')+"&node="+data.node.id.replace('tbranch-','');
href=$('#'+data.node.id).find('a:first').attr('href');
}

origHref = href;

if (typeof href !== 'undefined') {
href=href.replace('action=tree', 'action=tree_content');
href = href.replace('action=tree', 'action=tree_content');
$('.cactiGraphContentArea').hide();

$.get(href)
.done(function(data) {
$('#main').html(data);
applySkin();

$('.cactiGraphContentArea').show();

var mytitle = 'Tree Mode - '+$('#nav_title').text();
document.getElementsByTagName('title')[0].innerHTML = mytitle;
if (typeof window.history.pushState !== 'undefined') {
window.history.pushState({ page: origHref+'&hyper=true' }, mytitle, origHref+'&hyper=true');
}

window.scrollTo(0, 0);
resizeGraphContent();
})
.fail(function(data) {
getPresentHTTPError(data);
});
loadPage(href);
}

node = data.node.id;
}

resizeGraphContent();
resizeTreePanel();
})
.jstree({
'types' : {
@@ -335,7 +326,7 @@ function openNodes() {
});

$(document).resize(function() {
resizeGraphContent();
resizeTreePanel();
});

<?php print api_plugin_hook_function('top_graph_jquery_function');?>
@@ -1398,31 +1389,31 @@ function get_host_graph_list($host_id, $graph_template_id, $data_query_id, $host
);

if (cacti_sizeof($final_templates)) {
foreach ($final_templates as $graph_template) {
$sql_where = '';

if (get_request_var('rfilter') != '') {
$sql_where = " (gtg.title_cache RLIKE '" . get_request_var('rfilter') . "')";
}

if ($host_id > 0) {
$sql_where .= ($sql_where != '' ? ' AND ':'') . 'gl.host_id=' . $host_id;
}

$sql_where .= ($sql_where != '' ? ' AND ':'') . 'gl.graph_template_id=' . $graph_template['id'];

$graphs = get_allowed_graphs($sql_where);
$agg = get_allowed_aggregate_graphs($sql_where);
$graphs = array_merge($graphs, $agg);
$sql_where = '';
if (get_request_var('rfilter') != '') {
$sql_where = " (gtg.title_cache RLIKE '" . get_request_var('rfilter') . "')";
}

/* let's sort the graphs naturally */
usort($graphs, 'naturally_sort_graphs');
if ($host_id > 0) {
$sql_where .= ($sql_where != '' ? ' AND ':'') . 'gl.host_id=' . $host_id;
}

if (cacti_sizeof($graphs)) {
foreach ($graphs as $graph) {
$graph['graph_template_name'] = $graph_template['name'];
array_push($graph_list, $graph);
}
$graph_template_ids = [];
foreach ($final_templates as $graph_template) {
array_push($graph_template_ids, $graph_template['id']);
}
$sql_where .= ($sql_where != '' ? ' AND ':'') . 'gl.graph_template_id IN (' . implode(', ', $graph_template_ids) . ')';
$graphs = get_allowed_graphs($sql_where);
$agg = get_allowed_aggregate_graphs($sql_where);
$graphs = array_merge($graphs, $agg);

/* let's sort the graphs naturally */
usort($graphs, 'naturally_sort_graphs');

if (cacti_sizeof($graphs)) {
foreach ($graphs as $graph) {
$graph['graph_template_name'] = $graph_template['name'];
array_push($graph_list, $graph);
}
}
}
@@ -738,8 +738,23 @@ function update_order_string($inplace = false) {
$_SESSION['sort_data'][$page][get_request_var('sort_column')] = get_request_var('sort_direction');
$_SESSION['sort_string'][$page] = 'ORDER BY ' . $del . implode($del . '.'. $del, explode('.', get_request_var('sort_column'))) . $del . ' ' . get_request_var('sort_direction');
} elseif (isset_request_var('sort_column')) {
if (isset_request_var('reset')) {
unset($_SESSION['sort_data'][$page]);
unset($_SESSION['sort_string'][$page]);
}

$_SESSION['sort_data'][$page][get_request_var('sort_column')] = get_nfilter_request_var('sort_direction');
$_SESSION['sort_string'][$page] = 'ORDER BY ';

foreach($_SESSION['sort_data'][$page] as $column => $direction) {
if (strpos($column, '(') === false && strpos($column, '`') === false) {
$del = '`';
} else {
$del = '';
break;
}
}

foreach($_SESSION['sort_data'][$page] as $column => $direction) {
if ($column == 'hostname' || $column == 'ip' || $column == 'ip_address') {
$order .= ($order != '' ? ', ':'') . 'INET_ATON(' . $column . ") " . $direction;
@@ -23,7 +23,7 @@
*/

function import_xml_data(&$xml_data, $import_as_new, $profile_id, $remove_orphans = false) {
global $config, $hash_type_codes, $cacti_version_codes, $preview_only, $remove_orphans, $import_debug_info;
global $config, $hash_type_codes, $cacti_version_codes, $preview_only, $remove_orphans, $import_debug_info, $legacy_template;

include_once($config['library_path'] . '/xml.php');

@@ -42,7 +42,9 @@ function import_xml_data(&$xml_data, $import_as_new, $profile_id, $remove_orphan
$parsed_hash = parse_xml_hash($hash);

/* invalid/wrong hash */
if ($parsed_hash == false) { return $info_array; }
if ($parsed_hash == false) {
return $info_array;
}

if (isset($dep_hash_cache[$parsed_hash['type']])) {
array_push($dep_hash_cache[$parsed_hash['type']], $parsed_hash);
@@ -159,6 +161,10 @@ function import_xml_data(&$xml_data, $import_as_new, $profile_id, $remove_orphan
for ($i=0; $i<cacti_count($dep_hash_cache[$type]); $i++) {
$import_debug_info = false;

if (!isset($cacti_version_codes[$dep_hash_cache[$type][$i]['version']])) {
return false;
}

cacti_log('$dep_hash_cache[$type][$i][\'type\']: ' . $dep_hash_cache[$type][$i]['type'], false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('$dep_hash_cache[$type][$i][\'version\']: ' . $dep_hash_cache[$type][$i]['version'], false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('$cacti_version_codes[$dep_hash_cache[$type][$i][\'version\']]: ' . $cacti_version_codes[$dep_hash_cache[$type][$i]['version']], false, 'IMPORT', POLLER_VERBOSITY_HIGH);
@@ -275,7 +281,7 @@ function import_package($xmlfile, $profile_id = 1, $remove_orphans = false, $pre
$binary_signature = base64_decode(trim(str_replace(array('<signature>', '</signature>'), array('', ''), $x)));
$x = " <signature></signature>\n";

cacti_log('NOTE: Got Package Signature', false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('NOTE: Got Package Signature', false, 'IMPORT', POLLER_VERBOSITY_LOW);
}
$xml .= "$x";
}
@@ -297,7 +303,7 @@ function import_package($xmlfile, $profile_id = 1, $remove_orphans = false, $pre
return false;
}

cacti_log('Loading Plugin Information from package', false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('Loading Plugin Information from package', false, 'IMPORT', POLLER_VERBOSITY_LOW);

$xmlget = simplexml_load_string($xml);
$data = xml_to_array($xmlget);
@@ -310,7 +316,7 @@ function import_package($xmlfile, $profile_id = 1, $remove_orphans = false, $pre
exit;
}

cacti_log('Verifying each files signature', false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('Verifying each files signature', false, 'IMPORT', POLLER_VERBOSITY_LOW);

if (isset($data['files']['file']['data'])) {
$data['files']['file'] = array($data['files']['file']);
@@ -321,28 +327,29 @@ function import_package($xmlfile, $profile_id = 1, $remove_orphans = false, $pre
$fdata = base64_decode($f['data']);
$ok = openssl_verify($fdata, $binary_signature, $public_key, OPENSSL_ALGO_SHA1);
if ($ok == 1) {
cacti_log('NOTE: File OK: ' . $f['name'], false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('NOTE: File OK: ' . $f['name'], false, 'IMPORT', POLLER_VERBOSITY_LOW);
} else {
cacti_log('FATAL: Could not Verify Signature for file: ' . $f['name'], true, 'IMPORT', POLLER_VERBOSITY_LOW);
return false;
}
}

cacti_log('Writing Files', false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('Writing Files', false, 'IMPORT', POLLER_VERBOSITY_LOW);

foreach ($data['files']['file'] as $f) {
$fdata = base64_decode($f['data']);
$name = $f['name'];

if (strpos($name, 'scripts/') !== false || strpos($name, 'resource/') !== false) {
$filename = $config['base_path'] . "/$name";
cacti_log('Writing file: ' . $filename, false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('Writing file: ' . $filename, false, 'IMPORT', POLLER_VERBOSITY_LOW);

if (!$preview) {
if (is_writable($filename)) {
$file = fopen($filename,'wb');
if ((is_writeable(dirname($filename)) && !file_exists($filename)) || is_writable($filename)) {
$file = fopen($filename, 'wb');

if (is_resource($file)) {
fwrite($file ,$fdata, strlen($fdata));
fwrite($file , $fdata, strlen($fdata));
fclose($file);
clearstatcache();
$filestatus[$filename] = __('written');
@@ -358,21 +365,28 @@ function import_package($xmlfile, $profile_id = 1, $remove_orphans = false, $pre
} else {
$filestatus[$filename] = __('not writable');
}

cacti_log('Write Status file: ' . $filename . ', with Status ' . $filestatus[$filename], false, 'IMPORT', POLLER_VERBOSITY_LOW);
} else {
if (!is_writable($filename)) {
$filestatus[$filename] = __('not writable');
} else {
$filestatus[$filename] = __('writable');
}
}

} else {
cacti_log('Importing XML Data for ' . $name, false, 'IMPORT', POLLER_VERBOSITY_LOW);

$debug_data = import_xml_data($fdata, false, $profile_id, $remove_orphans, $preview_only);

if ($debug_data === false) {
return false;
}
}
}

cacti_log('File creation complete', false, 'IMPORT', POLLER_VERBOSITY_HIGH);
cacti_log('File creation complete', false, 'IMPORT', POLLER_VERBOSITY_LOW);

return array($debug_data, $filestatus);
}
@@ -392,9 +406,11 @@ function xml_to_graph_template($hash, &$xml_array, &$hash_cache, $hash_version,
if (!empty($_graph_template_id)) {
$previous_data = db_fetch_row_prepared('SELECT *
FROM graph_templates
WHERE id = ?', array($_graph_template_id));
WHERE id = ?',
array($_graph_template_id));
} else {
$previous_data = array();
clear_cached_allowed_types();
}

$save['id'] = (empty($_graph_template_id) ? '0' : $_graph_template_id);
@@ -421,8 +437,10 @@ function xml_to_graph_template($hash, &$xml_array, &$hash_cache, $hash_version,
$save['id'] = (empty($_graph_template_id) ? '0' : db_fetch_cell_prepared('SELECT gtg.id
FROM graph_templates AS gt
INNER JOIN graph_templates_graph AS gtg
ON gt.id=gtg.graph_template_id
WHERE gt.id = ? AND gtg.local_graph_id=0', array($graph_template_id)));
ON gt.id = gtg.graph_template_id
WHERE gt.id = ?
AND gtg.local_graph_id = 0',
array($graph_template_id)));

if (!empty($_graph_template_id)) {
$previous_data = db_fetch_row_prepared('SELECT *
@@ -499,7 +517,7 @@ function xml_to_graph_template($hash, &$xml_array, &$hash_cache, $hash_version,
FROM graph_templates_item
WHERE hash = ?
AND graph_template_id = ?
AND local_graph_id=0',
AND local_graph_id = 0',
array($parsed_hash['hash'], $graph_template_id));

if (!empty($_graph_template_item_id)) {
@@ -618,7 +636,7 @@ function xml_to_graph_template($hash, &$xml_array, &$hash_cache, $hash_version,

if (isset($hash_cache['graph_template_item'][$parsed_hash['hash']])) {
db_execute_prepared('REPLACE INTO graph_template_input_defs
(graph_template_input_id,graph_template_item_id)
(graph_template_input_id, graph_template_item_id)
VALUES (?, ?)',
array($graph_template_input_id, $hash_cache['graph_template_item'][$parsed_hash['hash']]));
}
@@ -669,7 +687,7 @@ function xml_to_graph_template($hash, &$xml_array, &$hash_cache, $hash_version,
}

function xml_to_data_template($hash, &$xml_array, &$hash_cache, $import_as_new, $profile_id) {
global $struct_data_source, $struct_data_source_item, $import_template_id, $preview_only, $import_debug_info;
global $struct_data_source, $struct_data_source_item, $import_template_id, $preview_only, $import_debug_info, $legacy_template;

/* track changes */
$status = 0;
@@ -713,7 +731,8 @@ function xml_to_data_template($hash, &$xml_array, &$hash_cache, $import_as_new,
INNER JOIN data_template_data AS dtd
ON dt.id=dtd.data_template_id
WHERE dt.id = ?
AND dtd.local_data_id=0', array($data_template_id)));
AND dtd.local_data_id = 0',
array($data_template_id)));

if (!empty($save['id'])) {
$previous_data = db_fetch_row_prepared('SELECT *
@@ -787,7 +806,7 @@ function xml_to_data_template($hash, &$xml_array, &$hash_cache, $import_as_new,
FROM data_template_rrd
WHERE hash = ?
AND data_template_id = ?
AND local_data_id=0',
AND local_data_id = 0',
array($parsed_hash['hash'], $data_template_id));

if (!empty($_data_template_rrd_id)) {
@@ -833,12 +852,42 @@ function xml_to_data_template($hash, &$xml_array, &$hash_cache, $import_as_new,
$save['rrd_heartbeat'] = read_config_option('poller_interval') * 2;
}

if ($legacy_template) {
if ($save['data_source_type_id'] == 1 || $save['data_source_type_id'] == 4) {
if ($save['rrd_maximum'] == '0' && $save['rrd_minimum'] == '0') {
$save['rrd_maximum'] = 'U';
}
} elseif ($save['data_source_type_id'] == 3 || $save['data_source_type_id'] == 7) {
if ($save['rrd_maximum'] == '0' && $save['rrd_minimum'] == '0') {
$save['rrd_maximum'] = 'U';
$save['rrd_minimum'] = 'U';
}
}
}

/* check for status changes */
$status += compare_data($save, $previous_data, 'data_template_rrd');

if (!$preview_only) {
$data_template_rrd_id = sql_save($save, 'data_template_rrd');

if ($legacy_template) {
// Correct max values in templates and data sources: GAUGE/ABSOLUTE (1,4)
db_execute("UPDATE data_template_rrd
SET rrd_maximum='U'
WHERE rrd_maximum = '0'
AND rrd_minimum = '0'
AND data_template_id = $data_template_id
AND data_source_type_id IN(1,4)");

// Correct min/max values in templates and data sources: DERIVE/DDERIVE (3,7)
db_execute("UPDATE data_template_rrd
SET rrd_maximum='U', rrd_minimum='U'
WHERE (rrd_maximum = '0' OR rrd_minimum = '0')
AND data_template_id = $data_template_id
AND data_source_type_id IN(3,7)");
}

$hash_cache['data_template_item'][$parsed_hash['hash']] = $data_template_rrd_id;
} else {
$hash_cache['data_template_item'][$parsed_hash['hash']] = $_data_template_rrd_id;
@@ -1198,7 +1247,7 @@ function xml_to_data_source_profile($hash, &$xml_array, &$hash_cache, $import_as
if (!empty($hash_items[0])) {
for ($i=0; $i<cacti_count($hash_items); $i++) {
db_execute_prepared('REPLACE INTO data_source_profiles_cf
(data_source_profile_id,consolidation_function_id)
(data_source_profile_id, consolidation_function_id)
VALUES (?, ?)',
array($dsp_id, $hash_items[$i]));
}
@@ -1290,7 +1339,7 @@ function xml_to_host_template($hash, &$xml_array, &$hash_cache) {

if (isset($hash_cache['graph_template'][$parsed_hash['hash']])) {
db_execute_prepared('REPLACE INTO host_template_graph
(host_template_id,graph_template_id)
(host_template_id, graph_template_id)
VALUES (?, ?)',
array($host_template_id, $hash_cache['graph_template'][$parsed_hash['hash']]));
}
@@ -1310,7 +1359,7 @@ function xml_to_host_template($hash, &$xml_array, &$hash_cache) {

if (isset($hash_cache['data_query'][$parsed_hash['hash']])) {
db_execute_prepared('REPLACE INTO host_template_snmp_query
(host_template_id,snmp_query_id)
(host_template_id, snmp_query_id)
VALUES (?, ?)',
array($host_template_id, $hash_cache['data_query'][$parsed_hash['hash']]));
}
@@ -1877,6 +1926,8 @@ function resolve_hash_to_id($hash, &$hash_cache_array) {
}

function parse_xml_hash($hash) {
global $legacy_template;

if (preg_match('/hash_([a-f0-9]{2})([a-f0-9]{4})([a-f0-9]{32})/', $hash, $matches)) {
$parsed_hash['type'] = check_hash_type($matches[1]);
$parsed_hash['version'] = strval(check_hash_version($matches[2]));
@@ -1916,6 +1967,10 @@ function parse_xml_hash($hash) {
return false;
}

if (cacti_version_compare($parsed_hash['version'], '1.2.3', '<')) {
$legacy_template = true;
}

return $parsed_hash;
}

@@ -954,24 +954,31 @@ private function getModules() {
if (isset($this->extensions) || empty($this->extensions)) {
$extensions = utility_php_extensions();

foreach ($extensions as $e) {
foreach ($extensions as $name => $e) {
if (!$e['installed']) {
$this->addError(Installer::STEP_CHECK_DEPENDENCIES, 'Modules', $e['name'] . ' is missing');
$this->addError(Installer::STEP_CHECK_DEPENDENCIES, 'Modules', $name . ' is missing');
}
}

$this->extensions = $extensions;
}

return $this->extensions;
}

/* getTemplates() - returns a list of expected templates and whether
* they have been selected for installation */
private function getTemplates() {
$known_templates = install_setup_get_templates();

if ($known_templates === false) {
return false;
}

$db_templates = array_rekey(
db_fetch_assoc('SELECT name, value FROM settings where name like \'install_template_%\''),
'name', 'value');
db_fetch_assoc('SELECT name, value FROM settings WHERE name LIKE \'install_template_%\''),
'name', 'value'
);

$hasTemplates = read_config_option('install_has_templates', true);
$selected = array();
@@ -981,7 +988,7 @@ private function getTemplates() {

foreach ($known_templates as $known) {
$filename = $known['filename'];
$key_base = str_replace(".", "_", $filename);
$key_base = str_replace('.', '_', $filename);
$key_install = 'install_template_' . $key_base;
$key_check = 'chk_template_' . $key_base;

@@ -1002,9 +1009,11 @@ private function getTemplates() {
$select_count++;
}
}

$selected['all'] = ($select_count == cacti_count($selected) || empty($hasTemplates));

log_install_high('templates', 'getTemplates(): Returning with ' . clean_up_lines(var_export($selected, true)));

return $selected;
}

@@ -1128,6 +1137,9 @@ private function setTables($param_tables = array()) {
log_install_high('tables',"setTables(): Checking table '$name' against key $key ...");
log_install_debug('tables',"setTables(): Table: ". clean_up_lines(var_export($known, true)));
$set = false;
if (!array_key_exists($key, $param_tables)) {
$param_tables[$key] = null;
}
$this->setTrueFalse($param_tables[$key], $set, 'table_'.$name, false);
$use = ($set || $param_all);
$value = $use ? $name : '';
@@ -2723,14 +2735,27 @@ private function installTemplate() {

$this->setProgress(Installer::PROGRESS_TEMPLATES_BEGIN);
$i = 0;

foreach ($templates as $template) {
$i++;
$result = false;
$package = $template['value'];

log_install_always('', sprintf('About to import Package #%s \'%s\'.', $i, $package));

if (!empty($package)) {
set_config_option('install_updated', microtime(true));
log_install_always('', sprintf('Importing Package #%s \'%s\' under Profile \'%s\'', $i, $package, $this->profile));
import_package($path . $package, $this->profile, false, false, false);
$this->setProgress(Installer::PROGRESS_TEMPLATES_BEGIN + $i);
$result = import_package($path . $package, $this->profile, false, false, false);

if ($result !== false) {
log_install_always('', sprintf('Import of Package #%s \'%s\' under Profile \'%s\' succeeded', $i, $package, $this->profile));
$this->setProgress(Installer::PROGRESS_TEMPLATES_BEGIN + $i);
}
}

if ($result === false) {
log_install_always('',sprintf('Import of Package #%s \'%s\' under Profile \'%s\' failed', $i, $package, $this->profile));
$this->addError(Installer::STEP_ERROR, 'Package:'.$package, 'FAIL: XML version code error');
}
}

@@ -973,12 +973,55 @@ function plugin_is_compatible($plugin) {
return array('compat' => true, 'requires' => __('Requires: Cacti >= %s', $info['compat']));
}

function plugin_load_info_defaults($file, $info, $defaults = array()) {
$result = $info;
$dir = @basename(@dirname($file));

if (!is_array($defaults)) {
$defaults = array();
}

if (!is_array($result)) {
$result = array();
}

$info_fields = array(
'name' => $dir,
'requires' => '',
'longname' => ucfirst($dir),
'status' => file_exists($file) ? 0 : -4,
'version' => __('Unknown'),
'author' => __('Unknown'),
'homepage' => isset($info['webpage']) ? $info['webpage'] : __('Not Stated'),
'capabilities' => '',
'directory' => $dir,
);

$info_fields = $info_fields + $defaults;
foreach ($info_fields as $name => $value) {
if (!array_key_exists($name, $result)) {
$result[$name] = $value;
}
}

if (strstr($dir, ' ') !== false) {
$result['status'] = -3;
} elseif ($dir != $result['name']) {
$result['status'] = -2;
} elseif (!isset($result['compat']) || cacti_version_compare(CACTI_VERSION, $result['compat'], '<')) {
$result['status'] = -1;
}

return $result;
}

function plugin_load_info_file($file) {
$info = false;
if (file_exists($file)) {
if (is_readable($file)) {
$info = parse_ini_file($file, true);
if (cacti_sizeof($info)) {
return $info['info'];
if (cacti_sizeof($info) && array_key_exists('info', $info)) {
$info = plugin_load_info_defaults($file, $info['info']);
} else {
cacti_log('WARNING: Loading plugin INFO file failed. Parsing INI file failed.', false, 'WEBUI');
}
@@ -989,5 +1032,5 @@ function plugin_load_info_file($file) {
cacti_log('WARNING: Loading plugin INFO file failed. INFO file does not exist.', false, 'WEBUI');
}

return false;
return $info;
}
@@ -1012,8 +1012,10 @@ function md5sum_path($path, $recursive = true) {
$filemd5s[] = md5sum_path($path . DIRECTORY_SEPARATOR. $entry, $recursive);
} elseif (is_dir($path . DIRECTORY_SEPARATOR . $entry)) {
// Ignore directories who are not recursive
} else {
} elseif (is_readable($path . DIRECTORY_SEPARATOR . $entry)) {
$filemd5s[] = md5_file($path . DIRECTORY_SEPARATOR . $entry);
} else {
cacti_log('WARNING: Unable to read file \'' . $path . DIRECTORY_SEPARATOR . $entry . '\' into Cacti resource cache.', false, 'POLLER');
}
}
}
@@ -1120,6 +1122,7 @@ function replicate_out($remote_poller_id = 1, $class = 'all') {
AND name NOT LIKE "stats%"
AND name != "rrdtool_version"
AND name NOT LIKE "poller_replicate%"
AND name NOT LIKE "install%"
AND name != "poller_enabled"
AND name NOT LIKE "md5dirsum%"
UNION

Large diffs are not rendered by default.

@@ -24,7 +24,7 @@
*/

/* trim all but hex-string:, which will return 'hex-' */
define('REGEXP_SNMP_TRIM', '/(counter(32|64):|gauge|gauge(32|64):|float:|ipaddress:|string:|integer:)|(up|down)\(|\)$/i');
define('REGEXP_SNMP_TRIM', '/(counter(32|64):|gauge:|gauge(32|64):|float:|ipaddress:|string:|integer:)|(up|down)\(|\)$/i');

define('SNMP_METHOD_PHP', 1);
define('SNMP_METHOD_BINARY', 2);
@@ -570,21 +570,11 @@ function snmpagent_get_pluginslist(){
$dh = opendir($path);
if ($dh !== false) {
while (($file = readdir($dh)) !== false) {
if ((is_dir("$path/$file")) && !in_array($file, $plugins_integrated) &&
(file_exists("$path/$file/setup.php")) && (!array_key_exists($file, $pluginslist))) {
if (file_exists("$path/$file/INFO")) {
$cinfo = plugin_load_info_file("$path/$file/INFO");

if (!isset($cinfo['author'])) $cinfo['author'] = 'Unknown';
if (!isset($cinfo['homepage'])) $cinfo['homepage'] = 'Not Stated';
if (isset($cinfo['webpage'])) $cinfo['homepage'] = $cinfo['webpage'];
if (!isset($cinfo['longname'])) $cinfo['longname'] = ucfirst($file);
$cinfo['directory'] = $file;

if ((is_dir("$path$file")) && !in_array($file, $plugins_integrated) &&
(file_exists("$path$file/setup.php")) && (!array_key_exists($file, $pluginslist))) {
if (file_exists("$path$file/INFO")) {
$cinfo = plugin_load_info_file("$path$file/INFO");
$pluginslist[$file] = $cinfo;
if (!isset($pluginslist[$file]['status'])) {
$pluginslist[$file]['status'] = 0;
}
}
}
}
@@ -810,6 +810,7 @@ function utilities_get_mysql_recommendations() {
// MySQL/MariaDB Important Variables
// Assume we are successfully, until we aren't!
$result = DB_STATUS_SUCCESS;

$variables = array_rekey(db_fetch_assoc('SHOW GLOBAL VARIABLES'), 'Variable_name', 'Value');

$memInfo = utilities_get_system_memory();
@@ -832,20 +833,21 @@ function utilities_get_mysql_recommendations() {
$recommendations = array(
'version' => array(
'value' => '5.6',
'class' => 'warning',
'measure' => 'ge',
'comment' => __('MySQL 5.6+ and MariaDB 10.0+ are great releases, and are very good versions to choose. Make sure you run the very latest release though which fixes a long standing low level networking issue that was causing spine many issues with reliability.')
)
);

if (isset($variables['innodb_version']) && version_compare($variables['innodb_version'], '5.6', '<')) {
if (version_compare($link_ver, '5.2', '>=')) {
if (version_compare($link_ver, '5.5', '>=')) {
if (!isset($variables['innodb_version'])) {
$recommendations += array(
'innodb' => array(
'value' => 'ON',
'class' => 'warning',
'measure' => 'equal',
'comment' => __('It is recommended that you enable InnoDB in any %s version greater than 5.1.', $database)
'measure' => 'equalint',
'comment' => __('It is STRONGLY recommended that you enable InnoDB in any %s version greater than 5.5.3.', $database)
)
);

@@ -855,13 +857,13 @@ function utilities_get_mysql_recommendations() {

$recommendations += array(
'collation_server' => array(
'value' => 'utf8_general_ci',
'value' => 'utf8mb4_unicode_ci',
'class' => 'warning',
'measure' => 'equal',
'comment' => __('When using Cacti with languages other than English, it is important to use the utf8_general_ci collation type as some characters take more than a single byte. If you are first just now installing Cacti, stop, make the changes and start over again. If your Cacti has been running and is in production, see the internet for instructions on converting your databases and tables if you plan on supporting other languages.')
),
'character_set_client' => array(
'value' => 'utf8',
'value' => 'utf8mb4',
'class' => 'warning',
'measure' => 'equal',
'comment' => __('When using Cacti with languages other than English, it is important to use the utf8 character set as some characters take more than a single byte. If you are first just now installing Cacti, stop, make the changes and start over again. If your Cacti has been running and is in production, see the internet for instructions on converting your databases and tables if you plan on supporting other languages.')
@@ -874,7 +876,7 @@ function utilities_get_mysql_recommendations() {
'innodb' => array(
'value' => 'ON',
'class' => 'warning',
'measure' => 'equal',
'measure' => 'equalint',
'comment' => __('It is recommended that you enable InnoDB in any %s version greater than 5.1.', $database)
)
);
@@ -934,14 +936,21 @@ function utilities_get_mysql_recommendations() {
),
'innodb_file_per_table' => array(
'value' => 'ON',
'measure' => 'equal',
'measure' => 'equalint',
'comment' => __('When using InnoDB storage it is important to keep your table spaces separate. This makes managing the tables simpler for long time users of %s. If you are running with this currently off, you can migrate to the per file storage by enabling the feature, and then running an alter statement on all InnoDB tables.', $database)
),
'innodb_file_format' => array(
'value' => 'Barracuda',
'measure' => 'equal',
'class' => 'error',
'comment' => __('When using innodb_file_per_table, it is important to set the innodb_file_format to Barracuda. This setting will allow longer indexes important for certain Cacti tables.')
),
'innodb_large_prefix' => array(
'value' => '1',
'measure' => 'equalint',
'class' => 'error',
'comment' => __('If your tables have very large indexes, you must operate with the Barracuda innodb_file_format and the innodb_large_prefix equal to 1. Failure to do this may result in plugins that can not properly create tables.')
),
'innodb_buffer_pool_size' => array(
'value' => '25',
'measure' => 'pmem',
@@ -950,7 +959,7 @@ function utilities_get_mysql_recommendations() {
),
'innodb_doublewrite' => array(
'value' => 'OFF',
'measure' => 'equal',
'measure' => 'equalint',
'class' => 'warning',
'comment' => __('With modern SSD type storage, this operation actually degrades the disk more rapidly and adds a 50%% overhead on all write operations.')
),
@@ -963,6 +972,11 @@ function utilities_get_mysql_recommendations() {
'value' => '50',
'measure' => 'ge',
'comment' => __('Rogue queries should not for the database to go offline to others. Kill these queries before they kill your system.')
),
'innodb_flush_method' => array(
'value' => 'O_DIRECT',
'measure' => 'eq',
'comment' => __('Maximum I/O performance happens when you use the O_DIRECT method to flush pages.')
)
);

@@ -1002,6 +1016,24 @@ function utilities_get_mysql_recommendations() {
'measure' => 'pinst',
'class' => 'warning',
'comment' => __('%s will divide the innodb_buffer_pool into memory regions to improve performance. The max value is 64. When your innodb_buffer_pool is less than 1GB, you should use the pool size divided by 128MB. Continue to use this equation upto the max of 64.', $database)
),
'innodb_io_capacity' => array(
'value' => '5000',
'measure' => 'ge',
'class' => 'warning',
'comment' => __('If you have SSD disks, use this suggestion. If you have physical hard drives, use 200 * the number of active drives in the array. If using NVMe or PCIe Flash, much larger numbers as high as 100000 can be used.')
),
'innodb_io_capacity_max' => array(
'value' => '10000',
'measure' => 'ge',
'class' => 'warning',
'comment' => __('If you have SSD disks, use this suggestion. If you have physical hard drives, use 2000 * the number of active drives in the array. If using NVMe or PCIe Flash, much larger numbers as high as 200000 can be used.')
),
'innodb_flush_neighbor_pages' => array(
'value' => 'none',
'measure' => 'eq',
'class' => 'warning',
'comment' => __('If you have SSD disks, use this suggestion. Otherwise, do not set this setting.')
)
);

@@ -1034,13 +1066,13 @@ function utilities_get_mysql_recommendations() {

$compare = '';
$value_recommend = isset($r['value']) ? $r['value'] : '<unset>';
$value_current = isset($variables[$name]) ? $variables[$name] : '<unset>';
$value_display = $value_current;
$value_current = isset($variables[$name]) ? $variables[$name] : '<unset>';
$value_display = $value_current;

switch($r['measure']) {
case 'gem':
$compare = '>=';
$value_display = ($variables[$name]/1024/1024).'M';
$value_display = ($variables[$name]/1024/1024) . 'M';
$value = trim($r['value'], 'M') * 1024 * 1024;
if ($variables[$name] < $value) {
$passed = false;
@@ -1050,9 +1082,20 @@ function utilities_get_mysql_recommendations() {
$compare = '>=';
$passed = (version_compare($value_current, $value_recommend, '>='));
break;
case 'equalint':
case 'equal':
$compare = '=';
$passed = (isset($variables[$name]) || $value_current != $value_recommend);
if (!isset($variables[$name])) {
$passed = false;
} else {
$e_var = $variables[$name];
$e_rec = $value_recommend;
if ($r['measure'] == 'equalint') {
$e_var = (!strcasecmp('on', $e_var) ? 1 : (!strcasecmp('off', $e_var) ? 0 : $e_var));
$e_rec = (!strcasecmp('on', $e_rec) ? 1 : (!strcasecmp('off', $e_rec) ? 0 : $e_rec));
}
$passed = $e_var == $e_rec;
}
break;
case 'pmem':
if (isset($memInfo['MemTotal'])) {
@@ -1069,8 +1112,8 @@ function utilities_get_mysql_recommendations() {

$compare = '>=';
$passed = ($variables[$name] >= ($r['value']*$totalMem/100));
$value_display = round($variables[$name]/1024/1024,0) . "M";
$value_recommend = round($r['value']*$totalMem/100/1024/1024,0) . "M";
$value_display = round($variables[$name]/1024/1024,0) . 'M';
$value_recommend = round($r['value']*$totalMem/100/1024/1024,0) . 'M';
break;
case 'pinst':
$compare = '>=';
@@ -1285,7 +1328,6 @@ function utility_php_verify_extensions(&$extensions, $source) {
'ctype' => array('cli' => false, 'web' => false),
'date' => array('cli' => false, 'web' => false),
'filter' => array('cli' => false, 'web' => false),
'gettext' => array('cli' => false, 'web' => false),
'gd' => array('cli' => false, 'web' => false),
'gmp' => array('cli' => false, 'web' => false),
'hash' => array('cli' => false, 'web' => false),
@@ -1413,6 +1455,7 @@ function utility_php_verify_optionals(&$optionals, $source) {
if (empty($optionals)) {
$optionals = array(
'snmp' => array('web' => false, 'cli' => false),
'gettext' => array('web' => false, 'cli' => false),
'TrueType Box' => array('web' => false, 'cli' => false),
'TrueType Text' => array('web' => false, 'cli' => false),
);
@@ -169,13 +169,27 @@ function null_out_substitutions($string) {
function expand_title($host_id, $snmp_query_id, $snmp_index, $title) {
if ((strstr($title, '|')) && (!empty($host_id))) {
if (($snmp_query_id != '0') && ($snmp_index != '')) {
return substitute_snmp_query_data(null_out_substitutions(substitute_host_data($title, '|', '|', $host_id)), $host_id, $snmp_query_id, $snmp_index, read_config_option('max_data_query_field_length'));
$title = substitute_snmp_query_data(null_out_substitutions(substitute_host_data($title, '|', '|', $host_id)), $host_id, $snmp_query_id, $snmp_index, read_config_option('max_data_query_field_length'));
} else {
return null_out_substitutions(substitute_host_data($title, '|', '|', $host_id));
$title = null_out_substitutions(substitute_host_data($title, '|', '|', $host_id));
}
} else {
return null_out_substitutions($title);
$title = null_out_substitutions($title);
}

$data = array(
'host_id' => $host_id,
'snmp_query_id' => $snmp_query_id,
'snmp_index' => $snmp_index,
'title' => $title
);

$data = api_plugin_hook_function('expand_title', $data);
if (isset($data['title'])) {
$title = $data['title'];
}

return $title;
}

/* substitute_script_query_path - takes a string and substitutes all path variables contained in it
@@ -30,8 +30,26 @@
WHERE id = ?',
array(get_filter_request_var('id')));

// Prevent redirect loops
if (isset($_SERVER['HTTP_REFERER'])) {
if (strpos($_SERVER['HTTP_REFERER'], 'link.php') === false) {
$referer = sanitize_uri($_SERVER['HTTP_REFERER']);
$_SESSION['link_referer'] = $referer;
} elseif (isset($_SESSION['link_referer'])) {
$referer = sanitize_uri($_SESSION['link_referer']);
} else {
$referer = 'index.php';
}
} elseif (isset($_SESSION['link_referer'])) {
$referer = sanitize_uri($_SESSION['link_referer']);
} else {
$referer = 'index.php';
}

if (!cacti_sizeof($page)) {
print 'FATAL: Page is not defined.';
raise_message('page_not_defined');
header('Location: ' . $referer);
exit;
} else {
global $link_nav;

@@ -68,10 +86,12 @@

print '</div>';
}

bottom_footer();
} else {
print 'ERROR: Page is not authorized.';
raise_message('permission_denied');
header('Location: ' . $referer);
exit;
}

bottom_footer();
}

BIN +2 Bytes (100%) locales/LC_MESSAGES/ar-SA.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/bg-BG.mo
Binary file not shown.
BIN +33 Bytes (100%) locales/LC_MESSAGES/de-DE.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/el-GR.mo
Binary file not shown.
BIN +164 Bytes (100%) locales/LC_MESSAGES/es-ES.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/fr-FR.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/he-IL.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/hi-IN.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/it-IT.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/ja-JP.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/ko-KR.mo
Binary file not shown.
BIN -4 Bytes (100%) locales/LC_MESSAGES/nl-NL.mo
Binary file not shown.
BIN -96 Bytes (100%) locales/LC_MESSAGES/pl-PL.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/pt-BR.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/pt-PT.mo
Binary file not shown.
BIN -79 Bytes (100%) locales/LC_MESSAGES/ru-RU.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/sv-SE.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/tr-TR.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/vi-VN.mo
Binary file not shown.
BIN -347 Bytes (100%) locales/LC_MESSAGES/zh-CN.mo
Binary file not shown.
BIN +2 Bytes (100%) locales/LC_MESSAGES/zh-TW.mo
Binary file not shown.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -384,7 +384,7 @@ cactiApplSpineMaxOids OBJECT-TYPE
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The maximum number of snmp get OID's to issue per snmpbulkwalk
"The maximum number of snmp get OIDs to issue per snmpbulkwalk
request."
::= { cactiAppl 13 }

@@ -174,37 +174,12 @@ function plugins_load_temp_table() {
if ($dh !== false) {
while (($file = readdir($dh)) !== false) {
if (is_dir("$path$file") && file_exists("$path$file/setup.php") && !in_array($file, $plugins_integrated)) {
if (file_exists("$path$file/INFO")) {
$cinfo[$file] = plugin_load_info_file("$path/$file/INFO");

if (!isset($cinfo[$file]['author'])) $cinfo[$file]['author'] = __('Unknown');
if (!isset($cinfo[$file]['homepage'])) $cinfo[$file]['homepage'] = __('Not Stated');
if (isset($cinfo[$file]['webpage'])) $cinfo[$file]['homepage'] = $cinfo[$file]['webpage'];
if (!isset($cinfo[$file]['longname'])) $cinfo[$file]['longname'] = ucfirst($file);
if (!isset($cinfo[$file]['version'])) $cinfo[$file]['version'] = __('Unknown');
if (!isset($cinfo[$file]['requires'])) $cinfo[$file]['requires'] = '';

$cinfo[$file]['status'] = 0;
$info_file = "$path$file/INFO";
if (file_exists($info_file)) {
$cinfo[$file] = plugin_load_info_file($info_file);
$pluginslist[] = $file;

if (strstr($file, ' ') !== false) {
$cinfo[$file]['status'] = -3;
} elseif ($file != $cinfo[$file]['name']) {
$cinfo[$file]['status'] = -2;
} elseif (!isset($cinfo[$file]['compat']) || cacti_version_compare(CACTI_VERSION, $cinfo[$file]['compat'], '<')) {
$cinfo[$file]['status'] = -1;
}
} else {
$cinfo[$file] = array(
'name' => ucfirst($file),
'longname' => ucfirst($file),
'author' => '',
'homepage' => '',
'version' => __('Unknown'),
'compat' => '0.8',
'requires' => '',
'status' => -4
);
$cinfo[$file] = plugin_load_info_defaults($info_file, false);
}

$exists = db_fetch_cell_prepared("SELECT COUNT(*)
@@ -713,7 +713,7 @@ function sig_handler($signo) {
/* no re-index or Rechache present on this run
* in case, we have more PCOMMANDS than recaching, this has to be moved to poller_commands.php
* but then we'll have to call it each time to make sure, stats are updated */
set_config_option('stats_recache_' . $poller_id, 'RecacheTime:0.0 DevicesRecached:0');
set_config_option('stats_recache_' . $poller_id, 'Poller:' . $poller_id . ' RecacheTime:0.0 DevicesRecached:0');
}

if ($method == 'spine') {
@@ -172,7 +172,7 @@
/* take time to log performance data */
$recache = microtime(true);

$recache_stats = sprintf('Poller:%i RecacheTime:%01.4f DevicesRecached:%s', $poller_id, round($recache - $start, 4), $recached_hosts);
$recache_stats = sprintf('Poller:%s RecacheTime:%01.4f DevicesRecached:%s', $poller_id, round($recache - $start, 4), $recached_hosts);

if ($recached_hosts > 0) {
cacti_log('STATS: ' . $recache_stats, true, 'RECACHE');
@@ -78,6 +78,12 @@ function sig_handler($signo) {
$forcerun = false;
$forcerun_maint = false;

global $total_system_time, $total_user_time, $total_real_time;

$total_system_time = 0;
$total_user_time = 0;
$total_real_time = 0;

if (cacti_sizeof($parms)) {
foreach($parms as $parameter) {
if (strpos($parameter, '=')) {
@@ -118,7 +118,7 @@
/* assume a scheduled task of either 60 or 300 seconds */
define('MAX_POLLER_RUNTIME', 298);

/* let PHP only run 1 second longer than the max runtime, plus the poller needs lot's of memory */
/* let PHP only run 1 second longer than the max runtime, plus the poller needs lots of memory */
ini_set('max_execution_time', MAX_POLLER_RUNTIME + 1);

/* initialize file creation flags */
@@ -213,8 +213,8 @@ function process_poller_output_rt($rrdtool_pipe, $poller_id, $interval) {

/* 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
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);

@@ -228,7 +228,7 @@ function process_poller_output_rt($rrdtool_pipe, $poller_id, $interval) {
@chmod($rt_graph_path, 0644);
}

/* now, let's update the path to keep the RRD's updated */
/* now, let's update the path to keep the RRDs updated */
$item['rrd_path'] = $rt_graph_path;

/* cleanup the value */
@@ -536,7 +536,7 @@ function poller_edit() {
unset($fields_poller_edit['dbsslca']);
}

if ($poller['timezone'] == '' || $poller['id'] == 1) {
if ($poller['timezone'] == '') {
$poller['timezone'] = ini_get('date.timezone');
}
}
@@ -623,8 +623,6 @@ function ping_database() {
pt = <?php print $pt;?>;

$(function() {
$('#row_timezone').hide();

if (pt == 1) {
$('#row_threads').hide();
}
@@ -41,6 +41,10 @@
$debug = false;

if ($config['poller_id'] > 1 && $config['connection'] == 'online') {
if (get_request_var('action') == 'runquery') {
db_force_remote_cnn();
}

$poller_db_cnn_id = $remote_db_cnn_id;
} else {
$poller_db_cnn_id = false;
@@ -454,3 +458,23 @@ function run_remote_discovery() {

return;
}

function db_force_remote_cnn() {
global $database_default, $database_hostname, $database_username, $database_password;
global $database_port, $database_ssl, $database_ssl_key, $database_ssl_cert, $database_ssl_ca;

global $rdatabase_default, $rdatabase_hostname, $rdatabase_username, $rdatabase_password;
global $rdatabase_port, $rdatabase_ssl, $rdatabase_ssl_key, $rdatabase_ssl_cert, $rdatabase_ssl_ca;

// Connection worked, so now override the default settings so that it will always utilize the remote connection
$database_default = $rdatabase_default;
$database_hostname = $rdatabase_hostname;
$database_username = $rdatabase_username;
$database_password = $rdatabase_password;
$database_port = $rdatabase_port;
$database_ssl = $rdatabase_ssl;
$database_ssl_key = $rdatabase_ssl_key;
$database_ssl_cert = $rdatabase_ssl_cert;
$database_ssl_ca = $rdatabase_ssl_ca;
}

@@ -1,5 +1,5 @@
<interface>
<name>Get Host MIB CPU's</name>
<name>Get Host MIB CPUs</name>
<script_path>|path_php_binary| -q |path_cacti|/scripts/query_host_cpu.php</script_path>
<arg_prepend>|host_hostname| |host_id| |host_snmp_version|:|host_snmp_port|:|host_snmp_timeout|:|host_ping_retries|:|host_max_oids|:|host_snmp_community|:|host_snmp_username|:|host_snmp_password|:|host_snmp_auth_protocol|:|host_snmp_priv_passphrase|:|host_snmp_priv_protocol|:|host_snmp_context|</arg_prepend>
<arg_index>index</arg_index>
@@ -1,5 +1,5 @@
<interface>
<name>Get Host MIB CPU's</name>
<name>Get Host MIB CPUs</name>
<script_path>|path_cacti|/scripts/ss_host_cpu.php</script_path>
<script_function>ss_host_cpu</script_function>
<script_server>php</script_server>
0 rra/.htaccess 100644 → 100755
Empty file.
@@ -1,18 +1,18 @@
#!/bin/php -q
#!/usr/bin/php -q
<?php

error_reporting(0);

include_once(dirname(__FILE__) . '/../include/cli_check.php');
include_once(dirname(__FILE__) . '/../lib/snmp.php');
include_once(dirname(__FILE__) . '/../lib/ping.php');

if (!isset($called_by_script_server)) {
include_once(dirname(__FILE__) . '/../include/cli_check.php');
array_shift($_SERVER['argv']);

print call_user_func_array('ss_fping', $_SERVER['argv']);
}

include_once(dirname(__FILE__) . '/../lib/snmp.php');
include_once(dirname(__FILE__) . '/../lib/ping.php');

function ss_fping($hostname, $ping_sweeps=6, $ping_type='ICMP', $port=80) {
/* record start time */
list($micro,$seconds) = explode(' ', microtime());
@@ -95,10 +95,10 @@ function ss_host_disk($hostname, $host_id, $snmp_auth, $cmd, $arg1 = '', $arg2 =
}
}
} else {
return array();
return '';
}
} else {
return array();
return '';
}
} elseif ($cmd == 'get') {
$arg = $arg1;
@@ -0,0 +1,77 @@
#!/usr/bin/php -q
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2019 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/

error_reporting(0);

if (!isset($called_by_script_server)) {
include_once(dirname(__FILE__) . '/../include/cli_check.php');

array_shift($_SERVER['argv']);

print call_user_func_array('ss_hstats', $_SERVER['argv']);
}

function ss_hstats($host_id, $stat) {
switch ($stat) {
case 'polling_time':
$column = $stat;
break;
case 'min_time':
$column = $stat;
break;
case 'max_time':
$column = $stat;
break;
case 'cur_time':
$column = $stat;
break;
case 'avg_time':
$column = $stat;
break;
case 'uptime':
$column = 'snmp_sysUpTimeInstance';
break;
case 'failed_polls':
$column = $stat;
break;
case 'availability':
$column = $stat;
break;
default:
return '0';
}

if ($host_id > 0) {
$value = db_fetch_cell_prepared("SELECT $column
FROM host
WHERE id = ?",
array($host_id));

return ($value == '' ? 'U' : $value);
}

return '0';
}

@@ -94,8 +94,10 @@ function form_save() {

/* obtain debug information if it's set */
$debug_data = import_xml_data($xml_data, $import_as_new, $profile_id, $remove_orphans);
if(cacti_sizeof($debug_data) > 0) {
if ($debug_data !== false && cacti_sizeof($debug_data)) {
$_SESSION['import_debug_info'] = $debug_data;
} else {
raise_message(15);
}

header('Location: templates_import.php?preview=' . $preview_only);
@@ -682,48 +682,54 @@ function perm_remove() {
}

function get_permission_string(&$graph, &$policies) {
$grantStr = '';
$rejectStr = '';
$grantStr = '';
$rejectStr = '';
$reasonStr = '';
$drejectStr = '';

if (read_config_option('graph_auth_method') == 1) {
$method = 'loose';
} else {
$method = 'strong';
}

if ($graph['disabled'] == 'on' && read_user_setting('hide_disabled', false, false, get_request_var('user_id'))) {
$drejectStr .= __esc('Device:(Hide Disabled)');
}

$i = 1;
foreach($policies as $p) {
$allowed = 0;
$rejected = 0;

if ($p['policy_graphs'] == 1) {
if ($graph["user$i"] == '') {
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . 'Graph:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$grantStr .= $grantStr . ($grantStr != '' ? ', ':'') . __esc('Graph:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
} else {
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . 'Graph:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$rejectStr .= $rejectStr . ($rejectStr != '' ? ', ':'') . __esc('Graph:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
}
} elseif ($graph["user$i"] != '') {
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . 'Graph:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$grantStr .= $grantStr . ($grantStr != '' ? ', ':'') . __esc('Graph:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
} elseif ($method == 'loose') {
$rejected++;
} else {
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . 'Graph:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$rejectStr .= $rejectStr . ($rejectStr != '' ? ', ':'') . __esc('Graph:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
}
$i++;

if ($p['policy_hosts'] == 1) {
if ($graph["user$i"] == '') {
if ($method == 'loose') {
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . 'Device:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . __esc('Device:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
} else {
$allowed++;
}
} else {
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . 'Device:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . __esc('Device:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
}
} elseif ($graph["user$i"] != '') {
if ($method == 'loose') {
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . 'Device:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . __esc('Device:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
} else {
$allowed++;
}
@@ -735,16 +741,16 @@ function get_permission_string(&$graph, &$policies) {
if ($p['policy_graph_templates'] == 1) {
if ($graph["user$i"] == '') {
if ($method == 'loose') {
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . 'Template:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . __esc('Template:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
} else {
$allowed++;
}
} else {
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . 'Template:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . __esc('Template:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
}
} elseif ($graph["user$i"] != '') {
if ($method == 'loose') {
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . 'Template:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . __esc('Template:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
} else {
$allowed++;
}
@@ -755,26 +761,39 @@ function get_permission_string(&$graph, &$policies) {

if ($method != 'loose') {
if ($allowed == 2) {
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . 'Device+Template:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$grantStr = $grantStr . ($grantStr != '' ? ', ':'') . __esc('Device+Template:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
} else {
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . 'Device+Template:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . __esc('Device+Template:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
}
} elseif ($rejected == 3) {
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . 'Graph+Device+Template:(' . ucfirst($p['type']) . ($p['type'] != 'user' ? '/' . $p['name'] . ')':')');
$rejectStr = $rejectStr . ($rejectStr != '' ? ', ':'') . __esc('Graph+Device+Template:(%s%s)', ucfirst($p['type']), ($p['type'] != 'user' ? '/' . $p['name']:''));
}
}

$permStr = '';
if ($grantStr != '') {
$permStr = "<span class='accessGranted'>Granted:</span> <span class='accessGrantedItem'>" . trim($grantStr,',') . '</span>';

if ($drejectStr != '') {
$reasonStr .= ($reasonStr != '' ? ', ':'') . __esc('Restricted By: ') . $drejectStr;
}

if ($rejectStr != '') {
if ($grantStr == '') {
$permStr = "<span class='accessRestricted'>Restricted:</span> <span class='accessRestrictedItem'>" . trim($rejectStr,',') . '</span>';
if ($grantStr != '') {
$reasonStr .= ($reasonStr != '' ? ', ':'') . __esc('Granted By: ') . trim($grantStr, ',');

if ($rejectStr != '') {
$reasonStr .= ', ' . __esc('Restricted By: ') . trim($rejectStr, ',');
}

if ($drejectStr == '') {
$permStr = "<span data-tooltip='" . trim($reasonStr) . "' class='accessGranted'>" . __('Granted') . '</span>';
} else {
$permStr .= ", <span class='accessRestrictedItem'>" . trim($rejectStr,',') . '</span>';
$permStr = "<span data-tooltip='" . trim($reasonStr) . "' class='accessRestricted'>" . __('Restricted') . '</span>';
}
} elseif ($rejectStr != '') {
$reasonStr .= ($reasonStr != '' ? ', ':'') . __esc('Restricted By: ') . trim($rejectStr, ',');

$permStr = "<span data-tooltip='" . $reasonStr . "' class='accessRestricted'>" . __('Restricted') . '</span>';
} else {
$permStr = __('Unknown');
}

return $permStr;
@@ -950,7 +969,8 @@ function graph_perms_edit($tab, $header_label) {
$sql_having = 'HAVING ' . $sql_having;
}

$graphs = db_fetch_assoc("SELECT gtg.local_graph_id, h.description, gt.name AS template_name,
$graphs = db_fetch_assoc("SELECT gtg.local_graph_id, h.description,
h.disabled, h.deleted, gt.name AS template_name,
gtg.title_cache, gtg.width, gtg.height, gl.snmp_index, gl.snmp_query_id,
$sql_select
FROM graph_templates_graph AS gtg
@@ -1028,6 +1048,19 @@ function graph_perms_edit($tab, $header_label) {
);
}

?>
<script type='text/javascript'>
$(function() {
$(document).tooltip({
items: '[data-tooltip]',
content: function() {
return $(this).attr('data-tooltip');
}
});
});
</script>
<?php

/* draw the dropdown containing a list of available actions for this form */
draw_actions_dropdown($assoc_actions);