From: Ian Jackson Date: Wed, 23 Nov 2011 18:37:13 +0000 (+0000) Subject: nntpid wip modulified X-Git-Tag: debian/4.1.31~19^2~7 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=commitdiff_plain;h=80bfbab221b1c8bbc5d59bee6db92acff7ec4fcd nntpid wip modulified --- diff --git a/scripts/ChiarkNNTP.pm b/scripts/ChiarkNNTP.pm new file mode 100644 index 0000000..5b69e28 --- /dev/null +++ b/scripts/ChiarkNNTP.pm @@ -0,0 +1,137 @@ +#!/usr/bin/perl + +use strict qw(subs); +use warnings; + +require 5.002; +use Socket; +use FileHandle; + + +BEGIN { + use Exporter (); + our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); + + # set the version for version checking + $VERSION = 1.00; + + @ISA = qw(Exporter); + @EXPORT = qw(cnntp_connect); + %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], + + @EXPORT_OK = qw(); +} +our @EXPORT_OK; + +sub cnntp_connect ($) { + my ($verbose) = @_; + + my $ns=$ENV{'NNTPSERVER'}; + if (!defined $ns or !length $ns) { + $ns = `cat /etc/nntpserver`; + chomp($ns); + } + my $port = (getservbyname("nntp", "tcp"))[2]; + $ns = inet_aton($ns); + my $proto = getprotobyname("tcp"); + my $paddr = sockaddr_in($port, $ns); + + my $sock = new IO::Handle; + socket($sock,PF_INET,SOCK_STREAM,$proto) or die "socket: $!"; + connect($sock,$paddr) or die "connect: $!"; + + $sock->autoflush(1); + + return bless { S => $sock, V => $verbose }; +} + +sub banner_reader ($) { + my ($c) = @_; + my ($code,$l) = $c->getline(); + $code =~ /^2\d\d/ or die "no initial greeting from server\n"; + $c->docmd("MODE READER"); +} + +sub disconnect ($) { + my ($c) = @_; + close $c->{S}; +} + +sub putline ($$) { + my ($c, $line) = @_; + my $s = $c->{S}; + my $v = $c->{V}; + print $v ">>> $line\n" if $v; + print $s "$line\r\n"; +} + +sub getline_raw ($) { + my ($c) = @_; + my $s = $c->{S}; + my $l = <$s>; + return $l; +} + +sub getline ($) { + my ($c) = @_; + my $v = $c->{V}; + my $l = $c->getline_raw(); + $l =~ s/[\r\n]*$//s; + my $code = substr($l,0,3); + print $v "<<< $l\n" if $v; + return ($code,$l); +} + +sub docmd ($$;$) { + my ($c,$cmd,$nocheck) = @_; + my ($code,$l); + for my $n (0,1) { + $c->putline($cmd); + ($code,$l) = $c->getline(); + if ($code eq "480") { $c->auth(); } else { last; } + } + if (!$nocheck) { + $code =~ /^2\d\d/ or die "failed on `$cmd':\n$l\n"; + } + return ($code,$l); +} + +sub auth ($) { + my ($c) = @_; + # Authentication. + return if $c->{Authed}++; + my $auth = $ENV{"NNTPAUTH"}; + if (defined $auth) { + $c->putline("AUTHINFO GENERIC $auth"); + pipe AUTHSTDIN, TOAUTH or die "unable to create pipes"; + pipe FROMAUTH, AUTHSTDOUT or die "unable to create pipes"; + flush STDOUT; + my $pid = fork; + if (!defined $pid) { + die "unable to fork for authentication helper"; + } elsif ($pid == 0) { + # we are child + $c->{V} = undef if $c->{V} eq 'STDOUT'; + $ENV{"NNTP_AUTH_FDS"} = "0.1"; + open STDIN, "<&AUTHSTDIN"; + open STDOUT, ">&AUTHSTDOUT"; + close $c->{S}; + exec $auth; + die $!; + } + # we are parent + close AUTHSTDIN; + close AUTHSTDOUT; + autoflush TOAUTH 1; + my ($code,$l) = $c->getline(); print TOAUTH "$l\n"; + while () { + s/[\r\n]*$//s; + $c->putline($_); + ($code,$l) = $c->getline(); + print TOAUTH "$l\n"; + } + die "failed authentication\n" unless $? == 0; + } +} + +1; diff --git a/scripts/nntpid b/scripts/nntpid index be961ee..e0e286a 100755 --- a/scripts/nntpid +++ b/scripts/nntpid @@ -3,33 +3,18 @@ # Originally by Simon Tatham # Modified by Richard Kettlewell, Colin Watson, Ian Jackson -require 5.002; -use Socket; -use FileHandle; +use ChiarkNNTP; -$verbose=1, shift @ARGV if $ARGV[0] eq "-v"; +our $verbose; +($verbose='STDERR', shift @ARGV) if $ARGV[0] eq "-v"; -$ns=$ENV{'NNTPSERVER'}; -if (!defined $ns or !length $ns) { - $ns = `cat /etc/nntpserver`; - chomp($ns); -} -$port = (getservbyname("nntp", "tcp"))[2]; -$ns = inet_aton($ns); -$proto = getprotobyname("tcp"); -$paddr = sockaddr_in($port, $ns); - -socket(S,PF_INET,SOCK_STREAM,$proto) or die "socket: $!"; -connect(S,$paddr) or die "connect: $!"; +my $c = cnntp_connect($verbose); +$c->banner_reader(); -S->autoflush(1); +our $code; -&getline; -$code =~ /^2\d\d/ or die "no initial greeting from server\n"; - -&docmd("MODE READER"); # some servers require a GROUP before an ARTICLE command -&docmd("GROUP misc.misc"); +$c->docmd("GROUP misc.misc"); if(@ARGV == 0) { while(<>) { @@ -49,7 +34,7 @@ if(@ARGV == 0) { } } -&docmd("QUIT"); +$c->docmd("QUIT"); close S; sub lookup { @@ -57,12 +42,12 @@ sub lookup { if($mid !~ /\@/ and $mid =~ /^(.*)[: ](\d+)$/) { my ($g, $n) = ($1, $2); - &docmd("GROUP $g"); - &docmd("ARTICLE $n"); + $c->docmd("GROUP $g"); + $c->docmd("ARTICLE $n"); } else { $mid =~ s/.*\.*//; - &docmd("ARTICLE <$mid>"); + $c->docmd("ARTICLE <$mid>"); } my $fh= 'STDOUT'; @@ -74,7 +59,7 @@ sub lookup { } while (1) { - &getline; + ($code,$_) = $c->getline(); s/[\r\n]//g; last if /^\.$/; s/^\.//; @@ -85,59 +70,3 @@ sub lookup { close $fh or die "$? $!"; } } - -sub putline { - my ($line) = @_; - print STDERR ">>> $line\n" if $verbose; - print S "$line\r\n"; -} - -sub getline { - $_ = ; - s/[\r\n]*$//s; - $code = substr($_,0,3); - print STDERR "<<< $_\n" if $verbose; -} - -sub docmd { - my ($cmd) = @_; - for my $n (0,1) { - &putline($cmd); - &getline; - if ($code eq "480") { &auth; } else { last; } - } - $code =~ /^2\d\d/ or die "failed on `$cmd':\n$_\n"; -} - -sub auth { - # Authentication. - if ($ENV{"NNTPAUTH"}) { - $auth = $ENV{"NNTPAUTH"}; - &putline("AUTHINFO GENERIC $auth"); - pipe AUTHSTDIN, TOAUTH or die "unable to create pipes"; - pipe FROMAUTH, AUTHSTDOUT or die "unable to create pipes"; - $pid = fork; - if (!defined $pid) { - die "unable to fork for authentication helper"; - } elsif ($pid == 0) { - # we are child - $ENV{"NNTP_AUTH_FDS"} = "0.1"; - open STDIN, "<&AUTHSTDIN"; - open STDOUT, ">&AUTHSTDOUT"; - close S; - exec $auth; - } - # we are parent - close AUTHSTDIN; - close AUTHSTDOUT; - autoflush TOAUTH 1; - &getline; print TOAUTH "$_\n"; - while () { - s/[\r\n]*$//s; - &putline($_); - &getline; - print TOAUTH "$_\n"; - } - die "failed authentication\n" unless $? == 0; - } -}