#!/usr/local/bin/perl ## ircautores.pl [an irc client to respond automatically] ## version: 0.02 (last modified at 02/03/28) ## Copyright (C) 2002, Ichikawa Hiromitsu (h-i@bigfoot.com) # ############# use IO::Socket; use IO::Select; ############ user settings ########### ## $ircserver="irc.server.domain"; # irc server $ircport='6666'; # irc port $ircnick="robot"; # irc nickname for this robot $ircpasswd=""; # irc password for connection (option) $ircrealname="Version Robot"; # irc realname $ircchannel="#mychannel"; # join the channel and watch it $interval=300; # interval_proc will be called every $interval sec ## ## end of setting ############################# ############ user code ########### # called every line of the $ircchannel sub resp_mesg_proc { my($msg)=shift @_; if($msg =~ /^:checkservers/i){ $buf="PRIVMSG $ircchannel :Now Checking...\r\n"; $sock->send($buf); my($args)="ALL"; # Is there any arguments? if($msg =~ /^:checkservers\ ([0-9a-zA-Z\-\ ]+)/i){ $args=$1; $args="ALL" if(length($args)>100); } # $args is tainted? no. # synchronous call to avoid DOS attack system("perl ./checkservers.pl $args"); # ignore lines to avoid DOS attack recv_line_all(); # $buf="PRIVMSG $ircchannel :Any request?\r\n"; $sock->send($buf); } if($msg =~ /^:checkalive/i){ $buf="PRIVMSG $ircchannel :IRC_AutoRes is alive.\r\n"; $sock->send($buf); } } # called every $interval second sub interval_proc { # $buf="PRIVMSG $ircchannel :interval(debug)\r\n"; # $sock->send($buf); # asynchronous call for performance system("perl ./checkservers.pl &"); } ################# don't chanage after this ############ # hook for signals sub donothing { } $SIG{INT} = 'donothing'; $SIG{HUP} = 'donothing'; # subroutine for receiving a line from $sock sub recv_line { my($data,$sum,$i); return "" unless( $myselect->can_read(10) ); $sum=""; for(;;){ $sock->recv($data,1); if($data eq ""){ print "------- Connection Closed...\n"; return undef; } last if(($data eq "\r") || ($data eq "\n")); $sum=$sum . $data; } return $sum; } # recv line repeatedly and discard the data sub recv_line_all { my($data); do{ $data=recv_line(); }while((defined $data)&&($data ne "")); if(!defined $data){ $sock->close(); return undef; } return "OK"; } # connect and negotiate sub irc_connect { undef $sock; print "Connecting.....\n"; $sock= IO::Socket::INET->new(PeerAddr => $ircserver, PeerPort => $ircport, Proto => 'tcp'); unless(defined $sock){ print "*** Cannot Connect ***\n"; return undef; } print "connected.....\n"; $myselect = IO::Select->new(); $myselect->add($sock); # send nickname $buf="nick $ircnick\r\n"; $sock->send($buf); # send password to connect (option) if($ircpasswd ne ""){ $buf="pass $ircpasswd\r\n"; $sock->send($buf); } # send user $buf="user $ircnick hostname $ircserver: $ircrealname\r\n"; $sock->send($buf); # read response print "recv before.....\n"; return undef unless(defined recv_line_all() ); print "recv after.....\n"; # send join to join the target channel if($ircchannel ne ""){ $buf="join $ircchannel\r\n"; $sock->send($buf); } # read response # return undef unless(defined recv_line_all() ); print "send join message.....\n"; return "OK"; } # process line sub proc_line { my($data,$data1,$data2,$data3,$data4); # read a line $data=recv_line($sock); return undef unless(defined $data); # do nothing for empty line return "OK" if($data eq ""); # split the message received ($data1,$data2,$data3,$data4)=split(" ",$data,4); # ignore server status return "OK" unless(defined $data2); return "OK" if($data2 =~ /^[0-9][0-9][0-9]$/); # reply PING-PONG if( $data1 =~ /^PING$/i ){ print "PONG>>$data\n"; $buf="pong $ircserver\r\n"; $sock->send($buf); return "OK"; } return "OK" if($data1 =~ /^NOTICE$/i); return "OK" if($data2 =~ /^PONG$/i); print ">>$data\n"; # send CTCP VERSION reply if( ($data2 =~ /privmsg/i) && ($data4 =~ /^:\01VERSION/i) ){ $buf="NOTICE $data3 :\01VERSION IRC_AutoRes.pl_by_ichikawa\01\r\n"; $sock->send($buf); return "OK"; } # extract user undef $user; if( $data1 =~ /^:(.*)!/ ){ $user=$1; } # channel check if( ($data2 =~ /privmsg/i) && ($data3 eq $ircchannel) ){ resp_mesg_proc($data4); return "OK"; } # else return "OK"; } # main loop sub main_loop { print "response ready.....\n"; $lastinterval=time(); while(1){ return unless(defined proc_line()); if($lastinterval+ $interval< time()){ interval_proc(); $lastinterval=time(); } } return; } # start main routine START: while(1){ if(defined irc_connect() ){ main_loop(); } sleep(10); } ################ ## EOF