All pastes #734966 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-10-13 05:38 UTC
rendered paste body
#!/usr/bin/perl

BEGIN { 
  local $_ = $0; 
  s#\\#/#g; # those ass backwards \'s annoy me
  m#.*/#; 
  push @INC, $& . "lib"; 
} 

$|++; 

use strict;
use warnings; 

use Carp qw(croak);
use Socket; 

use IRC::Sock; 
use IRC::Parser;

my $IRC = IRC::Sock->spawn(Host => 'irc.icq.com:6667');

my $Parser = IRC::Parser->new; 

print $IRC "NICK ubu\nUSER bob \"\" \"\" :unf\n"; 

while(<$IRC>) { 
  my($origin, $command, $target, $args, $text) = $Parser->break;
  my($nick, $host) = split /!/, $origin if defined $origin; 
  
  print $target . "; (" . $command . ")" . $text . "\n" if $text;   
  print $IRC "PONG :" . $text . "\n"   if($command eq 'PING') ;
 
  print $IRC "JOIN #bored\n" if $command eq '005';
  
  if (defined $nick) { 
    if ($nick eq 'stacey' && $text =~ /^die\s*(.*)/) { print $IRC "QUIT " . $1 . "\n"; }
	
  } 
}












package IRC::Parser; 

use strict; 
use warnings; 

# ok, the idea here.. 
# plugin always takes precedence, this way any protocol fixes for any ircd.. 
# can be easily added, defined.. 
# IRC does not need parsed twice, I really could give a fuck if someone thinks they 
# NEED TO in some special case.. so if they define a plugin, handle the line there!! simple enough.. 
# and I can't see any need in defining a protocol fix twice, so I'm not iterating through a list of them
# not that it'd be anymore difficult, just it'd be pointless to do so.


sub new { 
  my $class = shift;
  bless {
    origin => undef, 
    command => undef, 
    target => undef,
    args => undef, 
    text => undef, 
    raw => undef
  }, $class; 
} 

# ?origin? - command - ?target? - ?arguments? - ?text?
sub break { 
  my $self = shift;
  (local $_ = ($self->{raw} = shift || $_)) =~ s/[\r\n]$//g; 
  if(@{ $self }{qw(origin command target args text)} = $_ =~ /^
    (?:\x3a(\S+)\x20+)?
    (\d{3}|[A-Za-z]+)
    (?: 
      \x20+
      ((?!\x3a)\S+)
      \x20*		
      (
        (?:\x20*(?!\x3a)\S+)*
      )
    )?
    \x20*
    \x3a?
    (.*)
  $/x) { # gotta love that gibberish, IRC is a ludicrous protocol 
    my @broken = ($1, ($self->{command} = uc($2)), $3, $4, $5); 
    wantarray() ? @broken : \@broken;
  } else { warn "Failed to parse ($_); string does not conform to IRC protocol."; } 
} 

1;












package IRC::Sock; 

use strict; 
use warnings; 

BEGIN { 
  local $_ = $0; 
  s#\\#/#g; # those ass backwards \'s annoy me
  m#.*/#; 
  push @INC, $& . "lib"
} 


use Socket; 
use base 'IO::Handle'; 
use Carp qw(croak);

sub new { 
  @_ == 1 
     or croak 'usage: ' . __PACKAGE__ . '->new'; 
  my $Sock = (!ref $_[0] ? shift : ref shift)->SUPER::new;  
  $Sock->autoflush(1); 
  $Sock 
} 

#  IRC::Sock->spawn( 
#    Host => 'severed.org[:80]',
# ); 
sub spawn { 
  @_ >= 2 
    or croak 'usage: ' . __PACKAGE__ . '->connect(ADDRESS, PORT|SERVICE)'; 
  my $Class = shift; 
  my $Sock = $Class->new; 
  $Sock->connect(@_); 
  $Sock
} 

sub connect { 
 my($E, $Sock, %ar) = (undef, shift, @_); 
  my($proto, $host, $port) = $ar{Host} =~ m#^(?:(\w+)://)?((?!/).*\.[a-z]+)(?:[:/](\d+))?#i; 
  $port = getservbyname($proto, 'tcp') 
    if defined $proto && !defined $port; 
  socket($Sock, AF_INET, SOCK_STREAM, getprotobyname('tcp'))
    or croak "Cannot create socket! ($!)"; 
  my $iaddr = inet_aton($host)
    or croak "Cannot resolve host."; 
#	$Sock->blocking(1);
  connect($Sock, sockaddr_in($port || 6667, $iaddr)) || undef
}
1;