#!/afs/athena/contrib/perl/p

require '/afs/sipb/contrib/perl/nntp.pl';

sub nng {
require('getopts.pl');
$field = "subject";		# grep subject lines by default
$flg = "o";			# compile pattern only once
$opp = "";			# match specified pattern

sub usage
{
    die <<"EndoUsage"
usage: $0 [-<options>] <pattern> <newsgroup> ...
    options:	-s: 		search subjects (default)
		-f: 		search from lines
		-b: 		search article bodies
		-a: 		search entire articles
		-h <field>:	search specified header field
		-i:		case insensitive search
		-v:		match inverse of pattern
		-u:		limit search to unread articles
		-r <range>:	limit search to range
		-F <newsrc>:	use alternate newsrc file
		-S <server>:	use alternate news server
EndoUsage
    ;
}

# process command line arguments
&usage if ! &Getopts('sfbah:ivur:F:S:');

# set the article header field that is to be matched
$field = "article" if $opt_a;
$field = "body" if $opt_b;
$field = $opt_h if $opt_h;
$field = "from" if $opt_f;
$field = "subject" if $opt_s;
$flg = $opt_i ? "io" : "o";

$opp = "!" if $opt_v;		# match the opposite of pattern

$opt_u = 1 if $opt_F;		# always use .newsrc if specified
$opt_F = ($ENV{"HOME"} . "/.newsrc") if ! $opt_F;

# don't let the user specify a messy range
$opt_r = &nntp'canon_artlist($opt_r) if $opt_r;

# open a connection to the news server.  program will die if bad connection
$server = $opt_S ? &nntp'connect($opt_S) : &nntp'connect;

# get the pattern to match from the command line
&usage if ! ($pattern = shift);

# make a list of each group to scan
&usage if ! @ARGV;
while ($_ = shift)
{
    push(@groups, &nntp'list($server, $_));
}
die "No groups matched.\n" if (! @groups);

if ($field !~ /body|article/)
{
    $pattern =~ s/^\^/^[0-9]+ /;	# fix pattern to match article number

    foreach $ng (@groups)
    {
	next if $opt_u && ! &nntp'newsrc_get($opt_F, $ng, 0);

	@lim = &nntp'setgroup($server, $ng);
	next if ! @lim;			# this should never ever happen

	# generate an article range list for this news group
	$rangelist = "$lim[1]-$lim[2]";
	if ($opt_u)
	{
	    # user wants to look at unread messages only
	    local ($read) = &nntp'newsrc_get($opt_F, $ng, 0);
	    $rangelist = $read && 
		&nntp'canon_inverse(&nntp'canon_artlist($read),
 				    $lim[1], $lim[2]);
	}
	# intersect with the user's specified range.
	$rangelist = &nntp'canon_isect($rangelist, $opt_r) if $opt_r;

	# now do the hard stuff
	foreach $rng (&nntp'canon_expand($rangelist))
	{
	    local ($first, $last) = split(/-/, $rng);
	    local (@lines);

	    @lines = &nntp'grepfield($server, $field,
				     "$opp/$pattern/$flg", $first, $last);
	    foreach (@lines)
	    {
		s/^([0-9]+) /$1 /;
		$returnme .= "$ng $_";
	    }
	}
    }
}
else
{
    foreach $ng (@groups)
    {
	next if $opt_u && ! &nntp'newsrc_get($opt_F, $ng, 0);

	@lim = &nntp'setgroup($server, $ng);
	next if ! @lim;		# this should never ever happen

	# generate an article range list for this news group
	$rangelist = "$lim[1]-$lim[2]";
	if ($opt_u)
	{
	    # user wants to look at unread messages only
	    local ($read) = &nntp'newsrc_get($opt_F, $ng, 0);
	    $rangelist = $read && 
		&nntp'canon_inverse(&nntp'canon_artlist($read),
 				    $lim[1], $lim[2]);
	}
	# intersect with the user's specified range.
	$rangelist = &nntp'canon_isect($rangelist, $opt_r) if $opt_r;

	# now do the hard stuff
	foreach $rng (&nntp'canon_expand($rangelist))
	{
	    local ($first, $last) = split(/-/, $rng);
	    local (@lines);

	    @lines = &nntp'greptext($server, $field, "$opp/$pattern/$flg",
				    $first, $last);
	    foreach (@lines)
	    {
		s/^([0-9]+) /$1 /;
		$returnme .= "$ng  $_";
	    }
	}
    }
}
}


($group, $article, $line)=&nng;



