. * * * ************************************************************************ * * Bots/CGod.class.php * * simple C debugger... * */ class {$_NAME} extends Bot { private $uplink; private $c, $ccache = array(); public function load($uplink, $old = false) { $this->uplink = $uplink; if(!$old) { $nick = "C"; $ident = "c"; $host = "Services.WebGamesNet.net"; $ip = "0::0"; $realname = "C C C C C"; $modes = "ioknISD"; $this->c = $this->uplink->addUser($nick,$ident,$host,$ip,$modes,$realname); if(is_a($this->c, "P10_User")) { $this->uplink->join($this->c, "#c", (P10_Channel::USERPRIV_OPED | P10_Channel::USERPRIV_VOICE)); $this->uplink->join($this->c, "#dev", P10_Channel::USERPRIV_VOICE); $this->uplink->join($this->c, "#CoderCom", P10_Channel::USERPRIV_VOICE); } } else { $this->c = $old; } ModCMD::bind($this, BIND_CHANMSG, "recive_privmsg"); ModCMD::bind($this, BIND_QUIT, "recive_quit"); } public function unload($rehash = false) { foreach($this->ccache as $id => $c) { fclose($c['pipes'][1]); fclose($c['pipes'][2]); proc_terminate($c['proc'],9); } $this->ccache = array(); if($rehash) { return $this->c; } else { $this->uplink->delUser($this->c, "Bye."); } } public function loop() { foreach($this->ccache as $id => $c) { if(!$this->checkstate($c)) { unlink("tmp/debug_".$c['id'].".c"); unlink("tmp/debug_".$c['id']); unset($this->ccache[$id]); } } } function recive_privmsg($user, $channel, $message) { $opOnCChannel = false; $CChannel = P10_Channel::getChannelByName("#C"); if($CChannel) { $privs = $CChannel->getUserPrivs($user); $opOnCChannel = ($privs & P10_Channel::USERPRIV_OPED); } if(!$user->getModes()->hasMode('o') && !$opOnCChannel) return 0; $exp=explode(" ", $message, 2); switch (strtolower($exp[0])) { case "~c": if(count($this->ccache) > 5) { $this->uplink->notice($this->c, $user, "too many running c processes at the moment!"); return; } $entry=array(); $entry['channel'] = $channel; $entry['id'] = rand(1, 999999); 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 = "#include \"includes.h\" ".$codecontent; } else { $code = "#include \"includes.h\" ".$exp[1]; }; $fp = fopen("tmp/debug_".$entry['id'].".c", "w"); fwrite($fp, $code); fclose($fp); $err = shell_exec("gcc -o tmp/debug_".$entry['id']." tmp/debug_".$entry['id'].".c 2>&1"); if($err) { $err=str_replace("\r","",$err); $lines=explode("\n",$err); $i=0; foreach($lines as $line) { if($line == "") continue; $i++; if($i>100) { $this->uplink->privmsg($this->c, $entry['channel'], "too many lines!"); break; } $this->uplink->privmsg($this->c, $entry['channel'], $line); } } if(!file_exists("tmp/debug_".$entry['id'])) { unlink("tmp/debug_".$entry['id'].".c"); break; } $descriptor = array(0 => array("pipe", "r"),1 => array("pipe", "w"),2 => array("pipe", "w")); $entry['proc'] = proc_open('tmp/debug_'.$entry['id'], $descriptor, $entry['pipes']); if(!is_resource($entry['proc'])) { $this->uplink->notice($this->c, $user, "error while loading c!"); return; } $entry['time'] = time(); fclose($entry['pipes'][0]); $this->ccache[] = $entry; break; } } function recive_quit($user, $reason) { if($user === $this->c) { $this->load($this->uplink); } } function checkstate($c) { $data = proc_get_status($c['proc']); if(!$data['running']) { $out=""; while(!feof($c['pipes'][1])) { $out .= fgets($c['pipes'][1], 128); } $eout=""; while(!feof($c['pipes'][2])) { $eout .= fgets($c['pipes'][2], 128); } if($out != "") { $out=str_replace("\r","",$out); $lines=explode("\n",$out); $i=0; foreach($lines as $line) { if($line == "") continue; $i++; if($i>1000) { $this->uplink->privmsg($this->c, $c['channel'], "too many lines!"); break; } $this->uplink->privmsg($this->c, $c['channel'], $line); } } if($eout != "") { $eout=str_replace("\r","",$eout); $lines=explode("\n",$eout); $i=0; foreach($lines as $line) { if($line == "") continue; $i++; if($i>1000) { $this->uplink->privmsg($this->c, $c['channel'], "too many lines!"); break; } $this->uplink->privmsg($this->c, $c['channel'], "4".$line.""); } } fclose($c['pipes'][1]); fclose($c['pipes'][2]); proc_close($c['proc']); return false; } else { if($c['time']+10 > time()) { return true; } else { //TIMEOUT if($c['term']) { fclose($c['pipes'][1]); fclose($c['pipes'][2]); proc_terminate($c['proc'],9); $this->uplink->privmsg($this->c, $c['channel'], "c hard timeout. sending SIGKILL"); return false; } else { proc_terminate($c['proc']); $c['term']=true; $this->uplink->privmsg($this->c, $c['channel'], "c timeout. (maximum of 10 seconds exceeded) sending SIGTERM"); return true; } } } } } ?>