Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

414 lines
8.4 KiB

  1. # Net::SNPP.pm
  2. #
  3. # Copyright (c) 1995-1997 Graham Barr <[email protected]>. All rights reserved.
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the same terms as Perl itself.
  6. package Net::SNPP;
  7. require 5.001;
  8. use strict;
  9. use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  10. use Socket 1.3;
  11. use Carp;
  12. use IO::Socket;
  13. use Net::Cmd;
  14. use Net::Config;
  15. $VERSION = "1.11"; # $Id:$
  16. @ISA = qw(Net::Cmd IO::Socket::INET);
  17. @EXPORT = (qw(CMD_2WAYERROR CMD_2WAYOK CMD_2WAYQUEUED), @Net::Cmd::EXPORT);
  18. sub CMD_2WAYERROR () { 7 }
  19. sub CMD_2WAYOK () { 8 }
  20. sub CMD_2WAYQUEUED () { 9 }
  21. sub new
  22. {
  23. my $self = shift;
  24. my $type = ref($self) || $self;
  25. my $host = shift if @_ % 2;
  26. my %arg = @_;
  27. my $hosts = defined $host ? [ $host ] : $NetConfig{snpp_hosts};
  28. my $obj;
  29. my $h;
  30. foreach $h (@{$hosts})
  31. {
  32. $obj = $type->SUPER::new(PeerAddr => ($host = $h),
  33. PeerPort => $arg{Port} || 'snpp(444)',
  34. Proto => 'tcp',
  35. Timeout => defined $arg{Timeout}
  36. ? $arg{Timeout}
  37. : 120
  38. ) and last;
  39. }
  40. return undef
  41. unless defined $obj;
  42. ${*$obj}{'net_snpp_host'} = $host;
  43. $obj->autoflush(1);
  44. $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
  45. unless ($obj->response() == CMD_OK)
  46. {
  47. $obj->close();
  48. return undef;
  49. }
  50. $obj;
  51. }
  52. ##
  53. ## User interface methods
  54. ##
  55. sub pager_id
  56. {
  57. @_ == 2 or croak 'usage: $snpp->pager_id( PAGER_ID )';
  58. shift->_PAGE(@_);
  59. }
  60. sub content
  61. {
  62. @_ == 2 or croak 'usage: $snpp->content( MESSAGE )';
  63. shift->_MESS(@_);
  64. }
  65. sub send
  66. {
  67. my $me = shift;
  68. if(@_)
  69. {
  70. my %arg = @_;
  71. if(exists $arg{Pager})
  72. {
  73. my $pagers = ref($arg{Pager}) ? $arg{Pager} : [ $arg{Pager} ];
  74. my $pager;
  75. foreach $pager (@$pagers)
  76. {
  77. $me->_PAGE($pager) || return 0
  78. }
  79. }
  80. $me->_MESS($arg{Message}) || return 0
  81. if(exists $arg{Message});
  82. $me->hold($arg{Hold}) || return 0
  83. if(exists $arg{Hold});
  84. $me->hold($arg{HoldLocal},1) || return 0
  85. if(exists $arg{HoldLocal});
  86. $me->_COVE($arg{Coverage}) || return 0
  87. if(exists $arg{Coverage});
  88. $me->_ALER($arg{Alert} ? 1 : 0) || return 0
  89. if(exists $arg{Alert});
  90. $me->service_level($arg{ServiceLevel}) || return 0
  91. if(exists $arg{ServiceLevel});
  92. }
  93. $me->_SEND();
  94. }
  95. sub data
  96. {
  97. my $me = shift;
  98. my $ok = $me->_DATA() && $me->datasend(@_);
  99. return $ok
  100. unless($ok && @_);
  101. $me->dataend;
  102. }
  103. sub login
  104. {
  105. @_ == 2 || @_ == 3 or croak 'usage: $snpp->login( USER [, PASSWORD ])';
  106. shift->_LOGI(@_);
  107. }
  108. sub help
  109. {
  110. @_ == 1 or croak 'usage: $snpp->help()';
  111. my $me = shift;
  112. return $me->_HELP() ? $me->message
  113. : undef;
  114. }
  115. sub xwho
  116. {
  117. @_ == 1 or croak 'usage: $snpp->xwho()';
  118. my $me = shift;
  119. $me->_XWHO or return undef;
  120. my(%hash,$line);
  121. my @msg = $me->message;
  122. pop @msg; # Remove command complete line
  123. foreach $line (@msg) {
  124. $line =~ /^\s*(\S+)\s*(.*)/ and $hash{$1} = $2;
  125. }
  126. \%hash;
  127. }
  128. sub service_level
  129. {
  130. @_ == 2 or croak 'usage: $snpp->service_level( LEVEL )';
  131. my $me = shift;
  132. my $level = int(shift);
  133. if($level < 0 || $level > 11)
  134. {
  135. $me->set_status(550,"Invalid Service Level");
  136. return 0;
  137. }
  138. $me->_LEVE($level);
  139. }
  140. sub alert
  141. {
  142. @_ == 1 || @_ == 2 or croak 'usage: $snpp->alert( VALUE )';
  143. my $me = shift;
  144. my $value = (@_ == 1 || shift) ? 1 : 0;
  145. $me->_ALER($value);
  146. }
  147. sub coverage
  148. {
  149. @_ == 1 or croak 'usage: $snpp->coverage( AREA )';
  150. shift->_COVE(@_);
  151. }
  152. sub hold
  153. {
  154. @_ == 2 || @_ == 3 or croak 'usage: $snpp->hold( TIME [, LOCAL ] )';
  155. my $me = shift;
  156. my $time = shift;
  157. my $local = (shift) ? "" : " +0000";
  158. my @g = reverse((gmtime($time))[0..5]);
  159. $g[1] += 1;
  160. $g[0] %= 100;
  161. $me->_HOLD( sprintf("%02d%02d%02d%02d%02d%02d%s",@g,$local));
  162. }
  163. sub caller_id
  164. {
  165. @_ == 2 or croak 'usage: $snpp->caller_id( CALLER_ID )';
  166. shift->_CALL(@_);
  167. }
  168. sub subject
  169. {
  170. @_ == 2 or croak 'usage: $snpp->subject( SUBJECT )';
  171. shift->_SUBJ(@_);
  172. }
  173. sub two_way
  174. {
  175. @_ == 1 or croak 'usage: $snpp->two_way()';
  176. shift->_2WAY();
  177. }
  178. sub quit
  179. {
  180. @_ == 1 or croak 'usage: $snpp->quit()';
  181. my $snpp = shift;
  182. $snpp->_QUIT;
  183. $snpp->close;
  184. }
  185. ##
  186. ## IO/perl methods
  187. ##
  188. sub DESTROY
  189. {
  190. my $snpp = shift;
  191. defined(fileno($snpp)) && $snpp->quit
  192. }
  193. ##
  194. ## Over-ride methods (Net::Cmd)
  195. ##
  196. sub debug_text
  197. {
  198. $_[2] =~ s/^((logi|page)\s+\S+\s+)\S+/$1 xxxx/io;
  199. $_[2];
  200. }
  201. sub parse_response
  202. {
  203. return ()
  204. unless $_[1] =~ s/^(\d\d\d)(.?)//o;
  205. my($code,$more) = ($1, $2 eq "-");
  206. $more ||= $code == 214;
  207. ($code,$more);
  208. }
  209. ##
  210. ## RFC1861 commands
  211. ##
  212. # Level 1
  213. sub _PAGE { shift->command("PAGE", @_)->response() == CMD_OK }
  214. sub _MESS { shift->command("MESS", @_)->response() == CMD_OK }
  215. sub _RESE { shift->command("RESE")->response() == CMD_OK }
  216. sub _SEND { shift->command("SEND")->response() == CMD_OK }
  217. sub _QUIT { shift->command("QUIT")->response() == CMD_OK }
  218. sub _HELP { shift->command("HELP")->response() == CMD_OK }
  219. sub _DATA { shift->command("DATA")->response() == CMD_MORE }
  220. sub _SITE { shift->command("SITE",@_) }
  221. # Level 2
  222. sub _LOGI { shift->command("LOGI", @_)->response() == CMD_OK }
  223. sub _LEVE { shift->command("LEVE", @_)->response() == CMD_OK }
  224. sub _ALER { shift->command("ALER", @_)->response() == CMD_OK }
  225. sub _COVE { shift->command("COVE", @_)->response() == CMD_OK }
  226. sub _HOLD { shift->command("HOLD", @_)->response() == CMD_OK }
  227. sub _CALL { shift->command("CALL", @_)->response() == CMD_OK }
  228. sub _SUBJ { shift->command("SUBJ", @_)->response() == CMD_OK }
  229. # NonStandard
  230. sub _XWHO { shift->command("XWHO")->response() == CMD_OK }
  231. 1;
  232. __END__
  233. =head1 NAME
  234. Net::SNPP - Simple Network Pager Protocol Client
  235. =head1 SYNOPSIS
  236. use Net::SNPP;
  237. # Constructors
  238. $snpp = Net::SNPP->new('snpphost');
  239. $snpp = Net::SNPP->new('snpphost', Timeout => 60);
  240. =head1 NOTE
  241. This module is not complete, yet !
  242. =head1 DESCRIPTION
  243. This module implements a client interface to the SNPP protocol, enabling
  244. a perl5 application to talk to SNPP servers. This documentation assumes
  245. that you are familiar with the SNPP protocol described in RFC1861.
  246. A new Net::SNPP object must be created with the I<new> method. Once
  247. this has been done, all SNPP commands are accessed through this object.
  248. =head1 EXAMPLES
  249. This example will send a pager message in one hour saying "Your lunch is ready"
  250. #!/usr/local/bin/perl -w
  251. use Net::SNPP;
  252. $snpp = Net::SNPP->new('snpphost');
  253. $snpp->send( Pager => $some_pager_number,
  254. Message => "Your lunch is ready",
  255. Alert => 1,
  256. Hold => time + 3600, # lunch ready in 1 hour :-)
  257. ) || die $snpp->message;
  258. $snpp->quit;
  259. =head1 CONSTRUCTOR
  260. =over 4
  261. =item new ( [ HOST, ] [ OPTIONS ] )
  262. This is the constructor for a new Net::SNPP object. C<HOST> is the
  263. name of the remote host to which a SNPP connection is required.
  264. If C<HOST> is not given, then the C<SNPP_Host> specified in C<Net::Config>
  265. will be used.
  266. C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
  267. Possible options are:
  268. B<Timeout> - Maximum time, in seconds, to wait for a response from the
  269. SNPP server (default: 120)
  270. B<Debug> - Enable debugging information
  271. Example:
  272. $snpp = Net::SNPP->new('snpphost',
  273. Debug => 1,
  274. );
  275. =head1 METHODS
  276. Unless otherwise stated all methods return either a I<true> or I<false>
  277. value, with I<true> meaning that the operation was a success. When a method
  278. states that it returns a value, failure will be returned as I<undef> or an
  279. empty list.
  280. =over 4
  281. =item reset ()
  282. =item help ()
  283. Request help text from the server. Returns the text or undef upon failure
  284. =item quit ()
  285. Send the QUIT command to the remote SNPP server and close the socket connection.
  286. =back
  287. =head1 EXPORTS
  288. C<Net::SNPP> exports all that C<Net::CMD> exports, plus three more subroutines
  289. that can bu used to compare against the result of C<status>. These are :-
  290. C<CMD_2WAYERROR>, C<CMD_2WAYOK>, and C<CMD_2WAYQUEUED>.
  291. =head1 SEE ALSO
  292. L<Net::Cmd>
  293. RFC1861
  294. =head1 AUTHOR
  295. Graham Barr <[email protected]>
  296. =head1 COPYRIGHT
  297. Copyright (c) 1995-1997 Graham Barr. All rights reserved.
  298. This program is free software; you can redistribute it and/or modify
  299. it under the same terms as Perl itself.
  300. =cut