[inseparable changes from patch from perl5.003_12 to perl5.003_13]
[p5sagit/p5-mst-13.2.git] / lib / Net / SNPP.pm
CommitLineData
7e1af8bc 1# Net::SNPP.pm
2#
3# Copyright (c) 1995 Graham Barr <Graham.Barr@tiuk.ti.com>. All rights
4# reserved. This program is free software; you can redistribute it and/or
5# modify it under the same terms as Perl itself.
6
7package Net::SNPP;
8
9=head1 NAME
10
11Net::SNPP - Simple Network Pager Protocol Client
12
13=head1 SYNOPSIS
14
15 use Net::SNPP;
16
17 # Constructors
18 $snpp = Net::SNPP->new('snpphost');
19 $snpp = Net::SNPP->new('snpphost', Timeout => 60);
20
21=head1 NOTE
22
23This module is not complete, yet !
24
25=head1 DESCRIPTION
26
27This module implements a client interface to the SNPP protocol, enabling
28a perl5 application to talk to SNPP servers. This documentation assumes
29that you are familiar with the SNPP protocol described in RFC1861.
30
31A new Net::SNPP object must be created with the I<new> method. Once
32this has been done, all SNPP commands are accessed through this object.
33
34=head1 EXAMPLES
35
36This example will send a pager message in one hour saying "Your lunch is ready"
37
38 #!/usr/local/bin/perl -w
39
40 use Net::SNPP;
41
42 $snpp = Net::SNPP->new('snpphost');
43
44 $snpp->send( Pager => $some_pager_number,
45 Message => "Your lunch is ready",
46 Alert => 1,
47 Hold => time + 3600, # lunch ready in 1 hour :-)
48 ) || die $snpp->message;
49
50 $snpp->quit;
51
52=head1 CONSTRUCTOR
53
54=over 4
55
56=item new ( HOST, [ OPTIONS ] )
57
58This is the constructor for a new Net::SNPP object. C<HOST> is the
59name of the remote host to which a SNPP connection is required.
60
61C<OPTIONS> are passed in a hash like fasion, using key and value pairs.
62Possible options are:
63
64B<Timeout> - Maximum time, in seconds, to wait for a response from the
65SNPP server (default: 120)
66
67B<Debug> - Enable debugging information
68
69
70Example:
71
72
73 $snpp = Net::SNPP->new('snpphost',
74 Debug => 1,
75 );
76
77=head1 METHODS
78
79Unless otherwise stated all methods return either a I<true> or I<false>
80value, with I<true> meaning that the operation was a success. When a method
81states that it returns a value, falure will be returned as I<undef> or an
82empty list.
83
84=over 4
85
86=item reset ()
87
88=item help ()
89
90Request help text from the server. Returns the text or undef upon failure
91
92=item quit ()
93
94Send the QUIT command to the remote SNPP server and close the socket connection.
95
96=back
97
98=head1 EXPORTS
99
100C<Net::SNPP> exports all that C<Net::CMD> exports, plus three more subroutines
101that can bu used to compare against the result of C<status>. These are :-
102C<CMD_2WAYERROR>, C<CMD_2WAYOK>, and C<CMD_2WAYQUEUED>.
103
104=head1 SEE ALSO
105
106L<Net::Cmd>
107RFC1861
108
109=head1 AUTHOR
110
111Graham Barr <Graham.Barr@tiuk.ti.com>
112
113=head1 REVISION
114
115$Revision: 1.1 $
116$Date: 1996/07/26 06:49:13 $
117
118The VERSION is derived from the revision by changing each number after the
119first dot into a 2 digit number so
120
121 Revision 1.8 => VERSION 1.08
122 Revision 1.2.3 => VERSION 1.0203
123
124=head1 COPYRIGHT
125
126Copyright (c) 1995 Graham Barr. All rights reserved. This program is free
127software; you can redistribute it and/or modify it under the same terms
128as Perl itself.
129
130=cut
131
132require 5.001;
133
134use strict;
135use vars qw($VERSION @ISA @EXPORT);
136use Socket 1.3;
137use Carp;
138use IO::Socket;
139use Net::Cmd;
140
141$VERSION = do{my @r=(q$Revision: 1.1 $=~/(\d+)/g);sprintf "%d."."%02d"x$#r,@r};
142@ISA = qw(Net::Cmd IO::Socket::INET);
143@EXPORT = qw(CMD_2WAYERROR CMD_2WAYOK CMD_2WAYQUEUED);
144
145sub CMD_2WAYERROR { 7 }
146sub CMD_2WAYOK { 8 }
147sub CMD_2WAYQUEUED { 9 }
148
149sub import
150{
151 my $pkg = shift;
152 my $callpkg = caller;
153 my @export = ();
154 my %export;
155 my $export;
156
157 @export{@_} = (1) x @_;
158
159 foreach $export (@EXPORT)
160 {
161 if(exists $export{$export})
162 {
163 push(@export,$export);
164 delete $export{$export};
165 }
166 }
167
168 Exporter::export 'Net::SNPP', $callpkg, @export
169 if(@_ == 0 || @export);
170
171 @export = keys %export;
172 Exporter::export 'Net::Cmd', $callpkg, @export
173 if(@_ == 0 || @export);
174}
175
176sub new
177{
178 my $self = shift;
179 my $type = ref($self) || $self;
180 my $host = shift;
181 my %arg = @_;
182 my $obj = $type->SUPER::new(PeerAddr => $host,
183 PeerPort => $arg{Port} || 'snpp(444)',
184 Proto => 'tcp',
185 Timeout => defined $arg{Timeout}
186 ? $arg{Timeout}
187 : 120
188 ) or return undef;
189
190 $obj->autoflush(1);
191
192 $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
193
194 unless ($obj->response() == CMD_OK)
195 {
196 $obj->SUPER::close();
197 return undef;
198 }
199
200 $obj;
201}
202
203##
204## User interface methods
205##
206
207sub pager_id
208{
209 @_ == 2 or croak 'usage: $snpp->pager_id( PAGER_ID )';
210 shift->_PAGE(@_);
211}
212
213sub content
214{
215 @_ == 2 or croak 'usage: $snpp->content( MESSAGE )';
216 shift->_MESS(@_);
217}
218
219sub send
220{
221 my $me = shift;
222
223 if(@_)
224 {
225 my %arg = @_;
226
227 $me->_PAGE($arg{Pager}) || return 0
228 if(exists $arg{Pager});
229
230 $me->_MESS($arg{Message}) || return 0
231 if(exists $arg{Message});
232
233 $me->hold($arg{Hold}) || return 0
234 if(exists $arg{Hold});
235
236 $me->hold($arg{HoldLocal},1) || return 0
237 if(exists $arg{HoldLocal});
238
239 $me->_COVE($arg{Coverage}) || return 0
240 if(exists $arg{Coverage});
241
242 $me->_ALER($arg{Alert} ? 1 : 0) || return 0
243 if(exists $arg{Alert});
244
245 $me->service_level($arg{ServiceLevel}) || return 0
246 if(exists $arg{ServiceLevel});
247 }
248
249 $me->_SEND();
250}
251
252sub data
253{
254 my $me = shift;
255
256 my $ok = $me->_DATA() && $me->datasend(@_);
257
258 return $ok
259 unless($ok && @_);
260
261 $me->dataend;
262}
263
264sub login
265{
266 @_ == 2 || @_ == 3 or croak 'usage: $snpp->login( USER [, PASSWORD ])';
267 shift->_LOGI(@_);
268}
269
270sub help
271{
272 @_ == 1 or croak 'usage: $snpp->help()';
273 my $me = shift;
274
275 return $me->_HELP() ? $me->message
276 : undef;
277}
278
279sub service_level
280{
281 @_ == 2 or croak 'usage: $snpp->service_level( LEVEL )';
282 my $me = shift;
283 my $levl = int(shift);
284 my($me,$level) = @_;
285
286 if($level < 0 || $level > 11)
287 {
288 $me->set_status(550,"Invalid Service Level");
289 return 0;
290 }
291
292 $me->_LEVE($levl);
293}
294
295sub alert
296{
297 @_ == 1 || @_ == 2 or croak 'usage: $snpp->alert( VALUE )';
298 my $me = shift;
299 my $value = (@_ == 1 || shift) ? 1 : 0;
300
301 $me->_ALER($value);
302}
303
304sub coverage
305{
306 @_ == 1 or croak 'usage: $snpp->coverage( AREA )';
307 shift->_COVE(@_);
308}
309
310sub hold
311{
312 @_ == 2 || @_ == 3 or croak 'usage: $snpp->hold( TIME [, LOCAL ] )';
313 my $me = shift;
314 my $until = shift;
315 my $local = shift ? "" : " +0000";
316
317 my @g = reverse((gmtime($time))[0..5]);
318 $g[1] += 1;
319 $g[0] %= 100;
320
321 $me->_HOLD( sprintf("%02d%02d%02d%02d%02d%02d%s",@g,$local));
322}
323
324sub caller_id
325{
326 @_ == 2 or croak 'usage: $snpp->caller_id( CALLER_ID )';
327 shift->_CALL(@_);
328}
329
330sub subject
331{
332 @_ == 2 or croak 'usage: $snpp->subject( SUBJECT )';
333 shift->_SUBJ(@_);
334}
335
336sub two_way
337{
338 @_ == 1 or croak 'usage: $snpp->two_way()';
339 shift->_2WAY();
340}
341
342sub close
343{
344 my $me = shift;
345
346 return 1
347 unless (ref($me) && defined fileno($me));
348
349 $me->_QUIT && $me->SUPER::close;
350}
351
352sub DESTROY { shift->close }
353sub quit { shift->close }
354
355##
356## Over-ride methods (Net::Cmd)
357##
358
359sub debug_text
360{
361 $_[2] =~ s/^((logi|page)\s+\S+\s+)\S*/$1 xxxx/io;
362}
363
364##
365## RFC1861 commands
366##
367
368# Level 1
369
370sub _PAGE { shift->command("PAGE", @_)->response() == CMD_OK }
371sub _MESS { shift->command("MESS", @_)->response() == CMD_OK }
372sub _RESE { shift->command("RESE")->response() == CMD_OK }
373sub _SEND { shift->command("SEND")->response() == CMD_OK }
374sub _QUIT { shift->command("QUIT")->response() == CMD_OK }
375sub _HELP { shift->command("HELP")->response() == CMD_OK }
376sub _DATA { shift->command("DATA")->response() == CMD_MORE }
377
378# Level 2
379
380sub _LOGI { shift->command("LOGI", @_)->response() == CMD_OK }
381sub _LEVE { shift->command("LEVE", @_)->response() == CMD_OK }
382sub _ALER { shift->command("ALER", @_)->response() == CMD_OK }
383sub _COVE { shift->command("COVE", @_)->response() == CMD_OK }
384sub _HOLD { shift->command("HOLD", @_)->response() == CMD_OK }
385sub _CALL { shift->command("CALL", @_)->response() == CMD_OK }
386sub _SUBJ { shift->command("SUBJ", @_)->response() == CMD_OK }
387
388
3891;