home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl_ste.zip / WAIT / Client.pm
Text File  |  1997-08-12  |  5KB  |  228 lines

  1. #!/usr/bin/perl
  2. #                              -*- Mode: Perl -*- 
  3. # $Basename: Client.pm $
  4. # $Revision: 1.3 $
  5. # Author          : Ulrich Pfeifer
  6. # Created On      : Fri Jan 31 10:49:37 1997
  7. # Last Modified By: Ulrich Pfeifer
  8. # Last Modified On: Mon Aug 11 17:06:51 1997
  9. # Language        : CPerl
  10. # Update Count    : 88
  11. # Status          : Unknown, Use with caution!
  12. # (C) Copyright 1997, Ulrich Pfeifer, all rights reserved.
  13.  
  14. package WAIT::Client;
  15. use Net::NNTP ();
  16. use Net::Cmd qw(CMD_OK);
  17. use Carp;
  18. use strict;
  19. use vars qw(@ISA);
  20.  
  21. @ISA = qw(Net::NNTP);
  22.  
  23. sub search
  24. {
  25.   my $wait = shift;
  26.   
  27.   $wait->_SEARCH(@_)
  28.     ? $wait->read_until_dot()
  29.       : undef;
  30. }
  31.  
  32. sub info
  33. {
  34.   @_ == 2 or croak 'usage: $wait->info( HIT-NUMBER )';
  35.   my $wait = shift;
  36.   
  37.   $wait->_INFO(@_)
  38.     ? $wait->read_until_dot()
  39.       : undef;
  40. }
  41.  
  42. sub get
  43. {
  44.   @_ == 2 or croak 'usage: $wait->info( HIT-NUMBER )';
  45.   my $wait = shift;
  46.   
  47.   $wait->_GET(@_)
  48.     ? $wait->read_until_dot()
  49.       : undef;
  50. }
  51.  
  52. sub database
  53. {
  54.   @_ == 2 or croak 'usage: $wait->database( DBNAME )';
  55.   my $wait = shift;
  56.   
  57.   $wait->_DATABASE(@_);
  58. }
  59.  
  60. sub table
  61. {
  62.   @_ == 2 or croak 'usage: $wait->table( TABLE )';
  63.   my $wait = shift;
  64.   
  65.   $wait->_TABLE(@_);
  66. }
  67.  
  68. sub hits
  69. {
  70.   @_ == 2 or croak 'usage: $wait->hits( NUM-MAX-HITS )';
  71.   my $wait = shift;
  72.   
  73.   $wait->_HITS(@_);
  74. }
  75.  
  76. sub _SEARCH   { shift->command('SEARCH',   @_)->response == CMD_OK }
  77. sub _INFO     { shift->command('INFO',     @_)->response == CMD_OK }
  78. sub _GET      { shift->command('GET',      @_)->response == CMD_OK }
  79. sub _DATABASE { shift->command('DATABASE', @_)->response == CMD_OK }
  80. sub _TABLE    { shift->command('TABLE',    @_)->response == CMD_OK }
  81. sub _HITS     { shift->command('HITS',     @_)->response == CMD_OK }
  82.  
  83. # The following is a real hack. Don't look at it ;-) It tries to
  84. # emulate a stateful protocol over HTTP which is weird and slow.
  85. package WAIT::Client::HTTP;
  86. use Net::Cmd;
  87. use vars qw(@ISA);
  88. use Carp;
  89.  
  90. @ISA = qw(WAIT::Client);
  91.  
  92. sub new {
  93.   my $type = shift;
  94.   my $host = shift;
  95.   my %parm = @_;
  96.   my ($proxy, $port) = ($parm{Proxy} =~ m{^(?:http://)(\S+)(?::(\d+))});
  97.   $port = 80 unless $port;
  98.   
  99.   my $self = {
  100.               proxy_host => $proxy,
  101.               proxy_port => $port,
  102.               wais_host  => $host,
  103.               wais_port  => $parm{Port},
  104.               timeout    => $parm{Timeout}||120,
  105.              };
  106.   bless $self, $type;
  107.  
  108.   my $con;
  109.   if ($con = $self->command('HELP') and $con->response == CMD_INFO) {
  110.     return $self;
  111.   } else {
  112.     return;
  113.   }
  114. }
  115.  
  116. sub command {
  117.   my $self = shift;
  118.   my $con  =                    # Constructor inherited from IO::Socket::INET
  119.     WAIT::Client::HTTP::Handle->new
  120.       (
  121.        PeerAddr => $self->{proxy_host},
  122.        PeerPort => $self->{proxy_port},
  123.        Proto    => 'tcp',
  124.       );
  125.   return unless $con;
  126.  
  127.   $con->timeout($self->{timeout}) if defined $self->{timeout};
  128.   my $cmd = join ' ', @_;
  129.   
  130.   if ($self->{hits}) {
  131.     $cmd = "HITS $self->{hits}:$cmd";
  132.   }
  133.   $cmd = "Command: $cmd";
  134.   $con->autoflush(1);
  135.   
  136.   $con->printf("POST http://$self->{wais_host}:$self->{wais_port} ".
  137.                "HTTP/1.0\nContent-Length: %d\n\n$cmd",
  138.                length($cmd));
  139.   
  140.   unless ($con->response == CMD_OK) {
  141.     warn "No greeting from server\n";
  142.   }
  143.   if ($self->{hits}) {
  144.     unless ($con->response == CMD_OK) {
  145.       warn "Hits not aknowledged\n";
  146.     }
  147.   }
  148.   $self->{con} = $con;
  149.   $con;
  150. }
  151.  
  152. # We map here raw document id's to rank numbers and back for
  153. # convenience. Besides that the following search(), info(), and get()
  154. # are obsolete.
  155.  
  156. sub search
  157. {
  158.   my $wait = shift;
  159.   
  160.   if ($wait->_SEARCH(@_)) {
  161.     my $r = $wait->read_until_dot();
  162.     my $i = 1;
  163.     
  164.     delete $wait->{'map'};
  165.     for (@$r) {
  166.       if (s/^(\d+)/sprintf("%4d",$i)/e) {
  167.         $wait->{'map'}->[$i++] = $1;
  168.       } 
  169.     }
  170.     return $r;
  171.   }
  172.   return undef;
  173. }
  174.  
  175. sub info
  176. {
  177.   @_ == 2 or croak 'usage: $wait->info( HIT-NUMBER )';
  178.   my $wait = shift;
  179.   my $num  = shift;
  180.  
  181.   unless ($wait->{'map'}->[$num]) {
  182.     print "No such hit: $num\n";
  183.     return;
  184.   }
  185.   $wait->_INFO($wait->{'map'}->[$num])
  186.     ? $wait->read_until_dot()
  187.       : undef;
  188. }
  189.  
  190. sub get
  191. {
  192.   @_ == 2 or croak 'usage: $wait->info( HIT-NUMBER )';
  193.   my $wait = shift;
  194.   my $num  = shift;
  195.  
  196.   unless ($wait->{'map'}->[$num]) {
  197.     print "No such hit: $num\n";
  198.     return;
  199.   }
  200.   $wait->_GET($wait->{'map'}->[$num])
  201.     ? $wait->read_until_dot()
  202.       : undef;
  203. }
  204.  
  205. # We must store the hit count locally
  206. sub _HITS {
  207.   my $self = shift;
  208.   my $hits = shift;
  209.  
  210.   $self->{hits} = $hits;
  211.   ["Setting maximum hit count to $hits"];
  212. }
  213.  
  214. # We should use AUTOLOAD here. I know ;-)
  215. sub read_until_dot {shift->{con}->read_until_dot(@_)}
  216. sub message        {shift->{con}->message(@_)}
  217.  
  218. package WAIT::Client::HTTP::Handle;
  219. use vars qw(@ISA);
  220.  
  221. @ISA = qw(Net::Cmd IO::Socket::INET);
  222.  
  223.  
  224. 1;
  225.