#!/usr/local/bin/perl
($#ARGV == 1) || die "host group\n";

$nntphost=$ARGV[0];
$group=$ARGV[1];

# METHOD.
# telnet lingua nntp or use a socket.
# read until /^200/
#($a,$b,$fist,$last)= GROUP alt.desert-storm
#XHDR From $first-$last
#
#lots of lines of the form
#$number id		clarinews@clarinet.com
#
#HEAD	gets the header - lose the first line
#BODY	gets the body   - lose the first line
#
#QUIT to exit
#each command ends with a "."

$home=$ENV{'HOME'};
$dir=".";
$count="count";
if (open(IN,"<$count"))
	{
	$oldlast=<IN>;
	close(IN);
	}

require 'sys/socket.ph';
print STDOUT "connect to $nntphost\n";
do startnntp("$nntphost");
# or use the following
# do startnntp_telnet("$nntphost");
do read_nntp_header();
($first,$last)=&group_cmd();

if ($last == $oldlast)
	{
	print "No new articles\n";
	do quit_cmd(0);
	}

$first=$oldlast+1 if ($first < ($oldlast+1));
$oldlast=$last if ($last > $oldlast);

do xhdr_cmd($first,$last);
printf STDOUT "Got %d articles\n",$#from+1;
do getfiles(@from);

if (open(OUT,">$count"))
	{
	print OUT "$oldlast\n";
	close(OUT);
	}

exit(0);

sub getfiles
	{
	local(@files)=@_;
	local(@i);

	chdir("$dir") || die "chdir:$!";
	while ($_=shift(@files))
		{
		split;
		$num=@_[0];
		open(OUT,">$num") || die "open(>$num):$!";
		@txt=&head_cmd($num);
		print OUT @txt;
		print OUT "\n";
		@i=grep(/Subject/,@txt);
		print STDOUT "$num:$i[0]";
		@txt=&body_cmd($num);
		print OUT @txt;
		print OUT "\n\n";
		close(OUT);
		}
	}

sub head_cmd
	{
	local($name)=@_;
	local(@ret);

	print NNTP "HEAD $name\n";
	$_=<NNTP>;
	if (!/^221 /)
		{
		print STDOUT "head cmd problems ($name):$_";
		do quit_cmd(1);
		}
	@ret=&getlines();	
	return(@ret);
	}

sub body_cmd
	{
	local($name)=@_;
	local(@ret);

	print NNTP "BODY $name\n";
	$_=<NNTP>;
	if (!/^222 /)
		{
		print STDOUT "body cmd problems ($name):$_";
		do quit_cmd(1);
		}
	@ret=&getlines();	
	return(@ret);
	}

sub xhdr_cmd
	{
	local($a,$b)=@_;

	print NNTP "XHDR From $a-$b\n";
	$_=<NNTP>;
	if (!/^221 /)
		{
		print STDOUT "xhdr cmd problems\n";
		if (/^500 /)
			{ do manual_xhdr_cmd($a,$b); }
		else
			{ do quit_cmd(); }
		return;
		}
	@from=&getlines();	
	}

sub manual_xhdr_cmd
	{
	local($a,$b)=@_;
	local($i,@f,$j);

	$#from=$[;
	foreach $i ($a .. $b)
		{
		print NNTP "HEAD $i\n";
		$_=<NNTP>;
		if (/^221 /)
			{
			@f=grep(/^From: /,&getlines());
			print STDOUT "no From: line in article $i\n"
				if ($#f < 0);
			$f[0] =~ /^From: (.*)/;
			push(@from,"$i $1");
			}
		else
			{
			print "$_";
			}
		}
	}

sub getlines
	{
	local(@ret);

	while (<NNTP>)
		{
		if (/^\./ && (!/^\.\./))
			{
			chop;
			last;
			}
		s/\015//g;
		push(@ret,$_);
		}
	return(@ret);
	}

sub quit_cmd
	{
	local($code)=@_;
	print NNTP "QUIT\n";
	$_=<NNTP>;
	print STDOUT "close bad:$_" unless (/^205 /);
	exit($code);
	}

sub group_cmd
	{
	print NNTP "GROUP $group\n";
	$_=<NNTP>;

	split;
	($code,$num,$first,$last,$group)=@_;
	if ($code != 211)
		{
		print STDOUT "group cmd problems:$_";
		do quit_cmd(1);
		}
	return($first,$last);
	}

sub dokill
	{
	kill(9,$child) if $child;
	}

sub startnntp
	{
	local($name)=@_;

	$SIG{'INT'}='dokill';

	$sockaddr='Sna4x8';
	chop($hostname=`hostname`);

	($n,$aliases,$proto)=getprotobyname('tcp');
	($n,$aliases,$port)=getservbyname('nntp','tcp');
	($n,$aliases,$type,$len,$thisaddr)=gethostbyname($hostname);
	($n,$aliases,$type,$len,$thataddr)=gethostbyname($name);
	$this=pack($sockaddr,&AF_INET,0,$thisaddr);
	$that=pack($sockaddr,&AF_INET,$port,$thataddr);

	socket(NNTP,&PF_INET,&SOCK_STREAM,$proto) || die "socket: $!";
	bind(NNTP,$this) || die "bind: $!";
	connect(NNTP,$that) || die "connect: $!";

	select(NNTP); $|=1;
	select(STDIN); $|=1;
	select(STDOUT); $|=1;
	}

sub startnntp_telnet
	{
	local($name)=@_;

	pipe(RNNTP,TO_NNTP) || die "pipe $!";
	pipe(FROM_NNTP,WNNTP) || die "pipe $!";
	select(STDIN); $|=1;
	select(STDOUT); $|=1;
	select(FROM_NNTP); $|=1;
	select(TO_NNTP); $|=1;
	select(RNNTP); $|=1;
	select(WNNTP); $|=1;
	return if ($pid=fork);

	open(STDIN,"+<&RNNTP") || die "cannont dup nntp read $!\n";
	close(RNNTP);
	open(STDOUT,"+>&WNNTP") || die "cannont dup nntp write $!\n";
	close(WNNTP);
	select(STDOUT); $|=1;
	select(STDIN); $|=1;

	exec("/usr/ucb/telnet","$name","nntp");
#	exec("/bin/cat","/user0/eay/.profile");
	die("bad exec $!");
	exit(0);
	}

sub read_nntp_header
	{
	while (<NNTP>)
		{
		last if (/^200 /);
		last if (/^201 /);
		exit(1) if (/^400 /);
		}
	}
