mirror of
https://github.com/Cacti/cacti.git
synced 2026-11-01 01:27:14 +09:00
* PHPStan Level 8 - Phase 1 Conversion
Reduces the real (no-baseline) PHPStan level 8 error count from ~2,724 to 425
and regenerates phpstan-baseline.neon accordingly (8,941 -> 1,921 lines).
Core type-safety changes
- lib/database.php: narrow db_fetch_row()/db_fetch_row_prepared() to return
array (was bool|array) and db_fetch_assoc()/db_fetch_assoc_prepared() to
return array (was mixed); the _prepared workers coerce the connection-failure
path to an empty array so the declared type is honest. empty()/cacti_sizeof()
checks are unaffected.
- lib/database.php: narrow $db_conn guards from is_object() to instanceof PDO in
the transaction/quote/insert-id helpers so the PDO calls resolve.
- lib/mib_cache.php: the fluent MibCache methods mib()/object()/table()/row()
now return self instead of a bare object so chained calls type-check.
Type-safety casts and guards (mechanical, behaviour-preserving)
- Cast string|false/|null builtin results feeding string parameters
(json_decode, base64_encode, trim, htmle, preg_replace, explode, etc.).
- Cast int|string / int|false values feeding int id/pid parameters.
- Guard resource|false fopen()/popen() handles before fwrite/fclose/fread, and
wrap foreach over array|false/list|false results with `?: []`.
Genuine bugs found and fixed
- cli/add_tree.php / lib/api_tree.php: site tree nodes could not be created via
the CLI - the --site-id option was never parsed, $nodeTypes had no 'site'
entry (passing null to api_tree_item_save(int $type) -> TypeError), and
api_tree_item_save() never persisted site_id. All three fixed.
- tree.php: leaves_exist() is typed : int but returned db_fetch_assoc_prepared()
(an array of rows) for a SELECT COUNT(*); now uses db_fetch_cell_prepared()
and returns the scalar count.
- lib/mib_cache.php: $entries_per_object was a float (division / ceil) used as
an array key (PHP 8.1 implicit float-to-int key deprecation); now cast to int.
Config
- .phpstan.neon: add notIdentical.alwaysTrue and booleanAnd.alwaysFalse to the
existing always-true/false ignore family (same "PHPStan gets confused"
dynamic-constant cause already covered by identical.alwaysTrue,
notEqual.alwaysTrue, booleanAnd.leftAlwaysTrue, etc.).
- phpstan-baseline.neon: regenerated; the remaining 425 entries are the
untouched long tail for Phase 2.
* Remove redundant @phpstan-ignore comments
Follow-up cleanup for the level 8 Phase 1 work. Removes 14 inline
@phpstan-ignore comments that no longer suppress any reported error:
- cli/repair_database.php: `@phpstan-ignore booleanAnd.alwaysFalse` is now
covered by the global booleanAnd.alwaysFalse ignore added to .phpstan.neon.
- 13 others (host.php, include/global.php, include/session.php,
lib/api_automation.php x2, lib/functions.php x2, lib/html_utility.php x2,
lib/installer.php, lib/package.php, lib/reports.php, lib/rrd.php) no longer
match any reported error after the type-safety fixes (e.g. the
db_fetch_row_prepared() return-type narrowing removed the offset-assign
errors the api_automation ignores were suppressing).
Verified with reportUnmatchedIgnoredErrors enabled: 0 unmatched ignores
remain and the full level 8 run still reports 0 errors.
* ci: satisfy validator ratchet and refresh security sink baselines
- lib/api_tree.php: give the new tree-item site_id a real numeric
constraint ('^[-0-9]+$', matching html_reports.php) instead of an
empty regex, so the validator constraint ratchet passes without
bumping its baseline.
- tests/security/baselines: refresh the three sink/hotspot signatures
whose code text changed from the (string) casts added in this branch
(lib/poller.php setsid, cli/rrdresize.php json_encode, lib/import.php
simplexml_load_string).
* ci(js): allow DOMPurify 3.4.16 and update sync_js pin test
The dependabot bump (#8134) moved package.json/package-lock.json to
DOMPurify 3.4.16 on develop but left tests/js/sync_js.test.mjs pinned to
3.4.15, so the PR merge commit fails the 'DOMPurify is pinned' contract.
Bring package.json/package-lock.json to 3.4.16 (matching develop) and
update the pin test to expect 3.4.16.
* test: update sql.php null-handling assertion for the (string) cast
This branch changed scripts/sql.php from trim(\ ?? '') to
trim((string) \) (the phpstan-safe form that coerces both null and
false from shell_exec()). Update SqlScriptsTest's null-return assertion
to match the new cast instead of the removed '?? ''.
* fix: address Copilot review - ownership IDs, fopen guards, mib_cache bound
- chown()/chgrp(): pass integer UID/GID from fileowner()/filegroup()
(guarding the false lookup) instead of string-casting them, which made
them resolve account/group names like '1001' and fail. Covers
lib/api_device.php, lib/boost.php and poller_maintenance.php (x2).
- fopen() failure now short-circuits instead of reporting success:
lib/package.php returns false, lib/clog_webapi.php and utilities.php
render an error, and snmpagent_mibcachechild.php skips the cache write
and sentinel unlink so a concurrent writer's lock is preserved.
- lib/mib_cache.php: keep the float quotient as the loop bound and cast
only the array offset, so a non-even entries/columns split no longer
truncates the loop and drops a cached row.
* revert: keep db_fetch_* returning false on error; baseline Level 8 instead
Per review, restoring the intentional fail-safe: db_fetch_row[_prepared]()
return bool|array and db_fetch_assoc[_prepared]() return mixed again, so a
genuine SQL error (not just a missing connection) is signalled as false and
the === false checks in cdef_is_in_use(), boost_process_* and aggregate.php
work as before. Dropped the is_array() ? : [] coercion.
Level 8 stays green by regenerating phpstan-baseline.neon to capture the
re-introduced bool|array/mixed call-site errors (the ~1,850 the narrowing
had eliminated). Tightening those callers to drop them from the baseline is
Phase 2 work.
---------
Co-authored-by: TheWitness <copilot@users.noreply.github.com>
477 lines
15 KiB
PHP
477 lines
15 KiB
PHP
<?php
|
|
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2026 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/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
class MibCache {
|
|
private mixed $active_mib = '';
|
|
private mixed $active_object = '';
|
|
private string $active_table = '';
|
|
private string $active_table_entry = '';
|
|
private array $cache__tables = [];
|
|
private array $cache__tables_columns = [];
|
|
|
|
public function __construct(string $mib = 'CACTI-MIB') {
|
|
$this->active_mib = $mib;
|
|
}
|
|
|
|
public function __destruct() {
|
|
}
|
|
|
|
public function uninstall() : mixed {
|
|
// avoid that our default mib will be dropped by some plugin developer
|
|
if ($this->active_mib == 'CACTI-MIB') {
|
|
return false;
|
|
} else {
|
|
db_execute_prepared('DELETE FROM snmpagent_cache WHERE `mib` = ?', [$this->active_mib]);
|
|
db_execute_prepared('DELETE FROM snmpagent_cache_notifications WHERE `mib` = ?', [$this->active_mib]);
|
|
db_execute_prepared('DELETE FROM snmpagent_cache_textual_conventions WHERE `mib` = ?', [$this->active_mib]);
|
|
db_execute_prepared('DELETE FROM snmpagent_mibs WHERE `name` = ?', [$this->active_mib]);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public function install(string $path, bool $replace = false, string $mib_name = 'optional') : mixed {
|
|
include_once(CACTI_PATH_INCLUDE . '/vendor/phpsnmp/mib_parser.php');
|
|
|
|
$mp = new MibParser();
|
|
$mp->add_mib($path, $mib_name);
|
|
$mp->generate();
|
|
|
|
if (isset($mp->mib) && isset($mp->oids) && $mp->mib) {
|
|
// check if this mib has already been installed
|
|
$existing = db_fetch_cell_prepared('SELECT 1 FROM snmpagent_mibs WHERE `name` = ?', [$mp->mib]);
|
|
|
|
if ($existing) {
|
|
if ($replace == false) {
|
|
unset($mp->oids);
|
|
unset($mp->mib);
|
|
|
|
return false;
|
|
} else {
|
|
$this->uninstall();
|
|
}
|
|
}
|
|
db_execute_prepared('INSERT INTO snmpagent_mibs SET `id` = 0, `name` = ?, `file` = ?', [$mp->mib, $path]);
|
|
|
|
foreach ($mp->oids as $object_name => $object_params) {
|
|
if ($object_params['otype'] != 'TEXTUAL-CONVENTION') {
|
|
db_execute_prepared('INSERT IGNORE INTO `snmpagent_cache`
|
|
(`oid`, `name`, `mib`, `type`, `otype`, `kind`, `max-access`, `description`)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
[$object_params['oid'], $object_name, $object_params['mib'], $object_params['syntax'],
|
|
$object_params['otype'], $object_params['kind'], $object_params['max-access'],
|
|
str_replace("\r\n", '<br>', trim($object_params['description']))]);
|
|
|
|
if ($object_params['otype'] == 'NOTIFICATION-TYPE') {
|
|
foreach ($object_params['objects'] as $notification_object_index => $notification_object) {
|
|
db_execute_prepared('INSERT INTO `snmpagent_cache_notifications`
|
|
(`name`, `mib`, `attribute`, `sequence_id`)
|
|
VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE `sequence_id` = VALUES(`sequence_id`)',
|
|
[$object_name, $object_params['mib'], $notification_object, $notification_object_index]);
|
|
}
|
|
}
|
|
} else {
|
|
db_execute_prepared('INSERT INTO `snmpagent_cache_textual_conventions`
|
|
(`name`, `mib`, `type`, `description`)
|
|
VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE `description` = VALUES(`description`)',
|
|
[$object_name, $object_params['mib'], $object_params['syntax'], nl2br($object_params['description'])]);
|
|
}
|
|
}
|
|
|
|
unset($mp->oids);
|
|
unset($mp->mib);
|
|
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function mib(string $mib) : self {
|
|
$this->active_mib = $mib;
|
|
$this->active_object = '';
|
|
$this->active_table = '';
|
|
$this->active_table_entry = '';
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function object(string $object) : self {
|
|
$this->active_object = $object;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function table(string $table) : self {
|
|
if ($this->active_table != $table) {
|
|
if (!isset($this->cache__tables[$this->active_mib][$table])) {
|
|
$oid_table = db_fetch_cell_prepared('SELECT oid
|
|
FROM `snmpagent_cache`
|
|
WHERE `mib` = ?
|
|
AND `name` = ?
|
|
AND `type` = "SEQUENCE OF"',
|
|
[$this->active_mib, $table]);
|
|
|
|
if ($oid_table) {
|
|
// cache table oid and columns
|
|
$this->cache__tables[$this->active_mib][$table] = $oid_table;
|
|
$this->active_table = $table;
|
|
$this->cache__tables_columns[$this->active_mib][$table] = $this->columns();
|
|
$this->active_table_entry = '';
|
|
|
|
return $this;
|
|
} else {
|
|
// MIB table does not exist
|
|
$this->active_table = '';
|
|
$this->active_table_entry = '';
|
|
|
|
throw new Exception('MIB table does not exist');
|
|
}
|
|
} else {
|
|
// table exists and has already been cached
|
|
$this->active_table = $table;
|
|
$this->active_table_entry = '';
|
|
|
|
return $this;
|
|
}
|
|
} else {
|
|
// no changes necessary
|
|
return $this;
|
|
}
|
|
}
|
|
|
|
public function row(mixed $index) : self {
|
|
// limited to one single $index so far
|
|
$this->active_table_entry = $index;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function gettype() : void {
|
|
}
|
|
|
|
public function set(mixed $value) : mixed {
|
|
return db_execute_prepared('UPDATE `snmpagent_cache`
|
|
SET `value` = ?
|
|
WHERE `mib` = ?
|
|
AND `name` = ?',
|
|
[$value, $this->active_mib, $this->active_object]);
|
|
}
|
|
|
|
public function get() : mixed {
|
|
return db_fetch_row_prepared('SELECT *
|
|
FROM snmpagent_cache
|
|
WHERE name = ?
|
|
AND mib = ?',
|
|
[$this->active_object, $this->active_mib]);
|
|
}
|
|
|
|
public function count() : mixed {
|
|
return db_execute_prepared('UPDATE snmpagent_cache
|
|
SET `value` = CASE
|
|
WHEN `type`="Counter32" AND `value`= 4294967295 THEN 0
|
|
WHEN `type`="Counter64" AND `value`= 18446744073709551615 THEN 0
|
|
ELSE `value`+1 END
|
|
WHERE `mib` = ? AND `name` = ?',
|
|
[$this->active_mib, $this->active_object]);
|
|
}
|
|
|
|
public function insert(array $values) : bool {
|
|
$oid_entry = $this->exists();
|
|
|
|
if ($oid_entry == false) {
|
|
$columns = $this->cache__tables_columns[$this->active_mib][$this->active_table];
|
|
|
|
if ($columns && cacti_sizeof($columns) > 0) {
|
|
foreach ($columns as $column_params) {
|
|
$column_params['oid'] .= '.' . $this->active_table_entry;
|
|
$column_params['otype'] = 'DATA';
|
|
|
|
if (isset($values[$column_params['name']])) {
|
|
$column_params['value'] = $values[$column_params['name']];
|
|
}
|
|
|
|
db_execute_prepared('INSERT INTO `snmpagent_cache`
|
|
(`oid`, `name`, `mib`, `type`, `otype`, `kind`, `max-access`, `value`)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `mib`=VALUES(`mib`),
|
|
`type`=VALUES(`type`), `otype`=VALUES(`otype`), `kind`=VALUES(`kind`),
|
|
`max-access`=VALUES(`max-access`), `value`=VALUES(`value`)',
|
|
[$column_params['oid'], $column_params['name'], $column_params['mib'],
|
|
$column_params['type'], $column_params['otype'], 'Column Data',
|
|
$column_params['max-access'], trim($column_params['value'])]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function select(mixed $column = false) : mixed {
|
|
$result = [];
|
|
|
|
if ($this->active_table_entry) {
|
|
// focus on a dedicated MIB table row only
|
|
$oid_entry = $this->exists();
|
|
|
|
if ($oid_entry !== false) {
|
|
if ($column == false) {
|
|
// fetch the whole row
|
|
$filter = $oid_entry . '.%.' . $this->active_table_entry;
|
|
|
|
$entries = db_fetch_assoc_prepared('SELECT name, value
|
|
FROM snmpagent_cache
|
|
WHERE oid LIKE ?
|
|
GROUP BY name
|
|
ORDER BY oid',
|
|
[$filter]);
|
|
|
|
if ($entries && cacti_sizeof($entries) > 0) {
|
|
foreach ($entries as $entry) {
|
|
$result[$entry['name']] = $entry['value'];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
} elseif (is_string($column)) {
|
|
// fetch only the value of a given column
|
|
$filter = $oid_entry . '.%.' . $this->active_table_entry;
|
|
|
|
return db_fetch_cell_prepared('SELECT value
|
|
FROM snmpagent_cache
|
|
WHERE name = ?
|
|
AND oid LIKE ?
|
|
LIMIT 1',
|
|
[$column, $filter]);
|
|
} elseif (is_array($column) && cacti_sizeof($column) > 0) {
|
|
$filter = $oid_entry . '.%.' . $this->active_table_entry;
|
|
|
|
// fetch all values of specific columns given for that MIB table row
|
|
/* The names are bound rather than pasted between quotes. The
|
|
caller passes them, and a quote in one used to close the
|
|
string and leave the rest as SQL. */
|
|
$placeholders = implode(',', array_fill(0, cacti_sizeof($column), '?'));
|
|
|
|
$entries = db_fetch_assoc_prepared("SELECT name, value
|
|
FROM snmpagent_cache
|
|
WHERE name IN ($placeholders)
|
|
AND oid LIKE ?
|
|
GROUP BY name
|
|
ORDER BY oid",
|
|
array_merge(array_values($column), [$filter]));
|
|
|
|
if ($entries && cacti_sizeof($entries) > 0) {
|
|
foreach ($entries as $entry) {
|
|
$result[$entry['name']] = $entry['value'];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// query the whole MIB table
|
|
$oid_entry = $this->cache__tables[$this->active_mib][$this->active_table] . '.1';
|
|
|
|
if ($column == false) {
|
|
// fetch all rows
|
|
$columns = $this->cache__tables_columns[$this->active_mib][$this->active_table];
|
|
$num_columns = cacti_sizeof($columns);
|
|
$filter = $oid_entry . '.%.%';
|
|
|
|
$entries = db_fetch_assoc_prepared('SELECT name, value
|
|
FROM snmpagent_cache
|
|
WHERE oid LIKE ?
|
|
ORDER BY oid',
|
|
[$filter]);
|
|
|
|
if ($num_columns && $entries && cacti_sizeof($entries)) {
|
|
$num_entries = cacti_sizeof($entries);
|
|
$entries_per_object = $num_entries / $num_columns;
|
|
|
|
for ($i = 0; $i < $entries_per_object; $i++) {
|
|
$result[$i] = [];
|
|
|
|
for ($j = 0; $j < $num_columns; $j++) {
|
|
$index = (int) ($i + $j * $entries_per_object);
|
|
$result[$i][$entries[$index]['name']] = $entries[$index]['value'];
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
} else {
|
|
return $entries;
|
|
}
|
|
} elseif (is_string($column)) {
|
|
// fetch only the values of one single column
|
|
$filter = $oid_entry . '.%.%';
|
|
|
|
/* The alias is an identifier and cannot be bound, so confine it
|
|
to the characters one may hold. It was pasted between quotes
|
|
before, where a quote in the name ended the alias. */
|
|
/* The helper's default is 'id', which would quietly rename the
|
|
returned key to a real column name when the input strips to
|
|
nothing. Ask for an empty default and refuse instead. */
|
|
$alias = sanitize_sql_column($column, '');
|
|
|
|
if ($alias === '') {
|
|
return [];
|
|
}
|
|
|
|
return db_fetch_assoc_prepared('SELECT value AS `' . $alias . '`
|
|
FROM snmpagent_cache
|
|
WHERE name = ?
|
|
AND oid LIKE ?
|
|
ORDER BY oid',
|
|
[$column, $filter]);
|
|
} elseif (is_array($column) && cacti_sizeof($column) > 0) {
|
|
// fetch values of specific columns given
|
|
$filter = $oid_entry . '.%.%';
|
|
|
|
$placeholders = implode(',', array_fill(0, cacti_sizeof($column), '?'));
|
|
|
|
$entries = db_fetch_assoc_prepared("SELECT name, value
|
|
FROM snmpagent_cache
|
|
WHERE name IN ($placeholders)
|
|
AND oid LIKE ?
|
|
ORDER BY oid", array_merge(array_values($column), [$filter]));
|
|
|
|
if (cacti_sizeof($entries)) {
|
|
$num_objects = cacti_sizeof($column);
|
|
$num_entries = cacti_sizeof($entries);
|
|
$entries_per_object = (int) ceil($num_entries / $num_objects);
|
|
|
|
for ($i = 0; $i < $entries_per_object; $i++) {
|
|
$result[$i] = [];
|
|
|
|
for ($j = 0; $j < $num_objects; $j++) {
|
|
$index = (int) ($i + ($j * $entries_per_object));
|
|
$result[$i][$entries[$index]['name']] = $entries[$index]['value'];
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
} else {
|
|
return $entries;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function delete() : bool {
|
|
$oid_entry = $this->exists();
|
|
|
|
if ($oid_entry !== false) {
|
|
// get list of columns for this mib table
|
|
$columns = $this->cache__tables_columns[$this->active_mib][$this->active_table];
|
|
|
|
if ($columns && cacti_sizeof($columns) > 0) {
|
|
foreach ($columns as $column_params) {
|
|
$column_params['oid'] .= '.' . $this->active_table_entry;
|
|
db_execute_prepared('DELETE FROM `snmpagent_cache` WHERE `oid` = ?', [$column_params['oid']]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function update(array $values) : bool {
|
|
$oid_entry = $this->exists();
|
|
|
|
if ($oid_entry !== false) {
|
|
$columns = $this->cache__tables_columns[$this->active_mib][$this->active_table];
|
|
|
|
if (cacti_sizeof($columns) > 0) {
|
|
$sql = [];
|
|
|
|
foreach ($columns as $column_params) {
|
|
$column_params['oid'] .= '.' . $this->active_table_entry;
|
|
|
|
if (isset($values[$column_params['name']])) {
|
|
$sql[] = '(' . db_qstr($column_params['name']) . ', ' . db_qstr($values[$column_params['name']]) . ', ' . db_qstr($column_params['oid']) . ')';
|
|
}
|
|
}
|
|
|
|
if (cacti_sizeof($sql)) {
|
|
db_execute('INSERT INTO `snmpagent_cache`
|
|
(name, value, oid)
|
|
VALUES ' . implode(', ', $sql) . '
|
|
ON DUPLICATE KEY UPDATE value=VALUES(value)');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function replace(array $values) : bool {
|
|
$this->delete();
|
|
|
|
return $this->insert($values);
|
|
}
|
|
|
|
public function truncate() : bool {
|
|
$oid_entry = $this->cache__tables[$this->active_mib][$this->active_table] . '.1.%';
|
|
db_execute_prepared('DELETE FROM `snmpagent_cache`
|
|
WHERE `mib` = ?
|
|
AND `otype` = "DATA"
|
|
AND `oid` LIKE ?',
|
|
[$this->active_mib, $oid_entry]);
|
|
|
|
return true;
|
|
}
|
|
|
|
public function columns() : mixed {
|
|
/* As defined by SMI the OID value assigned to the row must be the same as the OID value assigned to the table containing
|
|
the row with addition of a single value of one. */
|
|
$filter = $this->cache__tables[$this->active_mib][$this->active_table] . '.1.%';
|
|
|
|
return db_fetch_assoc_prepared('SELECT *
|
|
FROM `snmpagent_cache`
|
|
WHERE `oid` LIKE ?
|
|
GROUP BY name
|
|
ORDER BY oid',
|
|
[$filter]);
|
|
}
|
|
|
|
private function exists() : bool {
|
|
$oid_entry = $this->cache__tables[$this->active_mib][$this->active_table] . '.1';
|
|
|
|
// check if entry exists
|
|
$exists = db_fetch_cell_prepared('SELECT 1 FROM `snmpagent_cache` WHERE `oid` = ?',
|
|
[$oid_entry . '.1.' . $this->active_table_entry]);
|
|
|
|
return ($exists) ? $oid_entry : false;
|
|
}
|
|
}
|