#!/afs/athena/contrib/perl/p # # File: nntpgrep - search news articles for patterns # $Header: /afs/sipb/contrib/perl/nntp/RCS/nntpgrep,v 1.1 1992/09/17 04:11:50 ckclark Exp $ # # KOPYKNOT (K) 1991 Free Knoware Foundation, Ink. # # This file is part of Randall's NNTP grep-n'-fetch-it utilites. # # NNTP grep-n'-fetch-it is free software. You can redistribute it and # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation or not. That's what makes # this a Kopyknot. You can use this code for any purpose whatsoever. # If you can make a dime off it, great. I'm not out to stop you. If # you want to claim you wrote it, great. It ain't up to me to blow your # cover. Go for it. # # NNTP grep-n'-fetch-it is distributed in the hope that it will make # Randall a famous net.personality. It includes ABSOLUTELY NO WARRANTY. # In fact, you should know that this code will probably fail in lots # of different ways on lots of different machines. If you want to fix # the problems, great. If you want to tell me what you changed, great. # If you want me to fix something for you, go screw yourself. I'm busy. # # This Kopyknot was inspired by the GNU Copyleft. I think that Richard # Stallman is a mensch. If I weren't so obsessed by the almighty buck, # I'd try to get a job working for him. If you want more information on # the GNU General Public License, get GNU Emacs, or write to the Free # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # I hope you don't feel insulted by my parody, Richard. unshift(@INC, "/afs/sipb.mit.edu/contrib/perl"); unshift(@INC, "/afs/sipb.mit.edu/contrib/perl/nntp"); require('getopts.pl'); require('nntp.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: -s: search subjects (default) -f: search from lines -b: search article bodies -a: search entire articles -h : search specified header field -i: case insensitive search -v: match inverse of pattern -u: limit search to unread articles -r : limit search to range -F : use alternate newsrc file -S : 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: /; print "$ng: $_\n"; } } } } 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: /; print "$ng: $_\n"; } } } }