ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-IRC3/lib/Net/IRC3.pm
Revision: 1.3
Committed: Sun Jul 16 11:11:17 2006 UTC (18 years, 3 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

# Content
1 package Net::IRC3;
2 use strict;
3 use AnyEvent;
4 use IO::Socket::INET;
5 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 our $ConnectionClass = 'Net::IRC3::Connection';
12
13 =head1 NAME
14
15 Net::IRC3 - An IRC Protocol module which is event system independend
16
17 =head1 VERSION
18
19 Version 0.2
20
21 =cut
22
23 our $VERSION = '0.2';
24
25 =head1 SYNOPSIS
26
27 use Net::IRC3;
28
29 my $irc3 = new Net::IRC3;
30
31 my $con = $irc3->connect ("test.not.at.irc.net", 6667);
32
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 =item B<connect ($host, $port)>
69
70 Tries to open a socket to the host C<$host> and the port C<$port>.
71 If successfull it will return a L<Net::IRC3::Connection> object.
72 If an error occured it will die (use eval to catch the exception).
73
74 =cut
75
76 sub connect {
77 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 eval "require $ConnectionClass";
90 my $con = $ConnectionClass->new ($self, $sock, $host, $port);
91
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 $con->disconnect ("EOF from IRC server '$host:$port'");
102 return;
103
104 } else {
105 $con->disconnect ("Error while reading from IRC server '$host:$port': $!");
106 return;
107 }
108 }
109 });
110
111 return $con;
112 }
113
114 =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 =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 You can export these with eg.:
152
153 use Net::IRC3 qw/parse_irc_msg/;
154
155 =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 mk_msg (undef, "PRIVMSG", "you suck!", "magnus");
242 # will return: "PRIVMSG magnus :you suck!\015\012"
243
244 mk_msg (undef, "JOIN", undef, "#test");
245 # 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 =head1 EXAMPLES
329
330 See the samples/ directory for some examples on how to use Net::IRC3.
331
332 =head1 AUTHOR
333
334 Robin Redeker, C<< <elmex@ta-sa.org> >>
335
336 =head1 SEE ALSO
337
338 L<Net::IRC3::Connection>
339
340 L<Net::IRC3::Client>
341
342 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;