ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-IRC3/lib/Net/IRC3.pm
Revision: 1.3
Committed: Sun Jul 16 11:11:17 2006 UTC (20 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.2: +40 -10 lines
Log Message:
version 0.2. added documentation and refactored code a bit.

File Contents

# User Rev Content
1 elmex 1.1 package Net::IRC3;
2     use strict;
3     use AnyEvent;
4     use IO::Socket::INET;
5 elmex 1.2 use Exporter;
6     our @ISA = qw/Exporter/;
7     our @EXPORT_OK =
8     qw(mk_msg parse_irc_msg split_prefix prefix_nick
9     prefix_user prefix_host);
10    
11 elmex 1.3 our $ConnectionClass = 'Net::IRC3::Connection';
12 elmex 1.2
13 elmex 1.1 =head1 NAME
14    
15     Net::IRC3 - An IRC Protocol module which is event system independend
16    
17     =head1 VERSION
18    
19 elmex 1.3 Version 0.2
20 elmex 1.1
21     =cut
22    
23 elmex 1.3 our $VERSION = '0.2';
24 elmex 1.1
25     =head1 SYNOPSIS
26    
27     use Net::IRC3;
28    
29     my $irc3 = new Net::IRC3;
30    
31 elmex 1.3 my $con = $irc3->connect ("test.not.at.irc.net", 6667);
32 elmex 1.1
33     ...
34    
35     =head1 DESCRIPTION
36    
37     L<Net::IRC3> itself is a simple building block for an IRC client.
38     It manages connections and parses and constructs IRC messages.
39    
40     L<Net::IRC3> is I<very> simple, if you don't want to care about
41     all the other things that a client still has to do (like replying to
42     PINGs and remembering who is on a channel), I recommend to read
43     the L<Net::IRC3::Client> page instead.
44    
45     =head1 METHODS
46    
47     =over 4
48    
49     =item B<new ()>
50    
51     This just creates a L<Net::IRC3> object, which is a management
52     class for creating and managing connections.
53    
54     =cut
55    
56     sub new
57     {
58     my $this = shift;
59     my $class = ref($this) || $this;
60    
61     my $self = { };
62    
63     bless $self, $class;
64    
65     return $self;
66     }
67    
68 elmex 1.3 =item B<connect ($host, $port)>
69 elmex 1.1
70     Tries to open a socket to the host C<$host> and the port C<$port>.
71 elmex 1.2 If successfull it will return a L<Net::IRC3::Connection> object.
72 elmex 1.1 If an error occured it will die (use eval to catch the exception).
73    
74     =cut
75    
76 elmex 1.3 sub connect {
77 elmex 1.1 my ($self, $host, $port) = @_;
78    
79     defined $self->{connections}->{"$host:$port"}
80     and return;
81    
82     my $sock = IO::Socket::INET->new (
83     PeerAddr => $host,
84     PeerPort => $port,
85     Proto => 'tcp',
86     Blocking => 0
87     ) or die "couldn't connect to irc server '$host:$port': $!\n";;
88    
89 elmex 1.3 eval "require $ConnectionClass";
90     my $con = $ConnectionClass->new ($self, $sock, $host, $port);
91 elmex 1.1
92     $con->{rw} =
93     AnyEvent->io (poll => 'r', fh => $sock, cb => sub {
94     my $l = sysread $sock, my $data, 1024;
95    
96     $con->feed_irc_data ($data);
97    
98     unless ($l) {
99    
100     if (defined $l) {
101 elmex 1.3 $con->disconnect ("EOF from IRC server '$host:$port'");
102 elmex 1.1 return;
103    
104     } else {
105 elmex 1.3 $con->disconnect ("Error while reading from IRC server '$host:$port': $!");
106 elmex 1.1 return;
107     }
108     }
109     });
110    
111     return $con;
112     }
113    
114 elmex 1.3 =item B<connections ()>
115    
116     Returns a key value list, where the key is C<"$host:$port"> and the
117     value is the connection object. Only 'active' connections are returned.
118     That means, if a connection is terminated somehow, it will also disappear
119     from this list.
120    
121     =cut
122    
123     sub connections {
124     my ($self) = @_;
125     return %{$self->{connections}};
126     }
127    
128     =item B<connection ($host, $port)> or B<connection ("$host:$port")>
129    
130     Returns the L<Net::IRC3::Connection> object for the C<$host> C<$port>
131     pair. If no such connection exists, undef is returned.
132    
133     =cut
134    
135     sub connection {
136     my ($self, $host, $port) = @_;
137     if ($host =~ m/^[^:]+:(\d+)$/) {
138     return $self->{connections}->{$host}
139     } else {
140     return $self->{connections}->{$host.':'.$port}
141     }
142     }
143    
144 elmex 1.1 =back
145    
146     =head1 FUNCTIONS
147    
148     These are some utility functions that might come in handy when
149     handling the IRC protocol.
150    
151 elmex 1.2 You can export these with eg.:
152    
153     use Net::IRC3 qw/parse_irc_msg/;
154    
155 elmex 1.1 =over 4
156    
157     =item B<parse_irc_msg ($ircline)>
158    
159     This method parses the C<$ircline>, which is one line of the IRC protocol
160     without the trailing "\015\012".
161    
162     It returns a hash which has the following entrys:
163    
164     =over 4
165    
166     =item prefix
167    
168     The message prefix.
169    
170     =item command
171    
172     The IRC command.
173    
174     =item params
175    
176     The parameters to the IRC command in a array reference,
177     this includes the trailing parameter (the one after the ':' or
178     the 14th parameter).
179    
180     =item trailing
181    
182     This is set if there was a trailing parameter (the one after the ':' or
183     the 14th parameter).
184    
185     =back
186    
187     =cut
188    
189     sub parse_irc_msg {
190     my ($msg) = @_;
191    
192     my $cmd;
193     my $pref;
194     my $t;
195     my @a;
196    
197     my $p = $msg =~ s/^(:([^ ]+)[ ])?([A-Za-z]+|\d{3})//;
198     $pref = $2;
199     $cmd = $3;
200    
201     my $i = 0;
202    
203     while ($msg =~ s/^[ ]([^ :\015\012\0][^ \015\012\0]*)//) {
204    
205     push @a, $1 if defined $1;
206     if (++$i > 13) { last; }
207     }
208    
209     if ($i == 14) {
210    
211     if ($msg =~ s/^[ ]:?([^\015\012\0]*)//) {
212     $t = $1 if $1 ne "";
213     }
214    
215     } else {
216    
217     if ($msg =~ s/^[ ]:([^\015\012\0]*)//) {
218     $t = $1 if $1 ne "";
219     }
220     }
221    
222     push @a, $t if defined $t;
223    
224     my $m = { prefix => $pref, command => $cmd, params => \@a, trailing => $t };
225     return $p ? $m : undef;
226     }
227    
228     =item B<mk_msg ($prefix, $command, $trailing, @params)>
229    
230     This function assembles a IRC message. The generated
231     message will look like (pseudo code!)
232    
233     :<prefix> <command> <params> :<trail>
234    
235     Please refer to RFC 2812 how IRC messages normally look like.
236    
237     The prefix and the trailing string will be omitted if they are C<undef>.
238    
239     EXAMPLES:
240    
241 elmex 1.2 mk_msg (undef, "PRIVMSG", "you suck!", "magnus");
242 elmex 1.1 # will return: "PRIVMSG magnus :you suck!\015\012"
243    
244 elmex 1.2 mk_msg (undef, "JOIN", undef, "#test");
245 elmex 1.1 # will return: "JOIN #magnus\015\012"
246    
247     =cut
248    
249     sub mk_msg {
250     my ($prefix, $command, $trail, @params) = @_;
251     my $msg = "";
252    
253     $msg .= defined $prefix ? ":$prefix " : "";
254     $msg .= "$command";
255    
256     # FIXME: params must be counted, and if > 13 they have to be
257     # concationated with $trail
258     map { $msg .= " $_" } @params;
259    
260     $msg .= defined $trail ? " :$trail" : "";
261     $msg .= "\015\012";
262    
263     return $msg;
264     }
265    
266     =item B<split_prefix ($prefix)>
267    
268     This function splits an IRC user prefix as described by RFC 2817
269     into the three parts: nickname, user and host. Which will be
270     returned as a list with that order.
271    
272     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
273    
274     =cut
275    
276     sub split_prefix {
277     my ($prfx) = @_;
278    
279     if (ref ($prfx) eq 'HASH') {
280     $prfx = $prfx->{prefix};
281     }
282    
283     $prfx =~ m/^\s*([^!]*)!([^@]*)@(.*?)\s*$/;
284     return ($1, $2, $3);
285     }
286    
287     =item B<prefix_nick ($prefix)>
288    
289     A shortcut to extract the nickname from the C<$prefix>.
290    
291     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
292    
293     =cut
294    
295     sub prefix_nick {
296     my ($prfx) = @_;
297     return (split_prefix ($prfx))[0];
298     }
299    
300     =item B<prefix_user ($prefix)>
301    
302     A shortcut to extract the username from the C<$prefix>.
303    
304     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
305    
306     =cut
307    
308     sub prefix_user {
309     my ($prfx) = @_;
310     return (split_prefix ($prfx))[1];
311     }
312    
313     =item B<prefix_host ($prefix)>
314    
315     A shortcut to extract the hostname from the C<$prefix>.
316    
317     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
318    
319     =cut
320    
321     sub prefix_host {
322     my ($self, $prfx) = @_;
323     return (split_prefix ($prfx))[2];
324     }
325    
326     =back
327    
328 elmex 1.2 =head1 EXAMPLES
329 elmex 1.1
330 elmex 1.2 See the samples/ directory for some examples on how to use Net::IRC3.
331 elmex 1.1
332     =head1 AUTHOR
333    
334     Robin Redeker, C<< <elmex@ta-sa.org> >>
335    
336     =head1 SEE ALSO
337    
338 elmex 1.2 L<Net::IRC3::Connection>
339    
340     L<Net::IRC3::Client>
341    
342 elmex 1.1 RFC 2812 - Internet Relay Chat: Client Protocol
343    
344     =head1 BUGS
345    
346     Please report any bugs or feature requests to
347     C<bug-net-irc3 at rt.cpan.org>, or through the web interface at
348     L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-IRC3>.
349     I will be notified, and then you'll automatically be notified of progress on
350     your bug as I make changes.
351    
352     =head1 SUPPORT
353    
354     You can find documentation for this module with the perldoc command.
355    
356     perldoc Net::IRC3
357    
358     You can also look for information at:
359    
360     =over 4
361    
362     =item * AnnoCPAN: Annotated CPAN documentation
363    
364     L<http://annocpan.org/dist/Net-IRC3>
365    
366     =item * CPAN Ratings
367    
368     L<http://cpanratings.perl.org/d/Net-IRC3>
369    
370     =item * RT: CPAN's request tracker
371    
372     L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-IRC3>
373    
374     =item * Search CPAN
375    
376     L<http://search.cpan.org/dist/Net-IRC3>
377    
378     =back
379    
380     =head1 ACKNOWLEDGEMENTS
381    
382     Thanks to Marc Lehmann for the new AnyEvent module!
383    
384     =head1 COPYRIGHT & LICENSE
385    
386     Copyright 2006 Robin Redker, all rights reserved.
387    
388     This program is free software; you can redistribute it and/or modify it
389     under the same terms as Perl itself.
390    
391     =cut
392    
393     1;