# infobot :: Kevin Lenzo (c) 1997 $DBformat = "lllll"; $DBprefix = 'HASH_'; if (!$filesep) { $filesep = '/'; } sub openDBM { my %newDBMS = @_; my $created = 0; my $failed = 0; if ($param{'plusplus'}) { dbmopen(%plusplus, $param{'plusplus'}, 0644) || warn "can't open plusplus db"; } foreach $d (keys %newDBMS) { next if $d =~ /^\s*$/; if (defined($DBMS{$d})) { &status("$newDBMS{$d} replaces $DBMS{$d}") unless $DBMS{$d} eq $newDBMS{$d}; } if (dbmopen(%{"$DBprefix$d"}, $newDBMS{$d}, undef)) { &status("opened $d -> $newDBMS{$d}"); $DBMS{$d} = $newDBMS{$d}; } else { if (dbmopen(%{"$DBprefix$d"}, $newDBMS{$d}, 0644)) { &status("created new db\t$d -> $newDBMS{$d}"); $DBMS{$d} = $newDBMS{$d}; $created++; my $c = 0; my $initfile = $infobot_base_dir.$filesep.$param{'miscdir'}.$filesep; $initfile .= "infobot-$d.txt"; my $dbname = $DBprefix.$d; &insertFile($initfile, $dbname); } else { &status("failed to open $d -> $newDBMS{$d}"); ++$failed; } } if ($param{sanePrefix}) { my $dbname = $DBprefix.$d; my $sane = $infobot_base_dir.$filesep.$param{'miscdir'}.$filesep.$param{sanePrefix}; $sane .= "-$d.txt"; if (-e $sane) { &status("loading sane defines $sane"); &insertFile($sane, $dbname); } else { &status("can't fine sane file $sane"); } } } return $failed; } sub insertFile { my ($factfile, $dbname) = @_; if (open(IN, $factfile)) { my ($good, $total); while() { chomp; my ($k, $v) = split(/\s*=>\s*/, $_, 2); if ($k and $v) { $$dbname{$k} = $v; $good++; } $total++; } close(IN); $dbname =~ s/^HASH_//; &status("loaded $factfile into $dbname ($good/$total good items)"); } else { $dbname =~ s/^HASH_//; &status("FAILED to load $factfile into $dbname"); } } sub closeDBM { if (@_) { foreach $d (@_) { dbmclose(%{"$DBprefix$d"}); &status("closed db $d"); } } else { &status("No dbs specified; none closed"); } if ($param{"plusplus"}) { dbmclose %plusplus; } } sub set { my ($db, $key, $val) = @_; my %dbs = %DBMS; if (!$key) { ($db, $key, $val) = split(/\s+/, $db); } # this is a hack to keep set param consistant.. overloaded if ($db eq 'param') { my $was = $param{$key}; $param{$key} = $val; return $was; } $dbname = "$DBprefix$db"; my $was = $$dbname{$key}; $$dbname{$key} = $val; #if ($param{'commitDBM'} eq 'ALWAYS') { # close and reopen the dbm file on each update. # what a pain. some implemenations commit to # disk on every update; some, however, do not. # if you don't do this on the ones that do not, # you can lose all new updates if the process # dies. # &closeDBM($db); # my $trycount = 0; # while ((++$trycount < 10) && &openDBM($db => $dbs{$db})) { # sleep 1; # } #} elsif ($param{'commitDBM'} =~ /^\d+/) { # if (!(++$strobe % $param{'commitDBM'})) { # # close and reopen the dbm file every N # # allow a refractory period. the dbm takes some time # # to close and reopen. this is safer but still # # a rather stupid way to do this. # &closeDBM($db); # my $trycount = 0; # while ((++$trycount < 10) && &openDBM($db => $dbs{$db})) { # sleep 1; # } # } #} return $was; } sub get { my ($db, $key) =@_; if (!$key) { ($db, $key) = split(/\s+/, $db); } $db = "$DBprefix$db"; return ${$db}{$key}; } sub whatdbs { my @result; foreach (keys %DBMS) { push(@result, "$_ => $DBMS{$_}"); } return @result; } sub showdb { my ($db, $regex) = @_; my @result; if (!$regex) { ($db, $regex) = split(/\s+/,$db, 2); } my @whichdbs; if (!$db) { &status("no db given"); &status("try showdb "); # @whichdbs = (keys %DBMS); } else { @whichdbs = ($db); } foreach $db (@whichdbs) { my $thedb = "$DBprefix$db"; if (!defined($DBMS{$db})) { &status("the database $db is not open."); &status("try showdb "); return(); } if (!$regex) { &status("showing all of $db"); foreach (keys %{$thedb}) { push(@result, "$_ => ${$thedb}{$_}"); } } else { &status("searching $db for /$regex/"); my $k; foreach $k (keys %{$thedb}) { my $v = $$thedb{$k}; if (($k =~ /$regex/) || ($v =~ /$regex/)) { push(@result, "$k => ${$thedb}{$k}"); } } } } return @result; } sub forget { return &clear(@_); } sub clear { my ($db, $key) =@_; if (!$key) { ($db, $key) = split(/\s+/, $db); } my $thedb = "$DBprefix$db"; &status("clearing $db->$key"); delete $$thedb{$key}; return ''; } sub getDBMKeys { my $what = $_[0]; return keys %{"$DBprefix$what"}; } sub basename { my $x = $_[0]; $x =~ s/.*\///; return $x; } 1;