#!/usr/bin/perl


use strict;
use IO::Socket ();
use LWP::UserAgent;
use HTTP::Request;
use URI::Escape;
use POSIX;
fork() and exit();
setsid();
my ($debug, $PORT, $TOHOST, $TOPORT, $SERVIP, $CLIENTIP, $goodpass, $listen);


$TOHOST = "chat.idx.pl";
$TOPORT = 6667;
$| = 1;


$PORT=1995 if (! $PORT);
$listen='0.0.0.0' if (! $listen);

################################################################################################

{

	my %o = ('port' => $PORT,
           'toport' => $TOPORT,
           'tohost' => $TOHOST);


    my $ah = IO::Socket::INET->new('LocalAddr' => $listen,
                                 'LocalPort' => $PORT,
                                 'Reuse' => 1,
                                 'Listen' => 10)
    || die "Failed to bind to local socket: $!";

  $SIG{'CHLD'} = 'IGNORE';
  my $num = 0;
  while (1) {
    my $ch = $ah->accept();
    if (!$ch) {
      print STDERR "Failed to accept: $!\n";
      next;
    }

    ++$num;

    my $pid = fork();
    if (!defined($pid)) {
      print STDERR "Failed to fork: $!\n";
    } elsif ($pid == 0) {
      $ah->close();
      Run(\%o, $ch, $num);
    } else {
      $ch->close();
    }
  }
}


sub Run {
  my($o, $ch, $num) = @_;
  my $th = IO::Socket::INET->new('PeerAddr' => $o->{'tohost'},
				 'PeerPort' => $o->{'toport'});
	

  $SERVIP=$th->sockhost;
  $CLIENTIP=$ch->peerhost;


  if (!$th) {
    exit 0;
  }

  my ($fh, $nick,$user,$authpass);

  my  $color=1;

  $ch->autoflush();
  $th->autoflush();

   while ($ch || $th) {


    my $rin = "";

    vec($rin, fileno($ch), 1) = 1 if $ch;
    vec($rin, fileno($th), 1) = 1 if $th;
    my($rout, $eout);
    select($rout = $rin, undef, $eout = $rin, 120);
    if (!$rout  &&  !$eout) {
      print STDERR "Child: Timeout, terminating.\n";
    }
    my $cbuffer = "";
    my $tbuffer = "";

    if ($ch  &&  (vec($eout, fileno($ch), 1)  ||
		  vec($rout, fileno($ch), 1))) {
      my $result = sysread($ch, $tbuffer, 1024);

	

		    if ($tbuffer=~ /NICK/ && ! $nick) {
	$nick=$tbuffer;
	$nick=~ s/NICK ~/NICK /s;
	$nick=~ s/^.*NICK (.*?)(\r|\n| ).*$/$1/s;

	


	 if ($tbuffer=~ /USER/) {
	$user=$tbuffer;
	$user=~ s/USER ~/USER /s;
	$user=~ s/^.*USER (.*?)(\r|\n| ).*$/$1/s;

	my $res = syswrite($th, "NICK $nick\n");
my $res = syswrite($th, "USER $nick $nick czat.idx.pl :$nick\n");
};
  
      	};

   



	$tbuffer=~ s/\002(.*?)\002/%Fb%$1%Fn%/sg;
	
	$tbuffer=~ s/(\003\d+),\d+/$1/sg;	

	$tbuffer=~ s/\0037([^\d])/%Cc86c00%$1/sg;
        $tbuffer=~ s/\00312([^\d])/%C0f2ab1%$1/sg;
	$tbuffer=~ s/\0032([^\d])/%C0f2ab1%$1/sg;
        $tbuffer=~ s/\0034([^\d])/%Ce40f0f%$1/sg;
        $tbuffer=~ s/\00310([^\d])/%C1a866e%$1/sg;
        $tbuffer=~ s/\003([^\d])/%C%$1/sg;
	$tbuffer=~ s/\\(\w+)/%I$1%/sg;
	
	
	$tbuffer=~ s/\003\d+/%C%/sg;
	

      if (!defined($result)) {
	print STDERR "Child: Error while reading from client: $!\n";
	exit 0;
      }
      if ($result == 0) {
	exit 0;
      }
    }

    if ($th  &&  (vec($eout, fileno($th), 1)  ||
		  vec($rout, fileno($th), 1))) {
      my $result = sysread($th, $cbuffer, 1024);
      if (!defined($result)) {
	print STDERR "Child: Error while reading from tunnel: $!\n";
	exit 0;
      }
      if ($result == 0) {
	exit 0;
      }


	

		$cbuffer=~ s/%Cc86c00%/\0037/sg;
		$cbuffer=~ s/%C0f2ab1%/\00312/sg;
		$cbuffer=~ s/%Ce40f0f%/\0034/sg;
		$cbuffer=~ s/%C1a866e%/\00310/sg;
		$cbuffer=~ s/%C%/\003/sg; 	 
	

	$cbuffer=~ s/%C\w+?%//sg;

		
		$cbuffer=~ s/%Fi/%F/sg;
		$cbuffer=~ s/%Fb(.*?)%/\002/sg;
		$cbuffer=~ s/(\002.*?)%Fn%/$1\002/;
	

	$cbuffer=~ s/%F.*?%//sg;

	$cbuffer=~ s/%I(\w+?)%/\ <$1> /sg;
	$cbuffer=~ s/&#261;/ą/sg;
$cbuffer=~ s/&#378;/ż/sg;
$cbuffer=~ s/&#263;/ć/sg;
 $cbuffer=~ s/&#281;/ę/sg;
$cbuffer=~ s/&#380;/ż/sg;
$cbuffer=~ s/&#347;/ś/sg;
$cbuffer=~ s/&#322;/ł/sg;
$cbuffer=~ s/&oacute;/ó/sg;

	
   }

    if ($fh  &&  $tbuffer) {
      (print $fh $tbuffer);
    }

    while (my $len = length($tbuffer)) {
      my $res = syswrite($th, $tbuffer, $len);
      if ($res > 0) {
	$tbuffer = substr($tbuffer, $res);
      } else {
	print STDERR "Child: Failed to write to tunnel: $!\n";
      }
    }
    while (my $len = length($cbuffer)) {
      my $res = syswrite($ch, $cbuffer, $len);
      if ($res > 0) {
	$cbuffer = substr($cbuffer, $res);
      } else {
	print STDERR "Child: Failed to write to tunnel: $!\n";
      }
    }
  }
}


