#
# ROADS::MeshTraversal - Traverse a Mesh of WHOIS++ servers
#
# Author: Jon Knight <jon@net.lut.ac.uk>
# $Id: MeshTraversal.pm,v 3.4 1998/09/05 13:58:57 martin Exp $

package ROADS::MeshTraversal;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(traversemesh %TEMPLATE);

use ROADS::WPPC;

#
# Main mesh traversal subroutine.  This is what you call from outside this
# module.  
#
sub traversemesh {
  my ($query,$maxservers,$debug,@results) = @_;
  my ($fullhandle,$thistemplate,$servercount,$serverhandle,$host,$port);
  my (@tempstore);

  print "[<EM>Into traversemesh with query: $query, maxservers: " .
    "$maxservers, debug: $debug</EM>]<P>\n" if $debug;
  $servercount = 0;

  foreach $fullhandle (@results) {
    last if $servercount == $maxservers;
    $thistemplate = $TEMPLATE{"$fullhandle"};
    next unless $thistemplate =~ /^#\s+SERVER\-TO\-ASK\s+(.*)/i;
    print "[<EM>thistemplate... $thistemplate</EM>]<P>\n" if $debug;

    $port = 63; # default WHOIS++ port - different to the ROADS default as
                # we don't make people run our server out of the box as root

    foreach $line (split(/\n/, $thistemplate)) {
      $line =~ /^\s*SERVER-HANDLE:\s+(.*)/i && ($serverhandle = $1);
      $line =~ /^\s*HOST-NAME:\s+(.*)/i && ($host = $1);
      $line =~ /^\s*HOST-PORT:\s+(.*)/i && ($port = $1);
    }

    undef($TEMPLATE{"$fullhandle"});
    next if($::QueriedServers{$serverhandle});

    $::QueriedServers{$serverhandle} = 1;
    $ServerToAsk{$serverhandle}="$host $port";
    print "[<EM>Searching host '$host', port '$port' " .
      "with query '$query'</EM>]<P>\n" if $debug;

    @tempstore = &wppc($host, $port, $query);

    if ($tempstore[0] =~ /noconnect/) {
      $::oops = "noconnect";
    } else {
      push(@results, @tempstore);
      push(@newresults, @tempstore);
    }
    print "[<EM>tempstore... ", join(' ', @tempstore), "</EM>]<P>\n" if $debug;

    $servercount++;
  }
  return(@newresults);
}

1;
__END__


=head1 NAME

ROADS::MeshTraversal - A class to perform centroid mesh traversal

=head1 SYNOPSIS

  use ROADS::MeshTraversal;
  # @results is populated by doing a WHOIS++ search, then...
  @newresults = traverse("tubby and toast", 5, 1, @results);

=head1 DESCRIPTION

This class defines a method which takes the results of performing a
WHOIS++ search and follows up any referrals which may have been
returned by the WHOIS++ servers which were queried.

=head1 METHODS

=head2 @expanded_results = traverse( query, max_servers, debug, @results );

The I<traverse> method takes four arguments :-

=over 4

=item B<query>

The WHOIS++ query which resulted in the original results being returned.

=item B<max_servers>

The upper limit on the number of servers to contact when doing mesh
traversal - this is to avoid going bonkers and trying to contact every
WHOIS++ server on the Internet.  We try not to hit any server more
than once, so this should be quite effective.

=item B<debug>

Whether to return debugging output or not.

=item B<results>

Original search results which are being expanded, as generated by the
B<ROADS::WPPC> WHOIS++ client.

=back

=head1 BUGS

We're a bit mixed up about where we're storing information, and this
whole result processing could do with a re-think.  If we're
objectifying ROADS a bit more, the obvious thing to do would be to
make each result item into an object, and hang the referrals off the
bottom of them ?

=head1 SEE ALSO

L<admin-cgi/admin.pl>, L<cgi-bin/search.pl>, L<ROADS::WPPC>

=head1 COPYRIGHT

Copyright (c) 1988, Martin Hamilton E<lt>martinh@gnu.orgE<gt> and Jon
Knight E<lt>jon@net.lut.ac.ukE<gt>.  All rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

It was developed by the Department of Computer Studies at Loughborough
University of Technology, as part of the ROADS project.  ROADS is funded
under the UK Electronic Libraries Programme (eLib), the European
Commission Telematics for Research Programme, and the TERENA
development programme.

=head1 AUTHOR

Jon Knight E<lt>jon@net.lut.ac.ukE<gt>

