From f52b0ba53718b1e7354d4ca894d0aeeff5342b16 Mon Sep 17 00:00:00 2001 From: pk910 Date: Wed, 30 Nov 2011 23:29:49 +0100 Subject: [PATCH] added Perl debugger (PerlGod.class.php) --- Bots/PerlGod.class.php | 187 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 Bots/PerlGod.class.php diff --git a/Bots/PerlGod.class.php b/Bots/PerlGod.class.php new file mode 100644 index 0000000..f992eb2 --- /dev/null +++ b/Bots/PerlGod.class.php @@ -0,0 +1,187 @@ +. * + * * + ************************************************************************ + * + * Bots/PerlGod.class.php + * + * simple Perl debugger... + * + */ + +class {$_NAME} extends Bot { + private $uplink; + private $bot, $execcache = array(); + + public function load($uplink, $old = false) { + $this->uplink = $uplink; + if(!$old) { + $nick = "Perl"; + $ident = "perl"; + $host = "Services.WebGamesNet.net"; + $ip = "0::0"; + $realname = "Perl Perl Perl Perl Perl"; + $modes = "ioknISD"; + $this->bot = $this->uplink->addUser($nick,$ident,$host,$ip,$modes,$realname); + if(is_a($this->bot, "P10_User")) { + $this->uplink->join($this->bot, "#perl", (P10_Channel::USERPRIV_OPED | P10_Channel::USERPRIV_VOICE)); + $this->uplink->join($this->bot, "#dev", P10_Channel::USERPRIV_VOICE); + } + } else { + $this->bot = $old; + } + + ModCMD::bind($this, BIND_CHANMSG, "recive_privmsg"); + ModCMD::bind($this, BIND_QUIT, "recive_quit"); + } + + public function unload($rehash = false) { + foreach($this->execcache as $id => $entry) { + fclose($entry['pipes'][1]); + fclose($entry['pipes'][2]); + proc_terminate($entry['proc'],9); + } + $this->execcache = array(); + if($rehash) { + return $this->bot; + } else { + $this->uplink->delUser($this->bot, "Bye."); + } + } + + public function loop() { + foreach($this->execcache as $id => $entry) { + if(!$this->checkstate($entry)) { + unset($this->execcache[$id]); + } + } + } + + function recive_privmsg($user, $channel, $message) { + $opOnPHPChannel = false; + $entryChannel = P10_Channel::getChannelByName("#PHP"); + if($entryChannel) { + $privs = $entryChannel->getUserPrivs($user); + $opOnPHPChannel = ($privs & P10_Channel::USERPRIV_OPED); + } + if(!$user->getModes()->hasMode('o') && !$opOnPHPChannel) return 0; + $exp=explode(" ", $message, 2); + switch (strtolower($exp[0])) { + case "~perl": + if(count($this->execcache) > 5) { + $this->uplink->notice($this->bot, $user, "too many running perl processes at the moment!"); + return; + } + $entry=array(); + $entry['channel'] = $channel; + $descriptor = array(0 => array("pipe", "r"),1 => array("pipe", "w"),2 => array("pipe", "w")); + $entry['proc'] = proc_open('perl', $descriptor, $entry['pipes']); + if(!is_resource($entry['proc'])) { + $this->uplink->notice($this->bot, $user, "error while loading perl!"); + return; + } + $entry['time'] = time(); + if(preg_match("#pastebin\.com/([a-zA-Z0-9]*)$#i", $exp[1])) { + $pasteid = explode("/", $exp[1]); + $pasteid = $pasteid[count($pasteid)-1]; + $codecontent = file_get_contents("http://pastebin.com/download.php?i=".$pasteid); + if(preg_match("#Unknown Paste ID!#i", $codecontent)) { + $this->uplink->notice($this->bot, $user, "Unknown Paste ID!"); + return; + } + $code = $codecontent; + } else { + $code = $exp[1]; + } + fwrite($entry['pipes'][0], $code); + fclose($entry['pipes'][0]); + $this->execcache[] = $entry; + break; + } + } + + function recive_quit($user, $reason) { + if($user === $this->bot) { + $this->load($this->uplink); + } + } + + function checkstate($entry) { + $data = proc_get_status($entry['proc']); + if(!$data['running']) { + $out=""; + while(!feof($entry['pipes'][1])) { + $out .= fgets($entry['pipes'][1], 128); + } + $eout=""; + while(!feof($entry['pipes'][2])) { + $eout .= fgets($entry['pipes'][2], 128); + } + if($out != "") { + $out=str_replace("\r","",$out); + $lines=explode("\n",$out); + $i=0; + foreach($lines as $line) { + $i++; + if($i>1000) { + $this->uplink->privmsg($this->bot, $entry['channel'], "too many lines!"); + break; + } + $this->uplink->privmsg($this->bot, $entry['channel'], $line); + } + } + if($eout != "") { + $eout=str_replace("\r","",$eout); + $lines=explode("\n",$eout); + $i=0; + foreach($lines as $line) { + $i++; + if($i>1000) { + $this->uplink->privmsg($this->bot, $entry['channel'], "too many lines!"); + break; + } + $this->uplink->privmsg($this->bot, $entry['channel'], "4".$line.""); + } + } + fclose($entry['pipes'][1]); + fclose($entry['pipes'][2]); + proc_close($entry['proc']); + return false; + } else { + if($entry['time']+10 > time()) { + return true; + } else { + //TIMEOUT + if($entry['term']) { + fclose($entry['pipes'][1]); + fclose($entry['pipes'][2]); + proc_terminate($entry['proc'],9); + $this->uplink->privmsg($this->bot, $entry['channel'], "perl hard timeout. sending SIGKILL"); + return false; + } else { + proc_terminate($entry['proc']); + $entry['term']=true; + $this->uplink->privmsg($this->bot, $entry['channel'], "perl timeout. (maximum of 10 seconds exceeded) sending SIGTERM"); + return true; + } + } + } + } + +} + +?> \ No newline at end of file -- 2.20.1