]> Untitled Git - dev/commitdiff
Добавлена новая библиотека, реализующая SNMPD passthrough агента,
authordirect <direct@1423-sleepy.empl.vvsu.ru>
Mon, 1 Feb 2021 02:09:44 +0000 (12:09 +1000)
committerdirect <direct@1423-sleepy.empl.vvsu.ru>
Mon, 1 Feb 2021 02:09:44 +0000 (12:09 +1000)
Добавлен новый функционал в mplib.

lib/SnmpdPassthroughAgent.php [new file with mode: 0644]
lib/mplib.old.php [new file with mode: 0644]
lib/mplib.php
nbproject/project.xml
sens/sens.ini [new file with mode: 0644]
sens/sens.php [new file with mode: 0644]

diff --git a/lib/SnmpdPassthroughAgent.php b/lib/SnmpdPassthroughAgent.php
new file mode 100644 (file)
index 0000000..9c34ba6
--- /dev/null
@@ -0,0 +1,323 @@
+<?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));
+    }
+    
+}
diff --git a/lib/mplib.old.php b/lib/mplib.old.php
new file mode 100644 (file)
index 0000000..a756d6a
--- /dev/null
@@ -0,0 +1,270 @@
+<?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
index a756d6aac8c14d2c801a98d021c343f1a4f7fe14..e1027fca326b06f6e1b4c3432d25705579725b90 100644 (file)
-<?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;
+       
+    }
+}
index d4f7c7210f262d561492c6fd673e29168c0eb554..e1166ea08bf48b157396f0714ca52c57b760c020 100644 (file)
@@ -3,7 +3,7 @@
     <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
diff --git a/sens/sens.ini b/sens/sens.ini
new file mode 100644 (file)
index 0000000..4bb0b17
--- /dev/null
@@ -0,0 +1,34 @@
+[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
+
diff --git a/sens/sens.php b/sens/sens.php
new file mode 100644 (file)
index 0000000..cbd005e
--- /dev/null
@@ -0,0 +1,191 @@
+#!/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);
+       }
+    }
+}