[comp.lang.perl] dbm and news history

richard@pegasus.com (Richard Foulk) (03/11/90)

I'm having a little trouble figuring out just how to use the dbm stuff
in perl.  Can someone give me an example of how to find an entry in
/usr/lib/news/history given the usual key (e.g. <123@xyz.UUCP>),
assuming the usual multi-megabyte history{,.pag} files?

Thanks.

-- 
Richard Foulk		richard@pegasus.com

merlyn@iwarp.intel.com (Randal Schwartz) (03/12/90)

In article <1990Mar11.130242.11596@pegasus.com>, richard@pegasus (Richard Foulk) writes:
| I'm having a little trouble figuring out just how to use the dbm stuff
| in perl.  Can someone give me an example of how to find an entry in
| /usr/lib/news/history given the usual key (e.g. <123@xyz.UUCP>),
| assuming the usual multi-megabyte history{,.pag} files?

I stole this code more-or-less from somewhere.  Sorry I don't have the
original author's name to give full credit.

################################################## snip snip
#!/usr/bin/perl

# print the appropriate line from /usr/lib/history
# usage: $0 [<]article-ID[>] ...

chdir "/r2/usr.lib.news" || # directory for /usr/lib/news
	die "Cannot chdir to /usr/lib/news ($!)";
dbmopen(HISTDB,"history",0666) ||
	die "Cannot open history.dir/pag ($!)";
open(HIST,"<history") ||
	die "Cannot open history ($!)";
for (@ARGV) {
	$_ = "<$_>" unless /^<.*>$/; # add brackets if necessary
	(warn "No such article: $_"), next
		unless defined $HISTDB{$_ . "\000"};
	seek(HIST, unpack('L', $HISTDB{$_ . "\000"}), 0);
	$_ = <HIST>;
	print;
}
################################################## snip snip

print join('',grep(s/.*"(.)".*/$1/,split(/\n/,<<)));
Gimme a "J"!
Gimme a "u"!
Gimme an "s"!
Gimme a "t"!
Gimme a " "! :-)
Gimme an "a"!
Gimme an "n"!
Gimme an "o"!
Gimme a "t"!
Gimme an "h"!
Gimme an "e"!
Gimme an "r"!
Gimme a " "! :-)
Gimme a "P"!
Gimme an "e"!
Gimme an "r"!
Gimme an "l"!
Gimme a " "! :-)
Gimme an "h"!
Gimme an "a"!
Gimme a "c"!
Gimme a "k"!
Gimme an "e"!
Gimme an "r"!
Gimme a ","! :-)
What's that spell??

-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

tchrist@convex.COM (Tom Christiansen) (03/12/90)

In article <1990Mar11.130242.11596@pegasus.com> richard@pegasus.com (Richard Foulk) writes:
>I'm having a little trouble figuring out just how to use the dbm stuff
>in perl.  Can someone give me an example of how to find an entry in
>/usr/lib/news/history given the usual key (e.g. <123@xyz.UUCP>),
>assuming the usual multi-megabyte history{,.pag} files?

This should do it -- it's out of my examples suite.

--tom

#!/usr/bin/perl
#
# xpost -- given article id's, check news history dbm file
# 	   for what newsgroups they're in.   shows how to 
#	   use associative arrays and bind them to external files.

$HIST = '/usr/local/lib/news/history';
dbmopen(HIST,$HIST,0666) || die "$0: couldn't dbmopen $HIST: $!\n";
open HIST || die "$0: couldn't open $HIST: $!\n";

foreach $key ( @ARGV ) {
    $key =~ tr/A-Z/a-z/;
    $key = "<$key>" if $key !~ /^<.*>$/;
    $key .= "\000";
    if (!defined $HIST{$key}) {
	print stderr "no article $key\n";
	next;
    } 
    ($pos) = unpack('L',$HIST{$key});
    seek(HIST,$pos,0);
    $line = <HIST>;
    print $line;
} 
--

    Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
    Convex Computer Corporation                            tchrist@convex.COM
		 "EMACS belongs in <sys/errno.h>: Editor too big!"

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/13/90)

In article <1990Mar11.130242.11596@pegasus.com> richard@pegasus.com (Richard Foulk) writes:
: I'm having a little trouble figuring out just how to use the dbm stuff
: in perl.  Can someone give me an example of how to find an entry in
: /usr/lib/news/history given the usual key (e.g. <123@xyz.UUCP>),
: assuming the usual multi-megabyte history{,.pag} files?

Two things you have to realize when accessing the history file (at least
in the news system we're currently using).

First, "<123@xyz.UUCP>" won't be found because the keys are canonicalized
to lower case:

	$key =~ y/A-Z/a-z/;

Second, "<123@xyz.uucp>" won't be found because there's a trailing null as
part of the key.  So you have to say

	$key .= "\0";

Now you should be able to say

	$data = $history{$key}.
	($loc) = unpack('l',$data);
	seek(HIST,$loc,0);
	$histline = <HIST>;
	($messid,$date,$artlist) = split(/\t/,$histline);

or some such, depending on your news system.  For a longer example see the
refetch script I posted a while back.

Larry

jwc@unify.uucp (J. William Claypool) (03/16/90)

In article <7383@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>In article <1990Mar11.130242.11596@pegasus.com> richard@pegasus.com (Richard Foulk) writes:
>: I'm having a little trouble figuring out just how to use the dbm stuff
>: in perl.  Can someone give me an example of how to find an entry in
>: /usr/lib/news/history given the usual key (e.g. <123@xyz.UUCP>),
>: assuming the usual multi-megabyte history{,.pag} files?

>or some such, depending on your news system.  For a longer example see the
>refetch script I posted a while back.

Of course, if you built cnews with dbz all bets are off.
-- 

Bill Claypool    +1 916 920 9092 | I know what I know if you know what I mean
jwc@unify.UUCP                   |--------------------------------------------
  ...!{csusac,pyramid}!unify!jwc |   SCCA SFR Solo II   74 es  1984 CRX 1.5