chiark / gitweb /
nntpid as found in chiark's /usr/local/bin/nntpid.old, apparently copied from a versi...
[chiark-utils.git] / scripts / nntpid
1 #!/usr/bin/perl
2
3 # By Simon Tatham
4
5 require 5.002;
6 use Socket;
7 use FileHandle;
8
9 $verbose=1, shift @ARGV if $ARGV[0] eq "-v";
10
11 die "usage: nntpid messageid\n" if !defined $ARGV[0];
12 $mid = $ARGV[0];
13 $mid =~ s/^<//;
14 $mid =~ s/>$//;
15 $mid = "<$mid>";
16
17 $ns=$ENV{'NNTPSERVER'};
18 if (!defined $ns or !length $ns) {
19   $ns = `cat /etc/nntpserver`;
20   chomp($ns);
21 }
22 $port = (getservbyname("nntp", "tcp"))[2];
23 $ns = inet_aton($ns);
24 $proto = getprotobyname("tcp");
25 $paddr = sockaddr_in($port, $ns);
26
27 socket(S,PF_INET,SOCK_STREAM,$proto) or die "socket: $!";
28 connect(S,$paddr) or die "connect: $!";
29
30 S->autoflush(1);
31
32 &getline;
33 $code =~ /^2\d\d/ or die "no initial greeting from server\n";
34
35 &docmd("MODE READER");
36 # some servers require a GROUP before an ARTICLE command
37 &docmd("GROUP misc.misc");
38 &docmd("ARTICLE $mid");
39 while (1) {
40   &getline;
41   s/[\r\n]//g;
42   last if /^\.$/;
43   s/^\.//;
44   print STDOUT "$_\n";
45 }
46 &docmd("QUIT");
47 close S;
48
49 sub putline {
50   my ($line) = @_;
51   print STDERR ">>> $line\n" if $verbose;
52   print S "$line\r\n";
53 }
54
55 sub getline {
56   $_ = <S>;
57   s/[\r\n]*$//s;
58   $code = substr($_,0,3);
59   print STDERR "<<< $_\n" if $verbose;
60 }
61
62 sub docmd {
63   my ($cmd) = @_;
64   while (1) {
65     &putline($cmd);
66     &getline;
67     if ($code eq "480") { &auth; } else { last; }
68   }
69   $code =~ /^2\d\d/ or die "failed on `$cmd':\n$_\n";
70 }
71
72 sub auth {
73   # Authentication.
74   if ($ENV{"NNTPAUTH"}) {
75     $auth = $ENV{"NNTPAUTH"};
76     &putline("AUTHINFO GENERIC $auth");
77     pipe AUTHSTDIN, TOAUTH or die "unable to create pipes";
78     pipe FROMAUTH, AUTHSTDOUT or die "unable to create pipes";
79     $pid = fork;
80     if (!defined $pid) {
81       die "unable to fork for authentication helper";
82     } elsif ($pid == 0) {
83       # we are child
84       $ENV{"NNTP_AUTH_FDS"} = "0.1";
85       open STDIN, "<&AUTHSTDIN";
86       open STDOUT, ">&AUTHSTDOUT";
87       close S;
88       exec $auth;
89     }
90     # we are parent
91     close AUTHSTDIN;
92     close AUTHSTDOUT;
93     autoflush TOAUTH 1;
94     &getline; print TOAUTH "$_\n";
95     while (<FROMAUTH>) {
96       s/[\r\n]*$//s;
97       &putline($_);
98       &getline;
99       print TOAUTH "$_\n";
100     }
101     die "failed authentication\n" unless $? == 0;
102   }
103 }