ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-IRC3/lib/Net/IRC3/Util.pm
Revision: 1.6
Committed: Tue Jul 18 11:12:09 2006 UTC (18 years, 4 months ago) by elmex
Branch: MAIN
Changes since 1.5: +22 -13 lines
Log Message:
hacked around for CTCP

File Contents

# User Rev Content
1 elmex 1.1 package Net::IRC3::Util;
2     use strict;
3     use Exporter;
4     our @ISA = qw/Exporter/;
5     our @EXPORT_OK =
6     qw(mk_msg parse_irc_msg split_prefix prefix_nick
7 elmex 1.6 decode_ctcp filter_ctcp_text_attr prefix_user prefix_host);
8 elmex 1.1
9     =head1 NAME
10    
11     Net::IRC3::Util - Common utilities that help with IRC protocol handling
12    
13 elmex 1.2 =head1 SYNOPSIS
14    
15     use Net::IRC3 qw/parse_irc_msg mk_msg/;
16    
17     my $msgdata = mk_msg (undef, PRIVMSG
18    
19 elmex 1.1 =head1 FUNCTIONS
20    
21     These are some utility functions that might come in handy when
22     handling the IRC protocol.
23    
24     You can export these with eg.:
25    
26     use Net::IRC3 qw/parse_irc_msg/;
27    
28     =over 4
29    
30     =item B<parse_irc_msg ($ircline)>
31    
32     This method parses the C<$ircline>, which is one line of the IRC protocol
33     without the trailing "\015\012".
34    
35     It returns a hash which has the following entrys:
36    
37     =over 4
38    
39     =item prefix
40    
41     The message prefix.
42    
43     =item command
44    
45     The IRC command.
46    
47     =item params
48    
49     The parameters to the IRC command in a array reference,
50     this includes the trailing parameter (the one after the ':' or
51     the 14th parameter).
52    
53     =item trailing
54    
55     This is set if there was a trailing parameter (the one after the ':' or
56     the 14th parameter).
57    
58     =back
59    
60     =cut
61    
62     sub parse_irc_msg {
63     my ($msg) = @_;
64    
65     my $cmd;
66     my $pref;
67     my $t;
68     my @a;
69    
70     my $p = $msg =~ s/^(:([^ ]+)[ ])?([A-Za-z]+|\d{3})//;
71     $pref = $2;
72     $cmd = $3;
73    
74     my $i = 0;
75    
76     while ($msg =~ s/^[ ]([^ :\015\012\0][^ \015\012\0]*)//) {
77    
78     push @a, $1 if defined $1;
79     if (++$i > 13) { last; }
80     }
81    
82     if ($i == 14) {
83    
84     if ($msg =~ s/^[ ]:?([^\015\012\0]*)//) {
85     $t = $1 if $1 ne "";
86     }
87    
88     } else {
89    
90     if ($msg =~ s/^[ ]:([^\015\012\0]*)//) {
91     $t = $1 if $1 ne "";
92     }
93     }
94    
95     push @a, $t if defined $t;
96    
97     my $m = { prefix => $pref, command => $cmd, params => \@a, trailing => $t };
98     return $p ? $m : undef;
99     }
100    
101     =item B<mk_msg ($prefix, $command, $trailing, @params)>
102    
103     This function assembles a IRC message. The generated
104     message will look like (pseudo code!)
105    
106     :<prefix> <command> <params> :<trail>
107    
108     Please refer to RFC 2812 how IRC messages normally look like.
109    
110     The prefix and the trailing string will be omitted if they are C<undef>.
111    
112     EXAMPLES:
113    
114     mk_msg (undef, "PRIVMSG", "you suck!", "magnus");
115     # will return: "PRIVMSG magnus :you suck!\015\012"
116    
117     mk_msg (undef, "JOIN", undef, "#test");
118 elmex 1.5 # will return: "JOIN #test\015\012"
119 elmex 1.1
120     =cut
121    
122     sub mk_msg {
123     my ($prefix, $command, $trail, @params) = @_;
124     my $msg = "";
125    
126     $msg .= defined $prefix ? ":$prefix " : "";
127     $msg .= "$command";
128    
129     # FIXME: params must be counted, and if > 13 they have to be
130     # concationated with $trail
131     map { $msg .= " $_" } @params;
132    
133     $msg .= defined $trail ? " :$trail" : "";
134     $msg .= "\015\012";
135    
136     return $msg;
137     }
138    
139    
140 elmex 1.6 =item B<decode_ctcp_req ($line)>
141 elmex 1.1
142     =cut
143    
144     sub decode_ctcp {
145 elmex 1.6 my ($line) = @_;
146 elmex 1.1
147 elmex 1.6 while ($line =~ /\G\001([^\001]*)\001/g) {
148     my $req = $1;
149     }
150 elmex 1.1
151 elmex 1.6 $line =~ s/\001[^\001]*\001//g;
152 elmex 1.1
153 elmex 1.6 return $line;
154     }
155 elmex 1.1
156 elmex 1.6 # implemented after the below CTCP spec, but
157     # doesnt seem to be used by anyone... so it's untested.
158     sub filter_ctcp_text_attr {
159     my ($line, $cb) = @_;
160     $cb ||= sub { '' };
161     $line =~ s/\006([BVUSI])/{warn "FIL\n"; my $c = $cb->($1); defined $c ? $c : "\006$1"}/ieg;
162     $line =~ s/\006CA((?:I[0-9A-F]|#[0-9A-F]{3}){2})/{my $c = $cb->($1); defined $c ? $c : "\006CA$1"}/ieg;
163     $line =~ s/\006C([FB])(I[0-9A-F]|#[0-9A-F]{3})/{my $c = $cb->($1, $2); defined $c ? $c : "\006C$1$2"}/ieg;
164     $line =~ s/\006CX([AFB])/{my $c = $cb->($1); defined $c ? $c : "\006CX$1"}/ieg;
165     return $line;
166 elmex 1.1 }
167    
168     =item B<split_prefix ($prefix)>
169    
170     This function splits an IRC user prefix as described by RFC 2817
171     into the three parts: nickname, user and host. Which will be
172     returned as a list with that order.
173    
174     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
175    
176     =cut
177    
178     sub split_prefix {
179     my ($prfx) = @_;
180    
181     if (ref ($prfx) eq 'HASH') {
182     $prfx = $prfx->{prefix};
183     }
184    
185     $prfx =~ m/^\s*([^!]*)!([^@]*)@(.*?)\s*$/;
186     return ($1, $2, $3);
187     }
188    
189     =item B<prefix_nick ($prefix)>
190    
191     A shortcut to extract the nickname from the C<$prefix>.
192    
193     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
194    
195     =cut
196    
197     sub prefix_nick {
198     my ($prfx) = @_;
199     return (split_prefix ($prfx))[0];
200     }
201    
202     =item B<prefix_user ($prefix)>
203    
204     A shortcut to extract the username from the C<$prefix>.
205    
206     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
207    
208     =cut
209    
210     sub prefix_user {
211     my ($prfx) = @_;
212     return (split_prefix ($prfx))[1];
213     }
214    
215     =item B<prefix_host ($prefix)>
216    
217     A shortcut to extract the hostname from the C<$prefix>.
218    
219     C<$prefix> can also be a hash like it is returned by C<parse_irc_msg>.
220    
221     =cut
222    
223     sub prefix_host {
224     my ($self, $prfx) = @_;
225     return (split_prefix ($prfx))[2];
226     }
227    
228     =back
229    
230     =head1 AUTHOR
231    
232     Robin Redeker, C<< <elmex@ta-sa.org> >>
233    
234     =head1 SEE ALSO
235    
236 elmex 1.6 Internet Relay Chat Client To Client Protocol from February 2, 1997
237     http://www.invlogic.com/irc/ctcp.html
238    
239 elmex 1.1 RFC 2812 - Internet Relay Chat: Client Protocol
240    
241     =head1 COPYRIGHT & LICENSE
242    
243 elmex 1.3 Copyright 2006 Robin Redeker, all rights reserved.
244 elmex 1.1
245     This program is free software; you can redistribute it and/or modify it
246     under the same terms as Perl itself.
247    
248     =cut
249    
250     1;