From: schemers@leland.Stanford.EDU (Roland Schemers)
Subject: gopher<->Webster perl script
Organization: Distributed Computing Group, Stanford University
Date: Sat, 25 Jul 92 00:12:30 GMT

Ok, here is yet another gopher gateway. Gopher to webster (dictionary
server). You need a webster server to point your links at, and a machine
to run the gopher<->webster daemon.

You have to run it from inetd.

----------------------------------------------------------------------
This gopher to webster gateway works by defining a simple command
format which takes Index queries sent by gopher clients.

When a gopher client sends back the selector string plus the input, the
gopher2webster daemon will send the query to the webster daemon. If there 
are no matches then a '.' is returned. If there are matches, they
are returned as files and the selector will contain the correct string
which will return the definition if the user selects it.

The gopher2webster daemon should be run from inetd. You need to pick
a port to run it on and set that port in the config file. Stanford's
webster server wont answer queries off our net, so you need to 
use another webster that will. You can look at the Webster menu at
Stanford's experiMENTAL root gopher server:

  gopher-server.stanford.edu 70

But at some point access will probably be restricted to SUNet.

The gopher2webster gateway uses the following format for commands:

index command word

Where:

index   Tells the webster server which index to look at.

         NeXT webster servers let you specifiy:

         dictionary      the default
         thesaurus       the Webster's Thesaurus
         dictionary-full the full content dictionary index            

         If your webster server doesn't understand the "INDEX" 
         command use default.

command  Is a webster command, like:

           DEFINE
           SPELL
           ENDINGS

word     Is the word you are looking up.


Examples:

default SPELL webster
default DEFINE spell
default ENDINGS foo

thesaurus SPELL hot
thesaurus DEFINE hot

How it works with gopher:

Set up the following Links. The port 'nnn' and host HOSTNAME should point 
to where your gopher2webster gateway is running.

Name=Lookup word in dictionary
Type=7
Port=nnn
Path=default SPELL
Host=HOSTNAME

Name=Show words that start with
Type=7
Port=nnn
Path=default ENDINGS
Host=HOSTNAME

If your webster server does understand the "INDEX" command, you can also add:

Name=Search text of entire dictionary
Type=7
Port=nnn
Path=dictionary-full SPELL
Host=HOSTNAME

Name=Thesaurus
Type=7
Port=nnn
Path=thesaurus SPELL
Host=HOSTNAME


#!/usr/local/bin/perl
#
# switch to nobody
#

($<,$>) = (-2,-2) unless $>;

# select your webster server and local port
#

$webster_server  = "webster.lcs.mit.edu";
$webster_port    = 103;

# stanford NeXT webster server
#
# $webster_server = "webster-server.stanford.edu";
# $webster_port   = 765;

$port=&my_port;               # port this script is running on 
 chop($host = `hostname`);

 $_ = <STDIN>; s/\r//; s/\n//;

 ($index,$cmd,$query) = /(\S+)\s+(\S+)\s+(\S+)/;

  &open_webster($webster_server,$webster_port);

  print WEBSTER "INDEX $index\r\n" if ($index ne 'default');

  if ($cmd eq "PSPELL") {                     # phonetic lookup
       print WEBSTER "SPELL $query ?\r\n";
  } else {
       print WEBSTER "$cmd $query\r\n";
  }

  $_ = <WEBSTER>; chop; chop;

  if (/^SPELLING 0/ || /^WILD 0/) {
        &reply(".");
   } elsif (/^SPELLING 1/) {
      &reply("0$query\t$index DEFINE $query\t$host\t$port"); 
      &reply(".");
   } elsif (/^SPELLING$/ || /^MATCHS$/ || /^WILD/) {
        $/ = "\200";
        $buf = <WEBSTER>;
        $buf =~ s/[\r\200]//g;
        foreach (split(/\n/,$buf)) { /\d+\s+(\S+)/; $words{$1}=""; }
        foreach (sort keys %words) { 
               &reply("0$_\t$index DEFINE $_\t$host\t$port"); 
        }
        &reply(".");
   } elsif (/^DEFINITION/) {
        $/ = "\200";
        $buf = <WEBSTER>;
        $buf =~ s/[\r\200]//g;
        print $buf;
   }

  print WEBSTER "QUIT\r\n";
  close(WEBSTER);

sub open_webster {
 local($server,$port) = @_;
 $sockaddr = 'S n a4 x8';
 (($name, $aliases, $type, $len, $saddr) = gethostbyname($server))||&death;
 $sin = pack($sockaddr, 2, $port, $saddr);
 socket(WEBSTER, 2, 1, 0) || &death;
 connect(WEBSTER, $sin)   || &death;
 select(WEBSTER); $| = 1; select(STDOUT); $| = 1;

}

sub reply { print "$_[0]\r\n";}
sub death { &reply("."); exit; }

sub my_port {
   return -1 if (-t STDIN);
   $sockaddr = 'S n a4 x8';
   $mysockaddr = getsockname(STDIN);
   ($myfamily,$myport,$myaddr) = unpack($sockaddr,$mysockaddr);
   return $myport;
}


-- 
Roland J. Schemers III              |            Networking Systems
Systems Programmer                  |            168 Pine Hall   (415)-723-6740
Distributed Computing Group         |            Stanford, CA 94305-4122
Stanford University                 |            schemers@Slapshot.Stanford.EDU
Newsgroups: alt.gopher