From: sleepy Date: Tue, 28 Apr 2020 14:50:07 +0000 (+1000) Subject: Косметические исправления X-Git-Url: http://git.ultra-x.su/?a=commitdiff_plain;h=4e57575c8912ba9bdfb52ed8e1f3446c72bbdafb;p=dev Косметические исправления --- diff --git a/check_code.php b/check_code.php index 8ec6b1b..be7c519 100644 --- a/check_code.php +++ b/check_code.php @@ -1,50 +1,75 @@ '; +$CALLWAITFORANSWER = 30; +$CALLFROM = '"verify code sytem" <3505>'; $RETRYCALL = 3; $INTERVAL = 5; +$CALLCONEXT = 'c-2'; +$AMIHOST ="127.0.0.1"; +$AMIUSER = "monast"; +$AMIPASS = "blabla"; // //test data -echo "
\n";
-$_GET['phone'] = '3400';
-var_dump($_GET);
+//$_GET['phone'] = '3400';
+//var_dump($_GET);
 
-if (!isset($_GET['phone']))
+if (php_sapi_name() != 'cli')
 {
+    $ADDR=$_SERVER["REMOTE_ADDR"];
+//    var_dump($ADDR);    
+//if ($ADDR=="192.168.10.225" || $ADDR=="10.20.2.120" || $ADDR=="217.74.116.10")
+//exit;
+    if (!isset($_GET['phone']))
+    {
+	exit();
+    }
+    if(preg_match('/^7\d{10}$/', $_GET['phone']) != 1)
+    {
+	echo 'BADPHONE'.PHP_EOL;
+	 exit();
+    }
+    $CALLEDPHONENUM = '8'.substr($_GET['phone'], 1);
+    //generate random pin
+    $PIN = [];
+    for ($cnt = 0; $cnt < $PINLEN;$cnt++)
+    {
+	mt_srand(str_replace('.', '', (string)array_product(sys_getloadavg())) * crc32(microtime()));
+	$cnte = mt_rand(0,30);
+	$cntr = 0;
+	do
+	{
+	    $rnd = mt_rand(0,9);
+	    $cntr++;
+	}
+	while($cntr < $cnte);
+	$PIN[] = $rnd;
+	usleep(mt_rand(1,250000));
+    }
+
+    echo implode('', $PIN),PHP_EOL;
+    system('php -f '.basename(__FILE__).' '.$CALLEDPHONENUM.' '.implode('-', $PIN));
     exit();
 }
-if(preg_match('/^7\d{10}$/', $_GET['phone']) != 1)
-{
-    //exit();
-}
-//generate random pin
-$PIN = [];
-for ($cnt = 0; $cnt < $PINLEN;$cnt++)
+if (!isset($argv[1]) || !isset($argv[2]))
 {
-    mt_srand(str_replace('.', '', (string)array_product(sys_getloadavg())) * crc32(microtime()));
-    $cnte = mt_rand(0,30);
-    $cntr = 0;
-    do
-    {
-	$rnd = mt_rand(0,9);
-	$cntr++;
-    }
-    while($cntr < $cnte);
-    $PIN[] = $rnd;
-    usleep(mt_rand(1,250000));
+    exit();
 }
 
-echo implode('', $PIN),PHP_EOL;
+$CALLEDPHONENUM = $argv[1];
+$PIN = explode('-', $argv[2]);
 
 //fork point
+$D = new Daemon();
+$D->daemonize();
 
 $AMI = new AMI(array('autorefresh' => TRUE, 'logverbose' => 3));
-$is_connected = $AMI->connect("127.0.0.1", "monast", "blabla");
+$is_connected = $AMI->connect($AMIHOST, $AMIUSER, $AMIPASS);
 
 if (!$is_connected)
 {
@@ -53,7 +78,7 @@ if (!$is_connected)
 
 for ($tryno = 0; $tryno < $RETRYCALL;$tryno++)
 {
-    $OriginateResponce = $AMI->Originate("Local/{$_GET['phone']}@c-2", NULL, NULL, NULL, 'AGI', 'agi:async', 30, $CALLFROM, ['CALLERID(ANI-num)' => '3505'], NULL, NULL, NULL);
+    $OriginateResponce = $AMI->Originate("Local/{$CALLEDPHONENUM}@{$CALLCONEXT}", NULL, NULL, NULL, 'AGI', 'agi:async', $CALLWAITFORANSWER, $CALLFROM);
     $OriginateResponce->WaitUntilReady();
     if ($OriginateResponce->Response == 'Success')
     {
@@ -67,7 +92,7 @@ if ($OriginateResponce->Response != 'Success')
 }
 $channel = $OriginateResponce->Channel;
 $AGI = $AMI->GetAsyncAGIInstance($channel);
-
+sleep(1);
 for ($tryno = 0; $tryno < $REPEATNO;$tryno++)
 {
     $AGI->StreamFile('your');
diff --git a/dvblastmaster/lib/mplib.php b/dvblastmaster/lib/mplib.php
deleted file mode 100644
index 871965c..0000000
--- a/dvblastmaster/lib/mplib.php
+++ /dev/null
@@ -1,271 +0,0 @@
- 0)
-        {
-            exit;
-        }
-	self::$origin_pid = posix_getpid();
-        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 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)
-	{
-	    // код для родителя
-	    $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)
-	{
-	    // код для ребёнка
-	    $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;
-	
-    }
-}
diff --git a/dvblastmaster/lib/sts.php b/dvblastmaster/lib/sts.php
deleted file mode 100644
index 9c7b8a5..0000000
--- a/dvblastmaster/lib/sts.php
+++ /dev/null
@@ -1,135 +0,0 @@
- $sectiondata)
-	    {
-		if(!is_array($sectiondata))
-		{
-		    return FALSE;
-		}
-		$_RETVAL .= '['.$sectionname.']'.PHP_EOL;
-		foreach ($sectiondata as $param => $data)
-		{
-		    if (is_array($data))
-		    {
-			$data = '';
-		    }
-		    $_RETVAL .= $param.' = '.$data.PHP_EOL;
-		}
-		$_RETVAL .= PHP_EOL;
-	    }
-	}
-	else
-	{
-	    foreach ($ini_array as $param => $data)
-	    {
-		$_RETVAL .= $param.' = '.$data.PHP_EOL;
-	    }
-	}
-	return $_RETVAL;
-    }
-    private static function GetSignalDescription()
-    {
-	if (self::$SigArray === FALSE)
-	{
-	    self::$SigArray = explode("\n", shell_exec('kill -l'));
-	}	
-    }
-    
-    public static function GetSignalMnemonicByNumber($signo)
-    {
-	self::GetSignalDescription();
-	if (isset(self::$SigArray[$signo]))
-	{
-	    return self::$SigArray[$signo];
-	}
-	else
-	{
-	    return FALSE;
-	}
-    }
-
-    public static function GetSignalNumberByMnemonic($sigmnemo)
-    {
-	self::GetSignalDescription();
-	return array_search($sigmnemo, self::$SigArray);
-    }
-
-    public static function stdout_prefix($prefix)
-    {
-	if (!self::$IsPrefixed)
-	{
-	    self::$StdPrefix = $prefix;
-	    ob_start(['self','ob_callback'],1);
-	    self::$IsPrefixed = TRUE;
-	    return TRUE;
-	}
-	else
-	{
-	    return FALSE;
-	}
-
-    }
-
-    public static function stdout_unprefix()
-    {
-	if (self::$IsPrefixed)
-	{
-	    ob_end_clean();
-	    self::$IsPrefixed = FALSE;
-	    return TRUE;
-	}
-	else
-	{
-	    return FALSE;
-	}
-
-    }
-    
-    private static function ob_callback($buffer)
-    {
-	if (self::$IsLastEol)
-	{
-	    $prefix = self::$StdPrefix;
-	}
-	else
-	{
-	    $prefix = '';
-	}
-	self::$IsLastEol = substr($buffer, -1) == PHP_EOL;
-	return $prefix.$buffer;
-
-    }
-    
-}
-
diff --git a/dvblastmaster/lib/timer.php b/dvblastmaster/lib/timer.php
deleted file mode 100644
index dc577cd..0000000
--- a/dvblastmaster/lib/timer.php
+++ /dev/null
@@ -1,119 +0,0 @@
-id = uniqid();
-        $this->time = $time;
-        $this->UserCall = $callable;
-	$this->UserCallArg = $args;
-        $this->type = $type;
-	if (!is_callable($this->UserCall, TRUE, $callablename))
-	{
-	    throw new Exception("parameter 2 must be callable, \$callable=". $callablename);
-	}
-	else
-	{    
-	    $this->start();
-	    self::$timers[$this->id] = &$this;
-	}
-    }
-
-    public function __destruct() 
-    {
-	unset(self::$timers[$this->id]);
-    }
-
-    private function getId()
-    {
-	return $this->id;
-    }
-
-    public function getTimeLeft()
-    {
-	    return $this->ltime;
-    }
-
-    public function setTimeLeft($time)
-    {
-	    $this->time = $time;
-    }
-
-
-    public function reset()
-    {
-	$this->StartTime = microtime(true);
-	$this->IsStop = FALSE;
-    }
-
-    public function start() 
-    {
-	$this->reset();
-	$this->IsStop = FALSE;
-    }
-
-    public function stop() 
-    {
-	$this->IsStop = TRUE;
-    }
-
-    public static function poll()
-    {
-	foreach (self::$timers as $timer)
-	{
-	    if ($timer->IsStop == FALSE)
-	    {
-		$timer->update();
-	    }
-	}
-    }
-
-    private function update()
-    {
-	$this->ltime = $this->StartTime - microtime(true) + $this->time;
-	if ($this->ltime <= 0)
-	{
-	    $this->ltime = 0;
-	    $this->task();
-	    if ($this->type === FALSE)
-	    {
-		$this->stop();
-	    }
-	    elseif ($this->type === TRUE)
-	    {
-		$this->reset();
-	    }
-	    elseif ($this->type === NULL)
-	    {
-		$this->stop();
-		$this->__destruct();
-	    }
-	}
-    }
-
-    private function task() 
-    {
-	call_user_func_array ($this->UserCall, $this->UserCallArg);
-    }
-}
diff --git a/lib/mplib.php b/lib/mplib.php
new file mode 100644
index 0000000..a756d6a
--- /dev/null
+++ b/lib/mplib.php
@@ -0,0 +1,270 @@
+ 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 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)
+	{
+	    // код для родителя
+	    $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)
+	{
+	    // код для ребёнка
+	    $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;
+	
+    }
+}
diff --git a/lib/sts.php b/lib/sts.php
new file mode 100644
index 0000000..9c7b8a5
--- /dev/null
+++ b/lib/sts.php
@@ -0,0 +1,135 @@
+ $sectiondata)
+	    {
+		if(!is_array($sectiondata))
+		{
+		    return FALSE;
+		}
+		$_RETVAL .= '['.$sectionname.']'.PHP_EOL;
+		foreach ($sectiondata as $param => $data)
+		{
+		    if (is_array($data))
+		    {
+			$data = '';
+		    }
+		    $_RETVAL .= $param.' = '.$data.PHP_EOL;
+		}
+		$_RETVAL .= PHP_EOL;
+	    }
+	}
+	else
+	{
+	    foreach ($ini_array as $param => $data)
+	    {
+		$_RETVAL .= $param.' = '.$data.PHP_EOL;
+	    }
+	}
+	return $_RETVAL;
+    }
+    private static function GetSignalDescription()
+    {
+	if (self::$SigArray === FALSE)
+	{
+	    self::$SigArray = explode("\n", shell_exec('kill -l'));
+	}	
+    }
+    
+    public static function GetSignalMnemonicByNumber($signo)
+    {
+	self::GetSignalDescription();
+	if (isset(self::$SigArray[$signo]))
+	{
+	    return self::$SigArray[$signo];
+	}
+	else
+	{
+	    return FALSE;
+	}
+    }
+
+    public static function GetSignalNumberByMnemonic($sigmnemo)
+    {
+	self::GetSignalDescription();
+	return array_search($sigmnemo, self::$SigArray);
+    }
+
+    public static function stdout_prefix($prefix)
+    {
+	if (!self::$IsPrefixed)
+	{
+	    self::$StdPrefix = $prefix;
+	    ob_start(['self','ob_callback'],1);
+	    self::$IsPrefixed = TRUE;
+	    return TRUE;
+	}
+	else
+	{
+	    return FALSE;
+	}
+
+    }
+
+    public static function stdout_unprefix()
+    {
+	if (self::$IsPrefixed)
+	{
+	    ob_end_clean();
+	    self::$IsPrefixed = FALSE;
+	    return TRUE;
+	}
+	else
+	{
+	    return FALSE;
+	}
+
+    }
+    
+    private static function ob_callback($buffer)
+    {
+	if (self::$IsLastEol)
+	{
+	    $prefix = self::$StdPrefix;
+	}
+	else
+	{
+	    $prefix = '';
+	}
+	self::$IsLastEol = substr($buffer, -1) == PHP_EOL;
+	return $prefix.$buffer;
+
+    }
+    
+}
+
diff --git a/lib/timer.php b/lib/timer.php
new file mode 100644
index 0000000..dc577cd
--- /dev/null
+++ b/lib/timer.php
@@ -0,0 +1,119 @@
+id = uniqid();
+        $this->time = $time;
+        $this->UserCall = $callable;
+	$this->UserCallArg = $args;
+        $this->type = $type;
+	if (!is_callable($this->UserCall, TRUE, $callablename))
+	{
+	    throw new Exception("parameter 2 must be callable, \$callable=". $callablename);
+	}
+	else
+	{    
+	    $this->start();
+	    self::$timers[$this->id] = &$this;
+	}
+    }
+
+    public function __destruct() 
+    {
+	unset(self::$timers[$this->id]);
+    }
+
+    private function getId()
+    {
+	return $this->id;
+    }
+
+    public function getTimeLeft()
+    {
+	    return $this->ltime;
+    }
+
+    public function setTimeLeft($time)
+    {
+	    $this->time = $time;
+    }
+
+
+    public function reset()
+    {
+	$this->StartTime = microtime(true);
+	$this->IsStop = FALSE;
+    }
+
+    public function start() 
+    {
+	$this->reset();
+	$this->IsStop = FALSE;
+    }
+
+    public function stop() 
+    {
+	$this->IsStop = TRUE;
+    }
+
+    public static function poll()
+    {
+	foreach (self::$timers as $timer)
+	{
+	    if ($timer->IsStop == FALSE)
+	    {
+		$timer->update();
+	    }
+	}
+    }
+
+    private function update()
+    {
+	$this->ltime = $this->StartTime - microtime(true) + $this->time;
+	if ($this->ltime <= 0)
+	{
+	    $this->ltime = 0;
+	    $this->task();
+	    if ($this->type === FALSE)
+	    {
+		$this->stop();
+	    }
+	    elseif ($this->type === TRUE)
+	    {
+		$this->reset();
+	    }
+	    elseif ($this->type === NULL)
+	    {
+		$this->stop();
+		$this->__destruct();
+	    }
+	}
+    }
+
+    private function task() 
+    {
+	call_user_func_array ($this->UserCall, $this->UserCallArg);
+    }
+}