Text File

#!/bin/perl # Gopher-nnrp Gateway version 2.0 rewrite by: Chad Adams (c-adams@bgu.edu) # 28-May-1993 version 2.0 Chad Adams # add newgroups database. # add multi level newsgroup menus. [each .part. of newsgroup automaticly # gets it's own menu instead of putting all (like all of comp) in one # menu. {now menus like comp.sys, comp.lang, comp.sources, ect..}] # convert to use xhdr instead of tin's xindex. If not used with INN using # overview files to speed up xhdr it may be slow. # # Gopher-NNTP Gateway version 1.0 # Author: Daniel Schales (dan@engr.latech.edu) # Major rewrite, socket support: Doug Schales (d1s8027@sc.tamu.edu) # # Set the 4 following variables for your setup. the 2 port variables # are set to the standard, be sure to set gopherhost and nntphost to # your respective hosts. ="news.ecn.bgu.edu"; =2008; # ='gopher-nntp'; ='nntp'; ="news.ecn.bgu.edu";

@INC=("/usr/local/lib/perl"); require 'sys/socket.ph'; dump QUICKSTART if @ARGV[0] eq '-dump'; QUICKSTART:

{'ALRM'} = 'stuck'; =shift; = '-h' if eq '-t'; while ( eq '-f') { = shift; = shift; open(CR, ); = <CR>; close(CR); chop(); print "0\t\t\t\r\n"; } =shift; if ( eq '-X') { @arts = @ARGV; } else { =shift; } # set an alarm 5 minutes from now, if it goes off we must be stuck alarm(300); open(LOG,">>/tmp/nntplog"); =`date`;chop(); print LOG ," ",," ",," ",,"\n"; close(LOG); = 'S n a4 x8'; (, , ) = getprotobyname('tcp'); (, , ) = getservbyname(, 'tcp'); (, , , , ) = gethostbyname();

= pack(, &AF_INET, , );

socket(NNTPSOCK, &PF_INET, &SOCK_STREAM, ) || die "socket: $!"; connect(NNTPSOCK, ) || die "connect: $!";

select(NNTPSOCK); $|= 1; select(stdout);

= <NNTPSOCK>;

if ( eq '-g') { dbmopen(newsgroups, '/usr/lib/newsgroups', 0444); print NNTPSOCK "LIST\n"; = <NNTPSOCK>; chop; chop; while( ne "."){ if( =~ "^"){ () = split; push(@out,"1 - {}\texec:-h :". "/bin/gonnrp\t\t\r\n"); } = <NNTPSOCK>; chop; chop; } print sort(@out); print ".\r\n"; } elsif ( eq '-G') { dbmopen(newsgroups, '/usr/lib/newsgroups', 0444); print NNTPSOCK "LIST\n"; = <NNTPSOCK>; chop; chop; = length() + 1; @grouplist = (); while( ne "."){ if( =~ "^"){ () = split; push(@grouplist, ); } = <NNTPSOCK>; chop; chop; } @grouplist = sort(@grouplist); for ( = 0; <= $#grouplist; ++) { = @grouplist[]; if ( eq ) { = ; print "1{}\texec:-T :". "/bin/gonnrp\t\t\r\n"; } else { = substr(,,40); if (index(,'.') != -1) { @grppart = split(/\./,); if (@grppart[0] eq ) { next; } = @grppart[0]; = @grppart[0]; print "1 - ".{"..all"}. "\texec:-G .". ":/bin/gonnrp\t\t\r\n"; } else { if ( eq substr(@grouplist[+1],0,length())) { print "1 - ".{"..all"}. "\texec:-G :". "/bin/gonnrp\t\t\r\n"; = ; } else { print "1 - {}\texec:-T :". "/bin/gonnrp\t\t\r\n"; } } } } print ".\r\n"; } elsif( eq '-X') { # = newsgroup # @arts = articles in this thread # or # @arts = 0 low high if list would be too long () = &group(); # build arts array if we were passed range @arts = split(' ', &buildidx(@arts[1], @arts[2])) if @arts[0] == 0; foreach (@arts) { {} = 1; } &xhdr('from', @arts[0], @arts[$#arts]); while (<NNTPSOCK>) { last if substr(,0,1) eq '.'; chop; chop; (, ) = split(/ /,,2); print "0\texec:-a ${item} :/bin/gonnrp\t". "\t\r\n" if {}; } print ".\r\n"; } elsif( eq '-T') { (, , , ) = &group(); &buildidx(, ); @keys = sort(keys %idx); foreach (@keys) { @arts = split(' ',{}); if ($#arts == 0) { # single article print "0\texec:-a ${item} @arts[0]:". "/bin/gonnrp\t\t\r\n"; } else { # thread if (length({}) < 80) { # send article list print "1\texec:-X {}:". "/bin/gonnrp\t\t\r\n"; } else { # give range print "1\texec:". "-X 0 @arts[0] @arts[$#arts]:". "/bin/gonnrp\t\t\r\n"; } } } print ".\r\n"; } elsif( eq '-l'){ (, , , ) = &group(); if( ne "0"){ print NNTPSOCK "ARTICLE \n"; =0; = <NNTPSOCK>; chop; chop; while( ne "."){ if () { print "\r\n"; } elsif ( =~ "^220 " || =~ "^222 ") { = 1; } } = <NNTPSOCK>; chop; chop; } } # rwp 20Aug92 Add ability to fetch last article.

elsif( eq '-h' || eq '-b' || eq '-s'){ (, , , ) = &group(); if( ne "0"){ &xhdr('subject', , ); = <NNTPSOCK>; chop; chop; while( ne '.'){ (,) = split (/ /,,2); if ( eq '-h' ) { print "0\texec:-a ${item} ${num}:". "/bin/gonnrp\t\t\r\n"; } elsif ( eq '-b') { print "0\texec:-a ${item} ${num} body". ":/bin/gonnrp\t\t\r\n"; } elsif ( eq '-s') { ="\L\E"; ="\L\E"; if ( =~ ) { print "0\texec:-a ${item} ${num}:". "/bin/gonnrp\t\t\t\r\n"; } } = <NNTPSOCK>; chop; chop; } } print ".\r\n"; } elsif( eq '-a'){ = ; = shift; () = &group(); if( eq "body") { print NNTPSOCK "BODY \n"; () = split(/ /,( = <NNTPSOCK>)); &checkcode(,222); } else { print NNTPSOCK "ARTICLE \n"; () = split(/ /,( = <NNTPSOCK>)); &checkcode(,220); } = <NNTPSOCK>; chop; chop; while( ne "."){ print "\r\n"; = <NNTPSOCK>; chop; chop; } }

print NNTPSOCK "QUIT\n"; shutdown(NNTPSOCK, 2); exit(0);

sub stuck { open(LOG,">>/tmp/nntplog"); =`date`;chop(); print LOG ," hung on ",," ",," ",,"\n"; close(LOG);

exit; }

# Chad Adams 28-May-1993 tin's xindex to xhdr conversion sub checkcode { # return error when nntp command failes local(, ) = @_; if ( != ) { print "0\t\t\t\r\n"; print ".\r\n"; exit; } } sub buildidx { # build subject threads local (, ) = @_; local (, , , ); = 1; &xhdr('subject', , ); = 0; while (<NNTPSOCK>) { last if substr(,0,1) eq '.'; chop; chop; (, ) = split(/ /,,2); while (1) { # remove Re: = substr(,0,2); =~ tr/A-Z/a-z/; if ( eq 're') { = substr(,2); next; } elsif (substr(,0,1) eq ':') { = substr(,1); next; } elsif (substr(,0,1) eq ' ') { = substr(,1); next; } last; } if () { = ; = 0; } {} .= " "; ++; } return {}; } sub group { # (code, count, low, high) = &group(newsgroup) local(@rtn); print NNTPSOCK "group @_[0]\n"; @rtn = split(/ /,( = <NNTPSOCK>), 5); &checkcode(@rtn[0],211); return @rtn; } sub xhdr { # &xhdr(header,low,high) local(); print NNTPSOCK "xhdr @_[0] ".@_[1].'-'.@_[2]."\n"; () = split(/ /,( = <NNTPSOCK>)); &checkcode(,221); }