home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: alt.gopher
- Path: sparky!uunet!stanford.edu!leland.Stanford.EDU!schemers
- From: schemers@leland.Stanford.EDU (Roland Schemers)
- Subject: gopher<->NNTP perl script
- Message-ID: <1992Jul25.002513.22566@leland.Stanford.EDU>
- Sender: news@leland.Stanford.EDU (Mr News)
- Organization: Distributed Computing Group, Stanford University
- References: <1992Jul25.001230.21597@leland.Stanford.EDU>
- Date: Sat, 25 Jul 92 00:25:13 GMT
- Lines: 302
-
- Ok, here is yet ANOTHER gopher gateway. Gopher to NNTP. This is
- different from MSU's approach in that it is done dynamically
- by changing gopher requests into NNTP requests and vice-versa.
-
- You have to run it from inetd.
-
- Your NNTP server must understand the XHDR command. Its possible
- to write this gateway so that command isn't needed, but your
- better off upgrading your NNTP server :-)
-
- I just wrote this in a couple of hours, and it works fairly well.
-
- Try:
-
- gopher slapshot.stanford.edu
-
- And select "News".
-
- Links should look like:
-
- Name=USENET News
- Type=1
- Port=4327
- Path=
- Host=Slapshot.Stanford.EDU
-
- To get all the news. You can get one group like so:
-
- Name=Stanford Events (su.events)
- Type=1
- Port=4327
- Path=ls su.events
- Host=Slapshot.Stanford.EDU
-
- Or a list of groups:
-
- Name=Stanford News Groups
- Type=1
- Port=4327
- Path=ls su
- Host=Slapshot.Stanford.EDU
-
- Or even one article:
-
- Name=Mercury news: Amiga dead!
- Type=0
- Port=4327
- Path=article su.amiga 55
- Host=Slapshot.Stanford.EDU
-
- The nice thing about this approach is now links could be setup to
- better describe news groups.
-
- Please let me know what you think!
-
- Roland
-
- #!/usr/local/bin/perl
- #
- # switch to nobody if we are root
- ($<,$>) = (-2,-2) unless $>;
-
- require 'getopts.pl';
-
- #
- # Simple gopher2nntp server. You can change the following variables.
- # nntp_port is hardcoded here since this is a stateless server and
- # no sense in reading it from /etc/services every time...
- #
- # A server that sticks around might be better...
- #
- # Note: The NNTP daemon must accept the XHDR command.
- #
- #
- # You should run "gopher2nntp -g" from cron to generate the groups
- # file. If you don't generate the groups file then this server will
- # grab it from the NNTP server, but thats a waste of time.
- #
- #
- $nntp_server = "leland.stanford.edu";
- $nntp_port = 119;
- $nntp_groups = "/usr/local/etc/newsgroups.gopher"; # could be active file
- #
- # Commands this server responds to:
- #
- # "" -> list top level groups
- # ls $group -> list group's articles and sub-groups
- # article $group $number -> get 1 article
- #
-
- $port=&my_port(); # port this script is running on
- chop($host = `hostname`);
-
- &Getopts('rdga:s:');
-
- if ($errs || $#ARGV!=-1) {
-
- print<<EOF;
-
- Usage: $0 [-s server] [-a active_file] [-g] [-d] [-r]
- -s server NNTP server to contact
- -a file Active file to use
- -n Don't use active file
- -g generate new active file\n";
- -d turn on debug (when typing commands from a tty)
- -r list articles in reverse order
- EOF
- exit;
-
- }
-
- $nntp_server = $opt_s if (defined($opt_s));
- $nntp_port = $opt_p if (defined($opt_p));
- $nntp_groups = $opt_a if (defined($opt_a));
-
- &create_groups($opt_g) if defined($opt_g);
-
- $_ = <STDIN>; s/\r//; s/\n//;
-
- &do_ls("") if /^$/;
- &do_ls($1) if /^ls\s+(.*)/i;
- &do_article($1,$2) if /^article\s+(\S+)\s+(\d+)/i;
-
- &reply("3Unknown command!");
- exit;
-
- sub do_article {
- local($group,$number) = @_;
-
- &open_nntp;
-
- &send("GROUP $group");
- $_ = &recv;
- &death if !/^211/;
-
- &send("ARTICLE $number");
- $_ = &recv;
- &death if !/^220/;
-
- while(<SERVER>) {
- print;
- last if /^\.\r\n$/;
- }
-
- &close_nntp;
- exit;
- }
-
- sub list_group {
- local($group) = @_;
-
- &send("GROUP $group");
- $_ = &recv;
- &death if !/^211/;
-
- ($n,$f,$l) = /211\s+(\d+)\s+(\d+)\s+(\d+)/;
-
- &send("XHDR Subject $f-$l");
- $_ = &recv;
- &death if !/^221/;
-
- while(<SERVER>) {
- chop; chop;
- last if /^\.$/;
- ($article,$subject) = /^(\d+)\s+(.*)/;
- $subject =~ s/\t/ /g; # just in case!
- if (defined($opt_r)) {
- push(@reply,"0$subject\tarticle $group $article\t$host\t$port");
- } else {
- &reply("0$subject\tarticle $group $article\t$host\t$port");
- }
- }
-
- if (defined($opt_r)) {
- for ($i=$#reply; $i!= -1; $i--) { &reply($reply[$i]); }
- }
-
- &reply(".");
- &close_nntp;
- exit;
- }
-
-
- sub do_ls {
- local($prefix) = @_;
-
- &open_nntp;
- &get_groups;
-
- foreach ( sort @groups) {
- if ($_ eq $prefix) { $do_list_group = $_; }
- elsif (/^$prefix\.([^.]*)\.?/) {
- $leaf=$1;
- $save{"$prefix.$leaf"} = "1$leaf\tls $prefix.$leaf\t$host\t$port";
- }
- elsif ($prefix eq '' && /([^.]*)/) {
- $save{"$1"} = "1$1\tls $1\t$host\t$port";
- }
- }
-
- foreach ( sort keys %save) { &reply($save{$_}); }
- &list_group($do_list_group) if ($do_list_group);
-
- &reply(".");
- &close_nntp;
- exit;
- }
-
- sub open_nntp {
- local($_);
- &open_server($nntp_server,$nntp_port);
- $_ = &recv;
- &death if !/^2/;
- }
-
- sub close_nntp {
- &send("QUIT");
- close(SERVER);
- }
-
- sub my_port {
- return -1 if (-t STDIN);
- $sockaddr = 'S n a4 x8';
- $mysockaddr = getsockname(STDIN);
- ($myfamily,$myport,$myaddr) = unpack($sockaddr,$mysockaddr);
- return $myport;
- }
-
- sub open_server {
-
- local($server,$port) = @_;
- $sockaddr = 'S n a4 x8';
- (($name, $aliases, $type, $len, $saddr) = gethostbyname($server))||&death;
- $sin = pack($sockaddr, 2, $port, $saddr);
- socket(SERVER, 2, 1, 0) || &death;
- connect(SERVER, $sin) || &death;
- select(SERVER); $| = 1; select(STDOUT); $| = 1;
-
- }
-
- sub send {
- print "send -> |$_[0]|\n" if (defined($opt_d));
- print SERVER "$_[0]\r\n";
- }
-
- sub recv {
- local ($_);
- $_= <SERVER>;
- chop; chop;
- print "recv -> |$_|\n" if (defined($opt_d));
- return $_;
- }
-
- sub reply { print "$_[0]\r\n";}
- sub death { &reply("."); exit; }
-
- sub get_groups {
- if (!defined($opt_n) && open(GROUPS,$nntp_groups)) {
- while(<GROUPS>) {
- chop;
- ($grp) = /^(\S+)/;
- push(@groups,$grp);
- }
- close(GROUPS);
- } else { # can't open file, get list from server!
- &load_groups;
- }
- }
-
- sub load_groups {
-
- &open_nntp;
- &send("LIST");
- $_ = &recv;
- &death if !/^215/;
-
- while(<SERVER>) {
- chop; chop;
- last if /^\.$/;
- s/^(\S+).*/$1/;
- push(@groups,$_);
- }
-
- }
-
- sub create_groups {
-
- &load_groups;
-
- open(GROUPS,">$nntp_groups") || die "$nntp_groups: $!";
- foreach (@groups) { print GROUPS "$_\n"; }
- close GROUPS;
-
- &close_nntp;
- exit;
- }
-
- --
- 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
-