Добавлен новый функционал в mplib.
--- /dev/null
+<?php
+
+class SnmpdPassthroughAgent
+{
+ protected $BaseOid;
+ public $OidTree = [];
+ protected $lastset = [];
+ protected $callcounter = 0;
+ protected $idlecounter = 0;
+
+ public function __construct($baseoid = '.')
+ {
+ $this->BaseOid = $baseoid;
+ stream_set_blocking(STDIN, FALSE);
+
+ }
+
+ public function CreateTable($TableOid)
+ {
+
+ }
+
+ public function AddOID($suffixoid, $type, $oidvalue = NULL, $rw = FALSE)
+ {
+ // проверка на существование
+ if (isset($this->OidTree[$suffixoid]))
+ {
+ return FALSE;
+ }
+ if ($type != 'integer' && $type != 'gauge' && $type != 'counter' && $type != 'timeticks' && $type != 'ipaddress' && $type != 'objectid' && $type != 'string')
+ {
+ return FALSE;
+ }
+ //вставка
+ $this->OidTree[$suffixoid] = NULL;
+ ksort($this->OidTree, SORT_NATURAL);
+ $this->OidTree[$suffixoid]['type'] = $type;
+ $this->OidTree[$suffixoid]['rw'] = (bool)$rw;
+ $this->OidTree[$suffixoid]['value'] = NULL;
+ $this->OidTree[$suffixoid]['nextoid'] = NULL;
+
+
+ $this->UpdateNextOid();
+ if (!is_null($oidvalue))
+ {
+ $this->SetOidVal($suffixoid, $oidvalue);
+ }
+ return TRUE;
+ }
+
+ public function SetRWOid($suffixoid)
+ {
+ // проверка на существование
+ if (!isset($this->OidTree[$suffixoid]))
+ {
+ return FALSE;
+ }
+ $this->OidTree[$suffixoid]['rw'] = TRUE;
+ return TRUE;
+ }
+
+ public function SetROOid($suffixoid)
+ {
+ // проверка на существование
+ if (!isset($this->OidTree[$suffixoid]))
+ {
+ return FALSE;
+ }
+ $this->OidTree[$suffixoid]['rw'] = FALSE;
+ return TRUE;
+ }
+
+ protected function UpdateNextOid()
+ {
+ //обновление nextoid
+ $oid_pointers = array_keys($this->OidTree);
+ foreach ($oid_pointers as $oid_index => $oid_pointer)
+ {
+ if (isset($oid_pointers[$oid_index + 1]))
+ {
+ $this->OidTree[$oid_pointer]['nextoid'] = $oid_pointers[$oid_index + 1];
+ }
+ else
+ {
+ $this->OidTree[$oid_pointer]['nextoid'] = FALSE;
+ }
+ }
+ }
+
+ public function DelOID($suffixoid)
+ {
+ $oid_pointers = array_keys($this->OidTree);
+ foreach ($oid_pointers as $oid_pointer)
+ {
+ if (preg_match('/^'.preg_quote($suffixoid).'/', $oid_pointer))
+ {
+ unset($this->OidTree[$oid_pointer]);
+ }
+ }
+ $this->UpdateNextOid();
+ }
+
+ public function GetOidVal($suffixoid)
+ {
+ if (!isset($this->OidTree[$suffixoid]))
+ {
+ return FALSE;
+ }
+
+ return $this->OidTree[$suffixoid]['value'];
+ }
+
+ public function SetOidVal($suffixoid, $val)
+ {
+ if (!isset($this->OidTree[$suffixoid]))
+ {
+ return FALSE;
+ }
+ if ($this->OidTree[$suffixoid]['type'] == 'integer' || $this->OidTree[$suffixoid]['type'] == 'counter' || $this->OidTree[$suffixoid]['type'] == 'timeticks')
+ {
+ $this->OidTree[$suffixoid]['value'] = (int) $val;
+ }
+ elseif($this->OidTree[$suffixoid]['type'] == 'gauge')
+ {
+ $this->OidTree[$suffixoid]['value'] = (float) $val;
+ }
+ else
+ {
+ $this->OidTree[$suffixoid]['value'] = (string) $val;
+ }
+ return TRUE;
+ }
+
+ protected function SnmpGet($oid)
+ {
+ $oidsuffix = $this->GetOidSuffix($oid);
+ if (isset($this->OidTree[$oidsuffix]))
+ {
+ $retval = $this->OidTree[$oidsuffix];
+ $retval['oid'] = $oid;
+
+ return $retval;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ protected function SnmpGetNext($oid)
+ {
+ $oidsuffix = $this->GetOidSuffix($oid);
+ if ($oidsuffix == "")
+ {
+ $retval = $this->OidTree[array_key_first($this->OidTree)];
+ $retval['oid'] = $this->BaseOid.'.'.array_key_first($this->OidTree);
+ return $retval;
+ }
+ $keys = array_keys($this->OidTree);
+
+ if (array_key_exists($oidsuffix, $this->OidTree))
+ {
+ if ($this->OidTree[$oidsuffix]['nextoid'] === FALSE)
+ {
+ return FALSE;
+ }
+ $retval = $this->OidTree[$this->OidTree[$oidsuffix]['nextoid']];
+ $retval['oid'] = $this->BaseOid.'.'.$this->OidTree[$oidsuffix]['nextoid'];
+ return $retval;
+ }
+ foreach ($keys as $key)
+ {
+ if (preg_match('/^'.preg_quote($oidsuffix.'.').'/', $key,$M))
+ {
+ $retval = $this->OidTree[$key];
+ $retval['oid'] = $this->BaseOid.'.'.$key;
+ return $retval;
+ }
+ }
+ return FALSE;
+ }
+
+ protected function SnmpSet($oid)
+ {
+ $oidsuffix = $this->GetOidSuffix($oid);
+ $value = $this->ReadSTDIN(10);
+ $value = explode(" ", $value, 2);
+ if (!isset($this->OidTree[$oidsuffix]))
+ {
+ return "not-writable";
+ }
+ if (!$this->OidTree[$oidsuffix]['rw'])
+ {
+ return "not-writable";
+ }
+ if ($this->OidTree[$oidsuffix]['type'] !== $value[0])
+ {
+ return "wrong-type";
+ }
+ preg_match('/^\"(.*)\"$|(.*)/', $value[1], $matches);
+ if (isset($matches[2]))
+ {
+ $fval = $matches[2];
+ }
+ else
+ {
+ $fval = $matches[1];
+ }
+ $this->SetOidVal($oidsuffix, $fval);
+ $this->lastset[][$oidsuffix] = $this->GetOidVal($oidsuffix);
+ return "DONE";
+
+ }
+ public function GetLastSet()
+ {
+ $retval = $this->lastset;
+ $this->lastset = [];
+ return $retval;
+ }
+
+ public function GetOidSuffix($oid)
+ {
+ //вычленение суффиксной части oid
+ if ($this->BaseOid == $oid)
+ {
+ return "";
+ }
+ return substr(str_replace($this->BaseOid, '', $oid), 1);
+ }
+
+ protected function Ping()
+ {
+ return 'PONG';
+ }
+
+ protected function ParseQuery($action)
+ {
+ switch ($action)
+ {
+ case 'get':
+ $oid = $this->ReadSTDIN(10);
+ return $this->SnmpGet($oid);
+ break;
+ case 'getnext':
+ $oid = $this->ReadSTDIN(10);
+ return $this->SnmpGetNext($oid);
+ break;
+ case 'set':
+ $oid = $this->ReadSTDIN(10);
+ return $this->SnmpSet($oid);
+ break;
+ case 'PING':
+ return $this->Ping();
+ break;
+
+ default:
+ return NULL;
+ break;
+ }
+
+ }
+
+ protected function ResponceQuery($result)
+ {
+ if ($result === FALSE)
+ {
+ echo "NONE\n";
+ return;
+ }
+ if ($result === NULL)
+ {
+ return;
+ }
+
+ if (is_array($result))
+ {
+ echo $result['oid']."\n";
+ echo $result['type']."\n";
+ echo $result['value']."\n";
+ return;
+ }
+ echo $result, "\n";
+ return;
+ }
+
+ protected function ReadSTDIN($timeout = 2)
+ {
+ $starttime = time();
+ $chars = '';
+ while (time() - $starttime < $timeout)
+ {
+ $line = rtrim(fgets(STDIN));
+ if ($line == '')
+ {
+ if ($this->idlecounter > 4)
+ {
+ $this->idlecounter = 5;
+ usleep(200000);
+ }
+ elseif ($this->idlecounter < 4 && $this->idlecounter > 1)
+ {
+ usleep(10000);
+ }
+
+ }
+ else
+ {
+ $this->idlecounter = 0;
+ return $line;
+ }
+ }
+ $this->idlecounter++;
+
+
+ return NULL;
+ }
+ public function SnmpWaitQuery()
+ {
+ $action = $this->ReadSTDIN(1);
+ $this->ResponceQuery($this->ParseQuery($action));
+ }
+
+}
--- /dev/null
+<?php\r
+\r
+/*\r
+ * VERSION 2.1.1b\r
+ */\r
+define('MPRole_PARENT', 0);\r
+define('MPRole_CHILD', 1);\r
+define('MPRole_ERROR', -1);\r
+\r
+class Daemon\r
+{\r
+ private static $unique_flag = FALSE;\r
+ private static $pidfilename;\r
+ \r
+ public static function shutdown()\r
+ {\r
+ if (self::$unique_flag)\r
+ {\r
+ @unlink(static::$pidfilename);\r
+ }\r
+ \r
+ }\r
+\r
+ public static function daemonize()\r
+ {\r
+ $pid = pcntl_fork();\r
+ if ($pid == -1)\r
+ {\r
+ return FALSE;\r
+ }\r
+ elseif ($pid > 0)\r
+ {\r
+ exit;\r
+ }\r
+ umask(0);\r
+ chdir('/');\r
+ if (posix_setsid() == -1)\r
+ {\r
+ return FALSE;\r
+ }\r
+ \r
+ fclose(STDIN);\r
+ fclose(STDOUT);\r
+ fclose(STDERR);\r
+ $GLOBALS['STDIN'] = fopen('/dev/null', 'r');\r
+ $GLOBALS['STDOUT']= fopen('/dev/null', 'w');\r
+ $GLOBALS['STDERR'] = fopen('/dev/null', 'w');\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ public static function is_unique($pidfilename)\r
+ {\r
+ $mypid = posix_getpid();\r
+ if (is_readable($pidfilename))\r
+ {\r
+ $pid = (int) rtrim(file_get_contents($pidfilename));\r
+ if ($pid == $mypid)\r
+ {\r
+ return TRUE;\r
+ }\r
+ if ($pid > 0 && posix_kill($pid, 0))\r
+ {\r
+ return FALSE;\r
+ }\r
+ }\r
+ return TRUE;\r
+\r
+ }\r
+ \r
+ public static function no_unique($pidfilename)\r
+ {\r
+ if (!@unlink($pidfilename))\r
+ {\r
+ return FALSE;\r
+ }\r
+ else\r
+ {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ public static function do_unique($pidfilename)\r
+ {\r
+ if (!self::is_unique($pidfilename))\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ $mypid = posix_getpid();\r
+ if (!@file_put_contents($pidfilename, $mypid.PHP_EOL))\r
+ {\r
+ return FALSE;\r
+ }\r
+ register_shutdown_function(['self','shutdown']);\r
+ return TRUE;\r
+ }\r
+} \r
+\r
+abstract class Children \r
+{\r
+ protected $PIPE;\r
+ protected $ROLE;\r
+ protected static $CHILDREN;\r
+ protected $CHILD;\r
+ protected $PARENT;\r
+ protected $IPCRXBUFFER = [];\r
+\r
+\r
+ public function __construct($data = NULL)\r
+ {\r
+ self::set_sig_handlers();\r
+ $this->create_child();\r
+ switch ($this->ROLE)\r
+ {\r
+ case MPRole_ERROR:\r
+ return FALSE;\r
+ case MPRole_PARENT:\r
+ return TRUE;\r
+ case MPRole_CHILD:\r
+ $this->ChildBody($data);\r
+ exit();\r
+ }\r
+ \r
+ }\r
+ \r
+ public function __destruct()\r
+ {\r
+ if ($this->ROLE == MPRole_PARENT)\r
+ {\r
+ posix_kill($this->CHILD, SIGTERM);\r
+ }\r
+ }\r
+\r
+ abstract protected function ChildBody($data);\r
+\r
+ static function set_sig_handlers()\r
+ {\r
+ pcntl_signal(SIGCHLD, [__CLASS__, 'handler_sigchld']);\r
+ }\r
+ \r
+ public function SendUnixSignal($sig)\r
+ {\r
+ return posix_kill($this->CHILD, $sig);\r
+ }\r
+ \r
+ public function IsAlive()\r
+ {\r
+ if ($this->ROLE == MPRole_CHILD)\r
+ {\r
+ return TRUE;\r
+ }\r
+ if (isset(self::$CHILDREN[$this->CHILD]))\r
+ {\r
+ return TRUE;\r
+ }\r
+ else\r
+ {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ public static function handler_sigchld()\r
+ { \r
+ $pid = pcntl_waitpid(0, $status, WNOHANG);\r
+ if($pid > 0 && isset(self::$CHILDREN[$pid]))\r
+ {\r
+ unset(self::$CHILDREN[$pid]);\r
+ }\r
+ }\r
+\r
+ protected function create_child()\r
+ {\r
+ $sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);\r
+ stream_set_blocking ($sockets[0] , 0);\r
+ stream_set_blocking ($sockets[1] , 0);\r
+ $pid = pcntl_fork();\r
+ if ($pid == -1)\r
+ {\r
+ $this->ROLE = MPRole_ERROR;\r
+ return FALSE;\r
+ }\r
+ elseif ($pid > 0)\r
+ {\r
+ // код для родителя\r
+ $this->CHILD = $pid;\r
+ self::$CHILDREN[$pid] = $pid;\r
+ $this->PARENT = FALSE;\r
+ $this->ROLE = MPRole_PARENT;\r
+ $this->PIPE = &$sockets[0];\r
+ unset($sockets);\r
+ usleep(5000);\r
+ }\r
+ elseif ($pid == 0)\r
+ {\r
+ // код для ребёнка\r
+ $this->CHILD = FALSE;\r
+ $this->PARENT = posix_getppid();\r
+ $this->ROLE = MPRole_CHILD;\r
+ $this->PIPE = &$sockets[1];\r
+ unset($sockets);\r
+ }\r
+ return TRUE;\r
+ }\r
+ \r
+ public function SendEvent($eventname, $data)\r
+ {\r
+ if (!is_resource($this->PIPE))\r
+ {\r
+ return FALSE;\r
+ }\r
+ $eventpack = base64_encode($eventname).chr(255).chr(0).chr(255).base64_encode(serialize($data)).chr(0).chr(15).chr(240).chr(255);\r
+ \r
+ $res = @stream_socket_sendto($this->PIPE, $eventpack); \r
+ if ($res == -1)\r
+ {\r
+ return TRUE;\r
+ }\r
+ else\r
+ {\r
+ return FALSE;\r
+ }\r
+ }\r
+ \r
+ public function WaitEvent($wait = TRUE)\r
+ {\r
+ if (count($this->IPCRXBUFFER) == 0)\r
+ {\r
+ if (!is_resource($this->PIPE))\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ $r = [$this->PIPE];\r
+ if ($wait)\r
+ {\r
+ while (stream_select($r, $w, $x, 0) == 0)\r
+ {\r
+ usleep(10000);\r
+ $r = [$this->PIPE];\r
+ }\r
+ }\r
+ elseif (stream_select($r, $w, $x, 0) == 0)\r
+ {\r
+ return NULL;\r
+ }\r
+ $ipc_msg = '';\r
+ while (substr($ipc_msg , -4) != chr(0).chr(15).chr(240).chr(255))\r
+ {\r
+ $rcv_buf = stream_socket_recvfrom($this->PIPE, 1500);\r
+ if ($rcv_buf == '')\r
+ {\r
+ return NULL;\r
+ }\r
+ $ipc_msg .= $rcv_buf;\r
+ }\r
+ $ipc_msg = explode(chr(0).chr(15).chr(240).chr(255), $ipc_msg);\r
+ array_pop($ipc_msg);\r
+ $this->IPCRXBUFFER = array_merge($this->IPCRXBUFFER, $ipc_msg);\r
+ }\r
+ $ipc_msg = array_shift($this->IPCRXBUFFER);\r
+ $ipc_msg = explode(chr(255).chr(0).chr(255), $ipc_msg);\r
+ \r
+ $retval['eventname'] = base64_decode($ipc_msg[0]);\r
+ $retval['data'] = unserialize(base64_decode($ipc_msg[1]));\r
+ \r
+ return $retval;\r
+ \r
+ }\r
+}\r
-<?php\r
-\r
-/*\r
- * VERSION 2.1.1b\r
- */\r
-define('MPRole_PARENT', 0);\r
-define('MPRole_CHILD', 1);\r
-define('MPRole_ERROR', -1);\r
-\r
-class Daemon\r
-{\r
- private static $unique_flag = FALSE;\r
- private static $pidfilename;\r
- \r
- public static function shutdown()\r
- {\r
- if (self::$unique_flag)\r
- {\r
- @unlink(static::$pidfilename);\r
- }\r
- \r
- }\r
-\r
- public static function daemonize()\r
- {\r
- $pid = pcntl_fork();\r
- if ($pid == -1)\r
- {\r
- return FALSE;\r
- }\r
- elseif ($pid > 0)\r
- {\r
- exit;\r
- }\r
- umask(0);\r
- chdir('/');\r
- if (posix_setsid() == -1)\r
- {\r
- return FALSE;\r
- }\r
- \r
- fclose(STDIN);\r
- fclose(STDOUT);\r
- fclose(STDERR);\r
- $GLOBALS['STDIN'] = fopen('/dev/null', 'r');\r
- $GLOBALS['STDOUT']= fopen('/dev/null', 'w');\r
- $GLOBALS['STDERR'] = fopen('/dev/null', 'w');\r
- \r
- return TRUE;\r
- }\r
- \r
- public static function is_unique($pidfilename)\r
- {\r
- $mypid = posix_getpid();\r
- if (is_readable($pidfilename))\r
- {\r
- $pid = (int) rtrim(file_get_contents($pidfilename));\r
- if ($pid == $mypid)\r
- {\r
- return TRUE;\r
- }\r
- if ($pid > 0 && posix_kill($pid, 0))\r
- {\r
- return FALSE;\r
- }\r
- }\r
- return TRUE;\r
-\r
- }\r
- \r
- public static function no_unique($pidfilename)\r
- {\r
- if (!@unlink($pidfilename))\r
- {\r
- return FALSE;\r
- }\r
- else\r
- {\r
- return TRUE;\r
- }\r
- }\r
-\r
- public static function do_unique($pidfilename)\r
- {\r
- if (!self::is_unique($pidfilename))\r
- {\r
- return FALSE;\r
- }\r
-\r
- $mypid = posix_getpid();\r
- if (!@file_put_contents($pidfilename, $mypid.PHP_EOL))\r
- {\r
- return FALSE;\r
- }\r
- register_shutdown_function(['self','shutdown']);\r
- return TRUE;\r
- }\r
-} \r
-\r
-abstract class Children \r
-{\r
- protected $PIPE;\r
- protected $ROLE;\r
- protected static $CHILDREN;\r
- protected $CHILD;\r
- protected $PARENT;\r
- protected $IPCRXBUFFER = [];\r
-\r
-\r
- public function __construct($data = NULL)\r
- {\r
- self::set_sig_handlers();\r
- $this->create_child();\r
- switch ($this->ROLE)\r
- {\r
- case MPRole_ERROR:\r
- return FALSE;\r
- case MPRole_PARENT:\r
- return TRUE;\r
- case MPRole_CHILD:\r
- $this->ChildBody($data);\r
- exit();\r
- }\r
- \r
- }\r
- \r
- public function __destruct()\r
- {\r
- if ($this->ROLE == MPRole_PARENT)\r
- {\r
- posix_kill($this->CHILD, SIGTERM);\r
- }\r
- }\r
-\r
- abstract protected function ChildBody($data);\r
-\r
- static function set_sig_handlers()\r
- {\r
- pcntl_signal(SIGCHLD, [__CLASS__, 'handler_sigchld']);\r
- }\r
- \r
- public function SendUnixSignal($sig)\r
- {\r
- return posix_kill($this->CHILD, $sig);\r
- }\r
- \r
- public function IsAlive()\r
- {\r
- if ($this->ROLE == MPRole_CHILD)\r
- {\r
- return TRUE;\r
- }\r
- if (isset(self::$CHILDREN[$this->CHILD]))\r
- {\r
- return TRUE;\r
- }\r
- else\r
- {\r
- return FALSE;\r
- }\r
- }\r
-\r
- public static function handler_sigchld()\r
- { \r
- $pid = pcntl_waitpid(0, $status, WNOHANG);\r
- if($pid > 0 && isset(self::$CHILDREN[$pid]))\r
- {\r
- unset(self::$CHILDREN[$pid]);\r
- }\r
- }\r
-\r
- protected function create_child()\r
- {\r
- $sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);\r
- stream_set_blocking ($sockets[0] , 0);\r
- stream_set_blocking ($sockets[1] , 0);\r
- $pid = pcntl_fork();\r
- if ($pid == -1)\r
- {\r
- $this->ROLE = MPRole_ERROR;\r
- return FALSE;\r
- }\r
- elseif ($pid > 0)\r
- {\r
- // код для родителя\r
- $this->CHILD = $pid;\r
- self::$CHILDREN[$pid] = $pid;\r
- $this->PARENT = FALSE;\r
- $this->ROLE = MPRole_PARENT;\r
- $this->PIPE = &$sockets[0];\r
- unset($sockets);\r
- usleep(5000);\r
- }\r
- elseif ($pid == 0)\r
- {\r
- // код для ребёнка\r
- $this->CHILD = FALSE;\r
- $this->PARENT = posix_getppid();\r
- $this->ROLE = MPRole_CHILD;\r
- $this->PIPE = &$sockets[1];\r
- unset($sockets);\r
- }\r
- return TRUE;\r
- }\r
- \r
- public function SendEvent($eventname, $data)\r
- {\r
- if (!is_resource($this->PIPE))\r
- {\r
- return FALSE;\r
- }\r
- $eventpack = base64_encode($eventname).chr(255).chr(0).chr(255).base64_encode(serialize($data)).chr(0).chr(15).chr(240).chr(255);\r
- \r
- $res = @stream_socket_sendto($this->PIPE, $eventpack); \r
- if ($res == -1)\r
- {\r
- return TRUE;\r
- }\r
- else\r
- {\r
- return FALSE;\r
- }\r
- }\r
- \r
- public function WaitEvent($wait = TRUE)\r
- {\r
- if (count($this->IPCRXBUFFER) == 0)\r
- {\r
- if (!is_resource($this->PIPE))\r
- {\r
- return FALSE;\r
- }\r
-\r
- $r = [$this->PIPE];\r
- if ($wait)\r
- {\r
- while (stream_select($r, $w, $x, 0) == 0)\r
- {\r
- usleep(10000);\r
- $r = [$this->PIPE];\r
- }\r
- }\r
- elseif (stream_select($r, $w, $x, 0) == 0)\r
- {\r
- return NULL;\r
- }\r
- $ipc_msg = '';\r
- while (substr($ipc_msg , -4) != chr(0).chr(15).chr(240).chr(255))\r
- {\r
- $rcv_buf = stream_socket_recvfrom($this->PIPE, 1500);\r
- if ($rcv_buf == '')\r
- {\r
- return NULL;\r
- }\r
- $ipc_msg .= $rcv_buf;\r
- }\r
- $ipc_msg = explode(chr(0).chr(15).chr(240).chr(255), $ipc_msg);\r
- array_pop($ipc_msg);\r
- $this->IPCRXBUFFER = array_merge($this->IPCRXBUFFER, $ipc_msg);\r
- }\r
- $ipc_msg = array_shift($this->IPCRXBUFFER);\r
- $ipc_msg = explode(chr(255).chr(0).chr(255), $ipc_msg);\r
- \r
- $retval['eventname'] = base64_decode($ipc_msg[0]);\r
- $retval['data'] = unserialize(base64_decode($ipc_msg[1]));\r
- \r
- return $retval;\r
- \r
- }\r
-}\r
+<?php
+
+/*
+ * VERSION 2.2.0b
+ */
+define('MPRole_PARENT', 0);
+define('MPRole_CHILD', 1);
+define('MPRole_ERROR', -1);
+
+class Daemon
+{
+ private static $unique_flag = FALSE;
+ private static $pidfilename;
+
+ public static function shutdown()
+ {
+ if (self::$unique_flag)
+ {
+ @unlink(static::$pidfilename);
+ }
+
+ }
+
+ public static function daemonize()
+ {
+ $pid = pcntl_fork();
+ if ($pid == -1)
+ {
+ return FALSE;
+ }
+ elseif ($pid > 0)
+ {
+ exit;
+ }
+ umask(0);
+ chdir('/');
+ if (posix_setsid() == -1)
+ {
+ return FALSE;
+ }
+
+ fclose(STDIN);
+ fclose(STDOUT);
+ fclose(STDERR);
+ $GLOBALS['STDIN'] = fopen('/dev/null', 'r');
+ $GLOBALS['STDOUT']= fopen('/dev/null', 'w');
+ $GLOBALS['STDERR'] = fopen('/dev/null', 'w');
+
+ return TRUE;
+ }
+
+ public static function is_unique($pidfilename)
+ {
+ $mypid = posix_getpid();
+ if (is_readable($pidfilename))
+ {
+ $pid = (int) rtrim(file_get_contents($pidfilename));
+ if ($pid == $mypid)
+ {
+ return TRUE;
+ }
+ if ($pid > 0 && posix_kill($pid, 0))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+
+ }
+
+ public static function no_unique($pidfilename)
+ {
+ if (!@unlink($pidfilename))
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+ public static function do_unique($pidfilename)
+ {
+ if (!self::is_unique($pidfilename))
+ {
+ return FALSE;
+ }
+
+ $mypid = posix_getpid();
+ if (!@file_put_contents($pidfilename, $mypid.PHP_EOL))
+ {
+ return FALSE;
+ }
+ register_shutdown_function(['self','shutdown']);
+ return TRUE;
+ }
+}
+
+abstract class Children
+{
+ protected $PIPE;
+ protected $ROLE;
+ protected static $CHILDREN;
+ protected $CHILD;
+ protected $PARENT;
+ protected $IPCRXBUFFER = [];
+
+
+ public function __construct($data = NULL)
+ {
+ self::set_sig_handlers();
+ $this->create_child();
+ switch ($this->ROLE)
+ {
+ case MPRole_ERROR:
+ return FALSE;
+ case MPRole_PARENT:
+ return TRUE;
+ case MPRole_CHILD:
+ $this->ChildBody($data);
+ exit();
+ }
+
+ }
+
+ public function __destruct()
+ {
+ if ($this->ROLE == MPRole_PARENT)
+ {
+ posix_kill($this->CHILD, SIGTERM);
+ }
+ }
+
+ abstract protected function ChildBody($data);
+
+ static function set_sig_handlers()
+ {
+ pcntl_signal(SIGCHLD, [__CLASS__, 'handler_sigchld']);
+ }
+
+ public function SendUnixSignal($sig)
+ {
+ return posix_kill($this->CHILD, $sig);
+ }
+
+ public function IsParentAlive()
+ {
+ if ($this->ROLE == MPRole_CHILD)
+ {
+ return posix_kill($this->PARENT, 0);
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+
+ public function IsAlive()
+ {
+ if ($this->ROLE == MPRole_CHILD)
+ {
+ return TRUE;
+ }
+ if (isset(self::$CHILDREN[$this->CHILD]))
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ public static function handler_sigchld()
+ {
+ $pid = pcntl_waitpid(0, $status, WNOHANG);
+ if($pid > 0 && isset(self::$CHILDREN[$pid]))
+ {
+ unset(self::$CHILDREN[$pid]);
+ }
+ }
+
+ protected function create_child()
+ {
+ $sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
+ stream_set_blocking ($sockets[0] , 0);
+ stream_set_blocking ($sockets[1] , 0);
+ $pid = pcntl_fork();
+ if ($pid == -1)
+ {
+ $this->ROLE = MPRole_ERROR;
+ return FALSE;
+ }
+ elseif ($pid > 0)
+ {
+ // код длÑ\8f родителÑ\8f
+ $this->CHILD = $pid;
+ self::$CHILDREN[$pid] = $pid;
+ $this->PARENT = FALSE;
+ $this->ROLE = MPRole_PARENT;
+ $this->PIPE = &$sockets[0];
+ unset($sockets);
+ usleep(5000);
+ }
+ elseif ($pid == 0)
+ {
+ // код длÑ\8f ребёнка
+ $this->CHILD = FALSE;
+ $this->PARENT = posix_getppid();
+ $this->ROLE = MPRole_CHILD;
+ $this->PIPE = &$sockets[1];
+ unset($sockets);
+ }
+ return TRUE;
+ }
+
+ public function SendEvent($eventname, $data)
+ {
+ if (!is_resource($this->PIPE))
+ {
+ return FALSE;
+ }
+ $eventpack = base64_encode($eventname).chr(255).chr(0).chr(255).base64_encode(serialize($data)).chr(0).chr(15).chr(240).chr(255);
+
+ $res = @stream_socket_sendto($this->PIPE, $eventpack);
+ if ($res == -1)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ public function WaitEvent($wait = TRUE)
+ {
+ if (count($this->IPCRXBUFFER) == 0)
+ {
+ if (!is_resource($this->PIPE))
+ {
+ return FALSE;
+ }
+
+ $r = [$this->PIPE];
+ if ($wait)
+ {
+ while (stream_select($r, $w, $x, 0) == 0)
+ {
+ usleep(10000);
+ $r = [$this->PIPE];
+ }
+ }
+ elseif (stream_select($r, $w, $x, 0) == 0)
+ {
+ return NULL;
+ }
+ $ipc_msg = '';
+ while (substr($ipc_msg , -4) != chr(0).chr(15).chr(240).chr(255))
+ {
+ $rcv_buf = stream_socket_recvfrom($this->PIPE, 1500);
+ if ($rcv_buf == '')
+ {
+ return NULL;
+ }
+ $ipc_msg .= $rcv_buf;
+ }
+ $ipc_msg = explode(chr(0).chr(15).chr(240).chr(255), $ipc_msg);
+ array_pop($ipc_msg);
+ $this->IPCRXBUFFER = array_merge($this->IPCRXBUFFER, $ipc_msg);
+ }
+ $ipc_msg = array_shift($this->IPCRXBUFFER);
+ $ipc_msg = explode(chr(255).chr(0).chr(255), $ipc_msg);
+
+ $retval['eventname'] = base64_decode($ipc_msg[0]);
+ $retval['data'] = unserialize(base64_decode($ipc_msg[1]));
+
+ return $retval;
+
+ }
+}
<type>org.netbeans.modules.php.project</type>\r
<configuration>\r
<data xmlns="http://www.netbeans.org/ns/php-project/1">\r
- <name>dev</name>\r
+ <name>dev_on_git</name>\r
</data>\r
</configuration>\r
</project>\r
--- /dev/null
+[index]
+1 = 28-011625a3ddee
+2 = 28-011625a4b9ee
+3 = 28-021621f7d0ee
+4 = 28-021621fbc0ee
+
+[28-011625a3ddee]
+description = hot corridor
+low_warn_threshold = 10000
+low_alarm_threshold = 3000
+high_warn_threshold = 30000
+high_alarm_threshold = 45000
+
+[28-011625a4b9ee]
+description = outdoor
+low_warn_threshold = -30000
+low_alarm_threshold = -40000
+high_warn_threshold = 35000
+high_alarm_threshold = 50000
+
+[28-021621f7d0ee]
+description = cold corridor 2
+low_warn_threshold = 10000
+low_alarm_threshold = 3000
+high_warn_threshold = 26000
+high_alarm_threshold = 30000
+
+[28-021621fbc0ee]
+description = cold corridor 1
+low_warn_threshold = 10000
+low_alarm_threshold = 3000
+high_warn_threshold = 26000
+high_alarm_threshold = 30000
+
--- /dev/null
+#!/usr/bin/env php
+<?php
+declare (ticks=1);
+require_once 'mplib.php';
+require_once 'SnmpdPassthroughAgent.php';
+
+$BaseOid = '.1.3.6.1.4.1.2021.14.1';
+
+class temp_reader extends Children
+{
+ protected $DEVDIR = '/sys/bus/w1/devices/';
+ protected $lasttemp = [];
+
+
+ protected function scanDevs ()
+ {
+ $DATA = [];
+ if (!file_exists($this->DEVDIR))
+ {
+ return FALSE;
+ }
+ $DIRlist = scandir ($this->DEVDIR);
+ foreach ($DIRlist as $element)
+ {
+ if (substr($element,0,3) == '28-')
+ {
+ $DATA[] = $element;
+
+ }
+ }
+ return $DATA;
+ }
+
+ protected function readTempData($device)
+ {
+ $value = @file_get_contents('/sys/bus/w1/devices/'.$device.'/temperature');
+ if ($value === FALSE)
+ {
+ return FALSE;
+ }
+ return $value;
+ }
+
+ protected function ChildBody($data)
+ {
+ cli_set_process_title ('temp reader');
+ $DEVS = $this->scanDevs();
+ $DATA = [];
+ while (TRUE)
+ {
+
+ foreach ($DEVS as $DEV)
+ {
+ $DATA[$DEV] = $this->readTempData($DEV);
+
+ }
+ $SR = $this->SendEvent('data', $DATA);
+ sleep(30);
+ if (!$this->IsParentAlive())
+ {
+ exit();
+ }
+ }
+ }
+
+}
+
+function gen_ini ($INI)
+{
+ $TXTINI = '';
+ foreach ($INI as $SECNAME => $SEC)
+ {
+ $TXTINI .= '['.$SECNAME."]\n";
+ foreach ($SEC as $key => $value)
+ {
+ $TXTINI .= $key.' = '.$value."\n";
+ }
+ $TXTINI .= "\n";
+ }
+ file_put_contents(__DIR__ .'/sens.ini', $TXTINI);
+}
+
+$TEMP_READER = new temp_reader();
+cli_set_process_title ('snmp passthrough responder');
+$SNMP_PA = new SnmpdPassthroughAgent($BaseOid);
+$INI = @parse_ini_file(__DIR__ .'/sens.ini', TRUE);
+$SNMP_PA->AddOID('1.1', 'string', 'head_description');
+$SNMP_PA->AddOID('1.2', 'string', 'index');
+$SNMP_PA->AddOID('1.3', 'string', 'w1_serial');
+$SNMP_PA->AddOID('1.4', 'string', 'description');
+$SNMP_PA->AddOID('1.5', 'string', 'temperature');
+$SNMP_PA->AddOID('1.6', 'string', 'low_warn_threshold');
+$SNMP_PA->AddOID('1.7', 'string', 'low_alarm_threshold');
+$SNMP_PA->AddOID('1.8', 'string', 'high_warn_threshold');
+$SNMP_PA->AddOID('1.9', 'string', 'high_alarm_threshold');
+
+if (!isset($INI['index']))
+{
+ $INI['index'] = [];
+}
+foreach ($INI['index'] as $index => $w1_ser)
+{
+ $SNMP_PA->AddOID('2.'.$index, 'integer', $index);
+ $SNMP_PA->AddOID('3.'.$index, 'string', $w1_ser);
+ $SNMP_PA->AddOID('4.'.$index, 'string', $INI[$w1_ser]['description'], TRUE);
+ $SNMP_PA->AddOID('5.'.$index, 'integer', 0);
+ $SNMP_PA->AddOID('6.'.$index, 'integer', $INI[$w1_ser]['low_warn_threshold'], TRUE);
+ $SNMP_PA->AddOID('7.'.$index, 'integer', $INI[$w1_ser]['low_alarm_threshold'], TRUE);
+ $SNMP_PA->AddOID('8.'.$index, 'integer', $INI[$w1_ser]['high_warn_threshold'], TRUE);
+ $SNMP_PA->AddOID('9.'.$index, 'integer', $INI[$w1_ser]['high_alarm_threshold'], TRUE);
+}
+
+while (TRUE)
+{
+ if (!$TEMP_READER->IsAlive())
+ {
+ exit();
+ }
+ $SNMP_PA->SnmpWaitQuery();
+ $LASTSET = $SNMP_PA->GetLastSet();
+ if (count($LASTSET) > 0)
+ {
+ foreach ($LASTSET as $LS)
+ {
+ foreach ($LS as $o => $v)
+ {
+ $o = explode('.', $o);
+ $w1_ser = $INI['index'][$o[1]];
+ switch ($o[0])
+ {
+ case '4':
+ $INI[$w1_ser]['description'] = $v;
+ break;
+ case '6':
+ $INI[$w1_ser]['low_warn_threshold'] = (int)$v;
+ break;
+ case '7':
+ $INI[$w1_ser]['low_alarm_threshold'] = (int)$v;
+ break;
+ case '8':
+ $INI[$w1_ser]['high_warn_threshold'] = (int)$v;
+ break;
+ case '9':
+ $INI[$w1_ser]['high_alarm_threshold'] = (int)$v;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ gen_ini($INI);
+ }
+ $EVENT = $TEMP_READER->WaitEvent(FALSE);
+ if (is_array($EVENT))
+ {
+ foreach ($EVENT['data'] as $w1_ser => $data)
+ {
+ if (!isset($INI[$w1_ser]))
+ {
+ if (count($INI['index']) == 0)
+ {
+ $INI['index'][1] = $w1_ser;
+ }
+ else
+ {
+ $INI['index'][] = $w1_ser;
+ }
+ $index = array_search($w1_ser, $INI['index']);
+ $INI[$w1_ser]['description'] = '';
+ $INI[$w1_ser]['low_warn_threshold'] = 0;
+ $INI[$w1_ser]['low_alarm_threshold'] = 0;
+ $INI[$w1_ser]['high_warn_threshold'] = 0;
+ $INI[$w1_ser]['high_alarm_threshold'] = 0;
+ $SNMP_PA->AddOID('2.'.$index, 'integer', $index);
+ $SNMP_PA->AddOID('3.'.$index, 'string', $w1_ser);
+ $SNMP_PA->AddOID('4.'.$index, 'string', '', TRUE);
+ $SNMP_PA->AddOID('5.'.$index, 'integer' , 0);
+ $SNMP_PA->AddOID('6.'.$index, 'integer', 0, TRUE);
+ $SNMP_PA->AddOID('7.'.$index, 'integer', 0, TRUE);
+ $SNMP_PA->AddOID('8.'.$index, 'integer', 0, TRUE);
+ $SNMP_PA->AddOID('9.'.$index, 'integer', 0, TRUE);
+
+
+ gen_ini($INI);
+ }
+ $index = array_search($w1_ser, $INI['index']);
+ $SNMP_PA->SetOidVal('5.'.$index, $data);
+ }
+ }
+}