line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::Chat::Jabber; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
Net::Chat::Jabber - Jabber protocol adapter for Net::Chat::Daemon |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 API |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=over 4 |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=cut |
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
680
|
use Net::Jabber qw(Client); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our $VERSION = '0.1'; |
15
|
|
|
|
|
|
|
our @ISA = qw(Net::Jabber::Client); |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
use Net::Jabber::JID; |
18
|
|
|
|
|
|
|
use Time::HiRes; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use strict; |
21
|
|
|
|
|
|
|
use warnings; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# my $DEFAULT_SERVER = "jabber.org"; |
24
|
|
|
|
|
|
|
my $DEFAULT_SERVER = undef; # Have not gotten permission from jabber.org |
25
|
|
|
|
|
|
|
my $DEFAULT_PASSWORD = "nopassword"; |
26
|
|
|
|
|
|
|
my $DEFAULT_RESOURCE = "default"; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Internal routine to display a log message depending on the loglevel |
29
|
|
|
|
|
|
|
# setting. |
30
|
|
|
|
|
|
|
sub _log { |
31
|
|
|
|
|
|
|
my $self = shift; |
32
|
|
|
|
|
|
|
my $message; |
33
|
|
|
|
|
|
|
my $level = 0; |
34
|
|
|
|
|
|
|
if (@_ == 1) { |
35
|
|
|
|
|
|
|
$message = shift; |
36
|
|
|
|
|
|
|
} else { |
37
|
|
|
|
|
|
|
($level, $message) = @_; |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
my $allow_level = $self->{loglevel} || 0; |
40
|
|
|
|
|
|
|
return if $level > $allow_level; |
41
|
|
|
|
|
|
|
print $message, "\n"; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=item B() |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
class - the name of the class we're creating |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
jid - a string giving the JID, or a JID object |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
%options |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
password - the password to provide during authentication. TODO: if |
53
|
|
|
|
|
|
|
this is not provided but a password is needed, some sort of |
54
|
|
|
|
|
|
|
authCallback is needed. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
loglevel - logs with level higher than this are not displayed. |
57
|
|
|
|
|
|
|
Defaults to 0. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=cut |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub new { |
62
|
|
|
|
|
|
|
my ($class, $app, $jid, %options) = @_; |
63
|
|
|
|
|
|
|
$jid = __default_jid($jid, $DEFAULT_SERVER, $DEFAULT_RESOURCE); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
my $self = $class->SUPER::new(); |
66
|
|
|
|
|
|
|
@$self{keys %options} = values %options; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
$self->{jid} = $jid; |
69
|
|
|
|
|
|
|
$self->{password} ||= $DEFAULT_PASSWORD; |
70
|
|
|
|
|
|
|
$self->{user} ||= $jid->GetUserID; |
71
|
|
|
|
|
|
|
$self->{server} ||= $jid->GetServer; |
72
|
|
|
|
|
|
|
$self->{resource} ||= $jid->GetResource(); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
$self->_log("[$self->{user}] pid=$$"); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$self->_init_callbacks($app); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
return $self; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub __default_jid { |
82
|
|
|
|
|
|
|
my ($jid, $server, $resource) = @_; |
83
|
|
|
|
|
|
|
$jid = new Net::Jabber::JID($jid); |
84
|
|
|
|
|
|
|
$jid->SetServer($server) if defined($server) && ! $jid->GetServer; |
85
|
|
|
|
|
|
|
$jid->SetResource($resource) if defined($resource) && ! $jid->GetResource; |
86
|
|
|
|
|
|
|
return $jid; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=item B() |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Connect to the server, attempting to register if the specified user is |
92
|
|
|
|
|
|
|
not yet registered. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=cut |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub connect { |
97
|
|
|
|
|
|
|
my ($self) = @_; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
$self->Connect(hostname => $self->{server}) or return; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
my @identification = (username => $self->{user}, |
102
|
|
|
|
|
|
|
password => $self->{password}, |
103
|
|
|
|
|
|
|
resource => $self->{resource}); |
104
|
|
|
|
|
|
|
my @result = $self->AuthSend(@identification); |
105
|
|
|
|
|
|
|
$self->_log(0, "auth status for $self->{user} ($$): $result[0] - $result[1]"); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
if ($result[0] eq "401") { |
108
|
|
|
|
|
|
|
@result = $self->RegisterSend(@identification); |
109
|
|
|
|
|
|
|
$self->_log(0, "register status: " . join(" - ", @result)); |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
if ($result[0] eq "ok") { |
112
|
|
|
|
|
|
|
@result = $self->AuthSend(@identification); |
113
|
|
|
|
|
|
|
$self->_log(0, "auth status for $self->{user} ($$): $result[0] - $result[1]"); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
$self->PresenceSend(); |
118
|
|
|
|
|
|
|
return 1; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=item B() |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
Reestablish a broken connection. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=cut |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub reconnect { |
128
|
|
|
|
|
|
|
my ($self) = @_; |
129
|
|
|
|
|
|
|
$self->connect(); |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=item B($jid) |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Subscribe to messages coming from $jid. |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=cut |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub subscribe { |
139
|
|
|
|
|
|
|
my ($self, $jid) = @_; |
140
|
|
|
|
|
|
|
$jid = __default_jid($jid, $self->{server}); |
141
|
|
|
|
|
|
|
$self->Subscription(type => "subscribe", to => $jid->GetJID("full")); |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# Internal routine to initialize callbacks. Converts Jabber-specific |
145
|
|
|
|
|
|
|
# callbacks into a simplified set. Which would be useful, if I were to |
146
|
|
|
|
|
|
|
# document what that supposedly simplified set is. |
147
|
|
|
|
|
|
|
sub _init_callbacks { |
148
|
|
|
|
|
|
|
my ($self, $app) = @_; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
$self->SetMessageCallBacks(normal => sub { |
151
|
|
|
|
|
|
|
local $app->{message} = $_[1]; |
152
|
|
|
|
|
|
|
$self->_onMessage($app, @_); |
153
|
|
|
|
|
|
|
}); |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
$self->SetMessageCallBacks(chat => sub { |
156
|
|
|
|
|
|
|
local $app->{message} = $_[1]; |
157
|
|
|
|
|
|
|
$self->_onMessage($app, @_); |
158
|
|
|
|
|
|
|
}); |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
$self->SetPresenceCallBacks(available => sub { |
161
|
|
|
|
|
|
|
for my $cb (@{ $app->{callbacks}{available} }) { |
162
|
|
|
|
|
|
|
return if ($cb->(@_)); # First true value handles |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
}); |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
$self->SetPresenceCallBacks(unavailable => sub { |
167
|
|
|
|
|
|
|
for my $cb (@{ $app->{callbacks}{unavailable} }) { |
168
|
|
|
|
|
|
|
return if ($cb->(@_)); # First true value handles |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
}); |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
$self->SetMessageCallBacks(error => sub { |
173
|
|
|
|
|
|
|
for my $cb (@{ $app->{callbacks}{error} }) { |
174
|
|
|
|
|
|
|
return if ($cb->(@_)); # First true value handles |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
my $error = $_[1]; |
177
|
|
|
|
|
|
|
my $from = $error->GetFrom(); |
178
|
|
|
|
|
|
|
my $subject = $error->GetSubject(); |
179
|
|
|
|
|
|
|
my $body = $error->GetBody(); |
180
|
|
|
|
|
|
|
$self->_log(-1, "($$) unnoticed error from $from: ($subject) $body"); |
181
|
|
|
|
|
|
|
}); |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=item B($to,$message,options...) |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Send the message text $message to $to. Available options: |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
subject: set the subject of the message (rarely used) |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
thread: mark the message as a reply in the given thread |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
attachments: an array of attachments, where each attachment |
193
|
|
|
|
|
|
|
is either a chunk of text, or an XML tree. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=cut |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub post { |
198
|
|
|
|
|
|
|
my ($self, $to, $message, %options) = @_; |
199
|
|
|
|
|
|
|
$to = __default_jid($to, $self->{server}); |
200
|
|
|
|
|
|
|
my $subject = $options{subject} || ref($self) . " message"; |
201
|
|
|
|
|
|
|
my @args = (); |
202
|
|
|
|
|
|
|
push(@args, thread => $options{thread}) if defined $options{thread}; |
203
|
|
|
|
|
|
|
my $thr = ($options{thread} ? " thr=$options{thread}" : ""); |
204
|
|
|
|
|
|
|
$self->_log(1, "($self->{user} -> $to$thr) $message"); |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
my $msg = new Net::Jabber::Message; |
207
|
|
|
|
|
|
|
$msg->SetMessage(to => $to->GetJid("full"), |
208
|
|
|
|
|
|
|
subject => $subject, |
209
|
|
|
|
|
|
|
body => $message, |
210
|
|
|
|
|
|
|
@args); |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
my @attachments = @{ $options{attachments} || [] }; |
213
|
|
|
|
|
|
|
if (@attachments > 0) { |
214
|
|
|
|
|
|
|
my $attaches_node = $msg->{TREE}->add_child("attachments"); # FIXME {TREE} |
215
|
|
|
|
|
|
|
foreach my $attachment (@attachments) { |
216
|
|
|
|
|
|
|
my $attach_node = $attaches_node->add_child("attachment"); |
217
|
|
|
|
|
|
|
if (! ref $attachment) { |
218
|
|
|
|
|
|
|
$attach_node->add_child("type", 'data'); |
219
|
|
|
|
|
|
|
$attach_node->add_child("data", $attachment); |
220
|
|
|
|
|
|
|
} else { |
221
|
|
|
|
|
|
|
while (my ($tag, $value) = each %$attachment) { |
222
|
|
|
|
|
|
|
$attach_node->add_child($tag, $value); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
$self->Send($msg); |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=item B(to,message,options...) |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
Send out a request, but do not wait for the reply. |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=cut |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub send_request { |
238
|
|
|
|
|
|
|
my ($self, $to, $message, %options) = @_; |
239
|
|
|
|
|
|
|
$options{thread} ||= "tid-" . Time::HiRes::time(); |
240
|
|
|
|
|
|
|
$options{subject} ||= ref($self) . " request"; |
241
|
|
|
|
|
|
|
$self->_log(1, "($self->{user}) starting transaction with thread $options{thread}"); |
242
|
|
|
|
|
|
|
$self->start_transaction($options{thread}, $options{onReply}); |
243
|
|
|
|
|
|
|
$self->post($to, $message, %options); |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
=item B(to,message,options...) |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
Make a synchronous request. Returns the body of the reply message. |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=cut |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
sub request { |
253
|
|
|
|
|
|
|
my ($self, $to, $message, %options) = @_; |
254
|
|
|
|
|
|
|
my $thread = $options{thread} ||= "tid-" . Time::HiRes::time(); |
255
|
|
|
|
|
|
|
my $reply; |
256
|
|
|
|
|
|
|
$options{onReply} = sub { $reply = shift; }; |
257
|
|
|
|
|
|
|
$self->send_request($to, $message, %options); |
258
|
|
|
|
|
|
|
while (1) { |
259
|
|
|
|
|
|
|
defined $self->Process() or die "jabber network error"; |
260
|
|
|
|
|
|
|
last if defined $reply; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
return $reply->GetBody(); |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# Internal routine that gets called on every message, before it gets |
267
|
|
|
|
|
|
|
# categorized as a request, reply, or whatever. |
268
|
|
|
|
|
|
|
sub _onMessage { |
269
|
|
|
|
|
|
|
my ($self, $app, $sid, $message, %extra) = @_; |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
$self->_log(1, "($$) got message from " . $message->GetFrom() . ": " . $message->GetBody()); |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# First, check whether it has a thread id of the syntax used for |
274
|
|
|
|
|
|
|
# request/reply pairs |
275
|
|
|
|
|
|
|
my $thread = $message->GetThread(); |
276
|
|
|
|
|
|
|
if (defined($thread) && $thread =~ /^tid-/) { |
277
|
|
|
|
|
|
|
$self->_log(2, " found thread $thread"); |
278
|
|
|
|
|
|
|
if (exists $self->{active}{$thread}) { |
279
|
|
|
|
|
|
|
$self->_log(2, " ending current transaction"); |
280
|
|
|
|
|
|
|
my $cb = $self->end_transaction($thread); |
281
|
|
|
|
|
|
|
if (UNIVERSAL::isa($cb, 'CODE')) { |
282
|
|
|
|
|
|
|
return $cb->($message, $thread, %extra); |
283
|
|
|
|
|
|
|
} else { |
284
|
|
|
|
|
|
|
return $app->onReply($message, $thread, %extra); |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
} else { |
287
|
|
|
|
|
|
|
$self->_log(2, " no current transaction, must be request"); |
288
|
|
|
|
|
|
|
return $app->onRequest($message, %extra); |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
} else { |
291
|
|
|
|
|
|
|
$self->_log(2, " no thread"); |
292
|
|
|
|
|
|
|
return $app->onMessage($message, %extra); |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=item B($transaction_id, $onReply) |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Start a transaction. A transaction is identified by the given id, |
299
|
|
|
|
|
|
|
and... blah blah blah this is very important but I don't remember |
300
|
|
|
|
|
|
|
what I did here. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=cut |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
sub start_transaction { |
305
|
|
|
|
|
|
|
my ($self, $trans_id, $onReply) = @_; |
306
|
|
|
|
|
|
|
$onReply ||= 1; |
307
|
|
|
|
|
|
|
$self->{active}{$trans_id} = $onReply; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=item B($transaction_id) |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Normally called automatically. Terminates a transaction and erases |
313
|
|
|
|
|
|
|
the transaction callback. |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=cut |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
sub end_transaction { |
318
|
|
|
|
|
|
|
my ($self, $trans_id) = @_; |
319
|
|
|
|
|
|
|
if (exists $self->{active}{$trans_id}) { |
320
|
|
|
|
|
|
|
my $cb = delete $self->{active}{$trans_id}; |
321
|
|
|
|
|
|
|
$self->remove_callback('message', $trans_id); |
322
|
|
|
|
|
|
|
return $cb; |
323
|
|
|
|
|
|
|
} else { |
324
|
|
|
|
|
|
|
$self->_log(-1, "tried to end nonexistent transaction '$trans_id'"); |
325
|
|
|
|
|
|
|
return; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=item B($transaction_id) |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
Return the number of active karfloomer hangers for the given |
332
|
|
|
|
|
|
|
transaction. The method name is awful; this is counting karfloomer |
333
|
|
|
|
|
|
|
hangers for a given transaction, not the number of transactions. FIXME |
334
|
|
|
|
|
|
|
when I figure this all out. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=cut |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub count_transactions { |
339
|
|
|
|
|
|
|
my ($self) = @_; |
340
|
|
|
|
|
|
|
return scalar(keys %{ $self->{active} }); |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=item B() |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
Wait until no more active transactions are outstanding. |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=cut |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
sub barrier { |
350
|
|
|
|
|
|
|
my ($self) = @_; |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
$self->_log(1, "[$self->{user}] ...pausing..."); |
353
|
|
|
|
|
|
|
while (1) { |
354
|
|
|
|
|
|
|
my $nactive = $self->count_transactions(); |
355
|
|
|
|
|
|
|
last if $nactive == 0; |
356
|
|
|
|
|
|
|
$self->_log(0, "[$self->{user}] ...pausing, $nactive active trans"); |
357
|
|
|
|
|
|
|
last if ! defined $self->Process(5); |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=item B() |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Check whether any messages are available. |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=cut |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub poll { |
368
|
|
|
|
|
|
|
my ($self) = @_; |
369
|
|
|
|
|
|
|
$self->Process(0); |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=item B([$timeout]) |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
Wait $timeout seconds for more messages to come in. If $timeout is not |
375
|
|
|
|
|
|
|
given or undefined, block until a message is received. |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
Return value: 1 = data received, 0 = ok but no data received, undef = error |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=cut |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
sub wait { |
382
|
|
|
|
|
|
|
my $self = shift; |
383
|
|
|
|
|
|
|
$self->Process(@_); |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
1; |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=back |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=head1 SEE ALSO |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
Net::Chat::Daemon, Net::Jabber, Net::XMPP |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=head1 AUTHOR |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
Steve Fink Esfink@cpan.orgE |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
Send bug reports directly to me. Include the module name in the |
399
|
|
|
|
|
|
|
subject of the email message. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
Copyright 2004 by Steve Fink |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
406
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=cut |