Category: Networking Code
Author/Contact Info motzmo motz@s7ick.org
Description: You have to choose one source server to copy all talks from (OUT_SERVER in %cfg) and other server to paste (IN_SERVER in %cfg) all from source. Looks like some irc 'spy'.
See code's %cfg to understand it better.

You can use some commands on IN_CHANNEL:
!say bla # will say bla to OUT_CHANNEL
!me bla # action say on OUT_CHANNEL
!sayto nick bla # will say bla to nick on OUT_SERVER
!list # will list all OUT_CHANNEL users
!whois nick # whois nick on OUT_SERVER
!nick newnick # change nick on OUT_SERVER


* can transcode between various codepages
* use local IP addr

########### FIXED BUGS ###############
№01: '!sayto nick message' is delivering receiver's nick instead of message
402: elsif($_[0] =~ /^sayto\s+([^\s]+)\s+(.+)/i) 403: { -404: print $out_sock "PRIVMSG ",$1," :",$1,"\r\n"; +404: print $out_sock "PRIVMSG ",$1," :",$2,"\r\n";
№02: wrong color handling on external msg echos
397: elsif($_[0] =~ /^say\s+(.+)/i) 398: { 399: print $out_sock "PRIVMSG ",$cfg{OUT_CHAN}," :",$1,"\r\n"; -400: print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'graylight'} +,"<",$color{'blue'},$cfg{OUT_NICK},$color{'graylight'},"> ",$clr,$1," +\r\n"; +400: print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'graylight'} +,"<",$color{'blue'},$cfg{OUT_NICK},$color{'graylight'},">",$clr,' ',$ +1,"\r\n";
#!perl -w
# Server2Server irc channel spy
# version: stable (0.0.4)
# by motzmo (s7ick.org)

$| = 1;
use strict;
use Encode qw( from_to );
use IO::Socket;
use IO::Select;

my (%cfg,%out_irc,%color,@threads,@userz,$msg,$in_sock,$out_sock,$hand
+le,$readin,$bold,$prop,$clr,$actionsay,$count);
%cfg = (
 OUT_SERVER => 'irc.hackzona.ru',
 OUT_PORT => 6667,
 OUT_CHAN => '#hackzona',
 OUT_NICK => 'antosha',
 OUT_IDENT => 'grisha',
 OUT_NAME => 'grihuil',
 OUT_ALTNICK => 'antosha['.int(rand(200)).']',
 OUT_CHARSET => 'CP1251',
 OUT_LOCALADDR => '77.88.21.3', # local IP address to use
 #
 IN_SERVER => 'irc.iloveyou.org',
 IN_PORT => 6667,
 IN_CHAN => '#bcast.hackzona',
 IN_NICK => '[nfo]',
 IN_IDENT => '0x00',
 IN_NAME => 'Informator.',
 IN_CHARSET => 'UTF-8',
 IN_nickserv_password => 'abcdefg',
 #
 PIDFILE => '.botpid'
);
####################################################################
####################################################################
open TMPFILE, ">".$cfg{PIDFILE};
print TMPFILE $$;
close TMPFILE;
in();out();
$bold = chr 2;
$prop = chr 31;
$clr = chr 3;
$actionsay = chr 1;
%color =
(
 'white'        => $clr."00",
 'black'        => $clr."01",
 'blue'            => $clr."02",
 'green'        => $clr."03",
 'red'            => $clr."04",
 'bardoviy'        => $clr."05",
 'violet'        => $clr."06",
 'orange'        => $clr."07",
 'yellow'        => $clr."08",
 'salad'        => $clr."09",
 'lightblue'    => $clr."10",
 'blueslight'   => $clr."11",
 'darkblue'        => $clr."12",
 'rose'            => $clr."13",
 'gray'            => $clr."14",
 'graylight'    => $clr."15"
);
$readin = IO::Select->new;
$readin->add($in_sock);
$readin->add($out_sock);

while ()
{
 @threads = $readin->can_read;
 foreach (@threads)
 {
  if ($_ eq $in_sock)
  {
$msg = <$in_sock>;
#        print $msg."\r\n"; #### uncomment for debug
#pingponging
     if($msg =~ /^PING\s([^\r]+)/)
     {
      print $in_sock "PONG $1\r\n";
      next;
     }
      elsif ($msg =~ /^\:([^\s\#]+)\!([^\s]+)\@([^\s]+)\s(PRIVMSG|NOTI
+CE)\s([^\s]+)\s\:(.+)\r$/)
      {
       %out_irc =
       (
        "nick" => $1,
        "user" => $2,
        "host" => $3,
        "msgt" => $4,
        "to" => $5,
        "msg" => $6
       );
     if($out_irc{'to'} =~ /^\#.*$/)
      {
       if($out_irc{'msg'} =~ /^\!(.+)/)
        {
         chan_cmds($1);
        }
        next;
      }
     }
#end of pingponging
    
       if(!$in_sock)  # # # # # # # # # ?>>?>>>>>#>#>#>/?????
       {
        $in_sock->close;
        $readin->remove($in_sock);
        sleep 8;
        in();
        $readin->add($in_sock);
       }
  }
  if ($_ eq $out_sock)
  {
$msg = <$out_sock>;
from_to( $msg, $cfg{OUT_CHARSET}, $cfg{IN_CHARSET} );
#    print $msg."\r\n"; #### uncomment for debug
#pingponging
     if($msg =~ /^PING\s([^\r]+)/)
     {
      print $out_sock "PONG $1\r\n";
      next;
     }
#end of pingponging
     elsif ($msg =~ /^\:([^\s\#]+)\!([^\s]+)\@([^\s]+)\s(PRIVMSG|NOTIC
+E)\s([^\s]+)\s\:(.+)\r$/)
      {
      ##### MAIN MESSAGES #####
       %out_irc =
       (
        "nick" => $1,
        "user" => $2,
        "host" => $3,
        "msgt" => $4,
        "to" => $5,
        "msg" => $6
       );
     if($out_irc{'to'} =~ /^\#.*$/)
      {
       if($out_irc{'msg'} =~ /^\!(.+)/)
        {
         #chan_cmds
        }
       if($out_irc{'msg'} =~ /^\Q$actionsay\EACTION/i)
       {
       $out_irc{'msg'} =~ s/\Q$actionsay\EACTION//ig;
       $out_irc{'msg'} =~ s/\Q$actionsay\E//g;
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'blue'},"* 
+",$out_irc{'nick'},$color{'graylight'},$clr,$out_irc{'msg'},"\r\n" if
+ $out_irc{'msgt'} eq "PRIVMSG";
       next;
       }
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'graylight'
+},"<",$color{'blue'},$out_irc{'nick'},$color{'graylight'},">",$clr,' 
+',$out_irc{'msg'},"\r\n" if $out_irc{'msgt'} eq "PRIVMSG";
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'darkblue'}
+,"-",$color{'rose'},$out_irc{'nick'},"/",$out_irc{'to'},$color{'darkb
+lue'},"-",$clr,' ',$out_irc{'msg'},"\r\n" if $out_irc{'msgt'} eq "NOT
+ICE";
       next;
      }
     elsif(lc($out_irc{'to'}) eq lc($cfg{OUT_NICK}))
      {
       if($out_irc{'msg'} =~ /\001(VERSION|FINGER|PING .+)\001/)
        {
            print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :->> CTCP ",$1,"
+ from ",$out_irc{'nick'}," [",$out_irc{'user'},"\@",$out_irc{'host'},
+"]\r\n";
            ctcp_answ ($out_irc{'nick'},$1);
            next;
        }
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$bold,"PRIVATE: ",
+$bold,$color{'graylight'},"<",$color{'blue'},$out_irc{'nick'},$color{
+'graylight'},">",$clr,' ',$out_irc{'msg'},"\r\n" if $out_irc{'msgt'} 
+eq "PRIVMSG";
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'darkblue'}
+,"-",$color{'rose'},$out_irc{'nick'},$color{'darkblue'},"-",$clr,' ',
+$out_irc{'msg'},"\r\n" if $out_irc{'msgt'} eq "NOTICE";
       next;
      }
     }
     elsif($msg =~ /^\:([^\s\#]+)\!([^\s]+)\@([^\s]+)\s(JOIN|PART)\s(\
+:?\#[^\s\:]*)\s?(\:.*)?\r$/i)
     {
     ##### JOINS/PARTS #####
       %out_irc =
       (
        "nick" => $1,
        "user" => $2,
        "host" => $3,
        "msgt" => lc($4),
        "to" => $5,
        "msg" => $6
       );
       $out_irc{'to'} =~ s/\:// if $out_irc{'to'} =~ ":";
       $out_irc{'msg'} =~ s/\:// if $out_irc{'msg'};
       if($out_irc{'msgt'} eq "join")
        {
         print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'green'},
+"* ",$bold,$out_irc{'nick'},$bold, " (",$out_irc{'user'},"\@",$out_ir
+c{'host'},") has joined ",$cfg{OUT_CHAN},"\r\n";
         #onjoin() if lc($out_irc{'nick'}) ne lc($cfg{OUT_NICK});
         next;
        }
       if ($out_irc{'msgt'} eq "part")
        {  
         print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'orange'}
+,"* ",$out_irc{'nick'}," (",$out_irc{'user'},"\@",$out_irc{'host'},")
+ has left ",$cfg{OUT_CHAN},"\r\n";
         next;
        }
     }
     elsif ($msg =~ /^\:([^\s\#]+)\!([^\s]+)\@([^\s]+)\sNICK\s\:([^\s]
++)\r$/)
     {
     ##### NICK CHANGES #####
       %out_irc =
       (
        "nick" => $1,
        "user" => $2,
        "host" => $3,
        "newnick" => $4
       );
       $cfg{OUT_NICK} = $out_irc{'newnick'} if $out_irc{'nick'} eq $cf
+g{OUT_NICK};
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'rose'},"*"
+,$clr,' ',$out_irc{'nick'}," is now known as ",$out_irc{'newnick'},"\
+r\n" if $out_irc{'nick'} ne $cfg{OUT_NICK};
       next;
     }
     elsif ($msg =~ /^\:([^\s\#]+)\!([^\s]+)\@([^\s]+)\sQUIT\s\:(.+)\r
+$/)
     {
     ##### QUITS #####
       %out_irc =
       (
        "nick" => $1,
        "user" => $2,
        "host" => $3,
        "quitmsg" => $4
       );
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'orange'},"
+* ",$out_irc{'nick'}," has quit (Quit: ",$out_irc{'quitmsg'},")\r\n";
       next;
     }
     elsif ($msg =~ /^\:([^\s\#]+)\!([^\s]+)\@([^\s]+)\sKICK\s(\#[^\s\
+:]*)\s([^\s\#]+)\s\:(.+)\r$/)
     {
     ##### KICKS #####
       %out_irc =
       (
        "nick" => $1,
        "chan" => $4,
        "target" => $5,
        "reason" => $6
       );
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'red'},'* '
+,$out_irc{'nick'},' has kicked ',$out_irc{'target'},' from ',$out_irc
+{'chan'},' (',$out_irc{'reason'},')',$clr,"\r\n";
       if($out_irc{'target'} eq $cfg{OUT_NICK}){
       print $out_sock "JOIN ", $cfg{OUT_CHAN}, "\r\n";
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :", $bold, "REJOIN...
+", $bold, "\r\n";
       }
       next;
     }
     elsif ($msg =~ /^\:([^\s\#]+)\!([^\s]+)\@([^\s]+)\sMODE\s(\#[^\s\
+:]*)\s([\+\-][^\s])\s?([^\s\#]*)\r$/)
     {
     ###### MODE CHANGES ######
       %out_irc =
       (
        "nick" => $1,
        "chan" => $4,
        "mode" => $5,
        "target" => $6
       );
       print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'rose'},"*"
+,$clr,' ',$out_irc{'nick'},' sets mode ',$out_irc{'mode'},' ',$out_ir
+c{'chan'},' ',$out_irc{'target'},"\r\n";
       next;
     }
    
    if(!$out_sock)
    {
        $out_sock->close;
        $readin->remove($out_sock);
        sleep 8;
        out();
        $readin->add($out_sock);
    }
  }
 }
} # _END_ WHILE LOL
#########################################################//
##################SUBS###################################//
sub out
{
 $out_sock = new IO::Socket::INET
 (
  'LocalAddr' => $cfg{OUT_LOCALADDR},
  'PeerAddr' => $cfg{OUT_SERVER},
  'PeerPort' => $cfg{OUT_PORT},
  'Proto' => 'tcp',
  'Timeout' => 15
 );
 print $out_sock "NICK ", $cfg{OUT_NICK}, "\r\n";
 print $out_sock "USER ", $cfg{OUT_IDENT}, " ", $out_sock->sockhost, "
+ ", $cfg{OUT_SERVER}, " :", $cfg{OUT_NAME}, "\r\n";
 while (<$out_sock>)
 {
  if($_ =~ /433/)
  {
    $cfg{OUT_NICK} = $cfg{OUT_ALTNICK};
    print $out_sock "NICK ", $cfg{OUT_NICK}, "\r\n";
    next;
  }
  elsif($_ =~ /^PING\s\:([^\r]+)/)
  {
    print $out_sock "PONG $1\r\n";
    last;
  }
  elsif($_ =~ /^\:.+?\s001\s([^\s\#]+)\s\:/)
  {
    last;
  }
 }
 print $out_sock "USER ", $cfg{OUT_IDENT}, " ", $out_sock->sockhost, "
+ ", $cfg{OUT_SERVER}, " :", $cfg{OUT_NAME}, "\r\n";
 print $out_sock "UMODE2 +x\r\n";
 print $out_sock "JOIN ", $cfg{OUT_CHAN}, "\r\n";
} # _END_ SUB OUT
sub in
{
 $in_sock = new IO::Socket::INET
 (
  'PeerAddr' => $cfg{IN_SERVER},
  'PeerPort' => $cfg{IN_PORT},
  'Proto' => 'tcp',
  'Timeout' => 15
 );
 print $in_sock "NICK ", $cfg{IN_NICK}, "\r\n";
 print $in_sock "USER ", $cfg{IN_IDENT}, " ", $in_sock->sockhost, " ",
+ $cfg{IN_SERVER}, " :", $cfg{IN_NAME}, "\r\n";
 while (<$in_sock>)
 {
 if($_ =~ /433/)
  {
    $cfg{IN_NICK} = $cfg{IN_ALTNICK};
    print $in_sock "NICK ", $cfg{IN_NICK}, "\r\n";
    next;
  }
  elsif($_ =~ /^PING\s\:([^\r]+)/)
  {
    print $in_sock "PONG $1\r\n";
    last;
  }
  elsif($_ =~ /^\:.+?\s001\s([^\s\#]+)\s\:/)
  {
    last;
  }
 }
 print $in_sock "USER ", $cfg{IN_IDENT}, " ", $in_sock->sockhost, " ",
+ $cfg{IN_SERVER}, " :", $cfg{IN_NAME}, "\r\n";
 print $in_sock "NICKSERV IDENTIFY ", $cfg{IN_nickserv_password}, "\r\
+n"; ## :)
  print $in_sock "JOIN ", $cfg{IN_CHAN}, "\r\n";
} # _END_ SUB IN
sub ctcp_answ
{
 if($_[1] eq "VERSION")
 {
    print $out_sock "NOTICE ",$_[0]," :",chr 1,"VERSION ",'s7ick secur
+ity::IRC Client Engine',chr 1,"\r\n";
 }
 elsif($_[1] eq "FINGER")
 {
    print $out_sock "NOTICE ",$_[0]," :",chr 1,"FINGER ",'.!.',chr 1,"
+\r\n";

 }
 elsif($_[1] =~ /^PING (.+)/)
 {
    print $out_sock "NOTICE ",$_[0]," :",chr 1,"PING $1",chr 1,"\r\n";

 }
} # _END_ CTCPz
sub chan_cmds 
{
 if ($_[0] =~ /^whois\s+([^\s]+)\s*$/i)
 {
  print $out_sock "WHOIS ",$1,"\r\n";
  while(<$out_sock>)
  {
   s/[\r\n]//g;
   if($_ =~ /^\:[^\s]+\s(311|307|319|312|317|318)\s\Q$cfg{OUT_NICK}\E\
+s(.+)/)
   {
    print $in_sock "PRIVMSG ",$out_irc{'nick'}," :",$2,"\r\n";
    last if $1 == 318;
    next;
   }
   elsif($_ =~ /^PING\s([^\r]+)/)
   {
    print $out_sock "PONG $1\r\n";
   }
  }
 }
 elsif ($_[0] =~ /^nick\s+([^\s]+)\s*$/i)
 {
  print $out_sock "NICK ",$1,"\r\n";
  $cfg{OUT_NICK} = $1;
 }
 elsif ($_[0] =~ /^list\s*$/i)
 {
  print $out_sock "WHO ",$cfg{OUT_CHAN},"\r\n";
  while(<$out_sock>)
  {
   s/[\r\n]//g;
   if($_ =~ /^\:[^\s]+\s352\s[^\s]+\s[^\s]+\s[^\s]+\s[^\s]+\s[^\s]+\s(
+[^\s]+)\s/)
   {
    push @userz, $1;
   }
   elsif($_ =~ /^\:[^\s]+\s315\s/)
   {
    print $in_sock "PRIVMSG ",$out_irc{'nick'}," :";
    $count = 0;
    foreach (@userz)
    {
     $count++;
     print $in_sock $_," [] ";
     if($count == 5)
      {
         $count = 0;
         print $in_sock "\r\n";
         print $in_sock "PRIVMSG ",$out_irc{'nick'}," :";
      }
    }
    print $in_sock "\r\n";
    @userz = ();
    last;
   }
   elsif($_ =~ /^PING\s([^\r]+)/)
   {
    print $out_sock "PONG $1\r\n";
   }
  }
 }
 elsif($_[0] =~ /^say\s+(.+)/i)
 {
 my $messodj = $1;
 from_to( $messodj, $cfg{IN_CHARSET}, $cfg{OUT_CHARSET} );
 print $out_sock "PRIVMSG ",$cfg{OUT_CHAN}," :",$messodj,"\r\n";
 print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'graylight'},"<",
+$color{'blue'},$cfg{OUT_NICK},$color{'graylight'},">",$clr,' ',$1,"\r
+\n";
 }
 elsif($_[0] =~ /^me\s+(.+)/i)
 {
 my $messodj = $1;
 from_to( $messodj, $cfg{IN_CHARSET}, $cfg{OUT_CHARSET} );
 print $out_sock "PRIVMSG ",$cfg{OUT_CHAN}," :$actionsay",$messodj,"$a
+ctionsay\r\n";

  print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'blue'},"* ",$cf
+g{'OUT_NICK'},$color{'graylight'},$clr," ",$1,"\r\n";
# print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :",$color{'graylight'},"<"
+,$color{'blue'},$cfg{OUT_NICK},$color{'graylight'},">",$clr,' ',$1,"\
+r\n";
 }
 elsif($_[0] =~ /^sayto\s+([^\s]+)\s+(.+)/i)
 {
 my $messodj = $2;
 from_to( $messodj, $cfg{IN_CHARSET}, $cfg{OUT_CHARSET} );
 print $out_sock "PRIVMSG ",$1," :",$messodj,"\r\n";
 print $in_sock "PRIVMSG ",$cfg{IN_CHAN}," :msg sent to ",$1,"\r\n";
 }
} # _END_ CMDS
unlink $cfg{PIDFILE};
# 2008, B.C.D. World Powered.