. * * * ************************************************************************ * * 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); $this->uplink->join($this->bot, "#CoderCom", 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) { $opOnPerlChannel = false; $entryChannel = P10_Channel::getChannelByName("#Perl"); if($entryChannel) { $privs = $entryChannel->getUserPrivs($user); $opOnPerlChannel = ($privs & P10_Channel::USERPRIV_OPED); } if(!$user->getModes()->hasMode('o') && !$opOnPerlChannel) 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; } } } } } ?>